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