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