|
- ;[FC音乐][MMC5 IRQ]
6 u# Z" k- X* @; U) l: f - ;FlameCyclone 20230710* y) O# |; x9 u( P0 e) Y
) I. ]/ u! `0 Z/ _- ;文件头
' |8 B8 ]$ h2 ]( z# K - ;======================================================================* r. [4 F2 _% J/ K- j$ |
- .INESPRG 4 ;16KB PRG 数量
& D V0 [- X& D4 M* G! G - .INESCHR 1 ;8KB CHR 数量& [) ~7 I c9 X0 ^2 V7 M
- .INESMAP 5 ;mapper 5% `8 A) {$ C: N3 U
- .INESMIR 1 ;命名表镜像 0水平 1垂直1 ?) W, p Y7 k& G* e0 C% X B
- ! M e! X7 c: o* J+ R. Y7 ^
- ;必要条件
8 z; B5 i b8 ] ], p - ;1.持有CHR ROM! V5 F& A. g$ Q" C( ]6 c2 y
- ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000* H: _; y/ ~$ ]5 Q. W* l
- ;3.精灵内存(OAM)不为空: J4 A2 Q6 m0 q' q) P
- J1 i( H w0 f# X% e) e3 m
- ;==================================================
/ v; n3 f+ b+ K4 |7 n - ;NES端口常量
A% _+ t; T* e" O6 N8 y' n - PPU_CTRL = $2000 ;PPU控制寄存器2 A3 g) c7 Y# ?/ ]
- PPU_MASK = $2001 ;PPU掩码寄存器
9 a9 e4 n( p! S. b% q7 _& r - PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
/ D) C1 w. Y) A' `5 T P( c. ` - PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1; U( ?4 I$ `! L, \) k- L" Q
- PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
: W5 ]7 Z) M1 L6 q; |9 P/ v8 }! R: o - PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
7 k6 C- E- u( ]4 q! D G" j5 I4 ` - PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加: P' D- a# b$ \1 ^; Y$ D
- PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
- u% ` e1 K" O7 i - OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
( z8 Q! Q% v# T, M - APU_STATUS = $4015 ;声音通道切换
" b7 N4 v" j1 {0 C O - JOY1_FRAME = $4016 ;手柄1 + 选通
( m# K; j$ s+ O7 u2 a. _ - JOY2_FRAME = $4017 ;手柄2 + 选通
( Q+ N) k6 \4 s$ }4 {5 j
6 Q- ?$ ]/ K# G! B$ t- ;==================================================' f2 l( `4 D- l3 s3 B4 M" t
- ;MMC5端口常量
+ `& w, `" P6 i+ T/ u! a - MMC5_PRG_MODE = $5100; 0: 32KB 1: 16KB * 2 2: 16KB + 8 * 2 3: 8*4
# [2 B) f3 r4 [: }3 X! i3 @" L - MMC5_CHR_MODE = $5101; 0: 8KB 1: 4KB * 2 2: 2KB * 4 3: 1KB * 8! _, v7 C; c% _
- MMC5_PRG_RAM_PROTECT_1 = $5102;( ~7 ?% @6 K9 ?# S4 S
- MMC5_PRG_RAM_PROTECT_2 = $5103;/ B+ T( y8 d; L
- MMC5_EX_RAM_MODE = $5104; 0: Write Only 1: Write Only 2: RW 3:R6 V8 W5 P- x* A2 r4 X7 e) E3 B; C
- MMC5_NT_MAPPING = $5105;6 Z2 {6 n/ B$ E- x' H
- MMC5_FILL_MODE_TILE = $5106. S$ R6 [' h, D2 u# ~" ~& r7 P' a
- MMC5_FILL_MODE_COLOR = $5107! @5 t0 x/ X P/ D! N) R
- 9 @. J6 a5 f) D' x$ u) Y$ O
- MMC5_PRG_BANK_6000 = $5113
2 v7 L; l7 `8 w0 H - MMC5_PRG_BANK_8000 = $51144 h2 \$ u) }/ Q& R6 @- }
- MMC5_PRG_BANK_A000 = $5115* I; g! Y- Y3 h% p
- MMC5_PRG_BANK_C000 = $51169 N! Q9 Y$ }5 ?4 W+ q- [
- MMC5_PRG_BANK_E000 = $5117
5 p$ n! `7 c/ W4 G7 C -
2 N4 q; o R; r) }3 X# | h6 l - MMC5_CHR_BANK_0000 = $5120
+ l# i2 l, y* s* [4 ], J+ X" m - MMC5_CHR_BANK_0400 = $5121) |; N8 F# O0 e, p/ d6 n0 t
- MMC5_CHR_BANK_0800 = $51221 |3 n: y4 n l& F3 d
- MMC5_CHR_BANK_0C00 = $51232 j4 {( \1 h, ]3 U& t V+ C
- MMC5_CHR_BANK_1000 = $5124
7 l W) Q: }1 T- z( S - MMC5_CHR_BANK_1400 = $5125
8 X ^9 U. H) B. W) Q& M( Q - MMC5_CHR_BANK_1800 = $5126 Y* U% o) e5 x% p! z9 f
- MMC5_CHR_BANK_1C00 = $5127
) R5 P5 w @3 y - 1 U: {2 w9 S$ K7 _
- MMC5_CHR_BANK_0000_1000 = $51289 P) L! h/ l; P' a8 F
- MMC5_CHR_BANK_0400_1400 = $5129
. h$ h' Q+ x1 @ - MMC5_CHR_BANK_0800_1800 = $512A/ g+ [' o* U) o3 Y8 b
- MMC5_CHR_BANK_0C00_1C00 = $512B
3 ?/ B0 e. g( z" d -
" x/ E7 E6 s4 j0 W/ `" q3 l - MMC5_CHR_BANK_UPPER = $5130
0 I7 _5 E( D7 _8 k+ x - MMC5_V_SPLIT_MODE = $5200
9 A- T9 r* Q# d! O/ `% [: w - MMC5_V_SPLIT_SCROLL = $5201! X0 G1 M) z" N( k) V4 x, ?/ e7 b U
- MMC5_V_SPLIT_BANK = $52027 n+ S0 l7 m) X1 G1 D; Y" L
-
% ]+ c3 d; H; E# U! p7 e' t" J - MMC5_IRQ_SCAN_CMP = $52033 o1 u1 y3 I! y; j+ @; p
- MMC5_IRQ_STATUS = $5204
7 N2 {( A0 @( A& Y - MMC5_MULTIPLIER_A = $5205& h# V# m- i# U" c
- MMC5_MULTIPLIER_B = $5206$ Z) |0 o% E3 Q, a1 ^! \) _
- : B2 s" v0 T1 A# f' _
- MMC5A_CL3_SL3_DATA = $5207* K1 f% Z2 r, F. Z" M2 h
- MMC5A_CL3_SL3_STATUS = $52081 O' `9 B! }- u8 C/ T, T/ X- q
- MMC5A_IRQ_TIMER_LSB = $5209
; x) l4 K* D5 U; ~ - MMC5A_IRQ_TIMER_MSB = $520A
0 \2 A- b# q) Z9 ~# {3 O
$ j- @1 S; P5 e5 K! l! B- ;==================================================
0 L" U$ |* d+ ]4 l - ;程序块配置
) y: Y2 x& {4 f4 h. K. P3 y - BANK_DATA_MASK = $071 ?4 I' L0 y% y' ~9 r* X; B
- ;-------------------------------------------------- q+ G7 Z" v) k' ~- M
- RESET_BANK = $073 g, H# l# _6 _, y1 w- z+ |
- RESET_ADDR = $FC00
% L u" S+ F5 y+ E$ I
8 @) {4 t$ @: Z+ ]7 c* W* ~/ q7 L) S- ;==================================================
4 }; p# J) S# ~/ z; m) }3 l - ;图像块配置/ O4 Z; H1 }9 [5 W1 M
- CHR_DATA_BANK = $08
# E8 [# t# b2 E! ?- \" S& l( \
) E9 W, I+ ~2 ?$ h e8 Q! k, L- ;==================================================
: v( a4 w& a. n+ o M V6 n `+ e - ;零页内存地址配置7 i6 K9 @4 z1 S& N- U
- Use_Ram_Addr = $80
0 y H/ q) X- f0 j+ y5 ?1 { - PPU_Ctrl_Buf = Use_Ram_Addr
6 p; L5 m/ l q' h+ q# N - PPU_Msak_Buf = PPU_Ctrl_Buf + $01
9 z2 J3 P/ G2 f. ?7 c4 h7 c5 K9 ]- ~ - PPU_Scroll_H = PPU_Msak_Buf + $01
! @+ d+ v% v5 E' c% Z - PPU_Scroll_V = PPU_Scroll_H + $01
- N. `' i, P$ R - FC_Data_L = PPU_Scroll_V + $01
# _! F6 T" c' }/ P9 t% [- V6 U& Q - FC_Data_H = FC_Data_L + $01
8 ~ @; j2 m: J+ D - FC_Data_Buf = FC_Data_H + $01
/ s% S/ s1 _1 s# @7 | - ;==================================================4 ^& g' g4 H! K' }- c
- 8 r8 n. `8 p5 A j
- GAMEPAD_MERGE_FLAG = $04( S8 U; c; v( n: y
- D6 J; Q7 t# e- Gamepad_Keep = FC_Data_Buf + 1% d/ _8 |0 p' m* `8 r$ H' K( N
- Gamepad_Once = Gamepad_Keep + 2
+ w% }; e, V3 a+ Y - Gamepad_Temp = Gamepad_Once + 24 G$ I; y8 F! G* w3 C
- # y9 O: F/ d& ~# t4 L Q
- Gamepad_0_State = Gamepad_Temp + 2
+ i0 J- C7 { ~ - Gamepad_1_State = Gamepad_0_State + 19 d) T: ^* d4 ?7 v$ E
- Gamepad_0_Value = Gamepad_1_State + 1
" l* \+ Q+ ?& O: K- b8 o. D - Gamepad_1_Value = Gamepad_0_Value + 1" J0 z/ X! T% \- U2 @
- Gamepad_Port_Value = Gamepad_1_Value + 1
: h+ X, R" R u' Q% G7 @% I! U; x - Gamepad_Merge = Gamepad_Port_Value + 15 Y+ Z/ x4 {! g3 M
- ) [. S, B% o7 p; D: M$ R4 T. m
- ;==================================================6 j1 \5 H7 \# Y6 f, K
- IRQ_Index = Gamepad_Merge + $01
3 ?4 p; ] y* n L4 {4 H - ;==================================================
# {" G2 \6 q: n3 A! O3 g
1 l" z( C/ B' f/ v- ;CHR图形数据8 }$ m) Y6 o1 R% v" B
- ;==================================================; g* I! P2 I- j# H
- .BANK CHR_DATA_BANK
) G. \# k6 w+ m+ N2 V+ e1 E+ S - .INCBIN "chr_bank/chr_data.chr"
. w8 i% N$ C- ~5 I, G/ g9 {3 l -
2 C4 }& j& L- y3 O' g1 n* Y - .BANK RESET_BANK & BANK_DATA_MASK
9 k ?+ M4 v, O! I7 } - .ORG RESET_ADDR
8 g% v1 S# l: N" `7 ? - , ], [6 L T: A* h$ A" V
- ;--------------------------------------------------, d" Z$ j7 O: V0 x3 N
- Attributes_Data
4 E9 ]& K& G K7 t# i - ;命名表属性, E* w) ]8 B: N' U* Z6 f; n; G. |
- .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
! ^+ j. K$ \' O! B! i6 h0 l - .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA1 x1 ^) m2 w% P
- .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
! j9 |2 v/ f4 z. [. A0 O - .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55: K/ T& D8 o" }- W
- ;--------------------------------------------------
$ X; R6 J" }0 e# d - ;调色板数据
1 u7 X9 j% A) r - Palette_Data
/ i1 n0 ? ^+ k# i- P+ P - .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
1 B8 z' H4 {, w - .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
[" ]4 d4 n# U7 S - ! ~+ a: a4 k) _" |! \: X
- ;==================================================
9 f$ g* e% f/ m i r" x6 I( q4 D5 L - ;命名表初始化
$ _0 a' m' f" m! j3 g! v - Init_Name_Table
( |/ p! h5 F- K9 b$ \( k% W- U - LDA #$209 ]/ h0 K* ?$ E* E& Q4 g2 I3 M% \
- STA PPU_ADDRESS
# v- p1 p: D# K4 w& `: ^ - LDA #$00
/ a9 \1 W A8 a3 n: F' d - STA PPU_ADDRESS4 I9 F$ g( C1 A8 g9 i2 J
- LDA #$00
9 A, |" w8 T# S( f4 t. G6 f - LDY #$00
% I9 v2 D$ A* k4 u, i) p - LDX #$10
* }% v* `+ X% l& `- j9 q R0 \ - Init_Name_Table_Write; c, f, s0 E2 T0 a1 A( C
- STA PPU_DATA
8 m, ~9 P+ Q$ A/ ~ B/ Y - INY
* X [4 A6 z7 ^5 {6 S! c: D+ { - BNE Init_Name_Table_Write3 l8 W' F2 t+ {' a7 N- w
- DEX$ N0 ~7 r @# v; @6 H
- BNE Init_Name_Table_Write \1 k3 _. z6 U% S9 l9 I
- RTS- s A# R+ n3 I, j* v- m' v2 U
-
$ J5 D3 A/ `2 G' C2 {0 ~9 ^" u - ;==================================================
% A" G4 S4 ^3 |6 p* Z3 S3 t( u+ F2 k - ;调色板初始化
# E1 s" r- f/ }# T1 Z3 s - Init_Palette
! R8 s B! M! w& G0 D) W6 g - BIT PPU_STATUS
% m/ l$ U0 ? ?, y9 k/ P - LDA #$3F
1 r( P0 E& x2 m! `# u! n - STA PPU_ADDRESS3 i2 D9 S- z: x; v, V/ ]
- LDA #$00
4 `9 q9 b# @9 X/ K& P6 ? - STA PPU_ADDRESS
- L, m' @# E8 [- q - LDX #$00; U- K* Z& Z# I: e) g8 l+ ^
- Init_Palette_Write' O8 |, W: ?* |, Z
- LDA Palette_Data,X
! e2 q" J4 i2 N h+ T - STA PPU_DATA0 B, l$ F; e% h) {# e
- INX; o9 t$ e$ W5 H) b( C" @
- CPX #$20/ a+ w8 \' a( U: a$ J* \. ?
- BCC Init_Palette_Write
y. m* C& E+ j J! L - RTS
. K( l$ Z" F. Z: _9 W% o -
' X! S; i2 s9 C6 {2 D( `( z - ;==================================================2 L) j& T6 V+ O( \: `
- ;设置命名表属性
8 s1 y) I. D5 T$ b, x3 y - Init_NameTable_Attributes- Y/ F' C7 I3 ~( L% d: v* O" i
- BIT PPU_STATUS( q$ q5 j% u* ?8 T& S
- LDA #$23
; {& r, G$ p/ e Y - STA PPU_ADDRESS1 A! @) \' L( I i* l+ O6 [0 f6 b1 G
- LDA #$C0
6 S. w* U4 ^& o% H. O - STA PPU_ADDRESS& j4 }8 G% _4 m. @7 a7 C9 o
- LDX #$00! a2 S% U m/ ]
- Init_NameTable_Attributes_Write! I" V3 @: a0 {" T# S! R: [
- LDA Attributes_Data,X! o' C6 g6 f7 j% m, ^2 X: N
- STA PPU_DATA
8 ^- H6 U+ q6 g5 w$ Z0 s8 [5 G - INX
" q0 e" o4 f/ K& {/ K& Z3 q - CPX #$40
- q. r* K0 v% z, D - BCC Init_NameTable_Attributes_Write
; G% Z6 L$ J2 q% j% H" y- k - RTS+ f8 J. J" k6 m( U* d
* e" ~) p$ N1 W$ G9 Z9 W: Y! Q- ;==================================================9 ? z! o- O4 u7 p( V6 S0 v
- ;初始化命名表文本
% ~% f" p; B0 U$ a- m - Init_Name_Table_Text( F- G, \8 [3 \" P4 V
- BIT PPU_STATUS
. T0 ^! J" b/ J4 _ - LDA #$207 j8 p! K$ \, V0 c# ^% [
- STA PPU_ADDRESS
6 [ Y; f. q# H6 f6 v3 Y6 ~ - LDA #$00
" r7 i8 Z# y$ ]% e2 S - STA PPU_ADDRESS
! G( P; I6 k# {6 V - LDA #$00
2 Y8 x2 c# O% F% K* [ - STA FC_Data_Buf
/ z) i/ u" {+ Y# M - LDY #304 M' ]; n A7 _8 G( h1 G- v# q6 k
- Init_Name_Table_Text_Write
7 r( t. L; C7 w9 M+ ] - LDX #32
7 ^6 v: A2 L8 G/ D - Init_Name_Table_Text_Write_Char
% h) K" H- Q! K* k2 K& _$ z - LDA #'0'
+ _( r6 m$ C* _, v; G; ]0 u7 V - CLC2 S8 B( R: L n1 f& R5 v2 w7 ~3 J
- ADC FC_Data_Buf/ @" {( N% S$ x+ R5 _8 Q* E2 n. u
- STA PPU_DATA- C. F q$ I8 c" ]2 Y+ Y _
- DEX! R, l5 \ D* H# P3 u
- LDA #$14+ y. i9 Q0 [& o d. g
- STA PPU_DATA
4 c# c2 P) k* I0 T0 f% H - DEX
* v' r, g U7 _2 [8 g+ H! D - BNE Init_Name_Table_Text_Write_Char. z; V! i, R' U& D3 W/ x7 y; S
- INC FC_Data_Buf% e" B- r% V" r6 ?0 ~
- DEY2 l) q$ N7 N, g5 |. ]/ S
- BNE Init_Name_Table_Text_Write8 t9 t7 o6 U% K
- RTS4 u& n. W/ [7 O/ q6 i: q! z4 R
: W5 o4 d' R" v( l @% j& J8 X- ;==============================
$ d& |% H; t( T: ? - Init_OAM_Ram;初始化精灵内存
' E, \# c L" D, x# z - LDX #$00
9 `- k) c/ x: K6 @# h, _4 C - LDA #$00
5 R& F1 i! ]( l# @4 A5 P n - STA PPU_OAM_ADDR; C5 u* [* \! a! o! K
- LDA #$F80 _2 s! V1 k9 q% v- r7 A& t: j4 L* `" W
- Init_OAM_Ram_Write
: k4 |: X: N+ A - STA PPU_OAM_DATA
9 G6 y& Y0 ~$ I0 l, ]/ a$ ^9 Y2 k/ C) ^ - INX! t0 J0 E9 v w; h3 C* t
- BNE Init_OAM_Ram_Write
8 P+ Q' _- t) A4 ] - RTS
9 E. E* J `* D+ t- E \6 v - ! |% D- p7 {/ h2 ^: i; Z6 v
- GamepadProcess;手柄处理
1 m" z; `, O' o. z' d; J0 r - JSR GamepadDatacan
& N. D. d# g7 }9 q5 K - LDA <Gamepad_0_Value6 E; f5 J/ [ s# p1 ?8 Y) G
- STA <Gamepad_0_State
7 z3 A6 l7 ?% Y2 O - LDA <Gamepad_1_Value$ e. f" L6 V3 y
- STA <Gamepad_1_State" Z' M* t* e' |/ `
- JSR GamepadDatacan
+ A9 _8 A# v# G. _ - LDX #$01$ P. Z; x" G6 h$ Q* ~3 q3 c
- GamepadMergeCheck;合并手柄输入检查
: W m0 K' t: p G& o6 D0 [ - LDA <Gamepad_0_Value,X
+ {5 ?* t# R: F4 Z" g' f7 G - CMP <Gamepad_0_State,X- [; l1 ~1 J6 ]5 V
- BEQ GamepadMergeInput3 I2 @8 Z/ x2 G1 g5 n# Y2 Y3 s
- LDA <Gamepad_Temp,X$ |# R: I( V0 y2 l
- STA <Gamepad_0_Value,X! _2 T! t2 m- A. A
- GamepadMergeInput;合并手柄输入# G& l8 k3 h0 Q5 f7 \
- DEX
3 o+ q) w& W3 x5 V" B8 S3 E - BPL GamepadMergeCheck
- R/ R5 G$ ^. | ?& w! }7 ] - LDA <Gamepad_Merge% g* X( {, b+ a5 b
- AND #GAMEPAD_MERGE_FLAG
3 N% F% R, G) g# w @ - BNE GamepadStateProcess% n3 _+ b$ D' T% x
- LDA <Gamepad_0_Value8 M7 ~) H0 a- f2 w/ w4 B# Z9 h6 ^
- ORA <Gamepad_1_Value
' G2 [2 l, y$ C u1 m8 e l - STA <Gamepad_0_Value P; u& i( _; q4 K* P
- GamepadStateProcess;手柄状态处理4 [8 K, X% \- l( |, a
- LDX #$011 J. m8 [1 h: v6 @7 @
- GamepadStateSave;手柄状态保存
5 J7 H, B, x3 N7 z' S- ` - LDA <Gamepad_0_Value,X! U U0 I# b+ `% T# l6 J
- TAY' [7 |% [, C( R/ T' W# \ N
- EOR <Gamepad_Temp,X9 C3 f7 z1 l. @! L3 d6 r p+ y
- AND <Gamepad_0_Value,X
" l& p# J' [* Y9 M, E. ~ - STA <Gamepad_Once,X7 X! ~$ I$ l! p) i2 j! B6 B
- STY <Gamepad_Keep,X5 \( B+ c' p7 m. ^9 E9 P
- STY <Gamepad_Temp,X1 o) q3 X3 Y, X8 ]
- DEX: H* n$ m n; _. w& \( c/ u
- BPL GamepadStateSave X" W0 E8 u1 O* G9 K: g7 a0 p8 W) G; y, o
- RTS' N9 m" \& @" n) }+ m) u
- ( ]/ @0 g, r: G& S
- GamepadDatacan;手柄数据扫描9 e* P4 c/ A* M/ H6 _2 D
- LDX #$01$ z, O" }. f* ~+ I
- STX $4016. F$ |* @3 B( B1 M
- DEX( _* h0 W( V& h
- STX $4016 o9 {5 ]/ N/ y! I9 _* ?
- LDY #$08
3 \! v6 b0 A) ?; W* i - GamepadPortScan;手柄端口扫描5 x! T' K6 d; N+ D! d4 h
- LDA $40163 s; K( w- F* n1 A/ K4 w" e
- STA <Gamepad_Port_Value
$ x' a; ~! f% J" ]% w: |0 Q& k - LSR A: L% i4 r2 z% ~2 h
- ORA <Gamepad_Port_Value
0 [/ `( N) Y# |, H; H0 ]/ H - LSR A" F9 B8 r9 d$ O; o# I( Y
- ROL <Gamepad_0_Value
) e9 `/ H" q2 ?7 D% S - LDA $4017! w; S# u$ L. b- B" `
- STA <Gamepad_Port_Value+ {2 {; b* V4 a( h q
- LSR A
7 S8 n' {! h, C, M3 A' a - ORA <Gamepad_Port_Value/ I1 p2 X7 j7 w4 E
- LSR A- i- E1 C9 W+ N. S! @! u$ h9 l4 U
- ROL <Gamepad_1_Value3 y, d' t: P' h
- DEY: V" P( w% A. Z/ m* ?( S3 a+ b
- BNE GamepadPortScan- |% B+ q+ d! C c U, J
- RTS
) l$ p1 B4 L3 X - 6 Q% Q' F: @8 b2 U6 r ?
- ;==================================================4 @( p# Y+ h) g; o- W$ G" H4 M" V
- ;PPU处理
1 Z- O+ F e$ t' A! z4 a - PPU_Process
h: c5 ]3 A: e5 W+ |8 k1 b4 A - LDA #$00
9 g& o" f; S3 F0 L1 e! W - STA PPU_MASK5 f8 R' C% y+ ?; w* e# _9 i
- 5 Z$ V$ [6 h8 e* \; Z" L) a7 L( ~- n; T
- BIT PPU_STATUS, `) b/ |( C( d, l! t
- LDA #$20
8 u; y' _2 D9 b, `. ?5 J3 H - STA PPU_ADDRESS7 a! r: t4 j' q: z
- LDA #$00+ ^& Z6 Z+ S) f8 B0 \* Y
- STA PPU_ADDRESS9 D( x$ J9 V5 L/ L# h
-
# {( h9 d+ y6 |+ F% i W; s4 r - STA PPU_SCROLL
6 s; v0 C# `/ V3 [7 P - STA PPU_SCROLL
6 x5 }% G* Y6 x1 G- I' y - T) K1 ]8 o$ d0 B8 @! k1 d/ {
- LDA PPU_Msak_Buf
1 @9 u/ z" m6 G; Q: _ - STA PPU_MASK
9 C" q; ]& n( x) b. l$ u7 y e
( s S" d: h9 b4 {3 K$ C0 q" l* T- RTS
5 M. } A$ K$ \& R - 2 B# r* t+ S' k
- ;==============================* D% r5 X2 I; Q# }# h$ R9 f
- Time_For_Vblank;延时等待
* ]; i' [% j3 O7 ^7 m- `" h6 J - LDA PPU_STATUS' ]8 u* c' p) o5 v5 I1 ^8 R
- BPL Time_For_Vblank: p+ g d1 q& Q; f" T2 B5 v8 y7 ^
- RTS
2 t1 @* `4 i1 }* r - 3 m7 b& X3 V# }! D- [5 N
- ;==================================================
: w5 e% Y- e6 F7 |. }7 \6 Y7 K - ;初始化MMC57 v* t+ z& T) q8 z$ o
- Init_MMC50 P3 p n3 i4 S) ~3 X- f6 l
- 6 h, d. W. q7 q- ^$ t
- ;设置一下6000-7FFF的RAM0 _! u$ m( k, U/ m4 y
- LDA #$00
! ^" m; y) Y' R$ j9 [6 |( e" M - STA MMC5_PRG_BANK_6000
; n* c; ^, L# I$ s -
: k! X, u% w7 T4 Y. q - ;开启 PRG RAM 写入
( g& e; k* ?/ w4 B - LDA #$02
/ U" I8 X8 q: b6 M - STA MMC5_PRG_RAM_PROTECT_1
6 Y& H. q5 f3 \( x - LDA #$016 a7 G7 J/ D8 }/ Q$ `
- STA MMC5_PRG_RAM_PROTECT_2
- T5 a' X! u) z7 _/ Y' @7 ]8 n' j -
+ p% O( c/ D3 z) c - ;启用 1KB 扩展RAM ($5C00-$5FFF)8 _% E5 R6 J9 e2 W$ A6 d
- LDA #$02, k% a5 W, G8 R1 F5 \$ X. d; x; N- u
- STA MMC5_EX_RAM_MODE
) o% c/ g) H: K) v% Z# U2 P0 j -
4 m7 x; ]( B) | - ;设置 CHR, {* ~. r- Y( ]- m8 K; O, s4 v1 [
- LDA #$00
c+ M8 |) w" H; Q - STA MMC5_CHR_BANK_0000
5 c; H5 O& v J; ~ - LDA #$01* H. N6 Y, a$ E3 t8 M2 i4 n7 i
- STA MMC5_CHR_BANK_0400: Y. B: F3 O" Q' \
- LDA #$02
* \- n# _! ?# c n% H& Z* ^ - STA MMC5_CHR_BANK_0800
9 ?7 y0 M2 D3 c& X+ D( E - LDA #$03
: Q9 t( b- h H: O9 Y; E F - STA MMC5_CHR_BANK_0C00
6 g4 X5 s" n! C; J4 l- G' F - LDA #$04
% t* L4 r( w$ ?$ }7 \4 |; x - STA MMC5_CHR_BANK_10000 t5 P& q0 ~* P1 R
- LDA #$05
2 L+ f6 r2 v/ u# U; w* r$ F4 Q - STA MMC5_CHR_BANK_14009 p, F0 @: K( W1 V( h9 S' Y
- LDA #$06
& M, c. q& I: w: o' _ - STA MMC5_CHR_BANK_1800- |) A6 n( p7 j; I* P
- LDA #$077 R- i( u% E0 R# {
- STA MMC5_CHR_BANK_1C00, \& S* u! M, E) u
- 5 Z+ n% j' v! w0 @# ~
- ;设置屏幕镜像
" y3 y5 u7 l2 B( S- T/ H - LDA #$50" K' b; V) K- t. G3 R3 h7 J: h
- STA MMC5_NT_MAPPING" X `' v4 K6 o0 _& f8 y, `
- ( o2 i) k% L6 `. w) o* ~
- ;禁用IRQ
$ {' d$ r4 v0 E* ^: s - LDA #$00
: Y* g, Z* w- z' o - STA MMC5_IRQ_SCAN_CMP
+ a) `: {; ^1 t) w3 y; d7 N" F- e - STA MMC5_IRQ_STATUS6 E! h! `! K9 ? L3 U2 V& p, _
-
& O( U5 H( C) G+ F3 |3 f$ E - RTS
$ y, u6 z2 A2 x1 x - $ h" S/ L& D1 R
- ;==================================================
& S. Y' \' W! t4 r3 N; H7 v( l6 E - ;重置中断处理
) K1 k9 m$ W+ t - ResetProgram
6 v; W3 r Z8 Z$ j) ] - SEI4 L) Z4 E; q2 B: v: o5 j W; x3 H
- CLD' `/ W& G& n9 v# |4 _
- LDA #$00 K5 G! [6 k6 U( a" ~0 p) h
- STA PPU_CTRL( J# k9 y/ O! X7 l4 l6 h8 O: v5 m
- STA PPU_MASK( F( Y/ b% z3 q i
- STA PPU_STATUS) d- C- \6 l3 \$ e6 ?
- STA JOY2_FRAME
6 L; T& z+ s& g6 e2 F8 N - STA APU_STATUS
/ A( Y5 e. Q9 P0 ?$ i8 F! _- F -
0 P( y' e9 r, j8 U - LDA #$C0
- ?$ H, m, Y3 A0 k# a - STA JOY2_FRAME# }; ] E* V4 O5 t1 D U; r$ w
-
$ _: ~. K* f. C% B) j: I - ;等待vblank
3 o5 X8 n8 v3 M; j2 L; | - LDX #$029 v, H' h6 ^ R" p! Y3 }$ R
- Vblank_Wait_1
& q& o1 n% Z- E: ]2 `9 N - BIT PPU_STATUS- I! t& p" C. u
- BPL Vblank_Wait_1
4 d8 u2 F, P0 t; u3 y- j. d - Vblank_Wait_2
+ R2 o- b# f U - BIT PPU_STATUS
) \" G; y( E7 K5 Q5 f9 U$ _( {7 X. s - BMI Vblank_Wait_2
/ R: B+ o) p* ]$ Q% B1 p8 L - DEX
$ x4 h( d/ o+ N7 l6 S- Z% m7 l - BNE Vblank_Wait_1 w# M) J) K. @ L
-
$ u% l! h5 r0 c: O* I" @' h- |' F& ? - LDX #$FF$ X' t+ h. J& U1 [1 H1 I7 u3 {3 |, O
- TXS
$ g( w+ j: J4 V8 Q -
d" {+ q: }- }7 S7 {$ r - ;初始化MMC5
+ B; K# }( _0 [& V* ^6 N( g - JSR Init_MMC5
% |1 G' ?2 E5 B+ g% a8 M) h - $ \9 {$ y2 }/ d. p$ B* {
- ;==============================
9 Z' h( o4 d! @: d! [/ ? - ;RAM初始化" l; b5 X8 A$ O/ p) t; z
- Nes_Ram_Init# C: h( l) s5 d8 @# i/ q
- LDY #$00
+ X0 l& F+ ^6 m: }2 q8 N0 y - LDX #$08
- r% h: q i; V- ^/ x - LDA #$00( t# N" c5 u9 l* g2 Y4 G" m( T
- STA <$00- J4 B _- Q1 V: i
- STA <$01
7 u" }" A( e4 ~8 j - Nes_Ram_Init_Write
2 \+ {( @, ]* l - STA [$00],Y+ G2 {4 J, ?; V+ t
- INY
) j0 b- n* G! C; R - BNE Nes_Ram_Init_Write
! C4 \1 F$ M, T& E% \& V+ ? - INC <$01
$ W) x- A& ~( _+ W0 \7 P2 h - DEX
2 U. ?, f3 s `% z - BNE Nes_Ram_Init_Write
6 a$ Z4 i1 k% c -
/ P: p c" J {0 h/ L - ;初始化命名表
: F) @2 F2 l1 A* u - JSR Init_Name_Table* b, F) c! N1 O) Y' D
- r; @' }! V3 Q# l; S* B9 ^, W$ A
- ;初始化调色板
0 f$ v7 u) [5 E } - JSR Init_Palette
* U2 I. o. x y& V - 6 y! P8 J, R- r0 P4 {4 [& i7 p* _
- ;初始化命名表属性7 _$ n5 o' t5 L3 E$ p0 z. M1 F
- JSR Init_NameTable_Attributes- m# ^: _& ^) c" O$ F
-
# s. G, W9 a$ y - ;初始化精灵内存; h; U u. }5 R
- JSR Init_OAM_Ram
' N+ t4 t! M$ e7 D% c - ( y7 G1 }. j8 M0 h0 l
- ;在屏幕上写点东西( Q; _: n& z9 | i2 }" `- E
- JSR Init_Name_Table_Text( p8 g9 n8 j! z7 z
-
0 S N- {6 C4 K - JSR Time_For_Vblank7 @/ v2 v+ X) o6 R) m7 l$ _+ @
- ;开启PPU控制
5 T) y+ k; Z; x2 w v4 X. X+ }! z - LDA #$88" a" c8 U9 l T9 L
- STA PPU_Ctrl_Buf
2 L( p9 a( `# L+ r. w$ q- f$ \9 f - STA PPU_CTRL
: X: p3 J+ a' l$ y( q -
( y$ t1 ~& ^$ w. J3 F5 E - ;开启PPU显示
! b" T. j+ w- P# M) F, z' } - LDA #$1E
3 q8 D9 J! S: A3 c0 |) ] - STA PPU_Msak_Buf, ^8 r4 H& z& e/ n! i( V
-
2 s L' R: X3 o9 B' D$ a1 H! p - CLI
# E6 ^! P, K% G/ E0 M6 C% z. Z: {% f - JMP Loop; ~" l/ b! u7 W9 P0 u4 U( G# B- T
- . q$ l& R: q+ B, ~
- ;==============================3 T- _1 N1 @% Z; t+ L
- ;死循环, 等待NMI中断9 V' C z4 x O: V4 j& ~
- Loop
( S* ~7 n1 E: X! d N - JMP Loop
" Q5 O/ ]& I3 K9 x
( C7 m7 {" Z" ?+ \( I. m. m- ;==================================================
/ D2 @! q) [2 w. B7 _% K* O: |1 Z6 ~ - ;NMI中断处理
( J) Q, e/ b4 i4 K# i8 v" B) U# O - NmiProgram
2 j x' B6 d- i - PHA
% N' j8 T( c! `! e4 j' d - TXA! E/ U9 h0 k# _. W3 [
- PHA- u" J& z, [- x- F& u$ H7 r( L
- TYA( `- O+ u$ D/ b
- PHA
" O. b+ _5 p" G; Y2 _( S' n -
. w1 W6 }9 m' w o& ? - BIT PPU_STATUS
2 T* [+ W' V8 v* o -
: Z/ w( n0 f! g! S1 R5 W# C3 S$ f - ;启动IRQ中断, 第16条扫描线触发5 |) E) d3 ]1 {( n
- LDA #16& `8 T; P) t: @) G
- STA MMC5_IRQ_SCAN_CMP+ T; S: c4 P: v O
- LDA #$80
& X( S/ t8 `* F. z& r; E - STA MMC5_IRQ_STATUS
1 |& ], M. x7 ^' a4 R - CLI
. O; r1 B( }: a) Y# a& R -
/ m' {* }" |$ f; s1 H& F' o - ;关闭PPU控制
+ t t1 ?% O9 U x8 G - LDA #$00
) Z( o. m' F U2 V5 z' X7 V* ~ - STA PPU_CTRL- _' ^) G2 j/ U9 G1 u8 s4 h, ]7 j
- ' C C1 m6 L5 A6 H$ W
- ;处理PPU1 t8 r; V) `" |6 c5 J ?
- JSR PPU_Process( i8 i8 B! g- l, a* J6 \8 |
-
. J% p; @+ W8 [( l2 a& G - ;开启PPU控制4 P7 ~6 D% f! `, V
- LDA PPU_Ctrl_Buf
. |/ K0 v7 ?) ?8 x& J. O* k - STA PPU_CTRL K7 q0 Q" J7 \0 r7 K& W% X
-
* p/ R8 t; p- R7 Z& ~6 F; f" d* P+ E - ;手柄处理
* o% n7 ^" u3 }+ i* ? - JSR GamepadProcess
+ f; A1 P4 U* z: o8 a, D - 9 J0 l" G( m- U7 Y6 b G
- LDA #$00' h O$ i$ _& i3 p. }
- STA IRQ_Index
6 F( e9 L( f$ o) Q* D - 2 [! K. @0 k$ T8 t( m
- PLA
. B6 `9 k* P; u5 [ - TAY
6 N6 U6 b' `" O: m6 y - PLA2 j4 X" R% W# Y' c# w0 R0 x% c
- TAX7 T' V) |% T! D8 ~
- PLA/ Y" t7 s+ Z( z9 m# E
- RTI
( s/ V" @( I$ X - p* Y! e: S& A1 `) W6 U1 g
- ;==================================================
. v* }! Y4 r; z! @+ N: p - ;IRQ中断处理
$ U0 O5 U: S) f, k0 F - IrqProgram
* L- H* \; j' e& }6 d& Z - PHA$ E4 C1 X* R. D* N( e, A: v) i! a! Y
- TXA
: K2 A! b5 h }: e+ I" q - PHA, L3 E c/ K3 I, L o. A( S
- TYA7 Y% T3 N/ f3 q% M* }7 @* `7 e
- PHA$ ~- @8 A( ^' D
- 3 q. C# u3 t) \' o. e# f9 P. I
- ;确认IRQ
2 N# k+ w! [$ f - LDA MMC5_IRQ_STATUS3 L- G/ [- j. R# F; M
- ! o% h4 Z0 I1 c& U+ x
- ;允许下个IRQ触发+ z+ t/ X" V+ `( q
- LDA #$808 N( [2 N" l+ @9 `
- STA MMC5_IRQ_STATUS
& P: q; q' e; C3 g -
0 l1 |1 ?) d( R. ] - ;IRQ处理, 每隔16条扫描线触发; ~ b) E( ~3 c9 C
- LDA <IRQ_Index. u3 y6 P+ E# {4 V
- CLC* V9 V+ v7 ~) o. L; K: W
- ADC #$02
, C) V% q6 G6 ~ i% P - ASL A ]4 x4 C( ^* M" m" w3 f( [
- ASL A s7 A4 l% e9 P. N( Y6 K
- ASL A: D- T9 @) m9 c: D+ i
- ASL A
; [% {) K" V2 ]4 g" ~( A. s - STA MMC5_IRQ_SCAN_CMP
. D! u& w! o( |5 m$ P. Q -
% k+ C9 m3 ^+ f - LDA <IRQ_Index
6 u& P7 W3 M: e D1 Y - BNE * + 4
+ |$ n9 f2 V! ` L- r; {0 \9 @ - INC <PPU_Scroll_H
2 [9 o; s- l% K" b - $ u$ A1 u9 S$ W7 Q/ G" l
- ;设置屏幕滚动8 E& I- T# f- p# m
- LDA <IRQ_Index
$ j- W3 S8 n; q, j) R$ ~) a - AND #$016 R( c& G# u7 L, c. J3 k9 T' Z, U
- BEQ Irq_Scroll_Right
) s: x( Q5 }# V$ n3 \5 z - 8 ~. B" t) ^( o+ m' g
- Irq_Scroll_Left, S0 c4 K9 A$ d+ q) x3 b
- BIT PPU_STATUS
* _$ d6 [) ~; U# h- [ - LDA <PPU_Scroll_H
- }9 |- s& B( `+ i- i - STA PPU_SCROLL
$ B& A; o; m9 \ c0 l9 R - STA PPU_SCROLL: z b7 d L/ i& a
- JMP Irq_Scroll_Over8 A" d7 t5 Y( c
- ) ?( _; e, ~0 G" N1 r# H& \- n
- Irq_Scroll_Right
5 p8 u {- c5 `+ Q) B ~ - SEC
; ?9 p5 Q+ P8 v9 ~+ b. R - SBC <PPU_Scroll_H
9 g5 l3 K% ? k - STA PPU_SCROLL) q; m e+ o% I# Z& t/ A
- STA PPU_SCROLL+ b& F1 ?; |. m2 p: q3 f
- Irq_Scroll_Over
# b2 c% j( a v3 a* } - - h, p: F+ |$ _# J8 x$ g
- INC <IRQ_Index
; r0 y/ H. N/ |& H5 g3 ?3 g3 i - % Z2 E9 D0 o9 c2 p+ [. K
- LDA <IRQ_Index
6 Z a# `& G0 n. I4 \% ]! M - CMP #14
; C& V& ~- X4 |# I8 R* A - BCC * + 5 @% }8 S% g1 O8 D
- ;关闭IRQ
* y4 c( B* s/ g$ t. g - LDA #$007 H' t! {* q9 J& N9 O" c8 ~% p- l
- STA MMC5_IRQ_STATUS- p9 @+ U; k1 t7 e, t% I* h& y
-
l+ ~- t1 M* r! H - IrqProgramEnd
9 k% I* x% x8 g* D/ m% A' V( y - PLA7 p7 q7 h+ A6 h: m+ d- u6 R: V7 w
- TAY
6 _8 l8 [* G) F* g; t - PLA; c# F2 e7 i7 Z; a7 Y
- TAX* p$ s$ u6 [8 w4 O* ^: _0 I
- PLA v# f+ T) I( N8 v: M$ c7 ]! t
- RTI
2 G, @- s; w$ {" ~' J8 m3 n- ]' p' | -
2 T% I* g3 E* U6 `9 V" o% S/ q2 P- Y - ;================================================== _. c% E! y+ I* S
- ;中断表
0 }: a. O9 M, p( V+ j - .ORG $FFFA: v5 C& X# g) X
- .WORD NmiProgram
4 Q- j4 E6 d) ]4 }# U* n2 m* z | - .WORD ResetProgram7 o8 t( f- w! Z9 }6 m
- .WORD IrqProgram
复制代码
: T) d+ W& N- b3 p4 J/ T. u$ v$ g |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|