|
|
- ;[FC][MMC3 精灵碰撞]
5 j, k1 x# B3 { - ;FlameCyclone 20230710
' i4 S+ q% S* n% `5 l6 K0 j
1 R- b# c. H4 r, ?. p5 E! F' b- ;文件头
( D% U% U: ^7 t8 x9 u% l - ;======================================================================% b4 e+ [3 v6 F: F) N: z+ K- F/ k9 ^
- .INESPRG 4 ;16KB PRG 数量) o3 e9 g& c4 R
- .INESCHR 1 ;8KB CHR 数量
' r( d6 G" s7 Z @! \- J - .INESMAP 4 ;mapper 4
4 k7 g# H5 g I( L& K6 B* x - .INESMIR 1 ;命名表镜像 0水平 1垂直8 w P) {- y" K/ Z8 W
- - D! d' ~: Z" O9 E# y
- ;必要条件! P/ s% Q. U: G' f
- ;1.持有CHR ROM
2 c4 D9 K+ @& _* _ - ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000+ r+ Y7 Q( D6 [ f
- ;3.精灵内存(OAM)不为空
$ b/ x1 o& G: y4 R) ]% |( ` - # t2 D8 b U( h% X; R
- ;==================================================
0 Z* ?! Y7 w+ o9 V$ x - ;NES端口常量, h! M6 O: c2 R
- PPU_CTRL = $2000 ;PPU控制寄存器
o$ s( G3 c) l1 q5 C( E1 K$ U - PPU_MASK = $2001 ;PPU掩码寄存器; P4 d/ y+ G7 q1 P: w! N
- PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位7 S" \8 G) m8 |( o0 D
- PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1" j3 G4 h1 b" n; }' h( k+ A' k6 P f3 V7 h
- PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1) ]4 {1 R+ J& A- _ P% c6 x) E
- PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
, Q; s$ ?4 W% k# N4 r& w0 v - PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加. f: V7 U) a; f3 J
- PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
- R. ~, B8 n4 d: B - OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存' y6 ?8 U2 H% z: m7 ~( h( S2 S# k1 A
- APU_STATUS = $4015 ;声音通道切换
/ _6 F: ~; H$ n; Y4 [9 I6 m6 A6 B - JOY1_FRAME = $4016 ;手柄1 + 选通
& B. m% G0 j+ p& b) f' g# i% `( {# Y/ g: e - JOY2_FRAME = $4017 ;手柄2 + 选通4 H p, c9 P }6 c
0 u! u! H. D* L, D) C- ;==================================================' C1 {* a" ?( U* @2 V5 H
- ;MMC3端口常量8 C+ F3 G5 h/ g) Y
- MMC3_BANK_CTRL = $80007 O8 l4 W) }* }! v
- MMC3_BANK_DATA = $8001
: v7 I2 O9 [6 k( B. `9 n) J# l - MMC3_MIRRORING = $A000
. W. }& N3 l. _2 H. H! |- _ - MMC3_PRG_RAM_PROTECT = $A0014 i2 ~8 o! y# R7 p8 P2 r
- MMC3_IRQ_LATCH = $C0002 l8 _; U1 f8 e
- MMC3_IRQ_RELOAD = $C001
* I) p" S7 S t8 L- L( Q - MMC3_IRQ_DISABLE = $E000
- C8 o7 _) c! u3 i Q. V2 C- z - MMC3_IRQ_ENABLE = $E001
* T! j2 N1 {5 o6 y6 @ - - z c: {. t: d3 e
- ;==================================================
, ?4 I8 O& r3 D5 h f6 P - ;程序块配置- v: k6 G) ~, d% K. G
- BANK_DATA_MASK = $07
! |) O' O0 f" ~# D0 Q: N# @ C+ u - ;--------------------------------------------------
# U" E- N ~4 x9 a - RESET_BANK = $07. n+ _/ N& X8 p. y
- RESET_ADDR = $FC00
# Z" s/ g: R' m% q C2 e; ] - 5 Y1 G4 ~2 u5 |- H- _2 _" C5 e
- ;==================================================
2 i3 N% ?; P4 a* t# K. H - ;图像块配置* P, Y$ W: E) o6 n6 `7 [. m
- CHR_DATA_BANK = $08
/ d1 G: }& r9 V/ Z4 K/ {7 E
6 A, o& h% H+ k0 V6 {. G& x- ;==================================================6 A5 ~& b; s- j, ^, G: _% w/ D
- ;零页内存地址配置
' Q7 f* q1 |# h W N1 V; x: c4 m- _ - Use_Ram_Addr = $80; w$ ~& o5 ]9 ]- [/ G
- PPU_Ctrl_Buf = Use_Ram_Addr4 \" y" j( X+ ^, }
- PPU_Msak_Buf = PPU_Ctrl_Buf + $01
$ r% N4 t9 u* B1 ~8 V* C+ y - PPU_Scroll_H = PPU_Msak_Buf + $01/ ~! |4 J' C0 \% B
- PPU_Scroll_V = PPU_Scroll_H + $01
. s6 a" c& }0 k$ V% s& I9 t' b0 Y - FC_Data_L = PPU_Scroll_V + $018 k2 f" {6 a7 |/ _1 Y
- FC_Data_H = FC_Data_L + $01
7 C* a. h* h) V D% P m( E! }" D8 E - FC_Data_Buf = FC_Data_H + $01% `1 M2 [, J9 Y, c: D9 O5 N
- ;==================================================
3 f# s# T9 E1 d; \* d8 C - 5 N' {$ V9 h# e1 D- [7 ~
- GAMEPAD_MERGE_FLAG = $04- F! t6 H8 t% V) n- q2 I. h5 n/ G3 c x, l
- ( A- \$ D) I' v. C$ \. m
- Gamepad_Keep = FC_Data_Buf + 1' {7 {( V" O5 L. g& Y" I
- Gamepad_Once = Gamepad_Keep + 2; ` m4 c! B* Z: r5 A- t
- Gamepad_Temp = Gamepad_Once + 2
1 |9 o0 }( Y" d. c' ?" W -
! c0 J7 X& y+ E0 i: y - Gamepad_0_State = Gamepad_Temp + 2
0 z P6 h) i: @ - Gamepad_1_State = Gamepad_0_State + 13 G2 B& u7 S7 ]/ q; w& _6 E; m- s H
- Gamepad_0_Value = Gamepad_1_State + 1
, r; Q8 B' Y1 j4 D - Gamepad_1_Value = Gamepad_0_Value + 10 s: D: c% w2 r+ a
- Gamepad_Port_Value = Gamepad_1_Value + 15 f! K: Z, l/ p
- Gamepad_Merge = Gamepad_Port_Value + 1
) R: |0 P4 q. y) Y& H8 _
G" w5 N$ {9 R- ;==================================================
, m( a2 ^/ O% n2 M" c. ]3 `/ x - IRQ_Index = Gamepad_Merge + $01
# M) I9 N' |& ~( f - Sprite_0_Y = IRQ_Index + $01
$ ^/ A7 c" h2 O3 R j2 u - Sprite_0_Tile = Sprite_0_Y + $019 U. @) P' L# ?. M
- Sprite_0_Mode = Sprite_0_Tile + $01
. \& o, B2 q) |9 G" q - Sprite_0_X = Sprite_0_Mode + $01: a$ f2 y. S" D1 i' L" y) _
- Sprite_0_Hit_Move_Direction = Sprite_0_X + $014 G1 s# Y. e0 q1 o
- ;==================================================( ?- ]1 ?3 G: \
- - c# V0 o8 x% d% c
- ;CHR图形数据$ b. `- p! S3 d6 k0 Y; e/ P
- ;==================================================9 V% i0 q% V, U2 d9 Q+ o
- .BANK CHR_DATA_BANK
# w( }1 F6 m2 M1 L- D - .INCBIN "chr_bank/chr_data.chr"
3 a$ A4 [0 w7 Z/ f6 K* n -
7 M& P: \2 l9 ^, U+ ]2 [2 W - .BANK RESET_BANK & BANK_DATA_MASK
1 j& M3 V* w E! e2 x% C - .ORG RESET_ADDR
# ^) P, L+ _% p4 s -
6 L; C& x/ j% Y" s9 e. { - ;--------------------------------------------------) S3 G' f' M7 Z, }/ N7 j
- Attributes_Data$ V# i5 c$ R8 r* n9 g
- ;命名表属性* N6 L! F6 H: ^" ^7 a8 Q# U
- .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00$ Z. e. R2 A% y' i1 U* r
- .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
' P5 r; C2 }# y6 e2 H/ J - .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
8 w+ |6 Z& ]+ [/ R+ R0 I" D - .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$551 l0 p: Y% o5 _$ j; R/ }' ]
- ;--------------------------------------------------
6 a" J7 q% R. E0 y - ;调色板数据
* N& {+ @+ F: {5 w8 f - Palette_Data( S$ X+ o( Q* a# U3 D- b" B
- .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
( t& L+ T) C; d" x1 O - .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
5 R7 Q; W7 e% J, a# G
% z7 y8 g3 s# U* I# Z0 U- ;==================================================
' O5 p R: d+ m1 f2 L) o - ;命名表初始化
P. P! w0 U; o. ]2 H - Init_Name_Table
0 M0 D! h& ^/ R8 i4 \9 k - LDA #$20
# s# F+ B# {) U9 f' Y$ k - STA PPU_ADDRESS
/ |2 A% M2 J7 r3 { - LDA #$00
( S/ f1 K a, W - STA PPU_ADDRESS& s& h7 h% e. \) a, [; d" A
- LDA #$002 R1 l! Z# ~2 F* l) D; [$ P+ ^
- LDY #$00
2 N. z+ d R2 @ M* G* L! A8 ^ - LDX #$10% k+ T* N& i3 s0 m" Y# E, U1 K
- Init_Name_Table_Write
n- q j- P3 c" {1 [- ] - STA PPU_DATA2 Y r- q6 N' r: G1 P
- INY: P' p* G5 q8 u- h
- BNE Init_Name_Table_Write; U" o! M$ j. d" I M+ F4 F
- DEX
' D% G7 s! q: o: C3 w) n. v$ Y - BNE Init_Name_Table_Write
5 @/ u7 y0 W/ `2 G% ~1 x+ M - RTS! \3 N3 F& U/ g) h$ ?, H
-
2 D" v3 O+ P$ [* P7 u - ;==================================================
1 u; ?% J! X M1 S u l - ;调色板初始化7 t4 B# e& F6 x3 _6 l
- Init_Palette
, R' ? d4 T! l" J9 ]' e9 M# {. \ - BIT PPU_STATUS
0 c8 e4 R. i( q& U - LDA #$3F) R) D: E& f5 R4 o R* U
- STA PPU_ADDRESS6 W3 \2 g( x6 I5 e, b# n# h2 E8 L
- LDA #$00
: V |) M! R% [. M; ]4 s% s - STA PPU_ADDRESS
/ a* I$ ?. a( W$ J: Y - LDX #$00& M7 t3 H# J7 X
- Init_Palette_Write
; {0 {5 W& S1 @0 `0 ]4 K - LDA Palette_Data,X
$ o: L. C) T* p/ W - STA PPU_DATA4 x" R6 s5 b; C' D& }4 B
- INX/ U+ k* v, r: \( H2 e9 k
- CPX #$20
+ W4 i9 l: {. I& e' [ - BCC Init_Palette_Write" C* `4 u$ B5 {: U( ~
- RTS/ ?- |" ^# k) K! ~
-
& Q% V, [- J& o. @0 N' B( w - ;==================================================- Y% q7 O& n$ j/ W. H) Y
- ;设置命名表属性0 ^# R) s+ h3 Q( i( c& Q
- Init_NameTable_Attributes
2 Q2 u4 l. S9 m l& n$ U - BIT PPU_STATUS
+ y9 \) D+ a3 I7 Z) } - LDA #$23
9 z0 b3 v: }. o, D( R" S/ ^; P' B7 c - STA PPU_ADDRESS- d1 E! g% p, C+ M$ H
- LDA #$C0
# F* v/ ]; l0 G# M - STA PPU_ADDRESS9 ]9 F& W4 h, z. J. @/ U
- LDX #$00
& K( G' R+ q1 y - Init_NameTable_Attributes_Write; |1 t3 a T1 k9 ]4 ?0 t ?5 y: n
- LDA Attributes_Data,X
" o# Y7 i. ^" v+ |; f - STA PPU_DATA$ C" y5 F. }. i$ e! T. i' d
- INX7 E. u' K" K! g+ N" }% A8 |
- CPX #$40
1 I+ f3 r l4 \% p - BCC Init_NameTable_Attributes_Write
: |/ v {, g9 _7 r. c - RTS. \* N0 z# z, M
$ s4 D& J' v% J3 t; u1 j; f- ;==================================================
4 c: i! |4 T" K- u5 w& s* K- a - ;初始化命名表文本
) |, g4 P! L2 |! E9 h$ g! I! P - Init_Name_Table_Text4 `3 \- t" \6 l/ U1 F8 D
- BIT PPU_STATUS
, b3 E1 u! J4 P( J, }! r' }( k - LDA #$20: L1 `& ^$ _8 I+ L( g9 j p, A
- STA PPU_ADDRESS
. E% G6 f. k& L+ w; X - LDA #$00
2 Q7 i2 p# C/ p1 k( n - STA PPU_ADDRESS
5 F; [ G. ^& I1 R - LDA #$005 K0 A) ?5 V, b3 M+ u' |
- STA FC_Data_Buf7 L! F/ g$ T- ^7 g
- LDY #30& F- g1 ~" w$ F
- Init_Name_Table_Text_Write# L) T5 e2 z( I4 V0 x" V& a( U6 n% o
- LDX #32, C: |; q) K, X' ^+ j
- Init_Name_Table_Text_Write_Char& A( Z$ i2 x! z8 x8 O. [& h0 P
- LDA #'0'
* Q9 J6 T/ n! t& Y7 X F4 W - CLC- |& E6 W4 q/ y6 B+ B9 v: `
- ADC FC_Data_Buf
( M9 {# G6 s% A5 G9 K - STA PPU_DATA
7 s+ A. L) G! r# e0 u& ]1 y. ?# K - DEX
- M2 j- W/ D. @% }4 S - LDA #$14* k1 }) B4 P' K( r. N, K, S
- STA PPU_DATA
h( O, P7 Z7 a B - DEX3 h$ H- s: j/ j
- BNE Init_Name_Table_Text_Write_Char/ V! |; Q4 X3 b3 C3 Y! `
- INC FC_Data_Buf
* k2 M1 C& s4 F2 h0 q. X) q8 t - DEY" o- v3 T# r9 W, o. t, X: E# }
- BNE Init_Name_Table_Text_Write& _( F" ?4 r( q5 a, W
- RTS
, S4 p) p( {% R9 j. J3 G# V
/ i$ A ?# J/ D, D- ;==============================3 e& q/ u# _8 f" ]; p
- Init_OAM_Ram;初始化精灵内存
2 y9 x2 \" W+ W: H5 p1 t - LDX #$00
( O$ c1 ?$ a5 w' g/ p - LDA #$00
/ L3 h8 ~& j; C2 x$ K P - STA PPU_OAM_ADDR
6 @$ i, {" @: ]6 O% a" {" k/ r - LDA #$F8* ~1 R' L- R' A& Z5 J$ H
- Init_OAM_Ram_Write
* l3 E3 A/ C! o% @1 G3 x, q. {0 ~6 K - STA PPU_OAM_DATA: ?1 S0 M+ K6 I# i2 q2 M
- INX
8 g+ k& R% B* { - BNE Init_OAM_Ram_Write/ a/ ^1 U1 ^7 b: J6 I+ C: n% N
- RTS
) b2 U" ~; c) |% l$ V - D9 k0 v1 P+ J1 |9 Y
- GamepadProcess;手柄处理4 F, Z% l' t" @! o2 R
- JSR GamepadDatacan
( h# l4 E1 |$ E - LDA <Gamepad_0_Value/ e! I, t( R5 c y# o
- STA <Gamepad_0_State
8 j. b; g3 G" {+ @& r - LDA <Gamepad_1_Value7 n3 @+ }8 B2 a9 D
- STA <Gamepad_1_State
" a! w4 v! m" X3 r - JSR GamepadDatacan8 n+ i" z. v$ i; m! Q
- LDX #$01& z3 r/ w* _4 m. ]- ]
- GamepadMergeCheck;合并手柄输入检查9 n) ?2 R2 x/ T4 b
- LDA <Gamepad_0_Value,X
; M* o" |. x2 M& T: v - CMP <Gamepad_0_State,X+ p6 _2 V' W) Q4 J
- BEQ GamepadMergeInput
) O+ o6 Q' m8 `- x+ ]4 ^ - LDA <Gamepad_Temp,X7 f# w, a+ k' @/ g/ H
- STA <Gamepad_0_Value,X
- P2 O+ q7 t/ Y. c2 L1 R - GamepadMergeInput;合并手柄输入
# ~( W; D2 h) v4 f5 \ - DEX
4 f$ i [& D& f - BPL GamepadMergeCheck3 H7 k2 K n, o( l0 N4 I2 ]
- LDA <Gamepad_Merge
6 _' \+ l# _: S. {3 A6 ^0 A* C& u - AND #GAMEPAD_MERGE_FLAG: C9 T5 A. Z4 x' B/ r! z
- BNE GamepadStateProcess6 O+ I; j# p) E/ n( B
- LDA <Gamepad_0_Value6 n. S" q. l. l' L2 X; L
- ORA <Gamepad_1_Value# P* }, W \' |) M
- STA <Gamepad_0_Value
# U1 R# [* X7 }- z$ i5 G* H# z5 z - GamepadStateProcess;手柄状态处理" P) p8 K; c+ } c; {- [
- LDX #$01( B/ C2 z2 n- l/ `' {/ s
- GamepadStateSave;手柄状态保存6 M2 B- i7 c3 z* ?4 m' Z
- LDA <Gamepad_0_Value,X" [0 l( I4 s5 d: v# M
- TAY1 T( E* J9 h1 e- V' G
- EOR <Gamepad_Temp,X
0 h- L4 a% B( T s' O - AND <Gamepad_0_Value,X
) j, `2 d. @) }4 y5 |) O* C" i5 m - STA <Gamepad_Once,X' O. K; q' S, Q# t
- STY <Gamepad_Keep,X
4 D) W$ y# ]5 ~* M% C- h2 V+ s - STY <Gamepad_Temp,X
+ O3 X! I% e" K7 V5 h4 u1 x - DEX1 `* W) O! b2 }, I
- BPL GamepadStateSave
8 p! I: z* L2 _) p - RTS- _( e- R9 e3 a9 J! K
9 J9 w2 j" ?2 _! g4 _& X0 o- GamepadDatacan;手柄数据扫描
5 ^& l5 j2 I# I$ i5 n - LDX #$01
( X! T4 L. r D! z - STX $4016
' J: f& y* L1 @: g$ S. q. ?! x - DEX- Q$ `8 g2 N, ^: l3 m: p
- STX $4016
) e, j# }+ ~! z) [( h- b - LDY #$08
5 x0 A8 i( \; W - GamepadPortScan;手柄端口扫描 b( O' U y" j, i3 k
- LDA $4016/ G. k K1 ]: `( w, S' D
- STA <Gamepad_Port_Value
7 V0 _2 [8 {# I" H" R6 h* v. ^ - LSR A& \. J) K$ i: b
- ORA <Gamepad_Port_Value
8 {' D! W! I$ J3 P# r; l- c" z - LSR A! Z# F3 e4 W5 e% T
- ROL <Gamepad_0_Value( r; r" o/ l- S4 U- a
- LDA $40177 o, A8 Y* x, [$ w2 D
- STA <Gamepad_Port_Value/ l, E' g6 W! F& w- s6 X
- LSR A
/ a4 }1 {& s7 y2 v, j* U - ORA <Gamepad_Port_Value
4 J3 ], L0 A# X w - LSR A- ?+ Z1 _4 q' K
- ROL <Gamepad_1_Value
' Z7 G1 Z. \* Q: `. o3 \2 P - DEY
! m- O3 `7 |5 W" N3 O - BNE GamepadPortScan$ s& o% @% ]7 W& C, u1 h
- RTS
4 M( o- g- U9 s- t' @ -
9 \$ m7 ?, y4 x, m - ;==================================================: ^5 Q5 r# [; O: q; S
- ;PPU处理0 @* h% T. Q+ r, d3 k, R2 K
- PPU_Process z! L1 O5 ~6 e- q1 r/ c/ ~& f
- LDA #$00
( N% M5 r9 Q- ]/ u$ O0 t( q) {7 O - STA PPU_MASK/ ?1 ?7 L6 ?+ f( H; b6 \) o
- 4 k5 Q r- ?" f3 O4 s$ ?0 m
- BIT PPU_STATUS
% c0 U( O' L- [3 n3 l5 ] - LDA #$20
: p I8 f2 [9 I. o$ r - STA PPU_ADDRESS; Q( A3 K& e! i8 k/ T& E
- LDA #$00! L: N+ t( M6 g: T
- STA PPU_ADDRESS: [8 h5 S8 S( P; T6 x. ]
- 4 ]4 G- q" H, H6 Q- {! g
- STA PPU_SCROLL
- Y/ f- X1 U4 b& \8 ^# y - STA PPU_SCROLL" U, Q4 V$ `: l; p
- / }! k7 f0 ^+ k5 H* \9 m2 z
- LDA PPU_Msak_Buf
+ t3 N* E6 y3 |2 ?! | - STA PPU_MASK9 B* k/ T: _; Y8 k0 e8 ?
- 7 E0 l G' ^; u# I( T* \5 C
- RTS
# C& @- F9 h( G4 l6 Z -
7 \" S2 E7 }% r& t0 S! P- h# b - ;==============================
, c. b# B# i; \+ v9 j; U - Time_For_Vblank;延时等待. M( l1 Q$ g& a3 {- M3 v7 m( N, f" U5 i
- LDA PPU_STATUS
# {) {2 w% c8 H" `1 o/ J( ~ - BPL Time_For_Vblank) }- d0 @, Z3 x+ k/ ^5 K
- RTS
+ r3 v1 B5 n; H! h - - l3 d+ \6 t/ g8 t
- ;==================================================5 P% v2 u4 p2 d1 A0 r
- ;初始化MMC3
; ]; P, }& M& {; z+ ~1 S - Init_MMC3$ c9 O8 E. M' \2 [, {
- STA MMC3_IRQ_DISABLE
6 k+ z3 h# f$ ?1 y& p( w -
. P. R3 M8 P6 T) p - ;设置MMC3水平镜像
2 |' g+ s/ \' z- e8 D j - LDA #$014 O* b; g% X# b' b9 C
- STA MMC3_MIRRORING
5 q1 w- |( G8 E' V4 @ -
8 x3 e: F: b C+ \ - LDX #$05
% D1 b2 @5 [# u1 x K& V; ~6 c - Init_MMC3_Chr_Bank_Write: F' R, Y5 _$ k1 Z
- STX MMC3_BANK_CTRL# E0 W/ \' a: Z
- LDA MMC3_Chr_Bank_Data,X& g3 O4 N$ _, v+ X
- STA MMC3_BANK_DATA3 }' }, r3 {9 A, k
- DEX
; r. ^' ?! Q! y, O - BPL Init_MMC3_Chr_Bank_Write" O: A% d7 [+ G' p& E. f
- RTS8 M) ^, Y. r: z
- ;--------------------------------------------------0 W/ c: T% J/ k( |1 J
- MMC3_Chr_Bank_Data
- B: W+ G7 f. v7 S - .DB $00,$02,$04,$05,$06,$07
3 A8 g1 ^; m: v6 k# q! B0 R - 4 _$ j$ V4 A& e& z
- ;==================================================
% u3 D+ I- s% l* i3 F( k' T. g - ;重置中断处理, m# s1 y7 J, P
- ResetProgram
$ l! Q$ P0 t9 ?- r7 c" F - SEI
, F8 R3 w# Y2 Y: M+ ?0 e - CLD
$ m# n" R2 u! X: N7 r: Z' J6 t - LDA #$00
9 E+ z5 o! p8 t( Q - STA PPU_CTRL
O2 i) N6 U |) {: e- v5 Q/ g - STA PPU_MASK p, ]* _1 s& k4 E
- STA PPU_STATUS0 I* o5 |* r$ i: ?7 V
- STA JOY2_FRAME' u/ E- b: S0 U( _
- STA APU_STATUS
3 H$ U7 x/ {, U* X - 9 s) g( z- I. q, u3 C3 X$ e+ }) f
- LDA #$C0
; a2 g5 C, V3 x9 H - STA JOY2_FRAME
! c+ o& }" K N2 o( c T6 \ -
! T3 U$ z9 t/ x+ b - ;等待vblank2 _' ^% |0 N1 C3 J' o9 Y
- LDX #$02% m) l6 d9 |9 ^: j0 @% ~! j7 f; d, [' F
- Vblank_Wait_18 g4 q3 K$ `, ~9 i$ w$ H4 G" }0 T
- BIT PPU_STATUS
2 n5 Q! y' I: p8 v, w; W& F - BPL Vblank_Wait_1
! U# f/ a$ q* B }+ ? - Vblank_Wait_2
+ u; g' P" F+ \8 r- b ^ - BIT PPU_STATUS
' p) k) P- B7 o - BMI Vblank_Wait_2
) P( X# Y4 K/ E$ v% S+ F5 U4 U - DEX- {5 Z' g6 t1 p y
- BNE Vblank_Wait_1& f; S U; w7 i. ~
-
; J u4 l+ p$ y8 U - LDX #$FF
) @6 g" G6 p2 U- V - TXS
. p/ \4 a# J; X' x8 M4 c - 4 W3 k1 Y0 M9 e9 P+ m, G+ y- V5 ~
- ;初始化MMC3
9 L6 ]; S" E# b: [' `- U! J - JSR Init_MMC3
$ v0 z% u; v1 |4 G. D9 ~1 { -
* P l, J7 `1 w) k - ;==============================
" \* F7 {: K( h( ] - ;RAM初始化1 s1 ]' e% C Z: i2 [ }
- Nes_Ram_Init9 u/ B6 J7 v2 p! ?( l
- LDY #$00
% \5 t8 D3 }6 ~! P, ]$ q+ b - LDX #$08
2 B& ]0 V0 C4 f - LDA #$00
" ~7 ~$ ~* q' N# _9 Q! | - STA <$00
2 }" M* ~3 v7 Z& M7 _ - STA <$01
5 E- I+ {; ~% I) R! d: g - Nes_Ram_Init_Write w, G8 L# M- `; l( x
- STA [$00],Y# L' @- j' r0 K6 z8 q3 [
- INY
# z, N& _/ K; f! L8 I6 y' e: `6 @: T5 d - BNE Nes_Ram_Init_Write5 k- Z- k' j8 X z
- INC <$01
6 D0 W7 i8 @; G @# E1 Y) @ - DEX
4 p4 i5 A) x) e$ s# } - BNE Nes_Ram_Init_Write9 Q# X0 q; p. L
-
9 U; C- z+ s S) m: g - ;初始化命名表
' F3 D9 C* k2 I8 s' _% l- i- [6 v K - JSR Init_Name_Table
7 t* V/ k! [2 N7 ^+ A' h - 1 I, y5 T# x6 T4 w) x& Q# Y
- ;初始化调色板
# r/ v* K& E; \2 c! ]( { - JSR Init_Palette
. V, N& R; v% H! B- o# L- r9 q: S - 8 i6 e. P9 f7 q4 b" W Z
- ;初始化命名表属性
# n/ D* W* `! }$ v; U; M - JSR Init_NameTable_Attributes) H2 a" |6 F5 |9 A) f$ t
-
, c; I& T; ^$ [2 m - ;初始化精灵内存4 s# ? a- z1 Q, c6 s3 V( M
- JSR Init_OAM_Ram
9 `* h% Y) X& @, G! D6 e6 p7 b( Y -
( l: S, L* s" ~3 ~0 ]% u - ;在屏幕上写点东西6 K6 ? u+ F% H V) K
- JSR Init_Name_Table_Text
/ C0 r5 y: j- |: N" ^, v; `9 U6 t -
& I# A \2 q' F- h8 f& m& A3 l - JSR Time_For_Vblank
) U/ k9 O- A; p# J( d/ m2 z6 \ - ;开启PPU控制
. a! B6 E4 U' U9 ~: e5 _/ p* Y+ T9 { - LDA #$80
. q4 n6 h* W3 q' a2 g) d - STA PPU_Ctrl_Buf4 G; Z2 V, R( q3 I0 O
- STA PPU_CTRL
, G# U% Q) V( u' } G2 E& X5 w8 n. g -
U1 a) y' C, K9 G - ;开启PPU显示% O9 K2 s4 x3 C4 O8 Z
- LDA #$1E
1 P# F Y7 T# z: K u, S B - STA PPU_Msak_Buf
W4 m5 r* |0 ?' ~ - & i9 _0 i8 E( r- }5 D7 P' p& Z
- LDA #77; R; _# S" u, S+ t+ j: Y, J
- STA Sprite_0_Y
! f9 o6 {, F, n K& { - LDA #$1E
7 A$ a: V3 g! V3 S - STA Sprite_0_Tile
+ \7 f' Q" {$ {; K H3 N - LDA #$20* U9 f# y6 A. ]( y$ n8 d/ h
- STA Sprite_0_Mode7 w+ F( I) M# P: J
- LDA #$00
; @" W+ q5 M, b' _3 n0 I' ~0 J. ~ - STA Sprite_0_X
) n3 G( o8 `3 D6 s3 x: O5 Z -
|5 I5 S, u) I; `1 t - CLI( a$ N1 G* N8 ]6 l0 M
- JMP Loop
# L9 T4 ]$ `- `8 u# T$ I) | -
! C" j2 a& g; [2 |7 @ - ;==============================
! a' V: ]5 S) [5 U, L* @ - ;死循环, 等待NMI中断
/ ?' R% Q7 B2 z5 w7 h - Loop
1 h5 P( J! }/ K9 I3 X' U# w - JMP Loop- [0 Z2 D/ d1 t4 F! I' l& c
- $ L# I1 k2 C1 O- I1 ^
- ;==================================================
! ?: _% |! S6 x- p) N( v - ;NMI中断处理9 \3 ?0 P, O! [- X' d7 q
- NmiProgram
; M8 L0 d$ e- }2 ^3 T ` - PHA
" S, s% J) t/ s, V9 c5 Q: X R - TXA
3 k" R0 Y9 j% p/ M% Q - PHA, b I' b' v2 P! k- j4 ]& B9 ~
- TYA
0 |# q1 y& O/ d/ K' D - PHA& w- C) G6 x( F; B' s; B0 [8 G2 N/ N
-
2 H6 G7 F: g5 `7 x! Z - BIT PPU_STATUS. C9 M- z8 y( H) X0 c% {1 K% Z
-
4 |2 o' J( T/ m9 y( q* c - ;关闭PPU控制- m# `; j t* G8 h; o1 m; Z
- LDA #$00* A0 ^% `, F. D( N0 ]+ L, l
- STA PPU_CTRL
% ]$ z0 ?+ v" q: D -
; j5 w1 t( g5 V. ]$ y - ;处理PPU! P" W' Z4 G3 O, H! R
- JSR PPU_Process4 H' T$ o5 g7 w7 \
- ! z+ e+ X- l. n0 i$ u6 ?! H$ W! r
- LDA #$007 J4 T: G* H# A2 E5 \
- STA PPU_OAM_ADDR6 x5 {& f5 X6 c8 B
- LDA <Sprite_0_Y) ]: }. w; v/ H& H: p
- STA PPU_OAM_DATA4 ^2 L f3 r7 _, C% j
- LDA <Sprite_0_Tile
% l6 o% W! ?5 R. p2 G- R0 ^ - STA PPU_OAM_DATA
' d n& N9 G& X5 `+ C- [$ s - LDA <Sprite_0_Mode7 s8 m9 m+ x2 w
- STA PPU_OAM_DATA
4 c y+ L: Z% _# w0 u! } - LDA <Sprite_0_X0 B, b$ u0 d* K7 T- ^; ^7 l$ a1 N
- STA PPU_OAM_DATA5 ~1 E+ R* G2 V- s* |
- 8 ^! R, |: C' X2 V- {3 T
- ;开启PPU控制
4 y! L% a c. W/ \ - LDA PPU_Ctrl_Buf
" X5 i, S7 c( U: M1 h* P' O - STA PPU_CTRL* h0 j! @2 X. u" D
-
0 Y; {9 U+ }$ @% T0 d& E - ;屏幕滚动
9 y3 D/ f0 }" c3 {" R, v$ i0 |; v - LDA <PPU_Scroll_H/ t6 R; D. P t% J0 e. G
- STA PPU_SCROLL
( V5 W* t0 Z6 B - LDA #$00
3 s1 `5 ^4 M7 R; J - STA PPU_SCROLL/ J: s F$ y N% U0 Z J
- # ^1 m8 ^* w; c' N2 t4 d. @- E
- ;手柄处理
3 e/ T Q9 R ` - JSR GamepadProcess
& Y. d' }, S# b4 l. L - 1 E" k+ {5 t. |( T4 u8 J1 Q6 S
- INC <PPU_Scroll_H
0 ~! T5 O. {6 m, Z$ I" F7 S - - `4 J" ^9 S; \" ~% r! }
- ;启动0号精灵碰撞检测
T, Y7 G* `3 j' V; y( v% J - LDA #$01
6 G/ s, O! k, ~5 A# e% g' V - STA Sprite_0_Hit_Move_Direction. U5 |, [: M! m: V4 l
- JSR Sprite_Hit_Test& g7 y$ X- p! [) n
- + ~; c6 ~+ ^1 K6 i$ `4 A
- PLA
' U# i2 P* p5 C' Q - TAY
0 R" P3 ^! _; w - PLA
. M" @3 o+ h6 ^1 }. O* [ y/ z; e - TAX/ v( G" ~/ v1 z1 R8 \
- PLA
6 R6 J g: K% v- `; Z - RTI
4 H( G' p8 t9 f7 h$ ?3 u5 `: t
2 H% N$ Z/ E/ T. Z/ \; u! _8 G2 H8 [- ;==============================( K9 H% O! r8 N! f+ C. }
- ;0号精灵碰撞测试
3 q P$ I: e3 [: B - Sprite_Hit_Test
: u7 n: F* ]1 T# \& F# D - 9 f. f& F" K/ b9 H3 P
- ;------------------------------+ c$ i. [/ Y* G
- ;等待0号精灵碰撞状态取消% G$ j- l& s( n+ ?. D
- LDA PPU_STATUS
8 f! ^& K* H6 r; |, y - ASL A
" w% r' Y/ U. S; _# P* D0 g6 x7 K* o - BMI * - 4
4 B& p* ~( ^ |7 {9 C; A( C* A, f -
8 s, @4 p8 U& ~; H* J - ;------------------------------
4 w& H6 i; r$ z0 y* m2 n! v; O y6 \ - ;等待0号精灵碰撞发生
6 f$ l# E: v& V/ T1 v; k9 A: Z - LDA PPU_STATUS
' n1 R8 A8 L ~; B' l - ASl A
. P/ G! s' Z5 b* x9 g. J9 O9 Y - BPL * - 4
e2 t# ?# B- d1 _
' k% ]7 ?( L- t0 s b- ;------------------------------
$ i: S* z4 c# r0 }& F5 D - ;行消隐等待2 x5 M% l2 B. B5 |/ s; X9 k
- Sprite_Hit_Scroll_Wait6 f% j6 b- V+ T
- LDX #$28* N1 L5 F" i5 s
- DEX( j7 S, u# i3 \" H7 O, R/ P" X7 S
- BNE * - 1$ H2 a% l) A5 O3 Z1 w- E. G
-
* j( t- ^) B _, R, k7 e - LDA Sprite_0_Hit_Move_Direction- x/ ^- v' |3 h, `# r
- AND #$01
% ]6 M# Y) O: |( E: f+ F - BNE Sprite_Hit_Scroll_Set_Right, B1 j; N7 m' J* w) }
; L$ j9 E# w# a- ;------------------------------
% I- T; m+ t- Q - ;分割画面向左滚动
, R' V% N" g& Z4 z$ R" `* P$ s p# X - Sprite_Hit_Scroll_Set_Left
3 R1 Q1 }2 R* H. d - LDA PPU_STATUS
3 S! i" r. C* R* L0 d - LDA <PPU_Scroll_H
, [$ L. _( n: G. H) N; A - STA PPU_SCROLL
# M6 U- o2 B. J$ Y* A! Z, B - LDA #$00
$ \: b. ~* a2 ~( i; Z# G - STA PPU_SCROLL
4 H0 ?7 j8 W5 y5 E - RTS: L. R7 t) v: J( q! d" ~
9 H2 S9 r I; s" E: I% C. b1 j& z- ;------------------------------
% O5 P$ M* i% p K - ;分割画面向右滚动& y s6 e& B# L' n
- Sprite_Hit_Scroll_Set_Right
" j9 r' J9 L! J; T - LDA PPU_STATUS
( u s) d S, a+ V - LDA #$00
( X6 u0 Q/ L K( m8 p$ h) s - SEC) [6 T, z5 _$ Z+ f
- SBC <PPU_Scroll_H
. Y" G; `! L# [0 p- r - STA PPU_SCROLL' S# c8 O5 Q0 L
- LDA #$00" I/ V6 x* f, k. u; N7 b% r
- STA PPU_SCROLL) O' B5 s5 L! \3 ]
- RTS
, \3 I" \* a3 v& y
/ Y- d+ t3 V! k8 R0 Q- ;==================================================% r1 g V! k: O4 g# l
- ;IRQ中断处理( N! [. c5 S7 Z2 b* }( a
- IrqProgram5 c7 M0 o6 F5 r% \7 H: y
- PHA4 z5 x: N& ?, A1 |* l# p4 k
- TXA& k8 Z6 j+ n4 o7 T% i
- PHA: I& L* u6 l. }3 ?
- TYA, i/ _/ p7 @- y& D" s& I
- PHA+ H3 G3 B2 j/ z3 f* i4 S6 X
- , K( M5 F; \7 Q
- ;关闭IRQ
" c4 t V7 _; p0 M6 V - STA MMC3_IRQ_DISABLE
$ Q1 ^3 v0 _) j; \6 i2 O -
. A o3 {* p# u3 O+ R8 c - ;允许下个IRQ触发
+ J; @3 g; M( W2 K1 \0 h - STA MMC3_IRQ_ENABLE
$ X% s9 n* Q. z+ x - 1 ?0 A. K( K4 i% {* M
- ;IRQ处理, 15线后继续触发
9 x. f' r' w3 ~5 D. [( I4 l. J - LDA #15
) E. s9 Z' X: F% C* p- }4 G3 ~& ~ - STA MMC3_IRQ_LATCH
3 t9 y8 G" x' X8 @$ n$ ^; V7 F7 n( M -
* L# ]# M6 Y i3 W3 Z" A M - LDA <IRQ_Index: W9 _4 r- P: N) K
- BNE * + 4+ H1 r0 h2 R) V& s* F* C
- INC <PPU_Scroll_H
" F* m% x$ T+ w6 ^; o' v+ V - ; M3 J7 u( j' N0 l- g
- ;设置屏幕滚动
$ W8 H9 u8 I% G - LDA <IRQ_Index8 j7 n) F- v' B2 G7 o6 [
- AND #$01
9 x- Y/ [/ n: T2 L, S - BEQ Irq_Scroll_Right
* X: }9 }# h% g* n- v+ _4 O - ' t7 f% q( c6 ?, r
- Irq_Scroll_Left
9 r' y& f- [2 c9 [9 h - BIT PPU_STATUS
/ z; z7 f$ e- Q - LDA <PPU_Scroll_H
$ S8 }* c/ l' ~+ J) w4 Y2 n0 z - STA PPU_SCROLL
7 g' C( T) l! B0 A3 C# b - STA PPU_SCROLL
3 b7 _& K" P7 K. p4 P1 h# f1 @ - JMP Irq_Scroll_Over
, }' l, a- O" V' Z3 \- I. E5 Y -
S2 m5 c0 b8 J* y/ R$ w: T/ `, u - Irq_Scroll_Right7 _6 ]- P% J) Z, w0 d
- SEC
3 V9 x% {0 m1 ~" B. p2 M4 r/ \ - SBC <PPU_Scroll_H5 Z) B ~5 [: O6 S- i
- STA PPU_SCROLL
5 x, v1 v: L, G" }( B( e& ~; l; F2 t- g - STA PPU_SCROLL) v7 @* b$ G2 e6 `
- Irq_Scroll_Over
2 w- ^6 d" R" C$ ^3 k4 ] -
2 D- J5 ^' F& x9 `# _& r; E' p6 n3 d - INC <IRQ_Index
. m: ]3 r" x0 r4 U, @8 w9 R -
1 r7 G1 R& N/ F - LDA <IRQ_Index
, I) ^- q$ o' _4 D5 ? - CMP #14
- b( Z% p! ^1 O& k - BCC * + 5$ V3 j O0 O# N- O2 h
- ;关闭IRQ; N+ y ?- H4 G4 ?
- STA MMC3_IRQ_DISABLE
/ W' c$ E' Z3 h5 F - 9 O; U) m" r8 g0 T" u& U
- IrqProgramEnd
; H; A2 x: s/ p2 i) Y: k - PLA1 Q L' r/ d z$ e1 C
- TAY9 ]+ [# E+ ?5 c/ k. Y! g* Z$ z
- PLA! I' Z: t2 |( Z
- TAX; f# q/ q7 d3 T; B. q8 ~# s
- PLA* P7 i5 B$ @0 q3 K7 [, t9 K
- RTI
% n" _3 {5 f! f' S; e4 f2 }* e6 h - " u7 N( D7 I$ t! Q( {( k. N" L5 ]$ g& Q
- ;==================================================0 n# i! C! d9 O+ b
- ;中断表
& H$ D7 J2 z* z+ s/ u - .ORG $FFFA( `6 X6 r3 P: J9 z5 W! G( |2 U
- .WORD NmiProgram
6 }" [8 J) U7 a+ r- @% ] - .WORD ResetProgram
- f S6 z& P7 g+ H) Z3 U$ ?2 F - .WORD IrqProgram
复制代码 7 U1 F0 i" G' ^8 ^
|
评分
-
1
查看全部评分
-
|