|
- ;[FC音乐][MMC5 IRQ]
, `% {, G: g" {, L2 a+ @+ T# ?: s" N1 s - ;FlameCyclone 202307109 h! A# P ? h8 p2 M' U
- : [* y4 J4 n2 K: Q8 r( y
- ;文件头; a" N( ]/ j3 U; Q$ V) T
- ;======================================================================
9 Y$ ^* T9 b; e, _ - .INESPRG 4 ;16KB PRG 数量
+ c X( J+ E, v- |! r- P. m - .INESCHR 1 ;8KB CHR 数量8 I* @3 C: S! T5 C( v* U G2 n" b
- .INESMAP 5 ;mapper 5+ `3 G ^! v V$ ~1 B5 u, R
- .INESMIR 1 ;命名表镜像 0水平 1垂直- G; d r$ n, b0 v
, h- I& s3 [+ T5 L# e% b2 j" w- ;必要条件5 y6 O6 E# q2 O
- ;1.持有CHR ROM
Z0 j4 s! h: q9 b4 L- ^/ [ - ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$10007 G( U* Z5 Q+ l
- ;3.精灵内存(OAM)不为空2 Q3 r6 ~1 @: W3 m1 J" r7 `
- 5 s0 X: b+ l$ z- D
- ;==================================================9 f# n5 ~8 v- ~: t
- ;NES端口常量: `1 Z6 n# X/ A2 F' Y3 L# G
- PPU_CTRL = $2000 ;PPU控制寄存器1 N$ z! L7 N0 F9 Q
- PPU_MASK = $2001 ;PPU掩码寄存器6 u1 u* R) o' i5 I% r" D
- PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位! C0 b7 U5 W+ @' A2 H
- PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加13 u2 F- g% N4 H" O* i0 i
- PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
8 j$ E% G" j) P; x% x w1 p - PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 ' a) }6 x% k& u- ~" x
- PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
7 i" M1 r/ ?4 [: t* S) V - PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
" ^( i/ @. T; j( D - OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存2 W. k! o: V/ V* H: N2 w# `* I
- APU_STATUS = $4015 ;声音通道切换
0 H9 f$ E, w: P5 g - JOY1_FRAME = $4016 ;手柄1 + 选通# S& ?7 t% N8 r6 D: F! d
- JOY2_FRAME = $4017 ;手柄2 + 选通; l3 P. ?' b7 I3 @/ L0 z$ I
$ i& Z3 m( h: `7 x9 g$ Q- ;==================================================
4 P& T' O* ?; c - ;MMC5端口常量
: D0 l! ^3 ]' j4 ]- { - MMC5_PRG_MODE = $5100; 0: 32KB 1: 16KB * 2 2: 16KB + 8 * 2 3: 8*41 `3 N' w6 ?+ \$ R
- MMC5_CHR_MODE = $5101; 0: 8KB 1: 4KB * 2 2: 2KB * 4 3: 1KB * 8) O. P4 G) ^, w' X
- MMC5_PRG_RAM_PROTECT_1 = $5102;
1 J% f; T) }% m$ {* j - MMC5_PRG_RAM_PROTECT_2 = $5103;& Z1 @# {8 C4 E! y& n; ~
- MMC5_EX_RAM_MODE = $5104; 0: Write Only 1: Write Only 2: RW 3:R5 _5 K- ^% }9 F# p3 P" H
- MMC5_NT_MAPPING = $5105;
3 k0 F/ k9 H' ?; F - MMC5_FILL_MODE_TILE = $5106
! f) z; f& R; Q8 J/ n$ i( r n - MMC5_FILL_MODE_COLOR = $5107
5 g( D) |* m+ Z T - $ O9 d; C4 [2 n$ r: L0 E
- MMC5_PRG_BANK_6000 = $5113
b h& f6 g; O$ b. P; { - MMC5_PRG_BANK_8000 = $5114
$ U. w [# x5 n6 y* Y. v - MMC5_PRG_BANK_A000 = $51155 h/ F$ y3 n! |% V
- MMC5_PRG_BANK_C000 = $5116
- ?: N! p# [& _/ |: X5 v( Q) v - MMC5_PRG_BANK_E000 = $5117& n/ U& F/ v, s; n
- 8 Y& L- C5 P' X% @, u
- MMC5_CHR_BANK_0000 = $51208 H- G z( Q; h7 E% n
- MMC5_CHR_BANK_0400 = $5121
+ i$ ~/ K& I$ ^6 X# i - MMC5_CHR_BANK_0800 = $5122
: V; G* k3 W2 o+ c: ~; T+ L2 g - MMC5_CHR_BANK_0C00 = $5123* e V4 s# H& ?3 G* q9 k/ L/ H
- MMC5_CHR_BANK_1000 = $5124' P6 P; |/ U5 M2 o+ {$ }
- MMC5_CHR_BANK_1400 = $51254 u. b: S& |. E$ {5 _
- MMC5_CHR_BANK_1800 = $5126
, ~% u1 P/ H' Y - MMC5_CHR_BANK_1C00 = $5127% k, F- {* d# l6 U, |& i
# B+ _+ n1 [, A6 `% S- MMC5_CHR_BANK_0000_1000 = $5128# K; b9 {3 z) u, B$ }
- MMC5_CHR_BANK_0400_1400 = $5129
( _% v5 Q7 Z4 l! Y( B! Z4 z - MMC5_CHR_BANK_0800_1800 = $512A
7 V2 h0 i0 g& I2 V6 G' n+ [$ l9 m - MMC5_CHR_BANK_0C00_1C00 = $512B a& Y; ^1 w1 Q" i" v4 F: q
-
7 _& s* U+ j0 e) f p: n1 }' v% F - MMC5_CHR_BANK_UPPER = $5130. c( m; T2 r7 Y5 ]& [0 x
- MMC5_V_SPLIT_MODE = $5200: P- f7 p9 l6 W- J. m: m
- MMC5_V_SPLIT_SCROLL = $5201
: R" J v& b" }3 k3 D" r - MMC5_V_SPLIT_BANK = $5202$ M4 j% P9 O: R; B- T+ J7 D
- 2 m u" o% X" l
- MMC5_IRQ_SCAN_CMP = $5203
) }+ r9 ~4 I, L+ x1 a - MMC5_IRQ_STATUS = $5204! [ Z. y V& Q3 {9 V+ m
- MMC5_MULTIPLIER_A = $5205
/ s: B3 k1 n3 m( u0 x: j - MMC5_MULTIPLIER_B = $5206) Q3 G1 r6 d5 ^) R: g
- & ]5 q# V9 F8 j8 S& y
- MMC5A_CL3_SL3_DATA = $5207( S5 L7 p; U) P" ?! a. J+ `" Y
- MMC5A_CL3_SL3_STATUS = $5208
. [1 s2 Y# j5 v! X" f9 X- c - MMC5A_IRQ_TIMER_LSB = $5209
$ g( E X: E" @* k6 J# _ F1 u - MMC5A_IRQ_TIMER_MSB = $520A
4 b& E$ u' J8 }5 E# _- U: m - / S# z& [$ o* M5 T& P
- ;==================================================( V% \& s ^: l$ R1 ~4 U+ u$ _
- ;程序块配置8 t8 {# B$ g4 s7 [- B1 C. ^
- BANK_DATA_MASK = $07& A7 n& a/ m, A; o% v" Q
- ;--------------------------------------------------
& h3 n; G% P- e% U - RESET_BANK = $07
% Q- \; d; [: M0 ^" v - RESET_ADDR = $FC007 b0 f+ ~# z$ a: m7 F
( [4 \4 U/ F; v, z# ^- ;==================================================
7 F% @: Z3 D7 x2 a# p9 g/ k; \ - ;图像块配置% K, k. \) |3 Y- `( v9 X0 C
- CHR_DATA_BANK = $08" E# ]$ l$ A8 X8 ]
; k+ @- g8 z2 {, y d& [% H6 V- ;==================================================9 [2 ~6 r( `# v: a. r
- ;零页内存地址配置
3 D. ~: G& n! ~- U: _ p: G6 o* U% [ - Use_Ram_Addr = $806 l! z! E9 l8 f2 i6 \
- PPU_Ctrl_Buf = Use_Ram_Addr
3 D2 y5 H' Q2 d( W" R - PPU_Msak_Buf = PPU_Ctrl_Buf + $01$ H# m: P, G* t
- PPU_Scroll_H = PPU_Msak_Buf + $01( O6 F/ N ~" E' U
- PPU_Scroll_V = PPU_Scroll_H + $012 w4 ^; q5 o" M( S8 Y: P& Z* V7 E
- FC_Data_L = PPU_Scroll_V + $01' H' S/ S6 j$ l% V, H
- FC_Data_H = FC_Data_L + $01
8 J2 o7 H; W& A( }+ O - FC_Data_Buf = FC_Data_H + $01, z# I+ S1 V1 a9 A
- ;==================================================
! a- W/ N; j; q& J. w
3 H5 `% Z/ n* w) g% E; {7 `# v- GAMEPAD_MERGE_FLAG = $047 |; ?. i( D6 `0 W% z, |* X8 i
- S$ t, g9 L' Y V
- Gamepad_Keep = FC_Data_Buf + 1' u" [2 }- v% q" E3 }$ \/ H, X$ l
- Gamepad_Once = Gamepad_Keep + 27 [8 T) U3 d: s$ S9 d) e7 F" \
- Gamepad_Temp = Gamepad_Once + 28 i/ B: Q8 i8 k: n
-
3 H4 O" t, F9 Q% ] - Gamepad_0_State = Gamepad_Temp + 2; A' o# i+ b! `/ l2 S- v: ~" f; F
- Gamepad_1_State = Gamepad_0_State + 1
% [- ~5 T9 p: F7 b8 V - Gamepad_0_Value = Gamepad_1_State + 1
. j( }* @ P' [ - Gamepad_1_Value = Gamepad_0_Value + 1
2 I2 U3 R; \8 v9 ^7 J - Gamepad_Port_Value = Gamepad_1_Value + 1; B$ I0 v& W$ h$ o9 m
- Gamepad_Merge = Gamepad_Port_Value + 1
; Y1 h' T: R6 A
/ m) o0 d1 ]$ l: u% I: S# ?- ;==================================================5 Z! j9 P# H! t8 @7 E
- IRQ_Index = Gamepad_Merge + $01# S" a) q$ `- g1 G6 l( M/ O3 s1 z& e9 M
- ;==================================================& i4 s& a' m# ]$ `; l
- * |- f/ ]3 u I9 g& I9 v0 m! K
- ;CHR图形数据; }3 k- `7 C& R* Y ]
- ;==================================================
# i J, J6 \* a) l _ - .BANK CHR_DATA_BANK
$ N' H* o0 y1 |; h V2 i2 r - .INCBIN "chr_bank/chr_data.chr"
# m& ]. l8 _$ p& d -
; A4 x4 q4 r A% N" @- u0 Q - .BANK RESET_BANK & BANK_DATA_MASK8 ?# E5 T8 a h7 y0 i3 Y* n
- .ORG RESET_ADDR
8 _3 |: n+ O* ` -
" Q& A% @# g% g - ;--------------------------------------------------' w0 p ?" C: w, o; {( |
- Attributes_Data) v; }" u# x; S# X0 U
- ;命名表属性
; w- k( v% j% [, {/ ? - .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
5 [/ g& s P) b, s ^* Y/ t" v - .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
. K% l$ h7 W0 i/ ]( N - .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA) F) a$ ?4 p6 u# r3 m7 \
- .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
( E* n. f q4 A3 X! S - ;--------------------------------------------------' p/ _8 I6 c5 X: |7 h* w) j+ S
- ;调色板数据
1 K A& s4 k5 O5 A! Q K1 y - Palette_Data
0 T$ p; [% P! v g! m - .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
) j1 u' K2 f( Y& \5 }- w1 V* R; W/ _9 a' E) r - .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F3 M+ X, O( P j3 x# x3 [9 _4 K) q
: e q. l! v: \( E. x- ;================================================== g7 i& N, t' I
- ;命名表初始化: w* g1 P, T j' N" h! [
- Init_Name_Table
1 o, P! a& j; L" x! `: I! r B/ v - LDA #$20 p5 H) z! |% q% k
- STA PPU_ADDRESS) L. ~4 r$ D6 m& l
- LDA #$00* Z9 Q7 I7 N+ F3 H% R, N5 N
- STA PPU_ADDRESS, @$ k) a& }4 x/ o& f
- LDA #$00
2 [5 k3 r- c1 R3 Z0 _; ~ - LDY #$00' H' N7 h0 k! Z% \5 ~9 v% Q
- LDX #$10( S" e) t/ r8 T; I6 w7 Z
- Init_Name_Table_Write
0 n. t8 X$ {) O% D - STA PPU_DATA% n- X9 `* W0 W* n, J* X
- INY
- R& [! ?9 ], {6 z - BNE Init_Name_Table_Write
) |( E5 K+ J3 g' m - DEX
) G# v9 a) I' L* H) C - BNE Init_Name_Table_Write
1 W7 {7 c8 A7 s( F& C - RTS, S# P& d* h+ Q# E
-
4 s! y3 h. L7 o% R% t - ;==================================================
5 b' q6 d+ ^! l: h' g- E. f! c - ;调色板初始化! b. J+ |1 a: H5 a
- Init_Palette
+ O( ?" T7 ^* A2 l( _- q - BIT PPU_STATUS [3 c Y& {* { ?8 G
- LDA #$3F( T$ x* h5 B% l. k* J
- STA PPU_ADDRESS
5 |8 l% ? a7 x6 [# O9 D - LDA #$00* Q9 _3 D- {+ {4 ^
- STA PPU_ADDRESS: ?$ Z, @4 O) }5 v, P. L* b4 n
- LDX #$00' v: e2 r4 R" H# {% C( f- t
- Init_Palette_Write5 s- r; k( ]( a, i" \
- LDA Palette_Data,X4 [* \5 F/ Q R8 m3 n* F2 ^
- STA PPU_DATA
9 f _% e/ ~. l% u9 H+ E - INX1 N, C( J! P( [6 `5 l/ o3 H) } p1 r
- CPX #$203 i) R" P1 x7 t! [. g
- BCC Init_Palette_Write# c8 b% Q' {1 p# b9 X) r# O
- RTS, S( q& ]# m! O' w' V" B2 |
- 3 c' E/ c/ n K5 O
- ;==================================================
' g7 a6 q! j% B& ^' m P3 y2 |. j - ;设置命名表属性 ^: B" ~2 }5 C3 h
- Init_NameTable_Attributes
* @ [' ~8 P/ m4 U$ e9 Y* j - BIT PPU_STATUS
! t( L, [. o U8 ` - LDA #$23
! _2 Q( c$ w: t/ D% h - STA PPU_ADDRESS9 f1 D; p5 E( D( n) F" ^- r/ g
- LDA #$C0) e; {) l# D' r L) L8 E+ I
- STA PPU_ADDRESS
2 \4 v2 X: P6 z, n/ K! B - LDX #$00# |8 n0 s. L6 M/ v9 K2 T
- Init_NameTable_Attributes_Write
& w4 H! {% \) y- J$ G1 r7 R - LDA Attributes_Data,X. n3 K( u# G+ M
- STA PPU_DATA
8 }, Z+ J# x" c _1 o N- J7 K - INX
, ]2 L; G2 w) L( a+ z! P* O - CPX #$40
7 A) [0 _! Q9 u1 k' n/ j: J& N - BCC Init_NameTable_Attributes_Write8 n# K# O, Q3 T% ?% t' L
- RTS: {8 i5 w4 X6 G8 i7 {
- 4 M" ^ a/ j/ i4 u3 c, Y
- ;==================================================
1 N5 y7 p1 j& T+ [9 a - ;初始化命名表文本/ Q$ A' z* N9 T7 X6 P( O
- Init_Name_Table_Text
0 S2 W$ [/ z$ R& M# Z" a; n - BIT PPU_STATUS* L p; A G( C3 |/ H
- LDA #$206 l# m- g- T) j( s; N% N2 P- K
- STA PPU_ADDRESS
8 m4 U y# f, h) N - LDA #$00) s3 W- Y! O) C5 \& i' H: r
- STA PPU_ADDRESS1 p' `) `& H! m. l5 N1 \7 F# m
- LDA #$00! \2 h5 H" y' e0 N8 L
- STA FC_Data_Buf
, u0 B- o+ C0 K, b+ p5 V- S$ n: V - LDY #308 R; G, ]* i' G E" j# |
- Init_Name_Table_Text_Write
. p! N, s. f6 r$ E+ O. D - LDX #32
8 R) K3 ?4 X# i% C3 n0 V - Init_Name_Table_Text_Write_Char# M% ^# W9 \& Q# k. e, D
- LDA #'0'
U5 P) i, H d" }9 @ - CLC: D3 \* V+ c$ p' ^4 ~: X
- ADC FC_Data_Buf
7 q8 u* `) |, L - STA PPU_DATA1 T/ a" `. T- @7 Q% f( K7 @. Y7 f5 U' Y
- DEX4 _4 R% V% S% a
- LDA #$14' k# [, `8 r! v6 m! T
- STA PPU_DATA9 E2 x; }0 g# l/ y+ t6 |7 [. ~
- DEX
6 ]. _# }7 U) M" @ - BNE Init_Name_Table_Text_Write_Char
5 W. }6 v8 c% L - INC FC_Data_Buf
' f) B# x# ~/ a( J6 D! U - DEY- u$ v& ^% q/ a0 f) l0 A& F9 S
- BNE Init_Name_Table_Text_Write
; [9 S# T+ Q6 N/ Y x2 @& H5 S2 k - RTS- o1 Y" H+ H5 g8 J n
6 j% G( H# V& H8 Q- n$ i K- ;==============================
+ K) ^4 S7 z9 {" K9 D - Init_OAM_Ram;初始化精灵内存8 D8 L* R7 j$ K f4 n' D
- LDX #$00# `2 G; y2 d, z) M
- LDA #$00# ]# f0 a( j3 z- E
- STA PPU_OAM_ADDR2 i) L* \; G9 c0 }( u# {
- LDA #$F8
# _+ N2 A6 W1 H, I, C i - Init_OAM_Ram_Write" v- }) p- d: b2 c4 ?% n5 e5 ~6 s
- STA PPU_OAM_DATA% S7 L0 D" ?% R9 N. V! h- D* U, e+ B
- INX
$ ^2 f* d" G! Z' C - BNE Init_OAM_Ram_Write
) |8 H, K+ O: z1 e - RTS7 U% P4 D0 K& W6 [; s( w
- 5 i! j q+ f; r8 q3 U0 v' z. m
- GamepadProcess;手柄处理
1 P* N! E) v- Y - JSR GamepadDatacan2 |9 K' |/ W7 }/ z
- LDA <Gamepad_0_Value
; q* x8 b; E' X+ v9 h - STA <Gamepad_0_State, Z) g; ~6 t+ ^" ^1 y. X+ C3 w
- LDA <Gamepad_1_Value
0 N) W0 ^' D0 b$ E/ u - STA <Gamepad_1_State
' J" P0 c3 T9 k. r3 B; j9 L+ S - JSR GamepadDatacan# V* \5 B3 \8 m3 l& k. k
- LDX #$01
! `, B8 i& X- F y - GamepadMergeCheck;合并手柄输入检查
2 s9 }. `' S% K8 E - LDA <Gamepad_0_Value,X
' z: V- a$ M c+ ~! F - CMP <Gamepad_0_State,X( a/ G& o/ y I1 c* r# A4 [
- BEQ GamepadMergeInput
# i* _0 V9 E1 k& n: Y - LDA <Gamepad_Temp,X
. p* i6 |6 e) y( f/ {* a - STA <Gamepad_0_Value,X3 [9 V9 f* U) x/ F8 G
- GamepadMergeInput;合并手柄输入
$ J+ j: Q- n' l! S2 _2 \ - DEX
' O1 `) y3 c8 H H5 } - BPL GamepadMergeCheck
$ Z" M6 t. W& i" S - LDA <Gamepad_Merge5 {1 R" n: h/ }2 |! p, a
- AND #GAMEPAD_MERGE_FLAG
+ x( }* E- p" L5 w" F) Q1 H - BNE GamepadStateProcess9 c9 Z- N$ d& }3 |. {
- LDA <Gamepad_0_Value$ Z! L+ E9 E0 o( ?% J9 K4 y5 Z
- ORA <Gamepad_1_Value
3 R& _; K' t5 a/ e - STA <Gamepad_0_Value( A% D0 P9 f b; ]
- GamepadStateProcess;手柄状态处理
$ L: A6 H0 @, M9 t: a - LDX #$01$ i% K. t; ^! O [! U2 H
- GamepadStateSave;手柄状态保存& q# ]$ m' c" P$ q2 ]& s* b0 `
- LDA <Gamepad_0_Value,X+ N! p& { m9 c& c, \/ } O
- TAY
6 N) U: H7 }4 r" {5 F - EOR <Gamepad_Temp,X
& P" f' X9 J6 Y4 U$ N+ c - AND <Gamepad_0_Value,X
: n& R2 l1 M+ y' x; R7 ? - STA <Gamepad_Once,X" t+ ^! _7 O5 _/ f6 |
- STY <Gamepad_Keep,X
; |8 ]. _* w2 g4 q - STY <Gamepad_Temp,X
; u" I" u8 r3 m U- ~9 h - DEX
. A9 l% Q/ {( ^6 I$ @+ u( ~3 d) X - BPL GamepadStateSave
3 n% m9 | Z7 J" V8 a8 i. u8 [5 ^7 r - RTS
* C! ^: C: B. y ^4 J8 v4 X
3 T( t, d& `( \3 A/ j, O9 v- GamepadDatacan;手柄数据扫描$ u2 u U5 Z4 {
- LDX #$01
) \% J1 A/ F6 N) t8 t - STX $4016 J5 v$ K! x3 r# w
- DEX
! E& c% n8 K, e# q( P/ @# Q - STX $4016
8 f! v. f8 S; o - LDY #$08
2 K G% f& C: E/ W: D$ U - GamepadPortScan;手柄端口扫描5 e) V8 E% t" N W2 t4 _! Y# L
- LDA $4016- Y5 J# @$ n6 E8 S( A' G
- STA <Gamepad_Port_Value ~: g5 U$ O4 M2 h0 b$ k
- LSR A
" J% O: O" Z: N! S) F' M7 _2 ^& E. H - ORA <Gamepad_Port_Value) ^# o6 K. G2 p8 n% W% C, n( h
- LSR A
! R1 d, j' _+ u- n7 x; C- b - ROL <Gamepad_0_Value& E0 w& ?& t a5 G0 I
- LDA $4017+ J6 v# _+ @/ G+ Z R- a/ y! ]" n$ e H
- STA <Gamepad_Port_Value7 i0 `0 q+ F8 v; m
- LSR A. F2 K" g" G( X' O: k( J
- ORA <Gamepad_Port_Value
5 x" O, _8 f# I% k+ t7 i. ` - LSR A
. y! e# x! V& }, x& |. n4 ]/ Y3 O/ Q: I - ROL <Gamepad_1_Value% I3 ?4 r, Q1 v. s- x
- DEY+ z G8 l1 E, ?5 z, _7 G
- BNE GamepadPortScan% B8 \0 x- Z: N$ G. d
- RTS! y* f* X- L0 A
-
, R. V- O h3 `+ i# {1 W - ;==================================================1 B6 L/ H5 [, N# s# R! j' ]
- ;PPU处理
* {8 |# Y/ B8 b8 p - PPU_Process; {/ H6 {: v. G0 z2 p, c
- LDA #$00
2 R8 B' |* B6 t4 ]. T9 @4 S0 C - STA PPU_MASK
# a. E6 V" ~, A/ M# n7 N8 H -
$ v5 E2 d3 e! _4 d; t* R- F+ X - BIT PPU_STATUS4 ~; f' v) @* z l0 s
- LDA #$205 g# |) z# S9 t' f9 O4 u9 [! T h
- STA PPU_ADDRESS2 T1 z& `0 r/ \& b/ u9 E
- LDA #$00+ L0 z) s9 s; X5 G; l. R# ^
- STA PPU_ADDRESS6 h7 q' c! k" o7 e8 Z- d9 C
-
6 _# S6 Z' g4 r$ X0 l. d, s - STA PPU_SCROLL
& P1 w) y. g- G: K8 M4 o - STA PPU_SCROLL
" E0 h. N% }0 S" [) a9 e -
% f4 Z% B I, N8 ]) U( D1 ] - LDA PPU_Msak_Buf7 H7 h* t* P' |: i6 ^7 x
- STA PPU_MASK
3 y+ ~. f4 d* X, C
# P9 o% P8 f1 |5 ?0 e2 ~2 _" g3 x- RTS
: Z4 @( m7 p" I% G: H- E+ R -
# \" ?2 c/ p! n4 |& f0 X, A, t - ;==============================2 r/ U" U# Y- }, p
- Time_For_Vblank;延时等待
9 P: q! {- s k5 c) ]$ W - LDA PPU_STATUS
' I0 s- q4 o ?* r8 t - BPL Time_For_Vblank
9 u+ S5 `. U6 H z7 P - RTS- F B' ^, w+ D/ _0 t" [* S Q$ I
-
; i* _' q5 J0 H& V - ;==================================================9 R1 R8 t) g9 a9 S' T
- ;初始化MMC5
8 \# y* i! t0 z- w! ^/ @ - Init_MMC59 D/ u) P6 f' v t$ ~0 H' A
- + o) N B& L! B
- ;设置一下6000-7FFF的RAM
$ B3 F5 O9 Z) R6 e4 o G - LDA #$00
) ~, s. ~+ n$ M9 p$ G& V - STA MMC5_PRG_BANK_60003 D0 G1 Z* r7 l' f
-
- Z0 }' v t9 p0 A" e - ;开启 PRG RAM 写入
8 ^2 H! d0 Q$ c - LDA #$02+ I: t/ B* b' M$ m8 W7 ^
- STA MMC5_PRG_RAM_PROTECT_1$ }* R, z; g ]6 I
- LDA #$01: k2 h8 I" L3 ?6 j7 f# h6 o
- STA MMC5_PRG_RAM_PROTECT_23 J; g2 K: \) `3 w5 {5 U3 o
-
9 k7 w2 J4 j3 L' _ - ;启用 1KB 扩展RAM ($5C00-$5FFF)- b* q/ Q, j2 G/ {& T
- LDA #$02# F ^$ L, K1 y( C; p: ^. Y
- STA MMC5_EX_RAM_MODE
; K- w4 C& A! f5 v$ P -
7 u+ R# z) q7 ]9 c! h. E - ;设置 CHR2 K- Y6 [9 }0 j: o9 e9 g/ m: O( \
- LDA #$00
7 {0 _5 D1 Q8 L; v+ z* ` - STA MMC5_CHR_BANK_0000- k, L4 H, }. U- y; q4 s
- LDA #$01
+ n1 [) _$ T" V V/ [" Y C - STA MMC5_CHR_BANK_0400% k8 S/ r: }& ?) y& X
- LDA #$02& D, W$ r, b% z
- STA MMC5_CHR_BANK_0800
' c! |8 ~' R3 |$ p" q* E# ~ - LDA #$03$ a9 D4 W& R$ A5 S0 ?& G
- STA MMC5_CHR_BANK_0C00
) f/ e, _1 A/ ]: t6 b. N - LDA #$04/ l! I4 m) {/ n. c: ^2 V/ J
- STA MMC5_CHR_BANK_1000
% T5 n: V M7 s$ V - LDA #$050 @! }+ j- e- ~7 y3 m
- STA MMC5_CHR_BANK_14005 b- ^1 h/ g# r+ |' G" O
- LDA #$06
' x' Q. i* M8 c* D% F% z - STA MMC5_CHR_BANK_1800
s) \' Y/ C0 F9 r) f - LDA #$07
+ w% J$ d- C. F( c; V - STA MMC5_CHR_BANK_1C00" M \1 J0 u8 t/ p( j
-
4 k5 ~! K3 I- F0 P, O6 G: O5 Y - ;设置屏幕镜像( w8 x$ l" s# s6 K
- LDA #$50 j! D/ M9 J0 ^# r. Q$ X
- STA MMC5_NT_MAPPING2 i5 H' {+ a* n, `$ F& r( U
-
7 H7 J p9 U; b" X a! O - ;禁用IRQ% }1 ]+ n& V* [2 K9 {
- LDA #$003 I' A. @, H5 l/ \! ^1 I9 N4 S
- STA MMC5_IRQ_SCAN_CMP. G$ K5 r! ?- t/ f5 B) L3 [
- STA MMC5_IRQ_STATUS6 c/ C% q1 G: a5 [; e' @$ l6 x
- - X2 x* {# }0 V. k u
- RTS# t% X" k' X0 Q c
- 3 x" X% r/ g5 o
- ;==================================================; U ~: N$ T- V( N8 Y# L& t& r% |' f
- ;重置中断处理5 [+ H- G: N* \9 h: B
- ResetProgram! U& t2 I! S& `. [8 _; S! Y- ]
- SEI( Z* T0 x- p& _, W7 U
- CLD
' a! q' [( x0 w9 r6 J5 k - LDA #$00: q% T1 l' K6 F; E( t
- STA PPU_CTRL
% M- i) [1 s# Q2 e( Z; w6 m; g% ], [ - STA PPU_MASK) h- `; a% B% Q7 U6 K$ q
- STA PPU_STATUS! S, m3 t3 w. S/ B" H- K
- STA JOY2_FRAME
7 k# o. _) t4 K - STA APU_STATUS! b( Q% ~, B# ?: x6 f
-
% ~, V% a# M# Y/ }9 S - LDA #$C0: [" r8 s. [9 F1 l
- STA JOY2_FRAME
) s$ O6 s' W( {5 |/ h - 4 d! x6 s ], Q- Q) B! R! Z
- ;等待vblank
5 @ T9 w0 H! `# D! u8 o1 X7 J - LDX #$02
( Z# r4 w. N7 C" t" S$ ]5 G6 ^ - Vblank_Wait_16 D7 i! S' m* ?0 t, a9 g
- BIT PPU_STATUS7 t0 z0 x! I! m; W; F7 ?
- BPL Vblank_Wait_1
; f9 b$ ]' o/ M - Vblank_Wait_20 B3 U* \9 B0 S; S2 T0 d
- BIT PPU_STATUS; J5 e8 J& M! \0 C& o
- BMI Vblank_Wait_2
, @* c" [. _$ A: O3 Q" D - DEX
& s7 e9 r; E. K% Y, g - BNE Vblank_Wait_1& Z1 ?! l* }9 I5 g0 K/ R
- / C1 q+ @+ Y6 n, U+ X/ X) |
- LDX #$FF
- _# q, [3 r# n0 k* X- m - TXS; K7 ^9 L% a) y* q
-
F$ k+ e9 F$ J4 ^, t - ;初始化MMC5- X t- X+ z2 k$ |% k
- JSR Init_MMC5- f2 @8 n! o+ L" \: l6 `
- 8 O1 |4 N- r8 g9 }5 \" W1 A, l
- ;==============================, D! R f$ x* i
- ;RAM初始化
) i3 Z+ {7 E* w - Nes_Ram_Init
0 e3 ~$ z8 h A' s+ E+ j+ G7 Z9 J) S - LDY #$00+ ]6 f& e3 }& Z7 @
- LDX #$08; F3 n+ ~) `: ^
- LDA #$00# |( N k7 u7 k/ c
- STA <$00
) l x/ A+ L. l3 I3 c+ e( \ - STA <$01
" A8 O; I W) H$ q+ c- z5 B - Nes_Ram_Init_Write: z( M; B4 q2 b6 z$ X: F2 l3 N7 {
- STA [$00],Y" C U0 L! M- p7 [" i6 w
- INY
# f; F8 c# E/ K4 ?1 b& g3 h) l: M - BNE Nes_Ram_Init_Write
8 j! W3 ]& {, z8 A, u. c$ b - INC <$01# C# S) F' k( l9 P7 }# T1 F% T
- DEX
8 J j+ S- P! b& Y - BNE Nes_Ram_Init_Write
$ \ v( ?1 r4 {3 Y, G -
O' Q+ x- v E: t1 U! [ - ;初始化命名表
7 B/ Y: t8 w6 a5 _ - JSR Init_Name_Table% D9 _& r; f! T/ v
- ' f2 U/ L4 N7 H
- ;初始化调色板4 {2 M4 E* G3 D0 I, h4 r
- JSR Init_Palette
% a- G. f- C, {3 A J' d -
' u: m) A/ {' m- _$ o; Z - ;初始化命名表属性7 T: c& ~; I) w9 |
- JSR Init_NameTable_Attributes3 `7 b# q6 b& _* U, C. ]
-
# x3 U6 r& t7 X - ;初始化精灵内存
! l% p' w5 U* t( a - JSR Init_OAM_Ram
; g F; W5 m+ r$ C9 _. Y4 p& M -
* p. v/ P: F, q - ;在屏幕上写点东西, `- \/ |. M' l5 T3 y7 K2 E- i
- JSR Init_Name_Table_Text
6 K6 o' @& K" } - + v' Y j' U. _
- JSR Time_For_Vblank% Y! K# `- L1 ~/ j
- ;开启PPU控制
1 L, T/ A' K/ P0 z- R& x2 s+ N - LDA #$88$ `) {1 g9 z8 o' s9 u+ d C- W6 Z
- STA PPU_Ctrl_Buf
2 c1 b+ r, M1 a4 s - STA PPU_CTRL
0 h/ Z/ t4 i" w. N -
+ v9 }* d) s8 f, n9 ^ - ;开启PPU显示
) v u: B/ o3 e: e - LDA #$1E
* V& f6 ` I( C' Y3 t* l - STA PPU_Msak_Buf* t/ s- J: S! k
-
2 e* S. w6 @: l7 N/ V - CLI9 Y* @9 f! @: V2 n+ w$ W1 n4 M
- JMP Loop& T1 X C- P% i7 E( ], e
- $ e5 @4 n+ N" L/ w: P. j
- ;==============================9 a, k) B3 ?* a. I
- ;死循环, 等待NMI中断
- P' z/ @8 b4 A) M - Loop
8 P+ L* d* C9 q0 @ - JMP Loop
' O0 J6 W3 n: x - : i# X( G, x: j
- ;==================================================
! S. C3 X. e% k6 J9 d8 N4 o - ;NMI中断处理
" Q1 |4 O: n7 h) h; W - NmiProgram
; V8 @$ w. f# k; c; M - PHA2 _1 Q5 }+ j% n. o4 R
- TXA, `, r. `6 H2 D0 ]
- PHA* d' s' h4 O- G6 N: k
- TYA; z, W) l+ X* d, W/ X
- PHA
" l* y& C. l: p2 ` W -
[) t V. C; Y6 Y0 e# x3 L, X8 P - BIT PPU_STATUS% K7 X, y) w: ~3 U( Z# }' ~+ F. G
-
1 E" z. M9 T$ Z' A1 ` - ;启动IRQ中断, 第16条扫描线触发; t9 N- |( o8 j* m: E
- LDA #16 i3 X% ]: E: ?2 r* g
- STA MMC5_IRQ_SCAN_CMP# A. \) E( ~& [9 A
- LDA #$80% L) _) V8 m7 g" A& m! o
- STA MMC5_IRQ_STATUS
! H- T# H$ f- Q7 y$ @4 U/ Z2 v - CLI
8 `- u* G) M7 [) Q( Y+ k+ Z - ! [$ b$ e, s; M) D8 p( ?
- ;关闭PPU控制
$ u+ i0 { \* l) b$ F5 O( b - LDA #$00. a1 i2 c8 z" Z
- STA PPU_CTRL
) z2 K; b Z8 F0 P, K* C - ! Y- Q% m4 |9 o( k0 X( e# y+ Q
- ;处理PPU, a& Q0 ~9 m7 g2 K6 }1 f, s
- JSR PPU_Process# f/ u( p% N- R3 N& [- Z, H) G
- 5 ]% e, x7 m/ `/ @
- ;开启PPU控制
" i: y! n5 C0 H/ D+ m/ E% d/ w/ h - LDA PPU_Ctrl_Buf
9 |% Y Y2 C8 Y& b' s( L+ _: X - STA PPU_CTRL. D% C2 S7 e2 b: l' _
-
0 r* @& I G- e& _ - ;手柄处理
- X0 l, U `' d - JSR GamepadProcess
# }, A/ v5 F% D$ ?% {7 v - + t" ^# R9 N2 H: j% a/ a
- LDA #$00+ _7 x' n1 P K8 G' M
- STA IRQ_Index# a. o/ j) H4 @% h
- ' o9 F8 \( L2 H. U# |; R
- PLA
+ t5 e7 o- t4 @ - TAY
3 k) E o, m( y! x - PLA
9 j) ?3 o! f9 h4 P+ T Z - TAX6 S2 B) z9 k) g
- PLA: N9 r$ P2 d, \: J6 ? R( ^$ m
- RTI
: _1 [1 U7 X b5 K' @ - / I& {. P4 N& _1 x5 W
- ;==================================================" z+ [* K6 y7 ^5 t" Z
- ;IRQ中断处理9 S' |% y8 r* D0 _6 D. `1 `
- IrqProgram
4 J. J) \- ]) P7 o7 E - PHA
9 M" s5 }: F8 ~1 ]# L: o. n5 _9 X* ]2 \ - TXA, v' f' [7 T+ W8 Z3 q
- PHA* g s2 l M- J7 Z5 d
- TYA& R9 c6 J/ Q4 ^1 S1 L
- PHA6 ~- E$ c: t0 C) h
- * `1 Q/ U5 D: v* h% ?; G
- ;确认IRQ; I. W4 O8 j5 ` ?. e% g
- LDA MMC5_IRQ_STATUS
4 o9 p( d6 N1 ]8 f' y \ -
% i3 N; S7 m( n+ c - ;允许下个IRQ触发
& q6 @" Q8 \4 ?4 v- E @0 b - LDA #$80/ t! D1 Y' P& P# B
- STA MMC5_IRQ_STATUS0 l8 i, X' S! t+ A2 E# F7 U
- ) ]/ K$ }, n5 p
- ;IRQ处理, 每隔16条扫描线触发
9 l+ l+ p$ X# c% U - LDA <IRQ_Index
& B& u( @% A/ W- d( i' @ - CLC
( I/ u4 g! B$ p/ x9 G - ADC #$02( N; m3 H" b5 h& Q! O
- ASL A
: \) U% W0 H+ `1 F4 d - ASL A
& F* m; M2 X8 b - ASL A2 D. S$ T0 b0 P4 G! ^$ V1 a3 Y1 z
- ASL A
, g% D: z6 C" Q( x) d - STA MMC5_IRQ_SCAN_CMP% e: g( p/ b P+ p$ J. S5 e( u
- 5 I6 R* l$ Q( I
- LDA <IRQ_Index+ W) \7 e3 C. [
- BNE * + 4. {9 q w# l- D
- INC <PPU_Scroll_H
9 `/ E$ d1 I2 B Q+ j -
7 U% M9 c! T4 n) f& Z. S - ;设置屏幕滚动" Z0 a8 f* V6 T% z( a) I( n' t
- LDA <IRQ_Index
6 [$ d5 p; m% Y# h3 J - AND #$017 A- U; r* m4 |" _* ?- `4 l
- BEQ Irq_Scroll_Right) s" C1 }5 _2 W E2 n1 N( }
- A$ e) B) E3 X- Irq_Scroll_Left% m" [9 V+ s" a- v
- BIT PPU_STATUS3 W' S: _( z/ i* k$ r( x( l+ C
- LDA <PPU_Scroll_H5 w& V0 H7 H7 i( t; J8 u
- STA PPU_SCROLL. h" h; T% |; \7 z
- STA PPU_SCROLL5 p6 C _( J6 n& \2 ^
- JMP Irq_Scroll_Over
2 P+ T8 O0 n4 O0 R ?; ? - 6 r# }( \' E f8 k
- Irq_Scroll_Right* q' `% U9 T2 v/ Z1 l7 G8 O& J
- SEC) \! Y; p; n% K6 P1 r! V2 Q; D
- SBC <PPU_Scroll_H
5 a- y5 b8 H) O- O! {6 m9 e - STA PPU_SCROLL
% \( P8 P7 \' w6 x) t6 E- v - STA PPU_SCROLL" ^4 s' o8 R* u
- Irq_Scroll_Over
5 {, F% W5 c( y - ' U8 E# z+ [9 i+ _) V% I1 d8 C- _
- INC <IRQ_Index1 b$ J. a5 A) b1 P1 a1 e: r3 L7 l
- 9 w3 _* D. B& \" z% t$ T
- LDA <IRQ_Index
5 X+ k6 u8 ^* J& @7 @) n/ Y( y% \ N - CMP #148 L- i/ H5 }* a3 f
- BCC * + 5
3 K9 ?' M+ I: e/ u' C - ;关闭IRQ
' ?& D& Z( U W( w J - LDA #$007 i. N5 _& f2 Y$ ?: R, h9 v
- STA MMC5_IRQ_STATUS
6 X/ g! C2 z4 j2 h$ h3 I" L9 O3 @ -
4 K( A, T) G, @; _2 ~ - IrqProgramEnd2 d' X; L1 m) d6 N) n4 x
- PLA) `0 y2 |; A, v( x2 Z- w
- TAY+ `0 E/ h: v( x% b: `0 U/ J, ^( R
- PLA" p- B; i y( x% \$ Y
- TAX7 e. d- |* t$ E- o0 H& L) k5 o
- PLA! [4 G. X7 E$ H! E& o
- RTI
% F. w) u- R: w5 O/ s x -
9 q) z+ [4 u- u( W - ;==================================================
( _8 W0 ?# H9 S+ M9 o- B' {8 r - ;中断表! ~$ N( V o" h5 f$ y
- .ORG $FFFA) A( ^% D: c$ m# u" S8 ?4 c
- .WORD NmiProgram, ?5 v4 L9 u* y8 n
- .WORD ResetProgram8 J. h& ~# a" u2 B) i9 l/ U* E! I$ S
- .WORD IrqProgram
复制代码
. C; I4 M+ i$ Z6 I: i) [ |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|