|
- ;[FC音乐][MMC5 IRQ]
6 a( K8 `3 J* [6 C9 `8 |) ` - ;FlameCyclone 20230710
8 N. O$ t9 ^5 i' P* p, s; v
8 h r) N) o; }! h- ;文件头
- E/ L; V$ z. o- B2 S - ;======================================================================
& p" h0 I) e. A1 ]' k5 ? - .INESPRG 4 ;16KB PRG 数量
) U8 ]. A4 `2 `9 ` - .INESCHR 1 ;8KB CHR 数量
. g) F! M, w% s3 T1 \ - .INESMAP 5 ;mapper 5* U) z" n( v- v+ u# X* ^
- .INESMIR 1 ;命名表镜像 0水平 1垂直- g: t" L5 V3 C; [" m8 {* f+ K- E
- 9 Q4 H% [; O" E, S k8 a |0 J' S
- ;必要条件
/ f% U' k/ L' a/ T8 u0 O - ;1.持有CHR ROM4 b) ~. t. ]6 D0 F: u1 M+ D5 {
- ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
5 F' H2 w5 C. g' r, z - ;3.精灵内存(OAM)不为空1 u \# x" {9 C5 p# S X- T8 U2 q
- 7 j6 y" A, N* A5 L! [
- ;==================================================
+ S; N3 J9 O' t0 c+ p2 J: m - ;NES端口常量4 F9 [2 J$ N% |
- PPU_CTRL = $2000 ;PPU控制寄存器- z6 b1 A1 q, A5 G
- PPU_MASK = $2001 ;PPU掩码寄存器
8 N, C/ g2 t$ u2 V - PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
; n% o1 J8 ]0 Y p4 z/ ?8 G - PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1, {" w+ Q* P6 x3 m# {# N1 f
- PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
& ?; }+ l& N! ^+ t1 h( ~ - PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
+ Y' x" m0 J' D- p: S j; ~7 y - PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
$ h. s r. a) ^; P" { - PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
* l7 X3 G8 w+ t - OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存8 y5 P" G! m, n4 P
- APU_STATUS = $4015 ;声音通道切换
6 u. U4 V* G! P; M! i - JOY1_FRAME = $4016 ;手柄1 + 选通$ @5 T- g" E8 Y- w
- JOY2_FRAME = $4017 ;手柄2 + 选通
: d6 w- y+ R2 t; L* k- e
% c6 a- l8 c1 |4 k4 x+ K- ;==================================================
8 _; c: u% r5 \* S% @ - ;MMC5端口常量# y6 k) ]7 a. G* y$ a
- MMC5_PRG_MODE = $5100; 0: 32KB 1: 16KB * 2 2: 16KB + 8 * 2 3: 8*4
* S$ G. p5 z! e$ n& v - MMC5_CHR_MODE = $5101; 0: 8KB 1: 4KB * 2 2: 2KB * 4 3: 1KB * 8
) }' z% G& l$ z' w! h5 B - MMC5_PRG_RAM_PROTECT_1 = $5102;
! X7 L3 s# J2 Z8 X. U% ? - MMC5_PRG_RAM_PROTECT_2 = $5103;0 S9 @, a% ]' X8 w
- MMC5_EX_RAM_MODE = $5104; 0: Write Only 1: Write Only 2: RW 3:R
6 a) m) z: v. ] - MMC5_NT_MAPPING = $5105;
: ?( @1 o& E* L - MMC5_FILL_MODE_TILE = $5106
h' s9 {: L* ?0 p9 s" |* [2 \, y - MMC5_FILL_MODE_COLOR = $51071 a( ~$ h0 E7 t3 ?9 Z' X
6 A, g9 Y, Y$ P8 ^5 k- MMC5_PRG_BANK_6000 = $5113
: _' v6 V( Z6 E- {% x/ L - MMC5_PRG_BANK_8000 = $51140 Y2 d( ~6 Q, d
- MMC5_PRG_BANK_A000 = $5115
! D4 s* Q0 H) J b3 {( [- { - MMC5_PRG_BANK_C000 = $5116
' ~6 u; P8 Q o2 s+ Q: R- o, v4 i - MMC5_PRG_BANK_E000 = $5117
* A; g7 A2 M& e. }$ C9 _$ ] -
0 T( z. J% ^8 J X! | - MMC5_CHR_BANK_0000 = $51202 B( b2 g$ U+ }/ I: @4 e( D
- MMC5_CHR_BANK_0400 = $5121
5 E) t- j3 s0 R( l$ F* ] t - MMC5_CHR_BANK_0800 = $5122
+ D' ?1 w2 L9 e& ?+ u - MMC5_CHR_BANK_0C00 = $5123) J7 u; Y4 X) W# P, C: h
- MMC5_CHR_BANK_1000 = $51246 ~9 R1 p! i% a0 x
- MMC5_CHR_BANK_1400 = $5125
8 f* X' ] W+ R5 d - MMC5_CHR_BANK_1800 = $5126
2 G, h/ ~: o! N5 c) j t+ q - MMC5_CHR_BANK_1C00 = $5127
, U3 H# |/ a3 M4 V8 Z/ W
" [! N' m; o D$ q7 z5 F% U- MMC5_CHR_BANK_0000_1000 = $5128% e- @* T1 D9 ^& F+ b* b7 K' \
- MMC5_CHR_BANK_0400_1400 = $5129
$ _/ k3 k8 ?- k! l; X0 s - MMC5_CHR_BANK_0800_1800 = $512A
3 |: |! V' f# q# f - MMC5_CHR_BANK_0C00_1C00 = $512B; K% f& g& [$ J/ J
- 5 {. }: F* J- c, `' K
- MMC5_CHR_BANK_UPPER = $5130
/ B% n( b" x$ P w" t - MMC5_V_SPLIT_MODE = $52004 C( q% ?" ~2 f. U/ _$ _5 t2 ]
- MMC5_V_SPLIT_SCROLL = $5201. H: O1 k' S0 S" z( R4 g7 I
- MMC5_V_SPLIT_BANK = $5202
3 g7 u+ [1 t' t: { t$ G - , x( z0 ]7 H3 _! K
- MMC5_IRQ_SCAN_CMP = $5203
$ L6 L) Y8 ^5 A) ?- s! L6 y* M+ R - MMC5_IRQ_STATUS = $5204
, L- _, p$ r5 K$ W% u - MMC5_MULTIPLIER_A = $5205
- F8 z1 S. e6 Z, g - MMC5_MULTIPLIER_B = $5206
8 |# x- Z& }/ d( V# ?2 ] -
1 e& Z" X* O2 g( U - MMC5A_CL3_SL3_DATA = $52076 [# B( c/ h( T2 `6 G; x& O
- MMC5A_CL3_SL3_STATUS = $5208; k' @7 J" j) i) D
- MMC5A_IRQ_TIMER_LSB = $52099 F. y7 F) R6 Z
- MMC5A_IRQ_TIMER_MSB = $520A
) o+ q4 ^3 Q/ U* b - , k/ J* b# ?- t" ~$ w
- ;==================================================/ t& P6 [8 T5 ^! X
- ;程序块配置! c3 q: p# x! p; y
- BANK_DATA_MASK = $07
, f8 I9 Y8 [6 z; ]" w - ;--------------------------------------------------
, t( k3 `0 o' a( p1 f6 K - RESET_BANK = $07% M3 {2 h; A7 k
- RESET_ADDR = $FC004 z2 R$ R, f! w1 {2 M/ V
h. f/ r' Q' f* Z) G5 C) z- ;==================================================
+ q! G0 l8 P3 X* o. F - ;图像块配置6 a; A, t4 B2 H* Z6 D- M
- CHR_DATA_BANK = $08
8 {' F# h2 t$ R( {8 m+ @. F4 G - 7 B0 V& C- ?6 \; i( B/ O
- ;==================================================
2 [1 I9 I, F1 `& s1 W - ;零页内存地址配置9 l, z% ?4 O5 O- ^& P7 c( A+ Q
- Use_Ram_Addr = $806 ~3 X, V: P9 M( Y4 B. w* _
- PPU_Ctrl_Buf = Use_Ram_Addr
" q$ w$ g/ m5 q4 I2 ^ - PPU_Msak_Buf = PPU_Ctrl_Buf + $010 p% K9 ^% g( w+ }% B7 l* L3 z
- PPU_Scroll_H = PPU_Msak_Buf + $01
4 [0 p# f/ y( O - PPU_Scroll_V = PPU_Scroll_H + $01
6 R1 x6 e1 w' n9 j! {' r2 f* I - FC_Data_L = PPU_Scroll_V + $01: G0 T0 q/ Q( o7 F) g8 {1 }/ Y
- FC_Data_H = FC_Data_L + $015 M( K8 p/ s% f9 m. k% y% E* O% d
- FC_Data_Buf = FC_Data_H + $017 s! a( U& n5 X; `8 Y6 |; Y
- ;==================================================1 q5 T1 b' b4 [8 k
- 4 \* g+ H7 l' ]& C
- GAMEPAD_MERGE_FLAG = $04
' H# C; P/ ?3 R* |6 ~' u M# ? - 9 r( \5 _0 r. |& t
- Gamepad_Keep = FC_Data_Buf + 1( M6 H( H9 c" z0 v
- Gamepad_Once = Gamepad_Keep + 2
% d" U B: k- v - Gamepad_Temp = Gamepad_Once + 28 \+ A' T3 n1 p2 s, b* W
-
: U3 P+ j. Z2 e - Gamepad_0_State = Gamepad_Temp + 2
5 N+ R. M$ O( C" S, P - Gamepad_1_State = Gamepad_0_State + 1" {/ F7 B9 s) v
- Gamepad_0_Value = Gamepad_1_State + 10 }/ @! ?% {1 ~' K q
- Gamepad_1_Value = Gamepad_0_Value + 10 e# n9 a h7 [- Y" ^) c
- Gamepad_Port_Value = Gamepad_1_Value + 1; F. [6 W, v7 e0 ]: _4 c
- Gamepad_Merge = Gamepad_Port_Value + 17 d7 d4 F9 C1 t2 e9 P; g
( s+ `4 m, g, m. A% \& r- ;==================================================
" y, D& w5 Q G2 \1 ] - IRQ_Index = Gamepad_Merge + $01# \7 n! K: c a8 C4 I' U. y6 u- e
- ;==================================================* d; `' Z4 D+ h* K. a L' Q. r
- $ u1 k% \: i* P7 _! {6 }6 l
- ;CHR图形数据
) O, K4 A! Q/ f - ;==================================================
% W3 }' i5 d8 Q u- C& c+ a( Q - .BANK CHR_DATA_BANK
2 u& A9 h* n4 V" g" Z3 H - .INCBIN "chr_bank/chr_data.chr"
: I- [) h$ Q9 T2 u" r5 E$ t3 l# D5 m - 6 F1 O4 t1 N' G! _
- .BANK RESET_BANK & BANK_DATA_MASK4 a1 c; L- J2 f/ f+ h% E4 s
- .ORG RESET_ADDR
# {3 q/ E5 v" V) W - 3 Z2 I: s+ w; \5 w7 D3 p+ V4 R" K
- ;-------------------------------------------------- [3 a. M$ R" ]1 `7 J# p
- Attributes_Data: y% Z( n8 b( w
- ;命名表属性3 t, {: E2 b( b3 H
- .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
% d5 M, @6 q( `4 ~7 X- P$ V) T - .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA7 W' p% r+ ]* C" h: u& Y0 K% R" H
- .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA5 G& I/ a3 I* ^
- .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55$ n9 \+ V4 ]7 }8 }" b
- ;--------------------------------------------------) j2 J% ~6 m9 q; b R+ Q
- ;调色板数据
& J: p4 |& |+ E - Palette_Data
0 ^8 v+ V6 x* e1 } - .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
, L/ r6 I5 ^+ W4 m4 X8 x# h) X4 e# A - .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
* n# ^2 b* ~% t& I0 i
5 D3 `) _& @2 Q! t& ?- ;==================================================' Q. x) `0 Q% ]! H% l
- ;命名表初始化
' P2 H" P% }& _! k' s - Init_Name_Table
* g g. r( V, s- } - LDA #$204 I$ K% Z/ [0 |* S8 f$ w1 B
- STA PPU_ADDRESS
6 l& X4 j. o- u - LDA #$00
0 p+ P5 m% ~) p8 m - STA PPU_ADDRESS4 s2 V, D+ ~8 u: d: U
- LDA #$00" ?" h4 s6 D" T# o8 Y7 M" G
- LDY #$00& k. r2 u' J3 n# h5 ?2 h f
- LDX #$10
9 E. ]7 q! W5 z; t+ H - Init_Name_Table_Write
: K$ e: h, S- Q. _6 w$ @ - STA PPU_DATA6 o2 X2 M. m- D; {, e* B
- INY
) [6 P/ ]# L; O' z: \ - BNE Init_Name_Table_Write* C5 }, y) n5 f% D, `
- DEX
/ T* o! V0 m- {9 \ - BNE Init_Name_Table_Write5 y4 J7 n# B' v$ E, A% O: G5 Z" ?
- RTS9 r% a6 ?, Q$ ]& ~+ c* e* T/ I
-
( q) o# o# ~- J0 R4 x Y - ;==================================================
" M5 E/ Z, `' ~" k0 _ - ;调色板初始化
5 a9 c+ t$ y e* {+ i* L - Init_Palette" c. J' E6 i I7 {3 \2 y
- BIT PPU_STATUS
+ r ?8 g7 h/ o6 R - LDA #$3F
- v8 Y p4 G' o5 B* k2 I- L - STA PPU_ADDRESS; t$ e2 K6 x5 E/ I, D- z
- LDA #$00
: ~5 Y( o1 f! J4 L9 Z2 O. Z - STA PPU_ADDRESS! z6 z3 \9 k$ j4 o/ m6 F5 n, G
- LDX #$00
: k8 \$ `( y z$ e/ Y: o' b - Init_Palette_Write6 G) N6 }* Q% E$ n/ j( P. e( O1 Y; _
- LDA Palette_Data,X% m9 v* f6 R' |/ @$ U1 f
- STA PPU_DATA
X9 I/ u* ^) i& Z; R& | - INX$ T7 @+ @. H" Y1 ?& H4 v1 N
- CPX #$20$ F$ h D" l8 ^6 s( C2 ~) r' k# z
- BCC Init_Palette_Write" d2 n% U! n1 h5 [ O8 g- P% E2 l
- RTS
- f f( @8 o- k$ ` - 3 b/ {" {6 @3 K# }" w
- ;==================================================
4 ]0 `+ A! N4 s9 n - ;设置命名表属性
4 x, v7 D1 i0 j( y( \' O+ Z7 [: q - Init_NameTable_Attributes
) `+ Z4 A3 R9 N1 c6 N - BIT PPU_STATUS- u, w3 f8 B" O1 r3 N
- LDA #$23
7 i {# a+ }- a+ A$ L9 E0 K ~ - STA PPU_ADDRESS
5 r; w; [8 h- |+ c5 i" f- g; y1 ` - LDA #$C0: W% P: B4 f ?5 r c( j S
- STA PPU_ADDRESS
) A" J% R5 I3 G6 m - LDX #$00
2 A. ]+ Z5 M0 [8 p5 F$ g0 Z1 B) r( k - Init_NameTable_Attributes_Write/ u, s) _0 A( k" T
- LDA Attributes_Data,X+ j& k: A9 M7 X$ _' f
- STA PPU_DATA2 ~2 p3 V. Q7 x7 i
- INX
1 p9 s+ P1 Q9 ~" Q+ | - CPX #$400 p3 o5 v2 t5 M2 c; O, m. _3 }! f
- BCC Init_NameTable_Attributes_Write
) Y+ [7 \) J- v! `3 @. e: m - RTS
5 V3 j( N5 A( W, B" v; `2 h - ! R. n3 H; J0 }2 d3 t. z
- ;==================================================: l, D- l) Z6 u+ k. f3 W
- ;初始化命名表文本
7 D, M2 L9 }+ ]8 b0 }; V/ v* g - Init_Name_Table_Text
9 y! S) i; j6 [! [ - BIT PPU_STATUS
/ @& q1 x) ^% ]! T3 a! r! [1 N - LDA #$209 F. Q' Z* B9 i9 d; h: v! u
- STA PPU_ADDRESS( |3 Z5 |8 M9 o: S8 N
- LDA #$00. O% P: o f( W$ x- {, N/ l m
- STA PPU_ADDRESS
P$ S/ Q5 k: I" r. M# R7 f r/ _ - LDA #$00
/ L( K y' N, @: `/ n" [ - STA FC_Data_Buf: J& j0 N7 U; d0 h
- LDY #30
+ i7 D( I& g* u - Init_Name_Table_Text_Write1 d* _" K( @; Z0 @. N$ e
- LDX #329 q3 o: b ~2 }/ [8 K+ D
- Init_Name_Table_Text_Write_Char
1 s% H/ F% i* U+ |+ s/ E. j6 b0 g - LDA #'0'6 U% X% V5 n' N* p
- CLC ]: {) u0 f2 a# Y
- ADC FC_Data_Buf0 l8 a/ i4 T8 G! B' c
- STA PPU_DATA3 D7 D8 g" e2 W0 R- L6 T* o8 M
- DEX
6 F; }2 I* K) j$ ?. n m8 a0 W6 n3 w - LDA #$14
$ W) _6 H$ L/ q; {' f: [$ l# ` - STA PPU_DATA9 _2 q" P+ N- t5 |# h5 ?1 X
- DEX* s2 `, L5 D( c! S
- BNE Init_Name_Table_Text_Write_Char
* ~6 k, D# U- j: p/ F# V/ z6 u/ w% E& @ - INC FC_Data_Buf$ ]2 ?; I$ `& R8 O1 P
- DEY7 r8 o2 X1 l2 W8 H8 i3 m
- BNE Init_Name_Table_Text_Write) K+ H/ z1 \& E5 s$ _) a, N6 T! ?5 p
- RTS% `& b) B5 r) L, f, z6 z4 A
6 Y" o; H6 J6 q. G: J- o- ;==============================6 t- M* M( |7 M$ P8 j
- Init_OAM_Ram;初始化精灵内存
- I/ \$ k+ E& B& V - LDX #$003 F4 Z# A/ ?0 O x
- LDA #$00
B# i' X6 y* z( @$ s, e4 Z - STA PPU_OAM_ADDR
6 V* t- [* o* I6 D; B - LDA #$F8
) W5 M! @" F- a# O- \ - Init_OAM_Ram_Write
: `1 B1 o% M; ]4 D - STA PPU_OAM_DATA' A# D: J9 X$ r
- INX N; @6 N- q6 I9 Z6 ?, k! b2 ?
- BNE Init_OAM_Ram_Write+ A# L9 k; ?( f* b+ G6 \6 @
- RTS5 E- W7 ]4 ~; f& c7 C2 X9 [
-
& m8 r6 O, V6 V# M% r' Q5 g: i, r - GamepadProcess;手柄处理
# m! p/ J2 p* x, l! q8 q - JSR GamepadDatacan5 B$ |1 H, }4 G9 O' O5 J9 F( y$ [
- LDA <Gamepad_0_Value% t* ^2 p0 T8 i' V( H3 {
- STA <Gamepad_0_State
3 n4 s/ L# Q S4 L$ Q6 @) ~ - LDA <Gamepad_1_Value: M* W! B- T2 n2 _* ]; ?" _
- STA <Gamepad_1_State, ^9 T# E5 B+ X0 {8 O: b
- JSR GamepadDatacan
# Z4 J2 }" [+ a& B* ` - LDX #$01, }( e) q: V. Y# H6 T$ `3 K
- GamepadMergeCheck;合并手柄输入检查
% X# \* ~% ]2 Q3 b; w - LDA <Gamepad_0_Value,X
7 l5 |, U$ g0 f - CMP <Gamepad_0_State,X. v, E. g! T% p
- BEQ GamepadMergeInput# \4 J: f: z; O( Z; E1 S4 X: z [0 d
- LDA <Gamepad_Temp,X# D) a7 p9 U/ v# d+ ~
- STA <Gamepad_0_Value,X
! S/ S$ a! }. {; J- i( G - GamepadMergeInput;合并手柄输入! f9 W1 H7 N1 D1 e
- DEX
0 v8 T. ?6 {) d% n' P4 L0 _ - BPL GamepadMergeCheck6 v6 |! U& [$ T& g. @3 Z+ W! [! a+ |
- LDA <Gamepad_Merge
}! p: y. F) t( J8 ] - AND #GAMEPAD_MERGE_FLAG! _3 ~& z' D; D. d5 p3 b! h8 O
- BNE GamepadStateProcess
; E4 x; e! ?* g! ] K - LDA <Gamepad_0_Value
! G: p9 ?. I; R' X2 T6 F - ORA <Gamepad_1_Value* [# |% I4 A' \2 ^! n. b
- STA <Gamepad_0_Value0 J" L8 V1 }7 a* }) |, g7 X
- GamepadStateProcess;手柄状态处理5 Q; E' l' E6 x
- LDX #$014 w8 @. x- F, _$ u
- GamepadStateSave;手柄状态保存
! G9 a- W' V' M( R$ r! a' ^ - LDA <Gamepad_0_Value,X
! _/ z j2 p7 T* \ - TAY
; _/ s: T- {3 ~2 r. h7 O$ I* Z1 E - EOR <Gamepad_Temp,X. X# _# k0 C* i9 ^ X% F
- AND <Gamepad_0_Value,X
+ U6 T4 Y$ d# A' K& j. n - STA <Gamepad_Once,X: s* j9 [4 _" J; B
- STY <Gamepad_Keep,X4 k5 ]* k. r2 @$ v6 r) E
- STY <Gamepad_Temp,X; K3 H; ~3 O& E2 k& n! s
- DEX
% b* B$ D" D2 k; S - BPL GamepadStateSave; H/ k: w1 @) n& B7 ~! S% q
- RTS9 `0 G1 W7 X8 M
- * T- B ^- r, T0 a. z* P; v
- GamepadDatacan;手柄数据扫描
0 z% w" T/ v' C - LDX #$01
& [8 g: N; ]/ }) U - STX $40163 b- W+ G3 R) n* Y4 D, y; I+ O
- DEX
7 Q! s- r5 q/ G; @/ f s4 q - STX $4016' O- P5 ^- B7 U1 x& U
- LDY #$08
0 }% M, M q6 b' {- c - GamepadPortScan;手柄端口扫描
7 ?/ G6 _% {$ d& ^ - LDA $4016; ?& Y! z7 }5 f
- STA <Gamepad_Port_Value4 f$ T5 i2 `5 H
- LSR A% v& D3 H: a. ]0 B- l7 ~
- ORA <Gamepad_Port_Value
: q7 C) J& w3 {4 u/ v$ b - LSR A
. B G4 x$ x3 \, c! s _7 r7 K - ROL <Gamepad_0_Value0 C4 Q2 K- u6 V& Y' S
- LDA $4017
- K2 r# j; \" W, a% q - STA <Gamepad_Port_Value
' l- ~& q% o8 }) `) ? - LSR A
( T2 p: `5 g: g9 G7 q5 r# i - ORA <Gamepad_Port_Value! U) T+ F0 @3 Q# s4 F( F9 W
- LSR A
6 o& h/ B0 M4 v, z4 Y - ROL <Gamepad_1_Value
7 a4 s8 b" [4 H4 c - DEY2 {: P5 [# m$ x" K! h5 z: ?
- BNE GamepadPortScan
* {/ P9 u4 `. Q" E) W - RTS
5 K. P, b# b. J9 Y -
: M1 S$ c% o. I* d/ I7 ^ - ;==================================================
: p# }" T) y7 A1 B# w - ;PPU处理
$ E5 `" N! }% s& @4 U B - PPU_Process
$ ?: I4 e1 t7 s' w- I - LDA #$00
# R" y5 r6 {# @ - STA PPU_MASK$ y( q( N4 x8 R
- . ~. G: h* P+ ?! U& }3 F# e
- BIT PPU_STATUS& u+ q7 m# f m) ~
- LDA #$20
4 d9 b# @. h% _0 ~+ g1 `+ _ - STA PPU_ADDRESS7 q* M& d+ _" a9 N. \
- LDA #$002 J# J3 g( E7 D* s, }
- STA PPU_ADDRESS0 ~) Y8 d. x& s/ ~0 N
- # z9 \5 d* I+ o. v6 b: d! d+ H
- STA PPU_SCROLL
$ \1 i' \2 j* g* V - STA PPU_SCROLL" B6 g" _- n8 J
- # w* Z$ m6 [+ z2 S0 ]4 `
- LDA PPU_Msak_Buf. E) g9 I, S2 }8 z) ~% F
- STA PPU_MASK5 b* ~$ Q# k* h9 P' T8 G
, P6 b2 ^ { L' s/ l% V2 r! l; F- RTS& h9 h2 E9 N. x6 {
-
0 O; j5 ^" v& g. x - ;==============================. B; ?3 H" B6 v
- Time_For_Vblank;延时等待
6 W. l7 Z. E& Q0 X$ Z% B: t z, a* f& @ - LDA PPU_STATUS
% s1 R/ ^' y7 S: m, r: A' j% O- x - BPL Time_For_Vblank
! p3 p$ [) y5 Y) Q. F2 Q, N1 R - RTS7 b; X2 C2 S6 P& M8 b$ h; S, I
-
3 C( n% B! }! G - ;==================================================, m6 Q. V. ?. {& ?
- ;初始化MMC5
! g. c' U2 H2 R" z' t/ `# U% ` - Init_MMC5$ Y0 P+ ^% k3 @: l! L5 c/ k3 F h
- $ ` y7 o0 Q/ i' ~! h# ?: X# W o
- ;设置一下6000-7FFF的RAM
0 L" f* Y* H, o1 \ - LDA #$00
7 M$ ?, ]! ?1 Z - STA MMC5_PRG_BANK_6000
7 `1 O" S, Q3 ^" v -
( ^5 q: f& N. N( A$ k2 q3 D+ {- m - ;开启 PRG RAM 写入 P" T7 @/ Q8 d" y1 j
- LDA #$020 O3 {1 p1 U ]3 |% _. M
- STA MMC5_PRG_RAM_PROTECT_1
. a+ U1 }5 x: o% q - LDA #$016 l9 ?6 _7 c( p9 j+ V) `6 ?5 @% W% s
- STA MMC5_PRG_RAM_PROTECT_2* F" A/ x9 W) O( i% \! h
-
% {: h7 @8 @: c$ a6 S - ;启用 1KB 扩展RAM ($5C00-$5FFF)
~( n% ? b# t9 P5 ] - LDA #$02
; A- t) I) P: T N0 a - STA MMC5_EX_RAM_MODE/ @& u1 z0 e: _3 ~% Z
- ' \* x+ a" V0 H0 \, d" K. c( b
- ;设置 CHR3 a2 I- F; Q/ y- |, ~; n1 V! F
- LDA #$00
0 O+ E4 M, I! K8 \9 C - STA MMC5_CHR_BANK_0000
) i) ? N. t8 g$ O- e - LDA #$01+ Y0 Q; S4 { y* [3 Y& s
- STA MMC5_CHR_BANK_04003 I% J6 C: `: q, u% _0 s$ M
- LDA #$02* H U- v* L: V" k2 r1 I% h, `
- STA MMC5_CHR_BANK_0800
3 i0 i4 O4 Z. x% R1 q - LDA #$03
, G( U5 \. n/ Z) e* r - STA MMC5_CHR_BANK_0C004 ?8 j2 s6 N: S& a3 Y! ?* O1 \
- LDA #$04& ^( G( U2 m5 U- L
- STA MMC5_CHR_BANK_1000% q4 E. K! l* z# V
- LDA #$054 O, p1 R) Z$ R3 v/ c: I
- STA MMC5_CHR_BANK_1400) Z( `7 c9 ~8 N% c7 v3 n; }
- LDA #$068 x# C+ f. S* J& A% |9 ]4 |7 z
- STA MMC5_CHR_BANK_1800
! d1 h" D k1 @$ _6 C8 e1 R0 C - LDA #$07% P0 R7 q8 M* B$ a4 f& x
- STA MMC5_CHR_BANK_1C00
& k0 I3 ^& u. m4 z" m - 6 I0 L' E' I/ z% }
- ;设置屏幕镜像
0 [# a, ^+ L" N. f1 p& @# L8 g( @ - LDA #$50
9 q6 N) C3 L6 [4 R6 T/ u - STA MMC5_NT_MAPPING
( Z7 h! H' x7 O: ~/ d! s. H -
6 ^' t' i, |6 L8 n/ n% V' B1 h - ;禁用IRQ. ^, e. R1 \ B
- LDA #$00, T! N3 q2 r- Y3 z, e
- STA MMC5_IRQ_SCAN_CMP
& t, C' n( s4 u5 p+ P' q( O9 C8 [% f - STA MMC5_IRQ_STATUS. ?; b2 O+ g1 a6 W8 h ~# H
- , v# n0 W7 M: q8 g* W' `8 b# y' b
- RTS
9 j: A) Y9 L" l8 l& I/ G/ y' N% _ - ' P/ q# X$ \/ ~( D
- ;==================================================- D' B2 j% L* q, ~. r9 g2 w
- ;重置中断处理 ?. j& p6 M; V6 ]1 r
- ResetProgram
9 W4 g1 P5 D0 @ y! W! Q7 f) c# h - SEI
9 E5 q9 k- p# M; p/ ?) w1 W( ^8 ? - CLD
; q9 a/ Y) y8 { - LDA #$008 M+ b& z; s! x6 _1 d# V
- STA PPU_CTRL
8 @" J6 |6 ^) W6 e - STA PPU_MASK- ~ T* h3 N# V
- STA PPU_STATUS( l* ^! Q2 z0 X; M7 w
- STA JOY2_FRAME1 C, y4 v) C6 Y% s3 O$ f5 }: D5 c
- STA APU_STATUS% S3 E6 s$ a0 T. o1 j: S7 e4 n
-
% t- R6 N$ G; Z' |5 h. H - LDA #$C05 o* E: T+ J! U9 J9 ]6 t
- STA JOY2_FRAME; B) X% `5 T& t( L! l* y: I
-
# c7 d, k4 K3 j6 ^8 O+ Y8 u' H - ;等待vblank7 |+ v- x W1 s
- LDX #$02- H7 C) F8 J, w1 |& H* e$ s; U
- Vblank_Wait_15 j* a& d) }' S. j$ r
- BIT PPU_STATUS
- d& h+ o$ }4 K9 Y# M, O5 K" G - BPL Vblank_Wait_1
$ q* h3 F: i% X& k& m7 h7 ~ - Vblank_Wait_2
/ @: w/ \5 d1 d4 P1 w - BIT PPU_STATUS
( U2 t; j8 W5 O4 v - BMI Vblank_Wait_2; w3 ~2 Q/ {. j1 y
- DEX% S) I$ r. w& x2 Q, a! X/ h: ]
- BNE Vblank_Wait_1
& }9 K W: K6 b2 ]3 T4 N# F -
, G1 s* V+ {' z' z# I - LDX #$FF3 k2 o7 ]9 F/ V6 S, e7 o
- TXS& `1 S4 a3 Z0 Z/ F* W" {, O
- 8 v: ]7 I( f' s' g! C! r" I$ S# o
- ;初始化MMC5
& ~6 a0 M9 r; `% A& t4 i: _& } - JSR Init_MMC5( v, ~. u6 }0 K9 u; y+ s
- 1 y4 T4 d( b. I5 ~+ N3 g: }
- ;==============================
/ N5 \ m' w9 b! C. Z3 C' u" \0 r% q% c3 U - ;RAM初始化
3 U# K8 b5 O& L; e s! [* O - Nes_Ram_Init
, B4 j$ o* F7 a% v& W2 g - LDY #$008 R" \8 p. K `" x8 s
- LDX #$08
7 J& q5 l5 W; p% v" I5 Q - LDA #$00
$ v! h- P( x+ X - STA <$00. T7 n7 S2 h; _3 D4 x* J% l3 A t
- STA <$01
. T' a7 j& ^' F5 Y( j- Z - Nes_Ram_Init_Write
( ?- P. b a2 l$ o u: z - STA [$00],Y" O' | k1 L+ `8 E) t
- INY% o& I# s- S) A
- BNE Nes_Ram_Init_Write i6 o( p P+ x6 e' [; S& f+ ?
- INC <$01/ b, B- A% W( r+ D$ B! U8 {7 Y) ^
- DEX
9 B5 ~* X$ T& l$ x3 d$ [ - BNE Nes_Ram_Init_Write
9 Y: O; ^: `$ ^7 L -
# B- a0 o2 p+ p1 c - ;初始化命名表2 Y; n7 }9 R7 }. n# T! C2 C4 f
- JSR Init_Name_Table
8 C- e- Q1 G0 Z8 N+ w) k8 [! X -
! h& B! Q2 [5 D' a: R" L0 k& J - ;初始化调色板
- T. T. o' x, h# u5 g5 S - JSR Init_Palette
) @ C5 Q4 D( O* ~1 c - 7 H4 t, ?$ t. {7 Y' k- e/ @! d
- ;初始化命名表属性* V G5 X/ i3 @' a3 \" T4 h
- JSR Init_NameTable_Attributes1 Y1 r. {# @2 W9 b
- 9 ` {& O" Z% i( Q1 J
- ;初始化精灵内存
! x; q$ j4 @4 {$ i6 |7 t - JSR Init_OAM_Ram* ^" ~* M5 w( k7 p% K1 v) D4 c
- , Q; C- A. r! G0 c6 d, t
- ;在屏幕上写点东西& Y4 M) a E, e" o
- JSR Init_Name_Table_Text
! O# Q* O5 F6 l( Y+ \4 V8 o - " K3 u' I- w7 d+ e
- JSR Time_For_Vblank6 E+ P Q6 U, A5 |
- ;开启PPU控制3 n c+ Z: r+ L4 m3 s# N
- LDA #$88. V% H5 q: Z; \& K- H& P; k5 V
- STA PPU_Ctrl_Buf5 K% M& E$ H0 e3 u u' T# A3 i2 B
- STA PPU_CTRL
* a6 n8 x" _7 y1 J9 X C# b' X - * W6 n' c# O( C( t
- ;开启PPU显示 o2 ~; k/ c3 J3 V, S
- LDA #$1E
/ d6 U: ^+ s3 P+ s$ Y' h [ - STA PPU_Msak_Buf5 R. l4 }! l0 W" c+ u* f4 p8 g
-
) j3 Z$ R0 y: M0 Q/ ?: V3 K5 R - CLI- @0 R+ ] N' ?- Q% a0 u' n
- JMP Loop- Q7 m' @6 n. ]" D. s7 Z, H3 G
-
' ^" `: ~) K: R' V% T' ^" j - ;==============================
3 b" ]5 G+ @7 L' r i5 S. N - ;死循环, 等待NMI中断
9 g. r6 ?8 J) I8 k- }' ]( H5 Z - Loop% |* o; W4 U) V8 W
- JMP Loop
- z, z. u# u, F- k - ! ]: R* N$ L, B1 [, _
- ;==================================================
) z' `% H. J! @+ p$ g - ;NMI中断处理5 V8 m$ Z) j) L, e4 [( c
- NmiProgram% L: Y: E4 q8 c4 K
- PHA
6 T( v w& O( `$ V4 y, H* R9 w( z - TXA4 l2 m: d% K, Q1 D! v, U3 l
- PHA
! n0 ]7 j4 d( h: b' [9 M3 F: Q - TYA
* b3 B- o4 Z. ]8 C9 _% W - PHA
0 p1 ?( }# ^5 T( I" n - * {* Q4 J4 U( N
- BIT PPU_STATUS; P1 F8 n) h5 F2 z& {' d2 W
- , E9 O( ? d) J- r
- ;启动IRQ中断, 第16条扫描线触发
$ b0 ]7 V) W% O7 \7 n - LDA #16
& [. j$ t# ?, e# E2 K8 L - STA MMC5_IRQ_SCAN_CMP
6 O+ R0 _) O A1 @- e' g' Q6 } - LDA #$80
/ }8 G. w! ~3 u- v4 b- t0 f - STA MMC5_IRQ_STATUS
+ r" u5 T3 {7 k - CLI
2 p5 H' y B, y1 u - + s- q: O' O* v, q. S9 n1 J6 \* Q
- ;关闭PPU控制, n& _$ ^$ W" |. H* }0 o" w& D4 _
- LDA #$00
8 O. z5 {% X* C+ a( e! F+ ? - STA PPU_CTRL
! n! ^4 K# Y9 F& m4 b4 R -
2 [ S. S1 b) @" n8 k2 C' }. q: w: ]1 x - ;处理PPU& H+ m% u; X0 Q( q) f5 b
- JSR PPU_Process0 ]3 ?3 o$ y+ N( q
-
( U( L" B+ E, }, ?( m, } - ;开启PPU控制
" l) U2 m) y5 D6 X - LDA PPU_Ctrl_Buf
- V0 J% ~, Q) J+ O! J- b$ o4 M: _ - STA PPU_CTRL4 t' L3 }8 b# ?6 U& h
- 6 w( @5 u# D5 }- S
- ;手柄处理
" a6 P: n4 S+ ~2 L) g - JSR GamepadProcess
; I7 i( _0 _8 f0 f2 W -
5 z( J# u9 z3 ?8 l/ F - LDA #$00# K! Q' ?1 J# r* V
- STA IRQ_Index0 Z* f' w& o, q7 L2 M% I
-
p2 z9 Y2 m) e - PLA! p+ [. \$ I h8 {
- TAY0 C6 |8 Q9 s/ x6 P/ S( }; v
- PLA, T: M: E# x5 @7 E& l; c
- TAX
, _, i0 `2 L; r - PLA! N- j- d* U! L4 d+ o6 e
- RTI; \, V9 _, w( |' O. m
- 5 _' Z6 f" g. X% J1 ^
- ;==================================================% ?4 p" |7 t6 P5 n
- ;IRQ中断处理, g- F9 C) E9 U/ M& M8 e
- IrqProgram& |# _2 s8 D& G( N9 W
- PHA
1 c. E. } y6 F0 o - TXA
" Z# T$ T# Q) T9 s/ W# g7 y3 }, N - PHA
1 b" a3 m3 b+ I% I, y: W6 A3 O9 J; b6 d - TYA
( u. G2 j. J6 j. n5 r - PHA
# t3 U7 L. N" A/ B3 N - . |8 W- k/ y0 Q; O9 a* H
- ;确认IRQ
- {# M; [9 T4 G+ ? - LDA MMC5_IRQ_STATUS
. {: r0 L8 Z( p- K$ w( V* M& [. M3 I -
, a5 q8 j% \ v/ P* i - ;允许下个IRQ触发
# I3 l( k; i- U7 _ - LDA #$80
+ g8 E3 k: A l& x8 E# w( p - STA MMC5_IRQ_STATUS
5 `9 u" J2 C3 s* c -
$ L9 [6 q$ u2 @" ^$ ] - ;IRQ处理, 每隔16条扫描线触发( X* t8 L0 }( Y
- LDA <IRQ_Index: W* m1 k( C! _0 D* t- M, K8 p
- CLC
6 _& c( K$ `& [, p: q% \9 b - ADC #$026 ~/ ?/ Q* l' I' J' E( P) p
- ASL A/ y$ C/ E9 U- U$ s3 o, e
- ASL A: T2 I: l$ l+ z6 W/ E1 X# ]. f
- ASL A3 d& Y5 W* a& {2 I5 P7 Z% C( y" k
- ASL A
: Y/ K2 v4 j: Y: H - STA MMC5_IRQ_SCAN_CMP# `- L# D b- n0 [/ {& J
- 2 \7 K. _0 d" m3 e, Z% A
- LDA <IRQ_Index
, ^6 U1 I6 H* g s1 b - BNE * + 4
. \0 u1 ~# ^8 h7 @6 N! _ - INC <PPU_Scroll_H
0 o* U- i+ a0 W- F5 \( I -
9 Z7 l C5 ~& j! z/ y' N0 a - ;设置屏幕滚动& n5 |: n0 V8 R2 ~
- LDA <IRQ_Index, F7 q1 w( u% h6 S
- AND #$01
+ i$ M1 W$ ~7 ]- |1 K& k* w - BEQ Irq_Scroll_Right
5 {% P4 ~- L9 Q) H m
' G5 L8 D; }7 g7 A' D9 \- Irq_Scroll_Left
7 r, ]& ~6 |# Z, c m4 S5 _ - BIT PPU_STATUS+ _& L& p+ f8 y& {: ]6 G9 ?, X0 d1 M
- LDA <PPU_Scroll_H; o }* M" X* e! b
- STA PPU_SCROLL
8 H) o! I& i* |( G$ Q! f/ a5 g+ Y - STA PPU_SCROLL. c% U" e" T: j4 b
- JMP Irq_Scroll_Over
; x$ I+ L f3 _1 P" H - 6 n% m( z j- ]# e6 I& e
- Irq_Scroll_Right9 u& A, y3 k( y# Z' J# }) r3 h& n
- SEC
6 p. U( H( C/ }; U1 M" V# T - SBC <PPU_Scroll_H) D( _ a; r( |& B+ X
- STA PPU_SCROLL
1 e7 `( d" F* f7 K4 ^ m% F - STA PPU_SCROLL" H+ C4 ~# P: P3 N q$ y( L: k
- Irq_Scroll_Over' ^) r* [+ u2 U( i
-
7 G( {$ m$ q6 k( H4 Y8 L - INC <IRQ_Index
5 `0 ]+ \+ g, [; q9 x$ b -
: e% I. a; d/ P - LDA <IRQ_Index# T8 D4 x* x3 Q8 \- y0 `. C4 w- K/ u8 y
- CMP #14
7 f: F* M# B7 @ Q3 q) t7 f8 | - BCC * + 5+ f6 r2 {0 m/ G3 ?5 H* n& v
- ;关闭IRQ* h J, k) m d8 y! e1 r7 y
- LDA #$00/ Q" ^/ A @5 b7 \3 d4 M' E& N
- STA MMC5_IRQ_STATUS$ s# z6 s) W0 i- n q& v7 H' A2 p D
- % e J; Z& |3 _, i+ r( u* p* f
- IrqProgramEnd1 e$ V& e7 o" d
- PLA
% o* j3 C4 z* i' K% x - TAY
: H% d3 v* Z3 ^: x1 w3 R - PLA
/ m! s% O- x% F, N - TAX
) j( f1 ?7 U+ A; o( ^: w/ i - PLA
8 G. j: _" H; g( r, q a - RTI
4 s; Q; f2 j9 d% H) [ x: y -
3 R3 g7 W! z* J* p& |, v( e - ;==================================================
; T, \0 Q7 L! ]* ^- z/ n. S - ;中断表; z9 E A( A; `- q% e
- .ORG $FFFA$ @. d! p- f2 b' t$ o
- .WORD NmiProgram x! A3 C4 N4 I* T+ N* c7 q
- .WORD ResetProgram e$ s6 `$ t2 ]8 f
- .WORD IrqProgram
复制代码
/ B# N9 u: q! a4 x |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|