|
- ;[FC][MMC3 精灵碰撞]
- M2 j3 |: q5 I - ;FlameCyclone 20230710
3 D6 ^) D4 H. B# l& E. m
% B8 {: U2 a/ Z# K9 R0 _- ;文件头
% I. ^7 E0 w1 Q5 I2 O/ v" t - ;======================================================================3 O/ |" j$ Z$ ~& Z3 t- Z0 V
- .INESPRG 4 ;16KB PRG 数量
; @. V2 l/ \$ E - .INESCHR 1 ;8KB CHR 数量
8 U' T7 w3 {2 K+ o - .INESMAP 4 ;mapper 4
# h% v8 Q& C0 C) R: J% | - .INESMIR 1 ;命名表镜像 0水平 1垂直4 a- s1 u- J4 c6 s) ?
- # w O( i; R# H: x) |5 P" D* k0 |% c
- ;必要条件
% D% n+ r# t2 |# a2 D5 j - ;1.持有CHR ROM2 I. ~1 X! t% G
- ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
& H# K$ o; M" |' V8 O+ O: [ - ;3.精灵内存(OAM)不为空! T9 N8 u/ R+ E
3 ^' n! `/ y7 w- ;==================================================$ h9 w( [1 P; v( e6 L
- ;NES端口常量# c! B" ~2 Y+ s) x
- PPU_CTRL = $2000 ;PPU控制寄存器) h/ {6 ?1 |( y/ Y
- PPU_MASK = $2001 ;PPU掩码寄存器1 @/ _" ?8 U( S3 Y: l: U
- PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
{* N$ E; l8 k0 ^) ~' X7 n; D. U, Y; e7 G - PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
: k, k' O) Q( E6 w7 N3 o& S - PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
# y4 f7 G( v0 L- U/ y2 p% \ - PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 7 [1 M6 P& [/ i2 P |* i- n5 k
- PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加+ ]; ?4 X3 _3 i2 R! Y
- PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 " G3 J& c: U" x" |, w( p8 `
- OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存# M0 c6 k' v \' g$ u
- APU_STATUS = $4015 ;声音通道切换: o0 Z' K: r* i- O% Q
- JOY1_FRAME = $4016 ;手柄1 + 选通+ P; x+ H% x* u; V9 I" w6 z" d6 I
- JOY2_FRAME = $4017 ;手柄2 + 选通) f5 s6 b I# c
- $ b8 ]4 |+ [+ k; P) x& b( W
- ;==================================================( Y/ M, H' k" r6 n# M
- ;MMC3端口常量4 @# E+ R4 z2 N; l$ c$ y$ R, b
- MMC3_BANK_CTRL = $80005 |1 X' @. f; G% [/ j7 ]
- MMC3_BANK_DATA = $8001
1 ]: d9 E! ]( r p3 H! @ - MMC3_MIRRORING = $A000! Z6 H* C) R z/ G* j$ M
- MMC3_PRG_RAM_PROTECT = $A001+ T o1 V: q7 ]/ Z4 I8 o7 B+ a0 ~
- MMC3_IRQ_LATCH = $C0006 ^5 f- ]' m: v
- MMC3_IRQ_RELOAD = $C001* {. Y' l) v3 n: |6 ]* y
- MMC3_IRQ_DISABLE = $E000" F& v" n" [% H' K( k, Z4 r
- MMC3_IRQ_ENABLE = $E001. Y# }2 y! n2 E/ M( j" j
- , J& F% W6 } Y2 W+ p( ?
- ;==================================================
* u9 Y: u+ g( H: X - ;程序块配置' n5 H x: d9 y% G
- BANK_DATA_MASK = $07) q- R+ z1 G* ~4 R3 i% p' l
- ;--------------------------------------------------/ L! b# U' y$ R2 N+ N9 e0 @4 w
- RESET_BANK = $07/ B0 n+ e: u/ S; h' C( i
- RESET_ADDR = $FC001 X, ~) H7 Y! z$ V4 W) J
- - V0 D0 q3 T0 u
- ;==================================================# ]1 P s; L3 Y) }0 T" Y
- ;图像块配置( l( l! k$ v2 M' f1 `0 A* V
- CHR_DATA_BANK = $08, s# w! R5 F+ v) Q2 d' }
/ E+ ^& |$ M. y( a; m$ M3 q- ;==================================================. P6 S# m; s0 d
- ;零页内存地址配置
$ ]1 T( y3 H6 ~* p - Use_Ram_Addr = $801 m) s4 V! ^8 f4 _$ e; ~4 m$ v
- PPU_Ctrl_Buf = Use_Ram_Addr6 q+ N% g2 O; @$ q" S- A
- PPU_Msak_Buf = PPU_Ctrl_Buf + $01% J) o$ m! w, b' a- e: C) B* @
- PPU_Scroll_H = PPU_Msak_Buf + $019 U0 s7 `! M/ a. u
- PPU_Scroll_V = PPU_Scroll_H + $01
2 J) {" S+ z2 w' d4 F7 d - FC_Data_L = PPU_Scroll_V + $014 F5 b& u; u: _3 }. f' q" e& Z5 D
- FC_Data_H = FC_Data_L + $017 H# J) S* n: z/ m6 T$ f2 H
- FC_Data_Buf = FC_Data_H + $018 U0 U# V; I" E9 Q% X* P/ {7 _$ o' }& J
- ;==================================================0 O$ D+ i% T3 u
7 M5 ]3 l; F0 r. ]' V' Q U+ Y Z- GAMEPAD_MERGE_FLAG = $04' @$ s( O0 f8 J% o
* S2 n# j, e$ r% g9 D1 ]* S- Gamepad_Keep = FC_Data_Buf + 1
2 f! |2 ?0 _1 Q% Y9 v/ ^. P+ a - Gamepad_Once = Gamepad_Keep + 2
: j0 ~+ i8 z2 E6 j - Gamepad_Temp = Gamepad_Once + 2
# ~1 @! `, E% A6 ? -
! {2 V$ A! F" [ `3 _# W - Gamepad_0_State = Gamepad_Temp + 2" a% S1 T, P9 U! P% x; q5 t
- Gamepad_1_State = Gamepad_0_State + 1
7 ~5 P$ U2 x" s% s" ^* E% E - Gamepad_0_Value = Gamepad_1_State + 1
: _7 Q, [. s& H2 I! L - Gamepad_1_Value = Gamepad_0_Value + 1* l" _ E, X9 M4 c: Y/ h
- Gamepad_Port_Value = Gamepad_1_Value + 1* \. T3 v3 [/ L0 l1 O) X( X1 O
- Gamepad_Merge = Gamepad_Port_Value + 1: R; Q+ M- H( Z5 {/ k
- ) d/ Y' l, p1 n# x9 G
- ;==================================================
& {; d4 p7 e6 e9 {; V3 q, _- h6 q# z0 A - IRQ_Index = Gamepad_Merge + $01
/ B T: y: ]& H# _; P - Sprite_0_Y = IRQ_Index + $01
7 L/ E+ f a$ Z; \ - Sprite_0_Tile = Sprite_0_Y + $017 N' e/ }+ D# D# @! Y2 a5 h- h
- Sprite_0_Mode = Sprite_0_Tile + $01) \/ \8 ]% \ M+ F7 _( P
- Sprite_0_X = Sprite_0_Mode + $017 A/ E; V: X# }& L" E
- Sprite_0_Hit_Move_Direction = Sprite_0_X + $01
- `% P/ m) M( f: |/ ^# T# a. O1 M - ;==================================================, T0 w/ A: h0 ]- _2 V+ S
{6 m, \5 t" g( d- ;CHR图形数据
1 ~8 E& C( |1 V7 ^+ v0 ?4 l - ;==================================================/ s/ d; y0 M7 r+ h I9 e0 d! u
- .BANK CHR_DATA_BANK0 B9 v5 A2 z7 F- J0 _: Z' H% u2 B
- .INCBIN "chr_bank/chr_data.chr"
+ X4 b% G. @" @% R1 [2 @7 | -
; N! V+ w' h1 s2 Y5 S3 j, x - .BANK RESET_BANK & BANK_DATA_MASK
/ L! y5 r5 T; ^9 k: g - .ORG RESET_ADDR
( v* Q% p: U5 s1 H -
/ b' I) Y, `5 O- }" p' | - ;--------------------------------------------------
- \& e4 S* v j- B - Attributes_Data1 R; j' c; t/ N. V5 o$ w
- ;命名表属性: p7 c" J& G4 o& }- o/ ]
- .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00- H) y4 c, k1 M6 x# F6 s
- .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
6 s; F$ T6 o. q3 r6 p - .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
: _: I. u' `: U- [) l - .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55/ I; F g7 V J8 A. ~( H! C
- ;--------------------------------------------------
0 M, U" s, R& B" ~+ o. K9 R - ;调色板数据" P3 K% E4 t# I5 }- Z# p- M0 o
- Palette_Data& @- n7 C+ @. `7 I% P0 O
- .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
% a% F `( t! M1 ~. R/ Q - .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F$ @1 I) D1 C H7 r
- Q0 Z' p. |# N) K- ;==================================================' q V+ n1 s0 D" a) ~& t
- ;命名表初始化
5 l6 l3 x% e! F3 w1 }0 f+ K4 ?( |8 p) c+ F - Init_Name_Table# Q. L' I# z4 f
- LDA #$205 e, k' l1 v0 ^3 `' a+ x; W
- STA PPU_ADDRESS
1 y) A3 m D, P( n% X - LDA #$00/ U3 w, u& N/ C6 g5 u2 N
- STA PPU_ADDRESS( A7 w6 a: G& b$ u/ f3 S( q( W
- LDA #$00
& }& R: U% \/ ]% G$ K- X - LDY #$00" x$ |% s# f5 E9 ]5 l& J; D
- LDX #$10
" O3 L' q3 o- h/ W* b - Init_Name_Table_Write
( s, c" t* O& ` - STA PPU_DATA
/ X* }0 D5 K H, j9 J- q, S( Q - INY
+ M" m/ I9 K4 |: T( n% q - BNE Init_Name_Table_Write
; E" v+ {! b# [# K; G9 n8 X - DEX
# |1 Q! w" L S/ x. v - BNE Init_Name_Table_Write L1 m# H4 O1 y3 Q3 }' B6 k: ^
- RTS
& k6 E6 ~0 x% y. k -
9 o: w' q$ x( c' t2 U7 _' |* p: u - ;==================================================& |- [( ^% S* O2 Z% h: M4 r" [! l, E
- ;调色板初始化
/ @7 V, P- o# {" s - Init_Palette
& X+ i* U; X# n8 {. D: a! R - BIT PPU_STATUS
0 n* L) O( j! }! l( {( m: Q - LDA #$3F3 J/ U$ j) E( h8 j% R
- STA PPU_ADDRESS
/ o7 d' J- u! v) T6 A# g - LDA #$00
' \# {' o% s v - STA PPU_ADDRESS3 _6 w; [- N4 H# |7 I8 n
- LDX #$007 n J" f, U' A W, s) o* Z3 b" a. a" f
- Init_Palette_Write9 f: C* m" q+ _* D& `; b
- LDA Palette_Data,X, ?$ \# `4 Y( W$ ]! I
- STA PPU_DATA
t7 q2 W. V& E8 N" A' R: ~ - INX' l+ G; u+ d5 }3 @8 a6 t
- CPX #$20; A4 x/ X- b' x0 k
- BCC Init_Palette_Write
' n- L1 u& f8 b: L9 r - RTS
# O' m: D" g! U& I8 m& m -
, x. f( m [* S: V - ;==================================================9 N: j0 l1 z* g$ b! b
- ;设置命名表属性: M- z$ e& K, U, i
- Init_NameTable_Attributes
) p5 U, j, e/ p8 ^5 X' c9 q - BIT PPU_STATUS* I+ [1 [) _4 y/ V
- LDA #$23
1 ]6 }1 D; T0 V% ~( q8 ^! T1 Y+ A - STA PPU_ADDRESS/ T' e. t) ?) {: N( `
- LDA #$C0$ r- E5 ^, Y( B2 t9 } e5 @' {$ S
- STA PPU_ADDRESS
/ R, d0 C% Q# F" A0 v+ P% M - LDX #$000 b- A2 s- I) g
- Init_NameTable_Attributes_Write
* U) F8 h5 k+ I% p* p' ] - LDA Attributes_Data,X
9 A- T: L/ @) Q8 \4 B - STA PPU_DATA) M& d, L1 d7 X+ U3 I
- INX' Y# E- b t5 G0 v* X' c7 t
- CPX #$40/ o5 P% Q, t5 Q
- BCC Init_NameTable_Attributes_Write! Y& z E2 G9 w7 i7 J8 w8 A7 L6 w
- RTS
/ B/ M# }: ?9 d/ ?! i2 t - 9 h5 ?# `( v5 S: H: W
- ;==================================================( @3 u+ X+ k. c. ~% q( _% i
- ;初始化命名表文本
4 N7 G% Z; [/ V. @/ ` g - Init_Name_Table_Text& c1 r# O* s: t$ z2 w+ |
- BIT PPU_STATUS/ f `. N0 N6 ?5 P+ A4 H0 r0 A
- LDA #$20
' T2 J( ?3 Q: ]( p6 W7 @ - STA PPU_ADDRESS
7 H1 C+ R$ l: ~. Q( c - LDA #$00( N) S; B/ s; P; k2 i
- STA PPU_ADDRESS' o: T3 a4 Q. c% s7 L
- LDA #$00" `( r6 b+ M( z
- STA FC_Data_Buf! ~% P1 p) u! l' C, ?( G
- LDY #30
; g# u% `1 d9 H- C0 M. u4 e - Init_Name_Table_Text_Write/ y6 I$ Y/ B# f6 n
- LDX #320 p* ]* o/ f: y/ `
- Init_Name_Table_Text_Write_Char
1 {" E! c" z: s4 n# R0 C! U - LDA #'0'
- Q0 g; p( h* c' Q - CLC8 t% ~ o! o5 ]" N. j) e% X- [4 K
- ADC FC_Data_Buf J8 ^6 S& j: l, t# B3 u$ g* I2 S
- STA PPU_DATA
" e) {$ n- e' M - DEX, K9 @ J0 h+ _# H' z
- LDA #$14" z% o0 g& f0 g6 g* G. ?
- STA PPU_DATA
2 \! `) d3 t" g! d s - DEX
; L; ^, ] ~- ]2 [: M+ D$ Z - BNE Init_Name_Table_Text_Write_Char. \ H; k9 X r" u: |' ` X$ ?
- INC FC_Data_Buf0 F+ i, E( X4 w
- DEY
. p0 m" j! f$ ^+ Q- a& t - BNE Init_Name_Table_Text_Write! B. Q2 F# I6 o; W( l( Y
- RTS
; A" w1 x9 G8 b/ x - b1 W1 {1 C: Z# A% X# n& b$ m5 X' n
- ;==============================. \( C& ]$ F# i: l
- Init_OAM_Ram;初始化精灵内存
" Y, ~- G- m" n) N. E5 K5 @ - LDX #$00+ E4 f8 {' w5 D! K$ F* x# U, M
- LDA #$009 l9 A% S2 \: f" d+ o. @3 j
- STA PPU_OAM_ADDR9 r4 F; o, E1 d6 U2 l% q- u
- LDA #$F8
( B9 ?' i( t4 } - Init_OAM_Ram_Write$ @4 @" \- ~7 l& f! {2 q0 y
- STA PPU_OAM_DATA% V0 ?1 u6 ~) |7 F* F
- INX
, s" U/ R2 Z% `" i - BNE Init_OAM_Ram_Write3 s- s0 U6 q- d* P
- RTS( C/ `$ g6 |% @: X7 K7 l/ w% |/ u
- & G* J2 c u9 `
- GamepadProcess;手柄处理3 ~: O; q3 j8 L! F2 V% p
- JSR GamepadDatacan& Z' C3 ]3 ~2 R& S s' G
- LDA <Gamepad_0_Value) A6 ~, ]3 Y, M) B( P
- STA <Gamepad_0_State2 s+ ?0 { [# i$ q. Z7 l
- LDA <Gamepad_1_Value( M0 K) o1 }( J- }. ~6 |1 b( M
- STA <Gamepad_1_State
7 ]" P; N; r# ^( Q0 w3 e - JSR GamepadDatacan
4 o6 M }; O7 w8 m$ g - LDX #$01
8 O4 V6 s5 X5 `3 { - GamepadMergeCheck;合并手柄输入检查
# F2 R0 r; O- }. u d5 A6 S - LDA <Gamepad_0_Value,X
# @6 S r; r( S& N7 h( G4 H) R% s6 z# | - CMP <Gamepad_0_State,X
; n( q% w: S- l" O! ?; z - BEQ GamepadMergeInput
* u& W% A, q/ O" E8 U# h/ g - LDA <Gamepad_Temp,X
4 k5 I! p8 c4 x - STA <Gamepad_0_Value,X
e; U% F% u8 L/ |/ N1 Y - GamepadMergeInput;合并手柄输入9 E8 W9 U1 s0 g* V/ R
- DEX* F. {, O# o( ]) ~7 Q
- BPL GamepadMergeCheck1 [4 V* o% V. ] p9 w+ ]/ U
- LDA <Gamepad_Merge/ P7 x9 x$ V3 p, m& |
- AND #GAMEPAD_MERGE_FLAG5 H/ o: l6 k' R
- BNE GamepadStateProcess
* F- p8 B% E. [8 g9 ~" t* S - LDA <Gamepad_0_Value8 e D6 y& ?7 I. C- I4 J+ ^2 ~
- ORA <Gamepad_1_Value
* ?& A2 R1 W1 b6 A" n4 l - STA <Gamepad_0_Value
& x, d- X" r4 [ - GamepadStateProcess;手柄状态处理
3 w- T1 v: [. Z9 |+ R - LDX #$010 R8 `* N+ ^/ z, z# ]- P
- GamepadStateSave;手柄状态保存2 K) T6 Z- a& K9 s
- LDA <Gamepad_0_Value,X- Z# u) U/ T A" h
- TAY
" W" Z" `/ O2 | - EOR <Gamepad_Temp,X( k4 x, H; o5 O; }: r- P
- AND <Gamepad_0_Value,X# p7 X3 p0 L$ {! Z. w9 A$ f
- STA <Gamepad_Once,X
: c1 s; d8 o$ i* Z - STY <Gamepad_Keep,X
* T( a6 W2 I+ m6 P1 X9 A0 X - STY <Gamepad_Temp,X
" h+ N0 C, a) Y0 k3 u - DEX9 C: Z2 u( G. W" s D
- BPL GamepadStateSave
5 w. C g6 O2 m$ C& m* | v5 S - RTS
4 W- ]; r8 Y2 Z - ( i2 E5 T/ X, _" f
- GamepadDatacan;手柄数据扫描7 y; ~+ X5 T; x1 S& M3 Y& b. V
- LDX #$01, B5 \* `' I% h2 n6 y. G& I
- STX $4016
+ J' n+ o: T% |; U Q6 ?2 v - DEX/ y9 b' n2 T: k9 h' R2 }6 ~ D
- STX $4016
. ~) b' R8 M# f' O - LDY #$08
( s+ P/ n2 p# X7 { - GamepadPortScan;手柄端口扫描) X# b" f; Z; N5 G1 ]2 s
- LDA $4016
( i4 E0 o+ [4 r - STA <Gamepad_Port_Value: k' `4 x& v( I- ]0 Y; P
- LSR A
& k/ C+ t- K4 y - ORA <Gamepad_Port_Value
3 r- [. D: o' x: O - LSR A
5 R8 q1 y, `, X6 |1 _ - ROL <Gamepad_0_Value
6 k* j% B% t. u( @2 [( c7 ? - LDA $4017
$ K: S! s" G2 H: P2 ~$ ~, R - STA <Gamepad_Port_Value
1 S* a- T1 {& k$ v3 d) G& | - LSR A# Q4 l/ z' u) g' }5 G
- ORA <Gamepad_Port_Value4 B8 M$ ~* o/ S W6 R& \7 C
- LSR A- G# `$ T. y/ g, n
- ROL <Gamepad_1_Value
7 d8 ?1 k; R; k0 v- D - DEY7 L3 J8 z, g% |- S3 Q" f
- BNE GamepadPortScan
( I/ m' d- @) p Y - RTS
2 W, o, y# D4 I! i) e; M -
5 h2 Q; v* }; [) o6 H - ;==================================================
+ f1 p7 A# l8 S. n - ;PPU处理
! Y- d" L3 {4 p - PPU_Process6 Y- g6 M% k1 V4 m, T
- LDA #$00: W& I, d5 m' q% o0 W/ ?3 {
- STA PPU_MASK _) g3 z7 K! s! k$ \) n
- ) V* Q; X+ ~' R% o
- BIT PPU_STATUS6 O+ T1 J' K1 s* T' g( c
- LDA #$20
( c% L) y" v- B4 j0 f* J8 B" y - STA PPU_ADDRESS: R. L$ q5 R' l1 ?. D- t# C
- LDA #$00
7 W: [6 f. e1 L# S1 s! b - STA PPU_ADDRESS; Y5 x" L0 T% W3 r# `1 @
- 0 o2 m& k4 t; X# d; ^6 E0 m8 s/ i" f/ {
- STA PPU_SCROLL
& ]/ f. S6 c- ]$ U - STA PPU_SCROLL
7 {- \8 s! k! q* I -
! s2 D1 f) [( t - LDA PPU_Msak_Buf5 ?# v# A4 h B+ v
- STA PPU_MASK+ T- \! M4 p1 b$ R0 p
! B2 l4 Q: C* ?2 }/ R- RTS7 Q/ J, E7 M) O
-
$ X) O( p" S% C - ;==============================: q. g# r4 b& p' M
- Time_For_Vblank;延时等待
# |( G& `$ x, k) F7 y- {; W9 ?* k - LDA PPU_STATUS
8 s% {) u; d: Q6 Q& q - BPL Time_For_Vblank" y3 Z! j% j Z7 j0 \0 _
- RTS
) J! A& ?! @: P: F/ f -
( Z7 b. R$ h6 [: d) I. W+ { - ;==================================================
) O3 ~. z( c5 @ - ;初始化MMC3
. o6 j4 S( C% H3 w5 k. ]) _7 e! B - Init_MMC3- u7 n1 T" Y f& J; m: b$ A* _
- STA MMC3_IRQ_DISABLE
. G& `, U9 g7 \: H -
) Q# ?) {% F9 a4 f - ;设置MMC3水平镜像: w9 m8 ]+ m+ b
- LDA #$01
% P6 Y' C8 u$ t! I - STA MMC3_MIRRORING
2 g; G1 p4 Q! q4 `# Q -
" `0 r( A9 e8 r: j6 ] q, K- | - LDX #$05
V4 o" ?2 O8 u$ z5 M C6 B - Init_MMC3_Chr_Bank_Write9 |* Y* I* ] g9 {+ H& W) m
- STX MMC3_BANK_CTRL
' S# b" \# \7 r+ N0 W1 u4 ]/ W - LDA MMC3_Chr_Bank_Data,X
% T. e/ I0 m3 ?$ q; q2 g" {+ V - STA MMC3_BANK_DATA
+ N4 v" m5 s" a' |1 Z - DEX/ \# D& A7 H+ A$ e3 }3 F
- BPL Init_MMC3_Chr_Bank_Write
* h( S! \; T6 k. v" r4 N4 b - RTS
& t6 u6 D1 u" u+ m; G, g - ;--------------------------------------------------! d. V: A$ E3 d2 ] P
- MMC3_Chr_Bank_Data4 F D& _5 G& o+ [1 s' U( E
- .DB $00,$02,$04,$05,$06,$07
' L% {" |# L5 t+ h+ v w - 5 q2 r8 V# R; ^( B
- ;==================================================
J r. o) Q6 U q& G4 N - ;重置中断处理$ U# ~8 \ E/ s3 j2 @ S2 N
- ResetProgram
/ Q3 p$ q! z7 A7 D, X" a8 P - SEI' B; ?" Q) P6 X
- CLD" p1 p" i8 q- F" j
- LDA #$00
1 ?2 A, z$ {4 h8 q+ O - STA PPU_CTRL; c5 U' j% r0 i' [& P
- STA PPU_MASK
8 ~" p8 L- C! q# e" I - STA PPU_STATUS
+ x. h$ `: ?( ~ - STA JOY2_FRAME7 x/ p$ b7 k: {' y
- STA APU_STATUS
2 e# @; h$ n G+ Q& Z -
9 l4 S* I$ V2 t' P - LDA #$C0
) j- ~4 |3 l, {7 | - STA JOY2_FRAME% @6 T9 x9 t. O% i8 U' h" A0 C0 b/ a
- 6 w! g) y) @$ U* Z; @7 n' {# a
- ;等待vblank+ _$ ?8 U1 W% [* ~1 a0 I8 N
- LDX #$02
; T3 l! b6 P! b; j) A6 }5 f - Vblank_Wait_1
+ E, N* h8 D4 ^" @" O - BIT PPU_STATUS
# g, q$ A2 p- M - BPL Vblank_Wait_1" m, y) E: S; l, S5 }3 O* q
- Vblank_Wait_2 `4 u. N! V& t2 A
- BIT PPU_STATUS) v" D9 f, _7 e$ C
- BMI Vblank_Wait_2# ]' [( S* Q# d, q; T) y
- DEX
' I9 H2 L/ T- x) `4 F - BNE Vblank_Wait_13 i, O. x, L$ g, l
- $ \3 b. }9 O. a
- LDX #$FF9 f. x3 y$ |$ W6 W2 k9 m
- TXS" @ Z. Q f. I; g
- 2 r/ L2 G9 {% c% x' T- r C
- ;初始化MMC3 I% z8 B/ A( Z- ^
- JSR Init_MMC36 P& i9 r6 A* B* V0 q
- ) [, c: P+ a3 ?0 T \2 J
- ;==============================
8 L6 y* a1 c+ f4 D - ;RAM初始化
8 Z {% v; m" Q: s, V( N0 ]. X - Nes_Ram_Init, ]- r: v, G) g
- LDY #$00
) }9 D" N$ h3 F9 {/ a+ i - LDX #$085 i/ u# i* ?- K$ @+ v
- LDA #$00
4 _* B9 E2 l( G- _# T - STA <$00# n4 @. R$ F7 s+ ~
- STA <$01; v/ B) N' p, w0 u: n
- Nes_Ram_Init_Write' t; b3 G2 |- s( [/ ~( b0 M. s$ d
- STA [$00],Y0 b! X, s# r+ c( c/ O% t! N: P
- INY
+ V7 ?, O- t7 \ X, [; m - BNE Nes_Ram_Init_Write* [9 O+ N7 b; j* y; ~
- INC <$01
' n6 @5 t8 B9 B. f$ w& J - DEX
6 U* P7 F! `, n' R/ ]; M# B ] - BNE Nes_Ram_Init_Write4 ]* v) v7 U! D. Y7 `/ \
- 7 l& U6 N2 N. J, ` ^
- ;初始化命名表6 L1 L2 W4 r8 d* |5 R+ l- ?
- JSR Init_Name_Table
* |) F+ ~; u |9 w - ( @! z M+ @7 b$ V( ?" z
- ;初始化调色板( X7 M: I: x8 A8 K" Q. B- f
- JSR Init_Palette% W; U8 M8 f/ D# h1 v
- 8 ]& a: c% C, P# V" q
- ;初始化命名表属性
% b+ r+ O8 q3 ?' c. q+ w - JSR Init_NameTable_Attributes/ c2 ~$ f6 u. A% Y: q; m
-
+ O3 @7 k4 F" T$ G - ;初始化精灵内存/ c" I7 V+ J- N5 b; u0 }$ V
- JSR Init_OAM_Ram4 q% p1 f7 W, Q
-
$ m. h/ d/ h4 {8 M - ;在屏幕上写点东西
I- q2 U5 L; w }$ j: u - JSR Init_Name_Table_Text C2 {$ G9 a3 `
-
6 P. a0 @! {; c5 N - JSR Time_For_Vblank( N" n8 Q+ ?: d9 H2 C7 n c
- ;开启PPU控制
2 |( V/ `& l. H- } - LDA #$80- |% C) {6 X1 ], \! p! S
- STA PPU_Ctrl_Buf
! m* O' _4 ~+ i - STA PPU_CTRL# ^, I* q I/ {7 \3 c5 G$ _
-
5 z) e$ U, {, { - ;开启PPU显示
7 w7 i1 S s* J" K9 { - LDA #$1E
% C5 Y4 N7 P" q - STA PPU_Msak_Buf* q+ ]1 g* y& B7 }% _2 y8 n1 ^
- & k) K$ {- p" b& C# M1 ~6 N" B7 X) C% Y
- LDA #77
9 q0 b" g/ M6 A* [1 e: }9 | - STA Sprite_0_Y: B8 A! d* z2 z, d' ]
- LDA #$1E
. M' K7 g2 p( ] - STA Sprite_0_Tile
6 ~4 F4 q) C" ]5 N9 e8 ]) k - LDA #$20" R5 d) w! s# s
- STA Sprite_0_Mode
3 e5 f! O2 }3 j; W9 \9 ? - LDA #$00
! I3 \9 N; V l& }# O - STA Sprite_0_X5 a0 F- o7 U0 V6 {, m" d* D8 c
- % D5 f1 @9 d+ C$ q/ {" {; w
- CLI$ z. ?4 d3 r! K. t/ J
- JMP Loop& N; }; |3 U6 V; ^" y
-
% \9 ^/ V! L U. C# f - ;==============================
0 A) c8 t, J0 ^ e4 t, z - ;死循环, 等待NMI中断
" c V) Q! e+ K" W3 m - Loop2 V9 y0 v) u( F2 X) B
- JMP Loop
% `! H! e& h/ B
7 B- B, r7 X& S( [- ;==================================================
1 f" x+ r( @: S5 s" J1 t% W - ;NMI中断处理
' ]$ K1 j& h# u9 i - NmiProgram
% O) I2 O# G+ o) I( d& Q - PHA; _% Y6 Z, X. C1 k9 b7 c8 c
- TXA
1 W% a4 m% }8 O6 K - PHA
/ r5 |, L& w4 b) p: c - TYA
! }" @; r& N7 j6 n, u3 B, B& d - PHA
a9 z4 D* D' L# i - + q' P5 k3 n6 M$ z; h+ l6 Y
- BIT PPU_STATUS7 t# {* x1 ^1 n a8 Z3 N9 \
-
+ r; V; O1 I' k - ;关闭PPU控制9 k% ]; [1 ^8 Y# c- A F5 q* y
- LDA #$00
; f3 `8 q" X* T8 Z0 h - STA PPU_CTRL
: b6 r: f$ Z, \. r -
, N) A" V& G2 \! d/ b& |: m - ;处理PPU
) U& B/ r( Q( q% k0 a) ^ - JSR PPU_Process
9 v$ S" k* b+ ]/ H. t/ S7 h - : f3 o/ c5 T* [9 i- X# {& g6 S
- LDA #$00
% r" y( w @. R% B* k - STA PPU_OAM_ADDR
: z7 C( ^; r& `; a. A& L6 K - LDA <Sprite_0_Y
- R3 }0 J: C) p- ]: E j - STA PPU_OAM_DATA
0 O8 }8 i( S( K - LDA <Sprite_0_Tile$ i& h& Q6 u0 e* d# B" E r+ P
- STA PPU_OAM_DATA. |# @# }) ^* b% i/ ~1 K" ^- m/ `
- LDA <Sprite_0_Mode
. {& Z; M4 [3 W0 Y: x' m/ c - STA PPU_OAM_DATA
* f* K5 d1 U0 ]0 T0 }% X4 g _ - LDA <Sprite_0_X) e" U: L4 x. V: J( n
- STA PPU_OAM_DATA7 Z H" M2 D4 ~
- " _8 i* O, Z0 ^7 W1 \. a5 U; S! r
- ;开启PPU控制
* e: b3 W) n- a6 L* j+ c - LDA PPU_Ctrl_Buf1 j& k! j$ a* O3 z: h; V
- STA PPU_CTRL2 d# n9 N3 m& a$ m! M
-
7 S3 t, C/ K, m5 Q - ;屏幕滚动
8 B, ~$ E3 X& s' h0 J" A - LDA <PPU_Scroll_H6 O, U4 y& E4 V* L3 ?
- STA PPU_SCROLL
1 Z K5 M; f; e( s! ?% J - LDA #$00
. m3 b& B& p9 |& a1 J# z - STA PPU_SCROLL
. a* {# R) W6 Q, p9 `% M - 4 m6 I- h/ c' R' `6 m- n( f! Q6 }
- ;手柄处理
q; L' I! m$ ~' k - JSR GamepadProcess
$ E4 g; p& \6 `6 g) ]- a( T# _ - 9 M9 e( W/ x6 G& x3 |0 V( `
- INC <PPU_Scroll_H
; Y- I# S" W' q' i* \ - 4 o# ]8 i8 C+ n0 P5 a# n8 D
- ;启动0号精灵碰撞检测
. I& Z7 a6 W9 V) u# ~# C - LDA #$01- y0 r! e* J4 ^9 M0 X& X
- STA Sprite_0_Hit_Move_Direction3 I; I5 l! z7 o8 A4 U# p6 m
- JSR Sprite_Hit_Test
9 E0 ~* E: `4 F. L% s m# p -
" ?& g! ]! T% O' p - PLA0 {* t/ Z7 H6 c6 v- I
- TAY8 j6 W( q* A1 P- P5 e z
- PLA
/ \! {/ f' k: K* c, a& H8 z7 ] - TAX
; Q3 B- z) S$ ^, ~* t - PLA
# A/ s" V3 O8 Y: A- k! |3 } - RTI7 Q$ @/ e: _- R+ H' K1 g
- 7 B/ l, I- M& ~) C1 o0 L
- ;==============================( f8 b2 \* i7 K9 X& T( m
- ;0号精灵碰撞测试9 H$ Q4 i0 t& H, e/ |- w% v
- Sprite_Hit_Test* a8 x3 h9 b: K a* G
, t) e3 f, b/ t/ \8 R( Z- ;------------------------------
) N: Y/ c3 {1 ?* y3 i; P - ;等待0号精灵碰撞状态取消4 C: j# j; x z- L
- LDA PPU_STATUS" s' N m% R) C2 {
- ASL A) ?& R+ ?( r* \6 ]. l& c6 \& z
- BMI * - 46 t# u0 g# g- e: X3 x* Y6 x
- * `' m I8 g4 L
- ;------------------------------
/ L. |! ^. A7 [' N2 H; r8 A; X - ;等待0号精灵碰撞发生
& q6 q0 H$ X5 p' U' l - LDA PPU_STATUS
1 t- p |3 q" F9 ? - ASl A
; M8 J d8 }2 A# c+ T8 Q - BPL * - 4& P1 ?' \9 {* Y2 A7 `
3 b% D. w- ?2 [, e! m! V7 x" `- ;------------------------------
) O3 o4 i' e( H - ;行消隐等待
2 U i2 \- y3 y8 V - Sprite_Hit_Scroll_Wait
% k2 h; U0 u+ I7 V8 Q8 q - LDX #$28
: M! w" N7 O% C- K3 u5 ^7 \ - DEX( P N+ L/ S" k* e( F
- BNE * - 10 G! \6 h0 g' \
- " J6 T; w: N3 V7 d' H! A
- LDA Sprite_0_Hit_Move_Direction- d) f& m" i0 \; z- P! O
- AND #$01' r% f/ F1 X! r* _) s- H( h
- BNE Sprite_Hit_Scroll_Set_Right
7 `& P. V, ~6 v& `
0 D0 a% K$ G! V7 `) G g/ |- ;------------------------------8 b. h S* q% A8 E* }
- ;分割画面向左滚动: v( U% R' ^+ C: j' I
- Sprite_Hit_Scroll_Set_Left/ y- r& H, {% F% \" L1 v3 P
- LDA PPU_STATUS
, k* [( k5 e; ~9 E5 ~1 F& S! A - LDA <PPU_Scroll_H. Z7 i- n1 A. N
- STA PPU_SCROLL) H9 r1 K% p) d/ G; p7 z
- LDA #$00
2 T2 G/ \# d: B - STA PPU_SCROLL
8 w, c+ F* `& p" q, n - RTS6 C* x" l m: P# W, d8 A) r% e! D+ H4 O, @ Y
) v \, V9 l6 ~3 ?2 L- ;------------------------------
2 w) p/ X4 S& ~ - ;分割画面向右滚动
4 o x8 {3 S4 x- v4 A - Sprite_Hit_Scroll_Set_Right
# n6 u/ B6 |; W9 |) } - LDA PPU_STATUS( K* y3 ~9 j+ J! f
- LDA #$00
_; I2 k- s$ X+ {( j - SEC
7 c9 X! J4 a" w2 I& M - SBC <PPU_Scroll_H1 I# v1 k: e: I% D
- STA PPU_SCROLL
" s6 l4 e. O7 `+ M/ i# @ - LDA #$00
$ H X+ ?) t$ T - STA PPU_SCROLL( X6 _7 J* l! n1 B" y& K7 T; u
- RTS* a& H0 }% {4 n: ?
- 0 Z( Z: L O( q# e: t7 p
- ;==================================================& d) ^+ D. @' j! m
- ;IRQ中断处理& s2 B7 s2 `; d; n8 e- m" t0 W
- IrqProgram
' w' t- \% i9 T% o5 y! a - PHA& J! r( L, T2 e V- g
- TXA- u" \, C- y, |( |9 |; m
- PHA/ u, q' g. l/ L: x/ a) y& r# f
- TYA
* O$ K/ K, U1 d+ \ - PHA* g, D: D6 Y+ p$ I
- ! Z4 c3 _4 s7 ?5 {
- ;关闭IRQ
6 y6 ?' _/ k- `8 K - STA MMC3_IRQ_DISABLE8 T6 f+ m) {( c6 Y
- ( ^3 S+ o' U; c( a, C$ [; ?5 T
- ;允许下个IRQ触发3 ?. I; P s0 N! ^
- STA MMC3_IRQ_ENABLE) ]" t! F% n i& ^
-
9 U0 A, L, O! g2 I- Q& y1 q - ;IRQ处理, 15线后继续触发' C, x0 L& J" m2 y0 b4 I( J D
- LDA #15
* s ?% s5 H3 I7 V - STA MMC3_IRQ_LATCH0 k. [: y6 @& T' V$ T
-
C! J/ l0 I& o# _6 N; T ]/ K( K - LDA <IRQ_Index. Z# s. a9 }5 u- s6 @! x Y
- BNE * + 4
5 v+ c7 p. z4 m: Z - INC <PPU_Scroll_H
# I4 y& l% K% B -
! f# E1 t5 b9 ~* q - ;设置屏幕滚动. D! m$ G3 U: F
- LDA <IRQ_Index
0 N" S y0 J4 a$ R1 \ - AND #$01" d" X2 I5 ^+ X' s$ c1 Y- \) V9 o
- BEQ Irq_Scroll_Right
, L K" a$ C: [7 g
- Z6 } E @8 J- M- Irq_Scroll_Left% a0 s! ]. Y( K6 J0 Y) k. M+ K" C h
- BIT PPU_STATUS
0 j; |. S7 P# Z: n - LDA <PPU_Scroll_H( ^% I7 [( J2 M: u' S5 s2 B1 q
- STA PPU_SCROLL
* }5 S& J% Q! B8 o - STA PPU_SCROLL4 J, S8 m/ O5 [# }2 P# r6 ^
- JMP Irq_Scroll_Over
+ y6 i0 W7 M1 k! \: _. v; | - ) T, ^" ]4 k8 b6 a/ u1 d! A
- Irq_Scroll_Right* g/ C9 @: P7 U! \
- SEC
% M+ z" y& G* e! o7 r - SBC <PPU_Scroll_H
; b: c0 ~+ {; a9 r* _6 v# ?* a - STA PPU_SCROLL7 l+ _0 c2 u+ p' _4 t% _2 A
- STA PPU_SCROLL
1 N# s' C' V$ d1 I - Irq_Scroll_Over
7 x' b( t0 b: K - 5 A2 ^9 c5 [% M a5 {
- INC <IRQ_Index
! ]9 f' I5 H* u - " E; n7 t t/ f+ R$ d2 T" L
- LDA <IRQ_Index
/ T8 b2 [5 e3 P8 Z - CMP #14
0 x. `% p! B" e* a6 O( P4 b - BCC * + 5; V5 Q7 Z/ k% J
- ;关闭IRQ! W% C# e* v/ H) E; D0 t
- STA MMC3_IRQ_DISABLE
0 X$ J: @8 A. I0 Z# Q% o ? - ) g! u `8 O# c0 J+ V3 C& m6 d% M
- IrqProgramEnd* ^+ _' G. |( z$ _
- PLA5 ]; H( S1 |. n9 _, w
- TAY$ M5 C2 ]% W- U! P- N4 {
- PLA
# C# y! Z# w, ]; t" b - TAX' v$ K: H% f& _& Y
- PLA
5 \% ]. W7 P. z- H1 W& g - RTI# `* m' y: V& s) Z( \! ?+ Y. q
-
2 L# H1 H1 y A. Y* P6 A Z - ;==================================================2 o5 K' X* T0 |8 k
- ;中断表% q3 B5 u0 ]$ P! S% p
- .ORG $FFFA
1 E( P! v8 ?0 B! w - .WORD NmiProgram
( O' {3 [, t& Y# B - .WORD ResetProgram
. l; B3 m& v4 L: f/ Q - .WORD IrqProgram
复制代码
- z7 r3 ^, E. V" F |
评分
-
1
查看全部评分
-
|