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