|
- ;[FC音乐][MMC5 IRQ]
# ^ G/ _; `# n* R; Y - ;FlameCyclone 20230710, `2 [8 {; W8 l2 D9 |! |* T
1 ]' n7 Y$ F8 C: b) M6 o- ;文件头6 ^- Q& p; _) _; [
- ;======================================================================- }- R& I$ L! h2 [9 z/ R
- .INESPRG 4 ;16KB PRG 数量
5 x# \; O H9 S9 t5 e6 I - .INESCHR 1 ;8KB CHR 数量( Y6 t7 F. j2 X6 s; f
- .INESMAP 5 ;mapper 5
' F, A, v+ N- G7 `8 V4 ~+ A, J, l - .INESMIR 1 ;命名表镜像 0水平 1垂直
- W. c7 K0 c# \( B+ Q+ R8 L
, z6 ^5 I, R5 R. p' {3 J- ;必要条件 D/ C6 p) ?+ m4 M+ s ~! Y1 r9 K; n
- ;1.持有CHR ROM; N" N3 f, Q, c, E- D
- ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$10005 u7 W+ A5 b, u
- ;3.精灵内存(OAM)不为空7 T8 y4 E: B7 R8 H; T2 [
- ' i" A: N- g" V6 }
- ;==================================================
! C, ?+ b/ }( \. v - ;NES端口常量
5 P, H" a( R& a, S% x5 ~% C2 W - PPU_CTRL = $2000 ;PPU控制寄存器
# p" E" h6 F# O - PPU_MASK = $2001 ;PPU掩码寄存器& d- L9 {( G5 ~# o
- PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
; f D! g% \8 l; Y* W - PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
+ ~$ q0 w$ _1 O* p" R/ M/ P" B5 B; b - PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1& ?) R5 U; q0 A) _9 F
- PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
, @# x2 t% ~; u0 B - PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
2 r. R a: m- B, ~ - PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
& h; y3 J8 Z! n3 g - OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存7 w+ y5 N* N1 a$ ?( G
- APU_STATUS = $4015 ;声音通道切换, W/ `& L2 X2 h C) k
- JOY1_FRAME = $4016 ;手柄1 + 选通- \9 ?, Z7 L1 u! L, ?! Y; U- C% m
- JOY2_FRAME = $4017 ;手柄2 + 选通
6 L6 V5 W# k5 J. H; _
+ y9 v0 @) n7 N$ e; }. h, `- ;==================================================( q( v3 v: }6 K+ o" \; A
- ;MMC5端口常量% P1 I. |8 i# d4 j5 E* x+ V" V. V+ B
- MMC5_PRG_MODE = $5100; 0: 32KB 1: 16KB * 2 2: 16KB + 8 * 2 3: 8*4
0 T/ u: h% c0 [: h& I - MMC5_CHR_MODE = $5101; 0: 8KB 1: 4KB * 2 2: 2KB * 4 3: 1KB * 8
2 I7 i6 w$ l* ~5 ~. f - MMC5_PRG_RAM_PROTECT_1 = $5102;+ e9 @5 z- {' }4 u( j4 c' Z
- MMC5_PRG_RAM_PROTECT_2 = $5103;
( S" U9 m- {5 A) x. E0 j! M, [0 Q/ e - MMC5_EX_RAM_MODE = $5104; 0: Write Only 1: Write Only 2: RW 3:R
. j0 i. I# y' ?& V5 k/ U. @, y$ q - MMC5_NT_MAPPING = $5105;
2 C, I( ~8 B) w2 v; v3 N# l- C - MMC5_FILL_MODE_TILE = $5106
1 L2 s% C* O! p0 d8 \' f - MMC5_FILL_MODE_COLOR = $5107
- c! |" G9 @' L( U' [
2 }3 n# B" S7 q' q' O& b( u- MMC5_PRG_BANK_6000 = $5113( m0 ?( `' `+ W6 ?8 U# u3 c6 u0 L9 h
- MMC5_PRG_BANK_8000 = $5114
6 j5 z8 E, U% m: ~& U - MMC5_PRG_BANK_A000 = $5115( r5 `1 N9 Z8 O$ u" K
- MMC5_PRG_BANK_C000 = $51161 O7 J! U/ v0 V3 C2 {$ p
- MMC5_PRG_BANK_E000 = $5117
& ~/ m+ O8 N8 m -
) O" U' D( r; r& a7 t# E - MMC5_CHR_BANK_0000 = $5120
9 F4 J E# y) f$ f) y- k# ` - MMC5_CHR_BANK_0400 = $5121' F' u) }6 j# c' R6 @
- MMC5_CHR_BANK_0800 = $51223 H$ p4 L2 L7 K+ F$ m0 f
- MMC5_CHR_BANK_0C00 = $5123
8 A4 }, r$ o3 s& Z$ j2 [ - MMC5_CHR_BANK_1000 = $51245 z+ R/ O( @! U" R
- MMC5_CHR_BANK_1400 = $5125
) r1 i' R. ~. G* ~0 u - MMC5_CHR_BANK_1800 = $5126
* p- W6 q. `7 ] - MMC5_CHR_BANK_1C00 = $51278 ?4 l7 x$ O6 Z+ K+ z
- 0 Z5 e2 M* R" m e8 l$ z
- MMC5_CHR_BANK_0000_1000 = $5128. W! S, o+ D* O. A, p' X2 W
- MMC5_CHR_BANK_0400_1400 = $5129
/ p4 |6 J- l' | ? - MMC5_CHR_BANK_0800_1800 = $512A
% S3 o: F+ d' A) ~( x - MMC5_CHR_BANK_0C00_1C00 = $512B2 |3 Y0 W; E+ X
- : g* l+ i! q5 p
- MMC5_CHR_BANK_UPPER = $5130+ f* c% u; I' Y' N6 O9 l
- MMC5_V_SPLIT_MODE = $5200
, S, J1 o% l- o3 o - MMC5_V_SPLIT_SCROLL = $5201& [' I! O7 p; T; [! x
- MMC5_V_SPLIT_BANK = $5202. S5 W, E' ?- x3 J& r
- * @& f) e: @: c' F3 {
- MMC5_IRQ_SCAN_CMP = $5203# q' r, t3 \; J# W% ?- ^7 [
- MMC5_IRQ_STATUS = $52049 ?' M5 K6 P4 \9 Y- u
- MMC5_MULTIPLIER_A = $52056 A, h8 E5 _% X$ }
- MMC5_MULTIPLIER_B = $5206: f1 e+ H0 ~+ j* H4 J
- : Y. k7 J6 ]% @2 [% U8 Q, a% X
- MMC5A_CL3_SL3_DATA = $5207
6 b% x! h( ]4 N - MMC5A_CL3_SL3_STATUS = $5208; n% A7 W f2 [3 I, G! s
- MMC5A_IRQ_TIMER_LSB = $5209
! ]' n+ u3 t4 ?. b' ? - MMC5A_IRQ_TIMER_MSB = $520A
5 f4 l2 |( u& ]& D* N5 A7 ?" E! ? - % f) A: ^$ Z; Q A7 }) \
- ;==================================================+ W* u2 q/ H3 }/ T
- ;程序块配置5 I8 ]$ g" u N3 @2 }7 O* c* l
- BANK_DATA_MASK = $07 a) X% b @8 l1 z) k
- ;--------------------------------------------------
3 S8 z9 b' r! _- n7 r% S - RESET_BANK = $07
+ ~2 C- p* k& [2 { - RESET_ADDR = $FC00
3 {0 ?3 d: Z' q- N& M. g( \
( l. K/ c) b& T' a* M- ;==================================================
1 ~: Y2 t. Q" p, z3 N* p- R1 ~ - ;图像块配置0 v' i2 j& L6 x6 A0 d
- CHR_DATA_BANK = $08
# L, T2 Q2 S2 o) P" j6 q
" \( B( w9 q# q6 O- ;==================================================3 A( _- C0 @* j$ J9 v$ \4 S
- ;零页内存地址配置# R8 D# K' G7 P3 P! n
- Use_Ram_Addr = $801 N6 n# S2 ~3 X& N. ]- C) o
- PPU_Ctrl_Buf = Use_Ram_Addr
. [7 M6 N$ {! I" D" ? - PPU_Msak_Buf = PPU_Ctrl_Buf + $01
, v3 W( h; R1 H. o" n* k - PPU_Scroll_H = PPU_Msak_Buf + $01. o4 v' d+ X9 `" A; ]) F
- PPU_Scroll_V = PPU_Scroll_H + $01
+ f1 G+ h5 Y- `$ H3 S) u - FC_Data_L = PPU_Scroll_V + $01
4 j# l4 t y" T" p/ o: u; \ - FC_Data_H = FC_Data_L + $01
7 Z8 M. q, |+ t - FC_Data_Buf = FC_Data_H + $01
; ?( r. G4 l! m8 c. u9 K - ;==================================================
4 `3 y/ L7 V' v4 \+ O7 }$ n# z( a
5 Y y5 x& ]# a- s. _6 P+ f; u) s- GAMEPAD_MERGE_FLAG = $04
$ L% u7 Q% b5 H: X - ) g" d Q( ]" y3 C0 a! H# f
- Gamepad_Keep = FC_Data_Buf + 1. `/ v/ S9 i. M6 `
- Gamepad_Once = Gamepad_Keep + 2
" {) A5 A( e9 ~3 G4 [ - Gamepad_Temp = Gamepad_Once + 27 \( W/ P; |$ G/ Z J6 r; t$ H7 |
- / G4 i; ?3 b" M, d- T8 u
- Gamepad_0_State = Gamepad_Temp + 2
1 W- P- V S0 q - Gamepad_1_State = Gamepad_0_State + 1
( R. W* _' g7 Y1 z8 H - Gamepad_0_Value = Gamepad_1_State + 1' U. ^1 w- H% z: ~. C4 \
- Gamepad_1_Value = Gamepad_0_Value + 1" J6 a c! C# X, d, M7 e
- Gamepad_Port_Value = Gamepad_1_Value + 1
( v: k$ k" c/ b6 `0 W: a - Gamepad_Merge = Gamepad_Port_Value + 1( j. T; Z* I; Q
1 j# `9 E- v. N$ c8 c6 P' M- ;==================================================. r9 ^, u% Y; }: O6 j. L: L
- IRQ_Index = Gamepad_Merge + $01
! n' Z3 E$ N4 } - ;==================================================
" w' u; y j3 [- a
2 w* ?: a+ O1 X' X- ;CHR图形数据
* w4 U) X# G: r+ |( @6 d$ D: K - ;==================================================
5 }6 f1 r- F4 j' N - .BANK CHR_DATA_BANK* v/ |& f' Z8 L# S' C
- .INCBIN "chr_bank/chr_data.chr"
! d9 _2 G, _3 _- g -
4 [9 n! q' n+ A/ F" X, C; b - .BANK RESET_BANK & BANK_DATA_MASK' |% }( s b$ p
- .ORG RESET_ADDR1 I3 m. X4 E6 B5 \# S
- $ \0 f( @0 a& r) Q1 _& _
- ;--------------------------------------------------
/ B1 }7 D5 D2 w3 j- [( Q' K, M - Attributes_Data' M9 Z3 J; _! U i1 {. u2 x
- ;命名表属性( M4 ?5 Y/ a; @# d: {
- .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00+ m* h2 V) P+ b6 H
- .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
7 m' v3 U; [. p& ]; b* { - .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA) ?5 \( G9 t' I8 R* P8 E
- .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$552 g9 b& \8 y) s! X
- ;--------------------------------------------------
a- b/ M9 {& n8 {2 E - ;调色板数据9 h8 N% @: ~; A7 p) `
- Palette_Data; j% t8 U9 C! A. n3 }" X! ^6 U3 A
- .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
1 {7 |$ L& K# v) v2 R+ m - .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F+ @& L' `; u; a6 c5 i
- $ B+ v& z/ c' }
- ;==================================================
9 g2 ?6 b" L9 \/ J& i, F - ;命名表初始化3 I9 c, g7 E6 k9 b4 I' o1 }
- Init_Name_Table f1 h ^* A. \; M& k3 m: W
- LDA #$20
/ E; v& @% _# V$ } - STA PPU_ADDRESS
! |" F* B+ A9 G3 B7 v - LDA #$00% g' w# X0 D3 @ T! z6 H) d7 D
- STA PPU_ADDRESS" P$ t; g' g: m2 k Z9 x# t
- LDA #$00
8 f& h* c1 Q+ J9 D' L5 F! u. I - LDY #$00
% V& ~% x+ o0 }; i! K6 G) q5 [ - LDX #$105 A# F( l# v$ J5 p2 A( j, d
- Init_Name_Table_Write6 E% R K" U4 i$ O" y! a0 O8 x6 U
- STA PPU_DATA
) }9 \ X( Z$ n5 H - INY
$ _* q' n2 E) s- x* Z - BNE Init_Name_Table_Write) d A% s/ J( y' I7 T
- DEX
d+ ~! r+ }+ y g0 p- d# b& b) l - BNE Init_Name_Table_Write4 P& l1 w! O6 E( D1 W) N2 `" n
- RTS
) j) G' Z& B- t, E- P -
5 b: L! X+ V2 M0 k5 N - ;==================================================
5 l7 p G1 t- Z& C8 @ - ;调色板初始化* h! ` f3 G' i; X- u5 z# O- [ u
- Init_Palette
+ w# J" ?9 m- t+ I$ } - BIT PPU_STATUS. O- p5 x) P* e! O* n3 R5 ]
- LDA #$3F
% x" ?" b9 W: k1 G8 ~ - STA PPU_ADDRESS7 O; F/ g; _2 K7 b( W
- LDA #$00
. e/ e' A0 g3 i- e2 G* _+ e7 D - STA PPU_ADDRESS
* S5 p/ K9 r) s( s* |4 G - LDX #$00" r) V" Q8 v# {# `" S* |: ^, S
- Init_Palette_Write
H# D1 B1 ~' W" ` - LDA Palette_Data,X( [# X% f- s1 V7 v# J& F
- STA PPU_DATA3 {: { k' L+ Y
- INX* a8 v( Y; |( @9 |& i+ C
- CPX #$20
6 V9 ^3 j$ y4 i0 i2 X- y5 w - BCC Init_Palette_Write
5 l" |5 }# } R* A3 _ - RTS1 d' i5 [* l: u2 z4 x" Y
-
! X$ T6 j# S+ O - ;==================================================
m' p. r e% J2 q+ [+ O - ;设置命名表属性" f/ n2 f2 w5 s9 \2 _
- Init_NameTable_Attributes
" V- W! L+ A9 r( E4 E. b - BIT PPU_STATUS
( Y+ _* z* `) T: Y Q: N" G5 q - LDA #$237 S* Y0 P& F, y s+ H
- STA PPU_ADDRESS
% Z( r. Q! P& h - LDA #$C0* x: a- y$ I1 X7 _) k- N* ^
- STA PPU_ADDRESS2 b5 C) q& f/ i* h. R5 @7 m
- LDX #$00
+ v1 O+ c4 x/ m" Z6 ]; A% ? - Init_NameTable_Attributes_Write
( r; a, v$ P; \! c - LDA Attributes_Data,X
$ m: I4 a- I4 W" | - STA PPU_DATA6 W! K8 c" `$ z8 e* b
- INX
/ y" D- `- O& D, \ - CPX #$40) I6 P6 {0 N$ Q0 z, w
- BCC Init_NameTable_Attributes_Write
8 c! I+ }3 D. J+ O6 ?# n- N - RTS8 S7 X# w5 J. e, @& i" J* K3 Q
+ f4 u- E# C+ A. n: F: q- ;==================================================
) a3 ^* x6 R) O: y0 k, I - ;初始化命名表文本% I# I8 d, ^+ n5 j
- Init_Name_Table_Text. t1 p: w# W$ B" G
- BIT PPU_STATUS
- f% U$ I: k% A- o6 a l$ j - LDA #$202 r7 x6 t) z8 z3 R c" S; R5 X( U
- STA PPU_ADDRESS. @5 y* H3 g4 e+ n
- LDA #$00. F% m# _8 D' j6 x
- STA PPU_ADDRESS- E- M0 a% k" f5 I& P
- LDA #$00; `" {# Z# f) V; x
- STA FC_Data_Buf
* h$ `" b% w) q2 A' O9 I7 v - LDY #30
& P; d7 b! q+ x- M - Init_Name_Table_Text_Write! t2 z+ y' H; ?5 ~: e
- LDX #32
5 Z1 @: O6 X9 v6 ~+ _6 z - Init_Name_Table_Text_Write_Char
7 y: t" z/ h- a* Q9 ~ - LDA #'0'
; S9 W* D5 T$ {- B- L4 P( N - CLC7 y' x# G$ h4 Z0 H1 }
- ADC FC_Data_Buf
+ Y+ _4 S, M$ k, [9 D. F, Y/ K - STA PPU_DATA: a2 O) d/ C$ M. ]2 u! v5 |
- DEX% _ J+ ]" \% E5 A; M
- LDA #$14- ?5 l8 ?7 v+ R5 W
- STA PPU_DATA" |" }: Y. w4 H3 l ^5 d
- DEX9 v+ ^0 D% i% y9 q/ W
- BNE Init_Name_Table_Text_Write_Char
5 Z/ i# Z/ y+ e. ~( c+ o - INC FC_Data_Buf m; j) [* k; |
- DEY4 m, @+ ]/ A/ v# q) Q
- BNE Init_Name_Table_Text_Write# D9 V2 U$ M6 I7 |, |
- RTS6 m! L0 ?4 G8 p( D* N
8 q# f- P$ ^+ m- ;==============================, p& r' w; l$ q- M! F
- Init_OAM_Ram;初始化精灵内存
. u+ M8 ?9 n' y - LDX #$000 o, _0 p! O3 Z: z' h2 p" r3 R! T, [* e
- LDA #$00
* w9 y) E2 l. k( W% t( H: L/ h - STA PPU_OAM_ADDR7 T/ I6 m2 G4 w- l
- LDA #$F8
# w- X' ]$ o1 ]( }* Z3 b. a - Init_OAM_Ram_Write
) I% X! G1 a2 [+ a8 O( c) C9 ~ - STA PPU_OAM_DATA3 n5 t4 J7 U# D& X
- INX
, E# x, ^* P# @; ^' g. E& d4 R - BNE Init_OAM_Ram_Write
4 t/ ]) D: Z* X. _# k - RTS) {- y7 _& {: E$ r& e8 ]4 [& j
- ; p* E% f7 \8 q
- GamepadProcess;手柄处理5 x: a* l! q9 f: c
- JSR GamepadDatacan% z3 D! K; g: }' W9 s5 Q3 X1 |, q$ t
- LDA <Gamepad_0_Value' r8 ^. [9 s3 p9 t r/ d. ~* C
- STA <Gamepad_0_State8 {$ S2 m* c% a+ J: b
- LDA <Gamepad_1_Value
, _. t# n8 {2 U - STA <Gamepad_1_State: M' D/ `: t& U, e# o6 a; _ K, k
- JSR GamepadDatacan
7 J% y( q/ p0 x4 ^ H6 s - LDX #$01
9 X! T- [8 ]8 ^% ]7 x5 Z/ C' o; u - GamepadMergeCheck;合并手柄输入检查- n6 _3 j3 i$ s/ T: C3 Q. I2 t8 \
- LDA <Gamepad_0_Value,X: M+ v: u$ [. i2 Y8 i
- CMP <Gamepad_0_State,X0 U: j" e2 H, ]: r" ^: g
- BEQ GamepadMergeInput+ e5 y ^$ b9 p) e8 X
- LDA <Gamepad_Temp,X
+ h& t' |* i) [, G - STA <Gamepad_0_Value,X
% y" K7 X: t# J$ H" a% \' c - GamepadMergeInput;合并手柄输入7 n! v; S0 u6 j
- DEX
, D' L9 _$ w& ~7 b2 | - BPL GamepadMergeCheck
8 T4 _3 B. N8 q9 ]0 ~6 k - LDA <Gamepad_Merge5 \2 O% }9 r& ]
- AND #GAMEPAD_MERGE_FLAG
# J7 B/ |6 L4 k- `2 n% a+ Q - BNE GamepadStateProcess' K: I& V) l% X3 X. t' g/ P
- LDA <Gamepad_0_Value
' r: G J4 x9 T - ORA <Gamepad_1_Value4 l$ u2 y' d' k" ?9 {3 I7 b7 u
- STA <Gamepad_0_Value
2 {9 C& j4 P1 j0 L - GamepadStateProcess;手柄状态处理
7 C& O: }: ]; A. g" R9 @4 |& { - LDX #$01
! K: Z+ |; ^" F& [# a+ a - GamepadStateSave;手柄状态保存) X3 r' P' U$ v8 N
- LDA <Gamepad_0_Value,X& M5 p z7 @# Z' p9 S
- TAY
$ D. I- A f! c4 E - EOR <Gamepad_Temp,X
) Q; e6 ?. N/ G$ D' d8 j' n3 ~ - AND <Gamepad_0_Value,X9 ~/ Y8 P1 Z( j+ G
- STA <Gamepad_Once,X
9 [3 n, ` H$ @9 K- [7 w1 f - STY <Gamepad_Keep,X
' ]+ B+ k" u" k2 r, J - STY <Gamepad_Temp,X5 p2 e+ x; @: t. c2 ]% _* L0 t
- DEX8 e% s6 B% u; u$ A
- BPL GamepadStateSave% i) w2 a5 y: S' t' o4 a
- RTS
" K+ h3 U: ?: {% [( s
+ @2 Z! [+ K! F3 T- GamepadDatacan;手柄数据扫描
6 j8 u. a. X2 U) R0 W0 k - LDX #$01$ n1 ?: e& Z! v; ~# h7 \
- STX $4016
2 f/ i- H2 h1 _6 p# S - DEX
* O, j- g# q0 r2 D) F/ U. V - STX $4016
$ l+ E( h" d% l4 ]7 q - LDY #$08
! f/ ^/ q" U+ K/ i8 G0 ]1 E/ X - GamepadPortScan;手柄端口扫描
+ F A7 Q! b, t; Q* z& Z y8 w - LDA $4016; m0 y" ?% x& f i
- STA <Gamepad_Port_Value
/ ~( C( m6 \7 P0 G" I7 k - LSR A
l! X: Q* B6 H - ORA <Gamepad_Port_Value- |" a" Z+ V$ H6 m$ t
- LSR A
. K" f: L# Z) |# ^/ F+ S- C - ROL <Gamepad_0_Value
; U7 o) [/ a! u - LDA $4017
0 _$ i1 i9 o9 O% | - STA <Gamepad_Port_Value
1 S" d8 A4 h+ E - LSR A
$ v1 G4 r* G$ ]/ [( Q - ORA <Gamepad_Port_Value! j/ ~ F/ P) Q$ T" B. T
- LSR A" [& \3 z; a3 g& s% X
- ROL <Gamepad_1_Value
3 [- n6 `: f% }6 y0 P - DEY
7 e9 H6 d2 e' L. v - BNE GamepadPortScan
$ J& P: K- J) r. O/ {3 r - RTS% V. Q" B; s5 p: f& g
- ! b, i. K/ v; [ L) c) x: D
- ;==================================================
6 D r5 l9 [$ O0 {: | - ;PPU处理
r7 G! O& k1 _- B ]3 ~+ d - PPU_Process
+ D+ d* q% x" } - LDA #$002 Y" P! y1 R. f, C3 g" E
- STA PPU_MASK, n5 a/ [/ |& j* Q9 ~8 ?
-
, F& [, W0 E7 _* w4 q/ z" Y - BIT PPU_STATUS9 q6 R8 G3 @8 \. c" ]; l+ f
- LDA #$20% T+ @7 P9 C0 C. k# C
- STA PPU_ADDRESS$ ~9 l! b) [; W* N: @$ c. }5 s
- LDA #$00
. y% k6 c4 L5 A1 s0 l - STA PPU_ADDRESS
+ }, w6 S4 @- ^ - 5 s" L! C! [, m: K* T
- STA PPU_SCROLL6 m( K* u7 {7 f) R9 S$ s8 E
- STA PPU_SCROLL' z0 {0 e6 ?, u' s& b
- 2 _; j5 c! v( Z
- LDA PPU_Msak_Buf- g1 G2 U3 m' e- f' T+ S
- STA PPU_MASK* c6 x% R- c5 W+ W
- $ a3 y9 ~# z' r' ]% v4 ]* B7 s
- RTS4 i* y$ j! ?1 B7 F
- 5 n& {- y" n! T, v1 i
- ;==============================1 q+ q2 D' {( O6 I! x6 F
- Time_For_Vblank;延时等待
% R2 u( y% x9 {4 c- x - LDA PPU_STATUS) Q% j, V* i; ?7 F
- BPL Time_For_Vblank; @% Z6 |0 D W7 [
- RTS
2 i% p& \, r6 m5 L -
- I4 s( ~2 n! y5 y, C8 @! V - ;==================================================
8 p2 J& g: S( W: J - ;初始化MMC5
" h. |# K, _7 b C6 e - Init_MMC5
) u* a: F+ \) ~2 `6 A - % g k) p1 b& S
- ;设置一下6000-7FFF的RAM
1 i0 }5 }5 W5 p( I - LDA #$00
( i4 s7 P1 z0 ?- G3 _3 v - STA MMC5_PRG_BANK_6000$ K" ]& `$ N+ B
- - D- ?! m4 L* b) P) Z
- ;开启 PRG RAM 写入4 Z) W/ [/ K/ T
- LDA #$02 A# {( _ ^: Z1 L/ d: B1 j
- STA MMC5_PRG_RAM_PROTECT_1
/ _1 A, x& C' S, ~8 D - LDA #$01
& I& {! S1 d9 w) o5 `1 N) o - STA MMC5_PRG_RAM_PROTECT_20 c/ T" v' O: j0 Z* T
-
. n5 ^1 Y: b$ e5 O - ;启用 1KB 扩展RAM ($5C00-$5FFF)
# k, E9 ]" f* Y - LDA #$02
# ^" M* E5 W3 u1 M - STA MMC5_EX_RAM_MODE
7 q; \4 x+ L2 X: g& W# X' z - + G8 e# u+ l2 K2 _7 |
- ;设置 CHR
- ~& t8 \0 h. Q - LDA #$00
! h/ g5 {: C5 v8 I/ [ - STA MMC5_CHR_BANK_0000
% V o- f) F# }! t - LDA #$01
1 Q5 _4 Q5 |% L: u6 J* W: }& P - STA MMC5_CHR_BANK_0400
: a R5 ]) C& X3 n1 v3 k - LDA #$02+ g% a1 Q i* C
- STA MMC5_CHR_BANK_08004 g& n2 i& X6 C0 C! Q* V1 l( R+ ~
- LDA #$037 L9 Y( J" N2 c8 x! D4 [
- STA MMC5_CHR_BANK_0C007 K# \" D& G" c. \
- LDA #$044 b/ q; E- O+ O K/ ? P# f( b
- STA MMC5_CHR_BANK_1000' z2 d+ Z# k8 L! v* E
- LDA #$05: z, O" Q4 O1 J* ?' `" o1 M' w
- STA MMC5_CHR_BANK_1400
3 ~2 X7 S: `* Q- B$ [$ J; K - LDA #$06
' b% y# w- }- y/ f- D8 _" a - STA MMC5_CHR_BANK_1800# ^( `8 `+ G) P C
- LDA #$07! {1 G2 r& z- A/ N5 P5 A% b9 H
- STA MMC5_CHR_BANK_1C00
/ H- a- M$ G3 x -
" q( K+ O1 ?2 ^ - ;设置屏幕镜像
9 H/ h7 k5 p$ ?5 g - LDA #$50
+ E2 l' \. g# ] w C - STA MMC5_NT_MAPPING4 x+ k- V8 V' k: J9 c( J: A9 E! K
-
/ g4 ]) [1 C2 i" f6 k- `9 J - ;禁用IRQ$ T( c0 |( u0 a9 Q& R
- LDA #$00
! {+ [! l& Y8 ?) x% z- O, _* p$ T - STA MMC5_IRQ_SCAN_CMP
8 X/ {6 C; c+ m5 {: y3 j! y$ R - STA MMC5_IRQ_STATUS( M; p; R; h# _- G+ i" u
-
8 k8 U! k& V' \ - RTS
' {+ r% p% C8 E _ -
: r1 E* I! y; Q" l+ L0 s+ L - ;==================================================
5 `/ s0 l$ F$ X- R- L& T& {5 |* K/ x - ;重置中断处理 _3 a- Q2 _1 Q! N4 s
- ResetProgram
* K& I0 K: N+ m S) w6 y' F$ t - SEI
) n+ C3 E: Q3 }& [ - CLD
2 o2 j1 A+ y0 d5 Y7 @ - LDA #$00, [9 y/ \, _! G# y0 _$ F
- STA PPU_CTRL5 U0 @, k6 T1 ^+ o1 w1 q/ j
- STA PPU_MASK
! a+ g9 ^2 H* S1 c2 ^ - STA PPU_STATUS
1 U' D: |2 ]$ t0 l2 Z% m3 Q1 _ - STA JOY2_FRAME& z" Z$ M! l% ?) v( {4 o
- STA APU_STATUS
W) h2 K. d ]% f. L -
- w9 w5 ~2 x5 g6 p' S - LDA #$C0
& d/ d8 P% K3 H( E9 `" u2 D1 ]7 l - STA JOY2_FRAME0 _$ P0 k8 j, s& y; { L
-
" r g- c ?0 k) o' i7 D- m9 ~! t9 I - ;等待vblank* R+ {5 w i9 {$ V5 z1 J
- LDX #$02
3 I/ K/ z, H. d8 ^8 U1 x, ^* V3 a - Vblank_Wait_1. I) D! W0 M9 z1 Z. R) e, W
- BIT PPU_STATUS
6 u' \# U, `5 A: d - BPL Vblank_Wait_1
# _ ]- B& v) R4 v" {6 K - Vblank_Wait_2& ]* n: a) t9 N" @$ \+ S& ~& D" r
- BIT PPU_STATUS m; R( e- G# L" l& Q. p9 x; i
- BMI Vblank_Wait_2
% V: Q6 i7 R+ u2 y+ K - DEX" H+ R9 g# v0 w$ Z% ^
- BNE Vblank_Wait_1( E( B) m. D, p, s! C" k
- * f2 V+ @: _0 O: N; n# H+ F# ~
- LDX #$FF: j1 {5 x# [) R- ^' I
- TXS9 \$ @' I9 W3 P) m! s! s
- 8 T6 Y: i( b8 o& j& x: q
- ;初始化MMC5* ]' }. \% p. S& b; ]
- JSR Init_MMC5+ y' @+ p; Y: H5 `9 b8 w: Y: e8 _
- . r0 y$ w% v% O5 ?* U9 f$ e7 ]
- ;==============================9 L( @1 h. h4 L+ e
- ;RAM初始化. w8 y8 t1 q2 u6 e8 M$ i8 v
- Nes_Ram_Init8 T3 m3 Z! s" i0 {+ {3 ?
- LDY #$00. L' n+ I3 F, H
- LDX #$08
R' z9 V" y% C N - LDA #$00
4 i6 c8 v7 f9 Y) f - STA <$00, O; N0 i( _7 x9 ?6 i Z
- STA <$01
/ o8 }( j' F q! U" Z1 M" _3 ^6 M V6 c - Nes_Ram_Init_Write
$ g1 Y; A" x4 r - STA [$00],Y% }! q9 ^1 o' I& p
- INY) I* s/ Z# x( ~" K
- BNE Nes_Ram_Init_Write: @! {5 }! m) A
- INC <$01* ?! E/ x8 p, @
- DEX
! @, Y. b$ [4 T7 G+ I& _! S0 t - BNE Nes_Ram_Init_Write& t8 T' F5 B. e g9 W
-
* }3 a3 X d: k5 u - ;初始化命名表$ d" X: `* O% A0 ]* L7 M% `8 t
- JSR Init_Name_Table
1 O( s0 @; x8 O/ Y6 W5 J -
2 ^; t; C$ q* S - ;初始化调色板
. S ~" g, }5 `6 U! z - JSR Init_Palette5 n+ N, Z; a* o% y/ s" ^) h
-
1 H6 U% ?5 T0 `- K - ;初始化命名表属性! S) k) ^5 v. ?+ y" H) ]7 y3 d+ a. A
- JSR Init_NameTable_Attributes' k5 K* a% z( p( O# x3 A
-
4 A$ h% D1 `6 Q& @# O! \ - ;初始化精灵内存
3 M# n7 G. [/ ` - JSR Init_OAM_Ram5 [( {3 Z" i. u q8 i
-
+ ~+ T. |: @% w7 l: n; x - ;在屏幕上写点东西5 M# f' `6 {" M7 c2 p
- JSR Init_Name_Table_Text
1 ? [0 C7 M/ w -
8 y8 S! @/ A" G - JSR Time_For_Vblank4 }: C8 g2 k$ f$ C8 J
- ;开启PPU控制
2 P j# y. }7 F7 {9 V% F& B; Q - LDA #$88+ ?- G+ d0 `: E- T
- STA PPU_Ctrl_Buf, [0 r0 e8 \( P) R1 N
- STA PPU_CTRL; @9 G2 B' X- X0 U# r7 L
- " [* {, s" @ q5 d8 s
- ;开启PPU显示
( Z' g2 @9 _& @1 B" M4 X. g - LDA #$1E; q6 D; W5 K% f, i5 x$ H& Y. T
- STA PPU_Msak_Buf k) }4 O; Z7 i) N5 h! k, x
-
- n; `6 D5 o- ^& M1 s; q - CLI
8 \5 `; ?& c0 K+ q8 G, L( v - JMP Loop" p4 I) G8 U6 i, l2 ^- k3 @
-
6 U& a5 V+ `7 Y( {7 h - ;==============================8 v9 S4 g8 d$ |' e6 O5 s: B
- ;死循环, 等待NMI中断+ d6 y' ?' }8 m6 ]. u
- Loop' W D1 H: g) U8 v' f7 v
- JMP Loop. W. L$ b+ s: `; i' q5 q
G) E7 P9 s: @- `( U7 U- ;==================================================1 h# a9 _! e# o
- ;NMI中断处理
: u. c l# t% l( O; m2 B, A - NmiProgram7 z0 l- i* G' B6 H+ B
- PHA
, y- v6 j! p, s, Z2 o% N+ U - TXA
% P0 I6 n9 O8 }2 T. E - PHA
1 l) @7 l4 ^! W; p4 S3 R - TYA
?! ]1 [4 }4 \ - PHA
' w) r! j# X1 T - 5 T. c' ^- M' g, e9 d1 q
- BIT PPU_STATUS
; s% A- G: g/ B* _0 g1 Y& G ?0 o2 B - 1 h6 t+ Q) @! ?4 M. J3 j7 k/ H
- ;启动IRQ中断, 第16条扫描线触发
' p" S) G$ E$ x1 z1 ^ - LDA #16 m: ~& d' e$ i, F
- STA MMC5_IRQ_SCAN_CMP# T( l4 C5 u" d& L3 b
- LDA #$80) f% H' O, Y) H! h; ]7 @% e
- STA MMC5_IRQ_STATUS; f8 D4 f! @2 Y
- CLI: L& u! y4 D6 x7 C
- * O; X) X/ `* W+ ?
- ;关闭PPU控制$ h0 {$ s9 Q6 C7 {( @9 W
- LDA #$00
8 J; \4 R& m: C/ @- v; \ - STA PPU_CTRL
+ f3 V" q4 j+ ]* R. P, c/ O/ m1 l0 j - 2 i7 x; ]% F3 a; ]. e
- ;处理PPU$ z8 M1 G# t" F
- JSR PPU_Process: m5 {% k6 T! R" O6 P
- # a2 T* R9 f2 M" g8 F( P
- ;开启PPU控制$ o5 o& p- ~; r! C. {" M+ N
- LDA PPU_Ctrl_Buf5 P# t# T9 ~" Q, q/ y( `4 o
- STA PPU_CTRL* R$ A/ Q. n- b8 f' z
-
. G9 {* \$ r7 \ - ;手柄处理6 d* I3 l) l# p
- JSR GamepadProcess$ R9 x, k, s' e* W& }( z$ g" k
-
1 G2 P$ | H6 H" O1 c - LDA #$00
4 @! S! n# h' Z9 i+ u R; N4 l - STA IRQ_Index9 H8 M: R* W! f0 b: N! B
- / ^% n# J2 ^. [% Z( n
- PLA
+ F* E9 ]# |7 i5 m, ]/ ^( j - TAY' k* R+ M3 [! H T* s4 V5 t
- PLA
0 j* \; {; l( ? - TAX0 q" X; y( b. P/ |
- PLA
. r$ f# f; V$ d* ^/ L: b$ ^ - RTI
8 p& m8 Y6 t: I' O$ f
0 w" ~6 ^: P: c) A1 J3 G+ C* p- ;==================================================
! J# \- {. p _1 ], e* S" a - ;IRQ中断处理
6 L( q2 ?3 X: | - IrqProgram) S& A7 m7 ]# }2 N7 |* ?& s8 K! f" C
- PHA4 n8 L$ z/ m3 R/ S! g
- TXA- s6 u3 g- h" ~, z# K8 k- c o' J
- PHA
; u0 F5 M9 q3 H - TYA
: z" R5 n+ Q3 M - PHA9 [# h! h7 d# b* K% ?
- " d2 u2 h( X) B, ], c9 E0 ?6 a
- ;确认IRQ
$ O" v1 k" V1 x2 I9 U5 N7 p& G - LDA MMC5_IRQ_STATUS0 u, {) A1 \) i
- 2 d/ u* p) Z6 f c
- ;允许下个IRQ触发 V' ?2 Q# S' d; {
- LDA #$80
( g* U% c8 m! A: K - STA MMC5_IRQ_STATUS
' V2 J1 g, i' A" Q B- u. p# { - # S" x6 ? o. d s X6 Z5 J, B
- ;IRQ处理, 每隔16条扫描线触发: v7 Z% B: e6 m+ ?4 h' R' g0 |
- LDA <IRQ_Index- R! r1 z* q X* ?; b* ~2 h- P6 i2 a
- CLC
, G% [4 |$ W; _& ~ - ADC #$02
) V9 e' ~) X, `% F0 i - ASL A; C, K4 y U" H, B. r8 b
- ASL A2 b- i' g" F2 z' F- x/ C8 x
- ASL A
, z( a' ^0 N; q! C- o/ N2 V - ASL A
' C( l$ z+ p. ^- Q" ^: @5 e# O - STA MMC5_IRQ_SCAN_CMP; h5 f# Z- U5 e m: \8 @. B. ]: e/ b
-
4 F) R; z- F- F& D - LDA <IRQ_Index
: n% R" Z. N8 U - BNE * + 4
& r0 i! K3 T+ j$ z# I) a y - INC <PPU_Scroll_H& D8 N6 J2 V) U. Z6 t# h6 O
- 7 n+ s+ j8 O X4 ^6 H
- ;设置屏幕滚动
# W8 \( ]: [. W2 i0 r - LDA <IRQ_Index
0 p: g7 ~- n& g4 \2 K - AND #$01
- z" l9 q& T; { - BEQ Irq_Scroll_Right8 [& G+ p% Z; p+ j: X
- ) b: l6 |4 Q! a& p/ k7 p& ]
- Irq_Scroll_Left
, X0 R( e$ _. N7 Q( c4 M - BIT PPU_STATUS% h' n; u5 Z6 C+ m# E+ ?
- LDA <PPU_Scroll_H& Y" i2 Z1 k3 k U- \) q6 p
- STA PPU_SCROLL
8 c w9 W. n8 H( `9 C - STA PPU_SCROLL# S4 Z! j, d; W9 } j
- JMP Irq_Scroll_Over, ~$ S' F! O7 J- ~* r! v9 ?
- / O, [6 \5 Y+ T& F. B
- Irq_Scroll_Right8 Y2 d1 I; @* u
- SEC! z, W' O" V$ ]$ o
- SBC <PPU_Scroll_H
9 o5 [& P, F* m. g, U+ n( h - STA PPU_SCROLL
1 C$ r0 \# ?/ T3 |. I- e - STA PPU_SCROLL c3 u5 M" X# K8 v2 z" }$ S
- Irq_Scroll_Over/ M5 v! M# R( L9 U
- p. l# C9 _( V
- INC <IRQ_Index
/ S8 d4 ]7 ?/ x3 ]3 o5 A - 3 ^& o$ }. ~: T
- LDA <IRQ_Index
1 T* }5 T4 B8 y3 h5 i - CMP #14
! V1 m* e: l9 D - BCC * + 5
& ^1 i- x+ K9 l$ T3 w, S* D - ;关闭IRQ
~9 ]4 b! Q0 f, \; E6 j- [ - LDA #$005 q) o, {& r8 x% G6 L6 _2 S" C& a
- STA MMC5_IRQ_STATUS
/ a& P' c) u9 B' Z0 j. Z0 N - * |! \" x2 C8 o2 j% t6 `. ]
- IrqProgramEnd: M- U" _ f0 q. s
- PLA) @9 P8 f& C2 _/ i5 L
- TAY
" Y2 f' w$ t' }: m - PLA
" |7 w* G9 B Y - TAX
9 g. u% O) i- ~/ Z, b" b! k - PLA
5 x2 p6 E# _0 v9 c0 ^ a4 c0 G& O - RTI
* x+ C; `: p, Y! ]' \" O, o, l* M6 K - 7 _5 ~# C: h9 L( H4 x
- ;==================================================0 y/ H8 {5 y6 e' N
- ;中断表
" l" D1 g$ W/ a( Y0 a - .ORG $FFFA6 a5 @) G. k' _, q# d$ N
- .WORD NmiProgram
, _( ^( o6 V# L; Y* x - .WORD ResetProgram
2 g/ W; s9 u/ \& Y6 J& { - .WORD IrqProgram
复制代码 , q5 T. _# E2 A+ S
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|