|
- ;[FC音乐][MMC5 IRQ]# R1 S0 g) [$ W) y3 m6 K
- ;FlameCyclone 20230710* Z4 R* Y% J! l ?, b# u7 F
- , ^4 B a- F4 A- n
- ;文件头
$ q) t: S% u0 d1 T! B/ e/ h5 d$ u - ;======================================================================
; h* R0 Y) T' d5 W4 j - .INESPRG 4 ;16KB PRG 数量
1 _: A9 z6 }$ |+ \ - .INESCHR 1 ;8KB CHR 数量; J1 P( B, P$ w6 o" V- t, m o
- .INESMAP 5 ;mapper 5
3 ]/ n( q+ p$ J - .INESMIR 1 ;命名表镜像 0水平 1垂直3 e/ ~8 k8 M( J- u3 ~& a
- * T8 |% e( ~: B7 H3 a2 F1 w3 n
- ;必要条件
) M$ t( |% m% F' f7 F3 m: r q - ;1.持有CHR ROM
Q; n( G& U+ f" H1 B/ t- v) c - ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$10000 {' J8 E: J7 ]& n: e
- ;3.精灵内存(OAM)不为空
, R+ I3 s, x5 ]; B9 ]3 a - & M2 m+ u2 }% o" X
- ;==================================================; P; |3 P9 P8 S
- ;NES端口常量
2 G* O* ~9 g; s0 I3 [5 R - PPU_CTRL = $2000 ;PPU控制寄存器
1 s$ c. F- I0 D8 Q/ i8 z4 l; V5 E - PPU_MASK = $2001 ;PPU掩码寄存器! I& H+ a7 t, c
- PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
" T" Z! Q" t# Y4 \5 X - PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
% c$ U3 Y! Q! M* P( ~* N4 { - PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加18 y' B0 q7 C" U0 V( j
- PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 $ K. L( R: a" Q; l
- PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加. \% u: X z+ P0 K/ j K, b" G
- PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
/ b8 g( V+ F2 \( G' |4 ~/ z0 _ d - OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存' q0 h$ X4 \# L# ]1 n% r
- APU_STATUS = $4015 ;声音通道切换 ^: L. ]! R$ q, o# Z1 `: {
- JOY1_FRAME = $4016 ;手柄1 + 选通
5 H4 G3 Q% B* n/ ] - JOY2_FRAME = $4017 ;手柄2 + 选通( S" s" r( L& q! p
/ H8 B2 T3 V: o( k- ;==================================================
( u5 A1 z, }) y( o0 W) Y+ l/ k( ~ - ;MMC5端口常量
/ @; O/ S5 q( l8 e6 G' N! I' A - MMC5_PRG_MODE = $5100; 0: 32KB 1: 16KB * 2 2: 16KB + 8 * 2 3: 8*4
% Q4 R3 O; Q& k# V4 Q; v5 w - MMC5_CHR_MODE = $5101; 0: 8KB 1: 4KB * 2 2: 2KB * 4 3: 1KB * 8( ~' o; }/ W, @! x+ R
- MMC5_PRG_RAM_PROTECT_1 = $5102;
) E- q. z# b% U4 _7 o" s. T - MMC5_PRG_RAM_PROTECT_2 = $5103;
* f) K* y3 }' t8 Q3 `6 R0 z - MMC5_EX_RAM_MODE = $5104; 0: Write Only 1: Write Only 2: RW 3:R1 b, q# c6 g- T! B i- C, T; w& d8 L
- MMC5_NT_MAPPING = $5105;
! H! z. n$ k1 |' ] - MMC5_FILL_MODE_TILE = $5106" s9 `4 G. p$ H6 D8 a% X
- MMC5_FILL_MODE_COLOR = $5107
, ^5 @, q2 f" X% ^) E - ; @) a7 c1 ?2 \ r
- MMC5_PRG_BANK_6000 = $5113
. a5 F# f6 a6 |' x# v- a6 x - MMC5_PRG_BANK_8000 = $5114! g" _( [$ U. h* i
- MMC5_PRG_BANK_A000 = $5115
1 ], @* b$ X& b1 ~ - MMC5_PRG_BANK_C000 = $5116# ^) A/ p# }! M
- MMC5_PRG_BANK_E000 = $5117; j" B# \. h9 }
-
7 X) f$ ]# v; z" a% u* S/ v' D. } - MMC5_CHR_BANK_0000 = $5120
4 w3 }% g( q5 C) s9 q [ - MMC5_CHR_BANK_0400 = $5121
5 o* R, j$ ]! l - MMC5_CHR_BANK_0800 = $5122
' g, S E0 K1 D6 I& \/ C5 q8 W - MMC5_CHR_BANK_0C00 = $5123
; y5 c# j" n: c- s& f& g% ] - MMC5_CHR_BANK_1000 = $5124
9 s/ g7 D" E! H$ L# n- o8 o7 p - MMC5_CHR_BANK_1400 = $5125
7 G# Q% K K8 d2 h- B) b - MMC5_CHR_BANK_1800 = $51267 p v* v; T1 E$ X9 C
- MMC5_CHR_BANK_1C00 = $5127
. h6 S" O" m! L8 J7 ` - ! ^3 i( a$ H* j- g1 h
- MMC5_CHR_BANK_0000_1000 = $5128
6 \$ ^% F2 }. O$ s0 E, x6 g - MMC5_CHR_BANK_0400_1400 = $5129
1 J* k5 n; G# s& E h: Y! a - MMC5_CHR_BANK_0800_1800 = $512A7 B, X& n) ~- E( |
- MMC5_CHR_BANK_0C00_1C00 = $512B
, @5 u# [* c; l4 U - 4 f1 o5 z0 ?3 M7 S4 C5 h+ y: m
- MMC5_CHR_BANK_UPPER = $5130% P' B9 i- E+ A1 I! D; }, q, p
- MMC5_V_SPLIT_MODE = $5200
7 }1 Y: }0 v; l; A# P - MMC5_V_SPLIT_SCROLL = $5201
, d( R8 v* i1 V( T( y- G - MMC5_V_SPLIT_BANK = $5202- i* r& W) X, a* f2 Q4 L
-
( e+ f: W! h6 ^* P% |; L - MMC5_IRQ_SCAN_CMP = $5203 Q @% X* _1 y! r- ], Q9 V( K
- MMC5_IRQ_STATUS = $52045 p2 \4 A/ [# q; q+ Z; }
- MMC5_MULTIPLIER_A = $5205
- E; U. |+ e+ U/ B0 p( P - MMC5_MULTIPLIER_B = $5206$ ^" P" t% ^/ `$ X0 j4 H& \& S/ A
-
# p+ m5 w5 q0 r - MMC5A_CL3_SL3_DATA = $5207
% _3 N$ V% r% t! w5 |; d E u5 y - MMC5A_CL3_SL3_STATUS = $5208; m7 t+ T) B% _0 `. r
- MMC5A_IRQ_TIMER_LSB = $5209
% s( Y. b; D' z5 d3 l - MMC5A_IRQ_TIMER_MSB = $520A5 a6 _/ f2 _: ^3 S K' D* O
- 2 f* Y1 I T; V: E
- ;==================================================! V, e! _+ I7 e9 N6 L! P
- ;程序块配置7 A1 |+ d5 }% u$ W: c
- BANK_DATA_MASK = $07: E& ^# B! `7 K+ O$ n3 p
- ;--------------------------------------------------7 b& f- O. o* q# b
- RESET_BANK = $070 |7 F/ e L/ {6 T/ Z: q5 w
- RESET_ADDR = $FC00* p6 n3 \! w$ n' z' Q+ x5 Q
- 7 p3 [" k. K8 B) D/ D8 c
- ;==================================================
% I" b' R8 G. _- j% G - ;图像块配置
5 Q+ k3 k9 k! p% z3 Q+ G1 y# g - CHR_DATA_BANK = $08$ t, b6 g, q! \
N6 \5 u+ F$ d$ j4 d- ;==================================================' |- `4 R& U/ D: p( B2 p: i
- ;零页内存地址配置
$ b0 V: o" k" O6 ?3 p( n& q9 ~ - Use_Ram_Addr = $80( E- x" g6 w h( ~" i$ g+ A
- PPU_Ctrl_Buf = Use_Ram_Addr7 F6 ~5 p0 P7 P( Y6 U
- PPU_Msak_Buf = PPU_Ctrl_Buf + $01
& n& o8 ?, h7 E+ a - PPU_Scroll_H = PPU_Msak_Buf + $01
+ v8 d, X& {, C% {% |. b; F - PPU_Scroll_V = PPU_Scroll_H + $01) G8 s& y2 r m* [) ?
- FC_Data_L = PPU_Scroll_V + $01# V, T. _( P: ~# F
- FC_Data_H = FC_Data_L + $01- W7 E! a9 M! I
- FC_Data_Buf = FC_Data_H + $01, x$ o) _2 t( [, ~
- ;==================================================, @- m5 I* B0 s& f/ T t- P8 `
/ D: G8 F, ^* [, i8 W- GAMEPAD_MERGE_FLAG = $04" @4 p$ y U( S) P3 f
- * @4 j0 p0 L/ n; s7 p# o
- Gamepad_Keep = FC_Data_Buf + 13 p, v5 K7 h" y5 K8 g* o$ l
- Gamepad_Once = Gamepad_Keep + 2
: T8 i' q0 {9 d* K5 g1 V - Gamepad_Temp = Gamepad_Once + 2
/ v9 N1 v- G) n0 H- | - ! W2 g: A2 {3 q" L: e0 a
- Gamepad_0_State = Gamepad_Temp + 2" t1 J. ~: H5 i/ ~( W/ ]/ o+ G! Q. @
- Gamepad_1_State = Gamepad_0_State + 1
3 h5 a" r o. G! f - Gamepad_0_Value = Gamepad_1_State + 1
' X' ~ a, X2 x5 Y R0 J - Gamepad_1_Value = Gamepad_0_Value + 1
: b3 b" {8 v5 |0 {1 v2 G5 G. d - Gamepad_Port_Value = Gamepad_1_Value + 1
* I0 x1 H6 e8 s7 }1 P o0 P: U - Gamepad_Merge = Gamepad_Port_Value + 1
% A8 l; q5 \ N3 `5 l. G) p
3 z# r9 c. q4 f9 p! L' P$ H$ E- ;==================================================* v% M3 X% X: _. k f: W
- IRQ_Index = Gamepad_Merge + $01
" S" X; W1 ]# F0 P - ;==================================================- G6 Y( _' j1 T& ?$ u
- " n' j- Z+ {- \* W2 @: | [
- ;CHR图形数据5 |6 x! T' T- \9 O3 U2 ?2 W
- ;==================================================& O3 X- }+ `7 W3 ?; |
- .BANK CHR_DATA_BANK
5 P( T; Z! c& ^6 r& A - .INCBIN "chr_bank/chr_data.chr"
3 ]- X0 B8 y* `, }) _" }- o -
5 H0 n0 n9 ?% k8 [- S7 Z - .BANK RESET_BANK & BANK_DATA_MASK" j0 d8 h- H- `* d' y
- .ORG RESET_ADDR
, [/ K3 M6 G9 a* O1 p5 c! s -
# T) |! u: {, \6 J1 f. n - ;--------------------------------------------------! F N: }2 G5 W& s8 n
- Attributes_Data; z. g0 B- T9 {6 b7 k; m
- ;命名表属性
( t* k8 |5 m A: T; P7 v: g - .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00/ o# P5 Y/ I" G j$ m
- .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA1 D9 ^$ h0 u& M% v. G4 s ]) o; o
- .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA& n2 `( y4 L) w; t; V( `6 e8 B
- .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55+ m0 b; e: O) n0 o% t: Y# g
- ;--------------------------------------------------: t$ z+ o" `9 R
- ;调色板数据; T x4 n6 ^1 ~1 @& \7 c, h
- Palette_Data0 s+ m @; s/ l' N- E" S+ E
- .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F& M7 g8 o8 l* Y/ N
- .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F- r* W; F1 K% v+ w2 `. _1 Y+ [
- 2 s- g' I% A M5 G5 x
- ;==================================================
. u- a' q& [: w. { G8 t - ;命名表初始化
& L8 f8 l. t- L0 U - Init_Name_Table
f; \' T* M J! f9 I, m u - LDA #$20
0 q6 M( l( H" V# e! Q - STA PPU_ADDRESS) O9 _7 g" Y: f. P; m9 i
- LDA #$005 G! w/ i5 o9 l! h$ J9 x* f8 w
- STA PPU_ADDRESS
3 ^% [) f7 [! d1 M: I) m5 N2 R% M. n- t - LDA #$00
4 B+ ?4 [( E) S5 n - LDY #$00" [$ l0 W y) c6 }4 W2 g7 E
- LDX #$10. F: y; i% P6 r% C
- Init_Name_Table_Write
9 v' x7 ~4 r2 e* g6 n2 k C5 Q - STA PPU_DATA1 d7 J7 t* o' e! i6 L8 G
- INY
% `; Y$ }* q: N) A - BNE Init_Name_Table_Write+ i( P- D- f8 d5 k% l* i
- DEX
! D' |$ j; S0 o, l- h' c6 ^ - BNE Init_Name_Table_Write
, A! X% x4 I2 W& D" ?8 C - RTS
# b2 S+ t& Q H) Q2 }: n - - {2 u) [2 i9 \$ M) y
- ;==================================================- l/ \2 l5 t$ R. f
- ;调色板初始化 [: C# S7 ^& @( i3 \
- Init_Palette8 N* V/ |+ t2 }9 Y7 q$ }4 I
- BIT PPU_STATUS
) ]8 e9 U& J% S9 X - LDA #$3F
9 q& n* P6 b4 g4 n, p& x' q - STA PPU_ADDRESS) O: j3 `. O/ z1 Z
- LDA #$00
- K+ g; t- R w1 P' q - STA PPU_ADDRESS
' ?& V8 |) C9 a1 I - LDX #$00, a+ W! _! C; z5 B( C' t" e
- Init_Palette_Write
* f& m8 z- W/ i) S$ n" \' m - LDA Palette_Data,X, T# \- V) b' z! `
- STA PPU_DATA
0 e( P5 t4 t2 i( C9 x& k* ]+ ~ - INX2 V! Z; I, c6 C7 I
- CPX #$205 F* r0 t s3 w- [% Z7 _
- BCC Init_Palette_Write
) i+ `8 z, c6 n/ ~+ ? - RTS7 l) T0 h/ d& n/ ]& f$ w
-
4 q. Q S8 o) g1 T - ;==================================================0 _5 F( @: a1 X9 e& j+ [
- ;设置命名表属性
3 ?# V* K! a$ m - Init_NameTable_Attributes. i3 [1 O+ n9 p5 F
- BIT PPU_STATUS
5 D, O# T1 q, A1 N - LDA #$23. H8 A( L! X& g/ G+ }$ y( D
- STA PPU_ADDRESS6 V8 L/ [1 g* U5 l% w5 v
- LDA #$C0# S/ y4 c* H! L) B. e
- STA PPU_ADDRESS3 G9 y" O8 U: l0 n' N4 u
- LDX #$00
, I$ U# N# E( ^/ b2 T, w - Init_NameTable_Attributes_Write
/ K2 x- u& F( Z y - LDA Attributes_Data,X: O# z) f p/ D h
- STA PPU_DATA
x( v: h5 X! A* H7 v* }- ~' Y - INX' D3 R+ M& i5 I6 j2 z2 T5 L( I! f' [# }
- CPX #$40
3 [0 x* [! @4 ~- ?2 N _ - BCC Init_NameTable_Attributes_Write. D" J% l# |) h4 T1 s1 ^& n
- RTS* c% E1 J2 L9 R* O4 U
2 c) _* d7 `/ a+ p* {- x- ;==================================================; c, D! e8 q7 r+ s" D% }
- ;初始化命名表文本* Q9 p; U' U* s- p" P6 A7 n: E
- Init_Name_Table_Text
4 ~4 T% z2 ~) {1 o' S% j; C1 j# E - BIT PPU_STATUS- J6 @* Q7 C2 ?, }- X/ v
- LDA #$20
+ u) W0 l+ m1 c7 S! a" _' T+ K - STA PPU_ADDRESS. d3 g+ c$ x& K; K* k
- LDA #$00
# a) L5 x) N1 u2 k- k - STA PPU_ADDRESS: C3 W. F1 r7 v1 j* x0 M0 @& j
- LDA #$00( P: U( @* j- I M% ]3 T4 S
- STA FC_Data_Buf' E( k8 ] t2 c; b" B
- LDY #304 _6 L7 ?+ p. x: H8 V6 ~
- Init_Name_Table_Text_Write
/ z5 A( {9 J. q) H - LDX #32
5 ~$ ?) u5 G8 |% B$ p7 O0 L - Init_Name_Table_Text_Write_Char
% z4 H2 @( ?1 Z: v1 q# t5 a4 F# l# q - LDA #'0'
& y" C0 n, p( f6 W6 J/ H" O/ r - CLC/ b5 H+ c: E9 h8 R: M* M9 ~
- ADC FC_Data_Buf8 S8 d+ D- E6 v" m
- STA PPU_DATA |7 y3 y3 S8 ~! @/ l
- DEX% C; D! X1 b( [0 w! I/ J& r
- LDA #$14
5 {! [1 L1 V5 d4 t& @ - STA PPU_DATA
7 ]( L9 Z1 {+ P( P - DEX/ ^; t1 ~) u& S3 K
- BNE Init_Name_Table_Text_Write_Char
0 F$ z1 t2 J+ r: k - INC FC_Data_Buf
# }6 B! ^7 E. s1 k% t* g - DEY( d9 v, a8 V- O7 i @. l+ f' K8 [
- BNE Init_Name_Table_Text_Write
7 t$ d8 n* v9 _% s& P: ?- c - RTS9 H9 f" d4 b- _0 I, ^( |5 o T. B
- , X7 k7 l+ a0 D
- ;==============================2 @, @0 s! v" m; L3 v r1 d
- Init_OAM_Ram;初始化精灵内存+ T6 ^0 q+ X/ }
- LDX #$00
& I+ R. l; d. i7 a& N, n8 Q - LDA #$00/ S: Y7 D. N! c- `: z
- STA PPU_OAM_ADDR
/ \6 `$ {1 w3 p* U; y, ~5 @3 Q - LDA #$F8
3 L, J( }7 G# L - Init_OAM_Ram_Write
+ q3 s/ W. R" ?7 A( U: J4 m9 c1 G - STA PPU_OAM_DATA2 N( ~. l: B- J: T4 z. |4 H% S; [
- INX+ \+ R0 l9 F& m1 x
- BNE Init_OAM_Ram_Write
: B, d- @% p, @# \% o4 k - RTS& R, V4 B: u2 x2 y8 n6 M2 z% c
- 6 b* H4 i$ _ k4 i
- GamepadProcess;手柄处理
, O* e( t0 F+ r Q/ _- `1 o8 ?- G) D - JSR GamepadDatacan
r, K6 T- Z9 X% D - LDA <Gamepad_0_Value! i- K& V H8 b) Q& V3 q3 G
- STA <Gamepad_0_State1 G/ ^% p$ v2 [8 ?8 p3 S) x2 {
- LDA <Gamepad_1_Value- F3 W; i0 ?3 }
- STA <Gamepad_1_State- J9 d ?- D1 C7 t5 i9 I
- JSR GamepadDatacan) a, l+ t: i' {
- LDX #$01, @* f! W& y& A3 t2 ^2 w) \0 S# _6 t
- GamepadMergeCheck;合并手柄输入检查
- h. r( [% d; o) V: a% g; U - LDA <Gamepad_0_Value,X
- _. p( @0 K6 h% x; i( F# I - CMP <Gamepad_0_State,X1 a: J! o h- V3 E# s
- BEQ GamepadMergeInput
8 g0 `4 |: z$ Z+ Q) _ - LDA <Gamepad_Temp,X
! K0 h: k5 ?1 K: n - STA <Gamepad_0_Value,X
( \, G! G' _. S4 O* F# E - GamepadMergeInput;合并手柄输入! C9 s; }+ l; h4 _( {
- DEX2 V* b8 E+ T8 N+ v
- BPL GamepadMergeCheck) t% C F) N" [' t, i2 h
- LDA <Gamepad_Merge
# j6 L, K+ T: m8 ?! G! D9 H - AND #GAMEPAD_MERGE_FLAG
. v+ q3 L5 T! C& d) Y/ |' c0 P l9 m - BNE GamepadStateProcess
& W$ E. n/ B1 i! F f - LDA <Gamepad_0_Value
. D* N0 A7 v% Q - ORA <Gamepad_1_Value
' B' t7 s( w' k/ w, [) f - STA <Gamepad_0_Value4 {) z4 o4 c6 ~& @3 d) k
- GamepadStateProcess;手柄状态处理
! G/ A! B9 ^' Z* z - LDX #$01
: N) ^6 z. Y* H. w+ ~ - GamepadStateSave;手柄状态保存1 \) I9 W: q, B9 z+ t4 T4 r6 C" W6 C, \
- LDA <Gamepad_0_Value,X
% t% d, v1 @+ c( y+ e+ G8 @ - TAY& m' i6 u4 t/ M3 J
- EOR <Gamepad_Temp,X
3 A$ x; {0 W* j - AND <Gamepad_0_Value,X a6 l/ Q, [- f7 w7 k
- STA <Gamepad_Once,X8 x9 j9 Y" d! w+ l) O
- STY <Gamepad_Keep,X
6 u% D; o/ n- N T! t K6 I - STY <Gamepad_Temp,X- P' i6 l; s- ^9 j4 G9 L: @- N. Y/ o. a2 q
- DEX0 B5 u% w* ^8 P5 _5 y- }3 E
- BPL GamepadStateSave2 F0 ^% j( g' @+ f% F5 i) r$ u# e
- RTS4 \7 k7 Y# S' t. |: I) S5 H: I) `( x1 n
7 H0 C+ |7 z, D- GamepadDatacan;手柄数据扫描8 u1 i$ s) S% t5 Q/ _ I
- LDX #$011 D4 W+ a' I5 [# b4 }
- STX $4016# e3 n; Y8 y# W0 l* G
- DEX
" e, U0 n8 b7 A- J; w' G7 v - STX $4016! p3 r1 I5 Z% t% j5 U- l% L: W
- LDY #$08* w u9 I8 y5 f4 R8 j& q
- GamepadPortScan;手柄端口扫描
" ~! F2 D b+ C - LDA $4016
. s0 Q3 O. [( q; d% b( _ - STA <Gamepad_Port_Value. S* C! }* N0 X- K6 D
- LSR A" E8 A- @- s- C1 a
- ORA <Gamepad_Port_Value
, P- w5 d' q5 a \2 q! S# A. G3 m - LSR A
/ W8 Z, o- }1 _ - ROL <Gamepad_0_Value2 _4 z- m, z$ c, H& D; D1 F4 J/ D
- LDA $4017
`* Y3 i' j- R- R- ^/ e0 R6 l - STA <Gamepad_Port_Value
& R2 M: I7 u3 p7 O - LSR A+ O2 I5 H3 p o/ c1 `
- ORA <Gamepad_Port_Value3 I6 l9 w( L9 G* x x5 y1 O8 I6 c* I
- LSR A
, B1 @% i+ y: V1 w/ H4 g# _. C - ROL <Gamepad_1_Value
8 H! A, b3 u" j! D( R7 D+ g8 L - DEY5 C$ i& F, N2 y2 H1 U3 p! z
- BNE GamepadPortScan
) V8 p7 W ]$ T* A - RTS& @( [( H' I4 L0 |
-
0 z. v( S8 {9 a - ;==================================================
% v3 D/ Y7 } a! E - ;PPU处理
" C' |+ g* e' _: ]: }# [ - PPU_Process
- ~* I! m2 `( y$ s( F& B0 A# P% d- U - LDA #$000 d. _' N" g/ q6 R
- STA PPU_MASK4 P h6 e9 P0 Q: p4 _9 E' B
-
! C! c+ j% @% |7 y) r - BIT PPU_STATUS
4 ~, R6 ~( r7 y6 C8 c - LDA #$20- {( ^3 R/ |" e
- STA PPU_ADDRESS1 j. ^+ X& a0 l/ u
- LDA #$00
) x( F/ {9 W+ s - STA PPU_ADDRESS
+ Z% c5 f! Q e" p! j9 _ - # \" T' H4 f! K9 S( v8 u* F
- STA PPU_SCROLL! S1 B0 x: o" d8 ^1 _
- STA PPU_SCROLL' E6 a3 n# Y8 c5 F
- I, ]. [4 h+ G- R9 J
- LDA PPU_Msak_Buf
5 s: F( O: i' q4 z) X! A# Y - STA PPU_MASK
. S5 j3 W" t0 k - ( Q$ {1 p# v9 p. _: R; z9 n
- RTS1 ^' x( s! G/ u1 Y) X
- * ^9 X: n4 K- T& d% ^/ Q
- ;==============================
( d6 k. D3 L8 O1 } - Time_For_Vblank;延时等待) W% H) ]& {/ N! d& G$ k- c
- LDA PPU_STATUS
$ X$ N4 G4 i Q) u - BPL Time_For_Vblank
! B* ?# [2 o& ?. j - RTS
* y& [9 D1 _1 _! d - $ w) t: `% ?# k: u; [
- ;==================================================% {5 W( |# N" H& u; g8 c; k
- ;初始化MMC5
. Q# ]. i3 r! U. N' M" j' F - Init_MMC5
( V6 C* J3 a8 s6 f - ! Q: _( r" I# D6 t8 H U$ X
- ;设置一下6000-7FFF的RAM
1 g8 i d$ L, Z- t: s2 G1 ` - LDA #$00
3 u1 K0 n ?6 ^6 G - STA MMC5_PRG_BANK_6000' _. l/ a! F4 S0 D3 k& u1 P
- % X$ _7 Z7 u* @3 b: |
- ;开启 PRG RAM 写入" u8 c* A f- ]+ ^" B" Z
- LDA #$02/ b6 F( o- Q% k& m9 ]4 g. R
- STA MMC5_PRG_RAM_PROTECT_1: x" y( g4 ^7 S, M
- LDA #$01. M- M5 |7 \& J/ @4 t; H: f
- STA MMC5_PRG_RAM_PROTECT_2( d5 C1 U% S# [3 l
- ' W0 V6 i/ V8 [7 n+ Y+ s- g. W+ c
- ;启用 1KB 扩展RAM ($5C00-$5FFF)# K) J/ G3 Y1 V8 H7 r& P
- LDA #$02
7 R* G& f. I, [4 w) e" v, x - STA MMC5_EX_RAM_MODE/ w2 X; z6 I7 o: i& t. }$ {
-
5 i3 \7 ?' O! S5 b5 l) _' X - ;设置 CHR k/ m* J5 q% {0 d: |! v7 }- }7 u
- LDA #$00
+ T9 z% ~* @3 G) X7 D+ d$ o - STA MMC5_CHR_BANK_0000
0 [2 m; X) g7 B! m& a6 \7 U. M - LDA #$01
9 s+ |# m! U4 J+ t2 ^0 F" `* p2 Y - STA MMC5_CHR_BANK_04007 F( h! x1 A/ W6 h$ E' W
- LDA #$02
5 w7 q. S* J4 u+ E. y - STA MMC5_CHR_BANK_0800
' t, q/ K( o. C( d+ ]! l4 e - LDA #$03
: y3 P. u9 P+ d, X/ v% H) o' O - STA MMC5_CHR_BANK_0C00
! j b; M; j$ J! ]7 v - LDA #$04! {5 q# k; h& @! z% }4 w A: c
- STA MMC5_CHR_BANK_1000
% L1 M: y- |. a% A3 p8 \ - LDA #$05
' c0 ^+ v5 D2 u& \, U6 f& J' H' c& S - STA MMC5_CHR_BANK_1400$ v3 R8 F2 k/ `3 k
- LDA #$064 V- f8 V: d# c, E3 H: z8 a4 ]
- STA MMC5_CHR_BANK_1800
/ a9 [& e) z) d3 G - LDA #$07
7 [, P( F# B% l' a - STA MMC5_CHR_BANK_1C00, T7 f4 s9 J! L8 U* P
-
3 r. L: w1 A$ b+ i/ i* c7 | - ;设置屏幕镜像 c) J# y1 m0 E, ^: Y7 T
- LDA #$50+ }* {! p5 U6 W" l
- STA MMC5_NT_MAPPING
4 Y8 T! o( w) D% x: e - + a. j/ y+ k. D' o/ P6 _
- ;禁用IRQ* N1 z0 b) _& w7 c8 O$ m
- LDA #$00( O5 P; g. @/ y7 i! x
- STA MMC5_IRQ_SCAN_CMP
1 C) d5 Q) M& J) d6 d, A - STA MMC5_IRQ_STATUS" `- | @6 U3 P z8 F
- ' L# H# O6 ~/ ~% n5 N% o& n
- RTS! T! G% d! D0 h% G) @
- 3 h- e% R4 m" y& m o: d/ L
- ;==================================================# y# o; K, @. Q W. h4 }2 R4 ]
- ;重置中断处理
0 N' q# V5 w4 I. _ - ResetProgram7 w m8 s6 w8 {2 k( D" x5 h
- SEI4 M# Y& _! r6 j. L/ c3 d% E
- CLD& I5 [: ^3 @- x4 s. T4 }" K) Y# R
- LDA #$00
. K8 P+ q4 G; q$ U; e- z. L - STA PPU_CTRL' f8 ]/ S1 _& V' k0 c
- STA PPU_MASK
4 }4 g4 {1 ]! p - STA PPU_STATUS
) D; N) T) L7 K8 ?, m# a; B) X - STA JOY2_FRAME4 }: i# E6 p5 m" A' l- W) K
- STA APU_STATUS
' p& N4 X( @' J -
1 n9 l# P- ?: q' m9 s0 y - LDA #$C0
5 a8 x7 P/ P3 s2 L) k: \+ D9 y - STA JOY2_FRAME5 u9 N6 Q! p U3 y" j G" `
- 1 P8 v2 f& y8 I6 E) j3 ?' F
- ;等待vblank% @ ~; s4 M/ k$ N
- LDX #$02
5 O0 C4 J# |3 M6 m - Vblank_Wait_1
# i" s" l" f2 f, t9 _ - BIT PPU_STATUS) w/ _% l3 Y! ?; j* L" H3 G
- BPL Vblank_Wait_1
% B, M9 O( g3 O* q8 G$ P! [ - Vblank_Wait_2/ W6 j1 a% n2 {- D2 O( q& j5 b7 `
- BIT PPU_STATUS
! o! t& \: e" r8 y - BMI Vblank_Wait_2* w! K4 P; b' H/ O, B4 |- H Q
- DEX
* B6 {0 h& @& r0 ~! n; \ - BNE Vblank_Wait_1) I& U. V. i# F8 z: l: g
- 4 C3 n4 w: l) t# O
- LDX #$FF
- \% s. o: A" o - TXS
1 V3 w; P' X9 B+ u( N: ]% Q! j" u5 k -
6 i3 ~: D1 z E" c - ;初始化MMC57 o7 B/ N, }/ \1 L0 k8 R! B% a% w
- JSR Init_MMC5
4 z# A/ C$ n! | - & |! H- [' s9 h1 ~+ m( p
- ;==============================* j0 M/ c7 r% u8 V
- ;RAM初始化9 D# g3 G2 D4 g. w1 L4 q% H, S8 L
- Nes_Ram_Init9 X3 p, l. I! V+ G! Y3 y# _
- LDY #$00* N& L8 Q7 o) w& P' d, \8 y; g
- LDX #$08
/ ^, h0 g8 J6 k( P- g8 M# ]+ o - LDA #$00# b: e% y% W: I2 w }, [. U4 K2 \
- STA <$00- P5 i, x/ \; c4 _+ y6 ^: Z6 f
- STA <$016 ^$ e4 e# M/ W+ I) B# S/ F% T: z! A* T
- Nes_Ram_Init_Write3 M3 A5 n' e4 `0 w: D
- STA [$00],Y/ S+ U o" |" Y5 _/ ~1 _
- INY
7 \- \( K' N Z& b - BNE Nes_Ram_Init_Write
8 c" U+ q, I9 `0 Q2 O - INC <$01
) U9 {. A: T3 |5 F6 a - DEX
% ?' W& H8 t, d - BNE Nes_Ram_Init_Write
% i( L5 ]* i; R# ?. p8 ^ -
# H1 E, y( }: V: C% X# @6 g - ;初始化命名表
" }+ l+ _( R! N - JSR Init_Name_Table- i# H* T+ E& m8 {7 c/ {
-
- a3 b: C1 S+ j3 Y9 l% Z- y# ^, \2 x - ;初始化调色板
; m- x# W F" z% n - JSR Init_Palette
% i* u1 _2 r( |7 u( F& N$ [" Y: n6 y - * j3 U8 @6 u# G6 m0 [8 n
- ;初始化命名表属性% o3 I2 @. b) A p
- JSR Init_NameTable_Attributes
$ J3 _ n% U2 B5 i9 R1 Z1 D -
9 m2 g( I% J3 w/ l - ;初始化精灵内存
. K3 X% ^: }5 i" t; `, W - JSR Init_OAM_Ram
- g; j! D8 b; ^' E) c - ) F7 Q8 T1 T( q) V$ R+ z- D( v
- ;在屏幕上写点东西+ F* @$ A0 X; [8 d$ a
- JSR Init_Name_Table_Text% L% X: F+ p) W5 H6 @5 d
-
# ^6 ^9 S7 K6 r9 u$ d% M; q6 | - JSR Time_For_Vblank
6 Y5 r' R) D# H/ Z - ;开启PPU控制# I' x" \( g8 k; \, z! z
- LDA #$88
5 B; n4 c* V, R3 i" c o. o: B - STA PPU_Ctrl_Buf
6 i: A @9 O+ Z( z - STA PPU_CTRL3 N) z$ n- t4 z4 V# H8 C$ V
- , r5 P7 ]7 m2 G+ t1 S: i
- ;开启PPU显示% Z/ }6 U' `7 {$ R
- LDA #$1E$ ?. i5 D# D- D) R- s5 L% \8 K
- STA PPU_Msak_Buf
- D" ?1 V, Y) O$ y$ j6 V( _; B0 ] -
5 i* |' i: g7 V - CLI# ~5 h- ?3 M$ k4 s; @" `1 @4 E
- JMP Loop1 n7 N' \$ Y) e
- 7 g& K* @/ i& {$ {4 n
- ;==============================3 ]: K0 C$ Z" K" Q+ d; ?3 o) G
- ;死循环, 等待NMI中断( \/ } j+ I3 _" H
- Loop5 I% K3 [- [: L A5 ~: s
- JMP Loop
) n- w, b+ _& C9 k( \
% y; n8 e3 f. a6 f/ _2 O7 o- ;==================================================
. t+ H/ Z& v- r - ;NMI中断处理
' @6 y( q- D0 Z2 ^ - NmiProgram/ f( H& _$ a) v
- PHA
# R! ^; a: O3 [ - TXA
7 G. r! k9 l; F$ I; m% B C - PHA+ f3 f9 \8 i/ D5 ~6 k' M1 Z- P- _
- TYA
# z* ]+ H! n1 [. A" m - PHA: z+ z6 T: `. D2 u
-
+ M3 X" T2 s8 O% p, c" u# ^ - BIT PPU_STATUS
8 j3 N* q8 p' ?/ t: ^, Z% l - % @) ~8 S7 F, ?. c" j% ^9 s' U
- ;启动IRQ中断, 第16条扫描线触发5 _: B2 @. R2 V3 r' R& k) B2 s- f
- LDA #16: Q2 ^; E: r" i# I4 m; b
- STA MMC5_IRQ_SCAN_CMP
. g( L% p v. p - LDA #$80' N, f* m. E% M. B$ ~8 d! P
- STA MMC5_IRQ_STATUS
. {% l; W1 Z# o( x - CLI
6 l( c( Y2 ~- ^ - / V2 g) B1 @' C# \* h# ^
- ;关闭PPU控制
3 `$ L8 ]& k T9 _$ s$ x - LDA #$00
) x2 {: b" I1 G1 t' } - STA PPU_CTRL8 k# j; q# d. B
- - i% P; ^& @! Y
- ;处理PPU6 a) [% a: Z$ [% H. N
- JSR PPU_Process0 x6 @+ d0 o; g6 N" i5 P9 u
- . K0 x( l6 L4 F" r- K0 d
- ;开启PPU控制
5 l0 Q2 K: C& j+ S' `, W* { - LDA PPU_Ctrl_Buf
$ [# _- j" m, i6 z! @' u0 y - STA PPU_CTRL
- E( z6 k4 T7 R' X - . M: W4 I0 K+ E. y" Z" [
- ;手柄处理
0 t9 s3 B$ ]) t - JSR GamepadProcess2 u( C1 Y: Y; }# c$ Z6 o
-
) F1 N& D, p: E9 I: m: m - LDA #$007 j; |2 l# ^; b) w' Q8 Q+ N
- STA IRQ_Index
9 ?9 S% M6 e# [3 {: \ -
/ f: N+ i% |9 e/ v2 a# b O! D' a } - PLA
6 }' B6 o, Q1 i8 E* j - TAY
8 x8 N2 P$ @* R) z+ M2 U - PLA! n, \0 H. j- {8 @* J
- TAX+ j+ j. x% _( L. K8 N1 I' t
- PLA
% R/ d9 ]/ y' m. u7 t9 g. W - RTI
4 A8 m) a! d# ^' Z% U: Y
$ ]6 o+ G& M) L7 x4 | M% e) n- ;==================================================
# X& i; W8 r6 s6 p - ;IRQ中断处理; J! A! [7 s% l7 j: m: a6 X: v# @
- IrqProgram
& q( I+ P# k& }1 o, ? - PHA" U8 a; K9 B: ~7 R5 Y$ {+ w
- TXA
/ a3 s2 D( m, L, N$ d# K( k: V - PHA _/ ?/ r2 @1 j% K8 l9 z' `* G
- TYA8 m' i1 M) Q0 `
- PHA
/ v4 a, ]# d0 f, Y5 O - p" S9 u" r% A
- ;确认IRQ
1 s! i9 \- N" _$ W5 a- a3 U - LDA MMC5_IRQ_STATUS. h! ~* Y; X1 F# @2 b- a6 ]
- - [3 q* K) r5 K5 Z
- ;允许下个IRQ触发6 t7 `- Z) c1 K7 j
- LDA #$805 X J L ?6 `% ^
- STA MMC5_IRQ_STATUS: W, t" r6 V! c
- 0 p0 ?+ K8 S+ J H
- ;IRQ处理, 每隔16条扫描线触发
% Y- R& ?1 j% C e2 O, N0 N1 a - LDA <IRQ_Index2 Q* k' m- |' ~ k7 W
- CLC( |7 {2 }' G3 L$ e$ L" C& K* x
- ADC #$020 @' u. P# W) k! O% Z/ O# R3 {
- ASL A0 R9 V, l) _3 |
- ASL A
, M( E4 B1 \9 D3 ?8 A) h - ASL A
$ ~( u& |# P5 U9 \9 V, {; ] - ASL A( p, M- g5 B: v; [" h
- STA MMC5_IRQ_SCAN_CMP! P! e6 ^. t5 ]5 @* P
-
; W8 _3 d4 Z0 O - LDA <IRQ_Index
2 V: ]# W# L: ]" P! d0 s4 a - BNE * + 4
% }: K( w: H* r$ ^8 P. Q! b: q - INC <PPU_Scroll_H
3 q; ]6 C' B# z6 w - 2 C- S/ w; l' ^% ?
- ;设置屏幕滚动1 y, M- R/ ?5 [: F$ B
- LDA <IRQ_Index
, q% @; U3 c3 P$ T* W - AND #$01, t5 b; I4 D5 F* }0 F
- BEQ Irq_Scroll_Right
+ C+ k7 C8 W- q' I6 @4 U# j8 l' ?
: s# M0 r* z6 ~+ L; ?. \5 I5 {- Irq_Scroll_Left
$ k4 {9 ^! @6 C) E- V - BIT PPU_STATUS# ?1 j2 W* e7 t2 R! T* Q
- LDA <PPU_Scroll_H8 _7 f! O' K d* M+ k, _ j& y! R
- STA PPU_SCROLL
7 ? V5 p7 F1 a: W1 ? - STA PPU_SCROLL- W# I( ^- x } P
- JMP Irq_Scroll_Over
1 y3 l+ Q( B& w9 r2 d) _ -
( C- x* P6 M( Y, Z! S+ P - Irq_Scroll_Right; Q) v5 g, t% D: z2 Y% I6 a
- SEC
8 r5 w% D* E7 p - SBC <PPU_Scroll_H
& O6 Q; D" t3 h - STA PPU_SCROLL( J6 p# B7 y/ Z' f/ h8 A+ O( N1 b
- STA PPU_SCROLL
& A* X# i! T9 c/ b7 l - Irq_Scroll_Over: F2 @' G. T5 Y9 N8 W: ?3 T7 f
-
" L$ T3 L- C+ ? - INC <IRQ_Index
' X# w$ Z& F1 H -
4 p& ~+ [% P0 K - LDA <IRQ_Index4 w; J- h* }+ P/ p, _0 w3 W' X
- CMP #14
( R# x: [0 d3 t0 W% S- p0 k: e [$ I& y - BCC * + 5
: ?6 S" c# {- {4 x/ U - ;关闭IRQ
8 p K& p0 {$ Q) E - LDA #$00: y9 {6 `) b) g! u% o) O
- STA MMC5_IRQ_STATUS
* |! V+ B8 l8 d! t7 } -
! j8 z$ h5 g7 [# B0 A3 X - IrqProgramEnd, O3 ^# |5 M( G' r9 b" @
- PLA
5 m/ c; _9 ~" \0 Z" E9 w9 O) W - TAY
, w, \4 a5 _3 \- p - PLA- X/ o; L) U( z {, I0 P2 w0 @
- TAX
6 j1 _; c0 |& x% A. D Q3 P- U - PLA+ \8 G% a3 \9 @
- RTI
& R ~; F9 v! `! N% P% D -
* `0 ], L! C) v - ;==================================================$ E0 r. A9 u6 W
- ;中断表
7 P6 X; P/ k" ^! ? - .ORG $FFFA
1 O; m2 T! [- R9 b$ _ - .WORD NmiProgram/ ?2 v% O- V3 M! |& w
- .WORD ResetProgram! I# u. C4 L; D# x- w* h
- .WORD IrqProgram
复制代码
- T* a8 w( }: [ |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|