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