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