|
- ;[FC音乐][MMC5 IRQ]9 j+ r( [* B( Q1 i A. r
- ;FlameCyclone 202307103 {% o& ^; _* @6 f! I1 j
5 a; T' v+ T( e* B$ H- ;文件头
4 `6 B- l1 w3 o% @5 k) q - ;======================================================================
, Q6 v4 ?& }6 P - .INESPRG 4 ;16KB PRG 数量
( C+ q% f$ a8 T5 k9 ~' V* S - .INESCHR 1 ;8KB CHR 数量( V i1 v* c, N( }
- .INESMAP 5 ;mapper 55 p5 V( \0 J7 m: M
- .INESMIR 1 ;命名表镜像 0水平 1垂直
' m9 x8 P3 B0 R3 f- N6 i% f
1 _% w) a" R) \! u2 p& T- ;必要条件
; H/ P2 y* `& V% f' W4 e& R - ;1.持有CHR ROM
! {3 ]: k8 B! i) v - ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000) b* @& f% p& H! F" U3 r2 K3 f
- ;3.精灵内存(OAM)不为空
9 \2 z* ? m# }, V! p/ M - ! s+ ^' j# ^2 l1 A- ^+ ]( M* z
- ;==================================================
4 C* ~5 v& R7 @' @9 W, C4 S - ;NES端口常量2 p% Z6 }2 b% w% H6 a/ V5 O# Z
- PPU_CTRL = $2000 ;PPU控制寄存器
5 K, J2 L" N% ^7 w - PPU_MASK = $2001 ;PPU掩码寄存器# ?( `, K$ S* f% a
- PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
+ p; `+ E2 W4 i4 K$ W3 y - PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
0 W) X% B9 z* n: S - PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
: q5 G8 m' O; S. } R5 z - PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
6 V2 I D8 z9 \, {$ C - PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加6 W. K7 A5 \' I. o
- PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
6 x, i* W3 G1 }! L% P! ?/ M - OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
9 Z. |' N; y V0 s - APU_STATUS = $4015 ;声音通道切换
3 }% |9 F2 }! W1 k! P# O8 [/ K - JOY1_FRAME = $4016 ;手柄1 + 选通! L0 |$ a, x- T( d9 m% W
- JOY2_FRAME = $4017 ;手柄2 + 选通
: `, g( }5 ]: v* f6 z
% ~2 y- J9 A( Y- |- ;==================================================
- s8 T" G- S+ T7 ] - ;MMC5端口常量! ~2 a4 h( G" g
- MMC5_PRG_MODE = $5100; 0: 32KB 1: 16KB * 2 2: 16KB + 8 * 2 3: 8*46 ]3 P& h( ^ {, Z. g
- MMC5_CHR_MODE = $5101; 0: 8KB 1: 4KB * 2 2: 2KB * 4 3: 1KB * 8
: F! S A" |- f* T+ w( b3 u% J - MMC5_PRG_RAM_PROTECT_1 = $5102;) F/ L; N$ |6 {3 K
- MMC5_PRG_RAM_PROTECT_2 = $5103;
; Q1 h+ p8 L# N: V' ]5 a/ V! K - MMC5_EX_RAM_MODE = $5104; 0: Write Only 1: Write Only 2: RW 3:R( l/ F8 `4 y4 C4 k0 w
- MMC5_NT_MAPPING = $5105;
$ A4 r+ r; P/ a2 x6 L* C7 _6 k - MMC5_FILL_MODE_TILE = $5106! Y* y1 G, n w1 k, ]( |0 S
- MMC5_FILL_MODE_COLOR = $5107
+ z4 [) D/ t" l% N: R- i - 6 P1 Y8 @! r% p, y, V( R6 S
- MMC5_PRG_BANK_6000 = $51138 V: `- P6 i* G: ~4 |# N& H
- MMC5_PRG_BANK_8000 = $5114
1 u* m+ O$ T' w* M6 L( o" p4 T3 Q - MMC5_PRG_BANK_A000 = $5115
6 l H! h* T3 C4 x* u - MMC5_PRG_BANK_C000 = $51162 ^: b' d1 Y% d6 {- `
- MMC5_PRG_BANK_E000 = $51174 ^- r ?% F* G& n q0 @
-
( _9 k: i8 U! ^1 X& Y7 Y - MMC5_CHR_BANK_0000 = $5120
" M$ n' l. ^# T3 { - MMC5_CHR_BANK_0400 = $51214 p' F( q! m# f4 ]1 \- F( S! R
- MMC5_CHR_BANK_0800 = $5122/ Z, x; z* C. z/ X+ V
- MMC5_CHR_BANK_0C00 = $5123
* b8 } A+ V# \9 b - MMC5_CHR_BANK_1000 = $5124" b' w' C" e0 R, ~* W; {) T
- MMC5_CHR_BANK_1400 = $5125
$ r# l; _2 i+ a) J" U( N - MMC5_CHR_BANK_1800 = $5126
6 h7 t# l1 g. D - MMC5_CHR_BANK_1C00 = $51273 S+ E6 n2 ~5 ~6 a% U& x# Z( A
- . B6 G. o! I9 A& z0 q+ g+ j( d
- MMC5_CHR_BANK_0000_1000 = $5128: o( H0 ?/ t M6 f+ X
- MMC5_CHR_BANK_0400_1400 = $5129
9 _0 @) \- B* u$ `; U3 i - MMC5_CHR_BANK_0800_1800 = $512A
3 {8 \1 V, s- N% M: z3 E/ T* \ - MMC5_CHR_BANK_0C00_1C00 = $512B
$ [5 S; Z& }9 W [ - 3 `( o, Z7 K* @' u
- MMC5_CHR_BANK_UPPER = $5130
l3 M- h2 q9 k0 |3 A - MMC5_V_SPLIT_MODE = $5200
$ _; Y. J! D- M6 e - MMC5_V_SPLIT_SCROLL = $5201 H8 `$ K/ N5 |3 M" C, _
- MMC5_V_SPLIT_BANK = $5202' G; u3 \+ S* ^/ n9 z, w+ x) ~/ g/ f @
- ' v$ j8 H. g8 m
- MMC5_IRQ_SCAN_CMP = $5203
% w; K4 Z: h, {' r% w% P$ P - MMC5_IRQ_STATUS = $5204* [( Q3 f' o/ X1 L0 w" D6 w" V% B
- MMC5_MULTIPLIER_A = $5205# d* q5 N7 j: ~0 U; R8 y. }4 O, E
- MMC5_MULTIPLIER_B = $5206
0 ^3 V) z d! X: r# S% P5 D; P -
# \, F% s3 O. E/ ?# q - MMC5A_CL3_SL3_DATA = $5207
1 n4 h8 E6 }% v! |/ _6 }: @1 X* ^ - MMC5A_CL3_SL3_STATUS = $5208
" D0 h" O. f. Z6 c9 |9 Z3 c5 e - MMC5A_IRQ_TIMER_LSB = $5209
( m2 g) D; p% o4 B0 [& I# ` - MMC5A_IRQ_TIMER_MSB = $520A
0 G! x( S; a( n. ]6 j! q! R
$ p6 n( h( w/ c5 t- x$ u- ;==================================================( Z4 d5 {1 w% Z( o' e; x
- ;程序块配置4 J# c* Q" g# z* f w
- BANK_DATA_MASK = $07
/ M0 V' x2 b0 T8 E - ;--------------------------------------------------
3 c ?# E( u0 V/ Z2 c: a, V2 Z- W% R - RESET_BANK = $07% ]$ e4 E9 e/ T* i+ Q: G* |. q
- RESET_ADDR = $FC00! J0 [# Z, [- D5 F9 \$ Z: H9 ~
/ V5 {2 e( V. X- ;==================================================
+ `: q# T. g. q. w" g - ;图像块配置; A1 f8 ^) h: t! v
- CHR_DATA_BANK = $08& T% N/ ?- r! I) n
- - L. S0 R0 j( L, T. q/ q- Y
- ;==================================================
" _' p9 |/ M( ~4 r1 V - ;零页内存地址配置
4 d7 c% a5 ^* D: Z - Use_Ram_Addr = $80
' q4 g* n: b g' u% ~ - PPU_Ctrl_Buf = Use_Ram_Addr
( W+ I) |: e# X3 i1 z - PPU_Msak_Buf = PPU_Ctrl_Buf + $01! e' }; j2 W2 F. z5 ~
- PPU_Scroll_H = PPU_Msak_Buf + $01 a! u* c3 }0 g7 U& ^% [+ }
- PPU_Scroll_V = PPU_Scroll_H + $01
4 x# i% t0 j; a# V - FC_Data_L = PPU_Scroll_V + $01+ i/ _/ F: |. m: |9 t! z3 ~5 k
- FC_Data_H = FC_Data_L + $01
4 w$ ` ]7 L# x7 r0 O - FC_Data_Buf = FC_Data_H + $01
0 F% d+ }9 _5 ?9 N5 A# x- e' S) j - ;==================================================
1 D- i1 @1 H) o - 6 A0 q8 _% d' C9 J, m/ F' }" \. U
- GAMEPAD_MERGE_FLAG = $04
6 _5 a$ s- e* L6 k' M, L
0 _- ?7 j% {9 X, ^- Gamepad_Keep = FC_Data_Buf + 18 q( [+ o- d% m" _ N8 k# q" h# w
- Gamepad_Once = Gamepad_Keep + 2
8 f1 ]1 n4 v2 |2 @' e6 c: d: n - Gamepad_Temp = Gamepad_Once + 26 H% j( P8 _( e/ h, z/ x8 y
- ! ^2 M. g6 y2 j' S- Z( p
- Gamepad_0_State = Gamepad_Temp + 2
; T! J6 a& A6 o - Gamepad_1_State = Gamepad_0_State + 1
$ r$ B' r0 j: Z8 A9 y6 O4 K - Gamepad_0_Value = Gamepad_1_State + 1
: q6 g# H, }4 P2 Q i' g/ C8 @ - Gamepad_1_Value = Gamepad_0_Value + 17 O6 O# }8 h. \4 L7 w' R# x
- Gamepad_Port_Value = Gamepad_1_Value + 1
( K7 o: K$ S9 H$ j$ c) e - Gamepad_Merge = Gamepad_Port_Value + 1+ ?) f3 Q4 d! R* o: w3 B
- 1 q0 l. V A$ u$ w; t3 p6 F8 q
- ;==================================================+ X, K! B2 ~1 L4 B7 A
- IRQ_Index = Gamepad_Merge + $01
; y$ ?5 V: I: j ^, W* T; p A - ;==================================================
* R7 E7 C$ D* G+ V I( K4 C
: E" K6 ]5 [+ x9 l8 V3 Y0 s) @- ;CHR图形数据( {! T Q1 s. N- K! S; R' b
- ;================================================== d9 d; u% ^3 U0 Z. V
- .BANK CHR_DATA_BANK
" N% |: I( E8 q8 P J0 r8 U/ A - .INCBIN "chr_bank/chr_data.chr"
5 w# [9 G2 t- Z9 q8 e5 F7 \ -
8 I& \2 X1 e9 y: t: ~! d5 ` - .BANK RESET_BANK & BANK_DATA_MASK! W( |! |7 z, r4 E1 D
- .ORG RESET_ADDR t# R7 x2 |5 r |# f
-
: P9 @' t4 m: K% s - ;--------------------------------------------------
# S" D4 i3 k9 c - Attributes_Data* o& A! T5 [9 T3 B4 X+ Y
- ;命名表属性0 X i2 n; ~1 a* l
- .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
4 I' Q) b7 W6 d% x9 M C* b0 Z - .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
7 A# D9 q3 n4 @7 I/ B" V R - .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA2 K7 I* Z( F' m. s
- .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
( x" T, a9 A3 h' r; B$ K& r - ;--------------------------------------------------) p! t e0 ?3 R! ]5 r7 G
- ;调色板数据) [3 U! N% w# T) n
- Palette_Data
* v+ ]% x! o5 }4 z - .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F) N* b9 C) A. e% |* Y
- .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
9 K7 w0 _6 A7 B1 k" i - 0 M6 N, [, X) ~; a
- ;==================================================8 ]9 U8 w5 {' q2 R# |: x
- ;命名表初始化# _& A8 b O% ]: M; {' y
- Init_Name_Table
" X5 C' ?. q% ^( C - LDA #$20
& q G9 G: a& z/ U/ d - STA PPU_ADDRESS, y5 m1 M4 h* O B/ r; x, c
- LDA #$000 N) T( X: p2 D) K
- STA PPU_ADDRESS
A# F8 z& f/ W - LDA #$00
L. z. D3 F! m. ]6 Q5 k R - LDY #$00
$ M. h$ p! }' ^9 d0 I P; ] - LDX #$10
- q+ W1 Q5 z+ _% y0 r4 H - Init_Name_Table_Write
' \2 B: n- v* h, J1 M$ c - STA PPU_DATA
, o3 c m% w& ~: s7 _2 w - INY
! F2 f/ Y. C$ S - BNE Init_Name_Table_Write
3 @( y4 h: u+ A: |* D0 v, ~+ u+ r1 A5 V - DEX
* e o# _% P$ s( j+ ` - BNE Init_Name_Table_Write
. k; S. w! u5 ]" i6 l7 r6 l - RTS
: @) b5 L0 r) {' S! @2 Q9 ] -
* u$ @ v; U1 J - ;==================================================: ?! U9 S- @# r) r9 J
- ;调色板初始化2 Y8 P- H! y6 S
- Init_Palette+ S! j9 a. r* ]4 b+ a! c
- BIT PPU_STATUS
/ V) w( e. C6 M$ J - LDA #$3F: s. e& ^8 |* p$ h" h0 u
- STA PPU_ADDRESS: x1 K( ]3 k0 g; B
- LDA #$00
2 }. h, k j2 }$ C( N - STA PPU_ADDRESS
2 i9 G3 `3 |, o$ S# h% B: V - LDX #$00: [8 L& N" h' N8 s1 ~$ ?
- Init_Palette_Write3 W3 F$ P( r8 d$ I' a; U9 Y
- LDA Palette_Data,X
5 w3 D2 E3 G \; S% c - STA PPU_DATA. R9 i' E; D: S. g! s) D
- INX8 k; p4 ~8 L2 G# p
- CPX #$20" e. f/ h @2 K; ~4 N# Y) B5 o
- BCC Init_Palette_Write6 b: w8 D) h1 |
- RTS
: [! ?, H5 f& X/ } - 2 H$ M. B5 ^) @5 |: }6 a
- ;==================================================; s$ ]1 S9 u: p+ Z: \8 ^4 a
- ;设置命名表属性. h [5 W6 U6 O6 z' S. n0 T# i
- Init_NameTable_Attributes; X$ K. g+ d, c6 x( W4 I8 l/ F# W
- BIT PPU_STATUS
( x" B' |5 p% N4 V$ `1 f - LDA #$23: Z7 O6 I, I5 d' Y
- STA PPU_ADDRESS, F- ~5 b; X$ d* f" o% j
- LDA #$C0: j( P( c" g- _0 H
- STA PPU_ADDRESS0 U+ U4 j+ p7 b- d' D. ]3 D
- LDX #$00 c/ _+ P) T$ x0 J$ R& f
- Init_NameTable_Attributes_Write% V b5 L- Y, ^
- LDA Attributes_Data,X# H- u1 b3 X: x& n* R
- STA PPU_DATA2 s2 T. X7 q* \0 {
- INX( t( q2 H; T8 ]: h+ c; A% a Q
- CPX #$40( s! r- v" l. {/ ]! m
- BCC Init_NameTable_Attributes_Write: y- `( n+ z. r% q. \
- RTS. a0 m& z9 |) b# {; F
- t/ k: ]" \9 y" l; P2 k) p) M
- ;==================================================: w& ^8 d! J/ V( n/ B% j& T$ y# X
- ;初始化命名表文本
: s, _) Z4 d7 `$ B1 T/ ]$ ^# D% j - Init_Name_Table_Text
7 V7 C9 ^8 b4 ~. S - BIT PPU_STATUS7 X9 e. i: r1 ^8 X& M$ ` P) I
- LDA #$20 f7 k/ o5 X6 x: _# u) \
- STA PPU_ADDRESS- h6 T! R7 T3 j- M! |
- LDA #$007 Y3 B$ I* R2 `) a1 g
- STA PPU_ADDRESS$ u% i* d; u2 s0 R
- LDA #$00
, z3 ^8 ~1 B8 `/ X$ w- h - STA FC_Data_Buf- x) k- S# p( M1 Z0 Q3 {6 L! s( w% L4 a
- LDY #30
) ]- S z* p: {' ?- V - Init_Name_Table_Text_Write
) x* p& p# e1 s6 i2 j& U: ~ - LDX #32
8 P$ e' X6 t3 T! x- ~2 |# s - Init_Name_Table_Text_Write_Char' Q' M* N! r# [9 {# v' z& b
- LDA #'0', E7 i7 S7 t2 M* i
- CLC# |6 Y" p0 c) x2 O7 Z
- ADC FC_Data_Buf) y6 w% v, D) D' @# n7 M
- STA PPU_DATA# J' z: T/ A, c& `7 l0 r n R
- DEX% O; {. @6 u; @" |* P
- LDA #$14* k1 d9 ^+ p4 s$ l
- STA PPU_DATA
9 i' y+ B- T* Y* d- X' i - DEX4 `1 |( _! O8 n* p7 l/ r
- BNE Init_Name_Table_Text_Write_Char
1 ~9 B/ z n/ K - INC FC_Data_Buf+ F. B8 X1 c/ o% l2 b! m9 ^; [' D
- DEY
. ^2 Y) p. I" e1 [! N - BNE Init_Name_Table_Text_Write7 b6 p1 m7 x D) L
- RTS
1 |' M" i5 O8 c& |3 n* `% E. G
: z* p9 X4 Y. S& W- ;==============================
8 m) w+ ~, y- M. ]& }, q! y/ X0 L3 f - Init_OAM_Ram;初始化精灵内存# e! b3 y5 T: j: ^8 z( b
- LDX #$00! q0 n- o9 |4 Q) t' k2 k+ R) L( ^
- LDA #$001 o! \6 R' R- U" u. ~4 @6 g
- STA PPU_OAM_ADDR
6 m) r0 D# ^ c4 R, L - LDA #$F8! v$ b# ~: k) U% f2 W) W' t
- Init_OAM_Ram_Write
7 O' j* {' }* I - STA PPU_OAM_DATA$ ^! Z3 m2 |) g. K/ x/ y
- INX' y2 n H9 }; J0 T1 q
- BNE Init_OAM_Ram_Write
' I% N7 z! i3 T) |* {. h - RTS( t' W2 l* D! _+ C" |- v5 T
- " b! p; x+ m7 h& H. N' `
- GamepadProcess;手柄处理) d# b5 a: H+ s9 u
- JSR GamepadDatacan9 y) M: O4 _% Z/ I
- LDA <Gamepad_0_Value( }- M! K& w" Q8 K2 R; n
- STA <Gamepad_0_State: Q- v2 S, M$ H
- LDA <Gamepad_1_Value( `7 z3 n1 G3 T) b- Q
- STA <Gamepad_1_State9 k4 }* m' A) H8 C
- JSR GamepadDatacan e2 c# U9 l( k7 l) }2 d* y
- LDX #$01# F8 a+ `% V- o5 e" z6 S
- GamepadMergeCheck;合并手柄输入检查
* V9 x4 }1 r+ U, K - LDA <Gamepad_0_Value,X1 e/ R6 j* z4 i
- CMP <Gamepad_0_State,X
: x, Y* P. v1 d" M! W - BEQ GamepadMergeInput
" z, S7 S5 W l+ k0 G/ I7 S - LDA <Gamepad_Temp,X
9 v+ v5 G { R - STA <Gamepad_0_Value,X
0 }. E* I, s5 } - GamepadMergeInput;合并手柄输入- {" u3 S0 K2 x
- DEX. r: W0 V7 a& I, N; A
- BPL GamepadMergeCheck
4 o+ M, l+ v6 y, n/ t - LDA <Gamepad_Merge3 U2 r# B o& Y) J- }& V r) q
- AND #GAMEPAD_MERGE_FLAG
- X6 }# B! ^5 Y( H5 i4 { - BNE GamepadStateProcess
+ L5 }0 W( {/ I. q: _! C - LDA <Gamepad_0_Value
( a5 T. h, ?/ Z2 p - ORA <Gamepad_1_Value4 V5 H% j! t; e6 R. Y7 y( y
- STA <Gamepad_0_Value* |& G# [% v" @7 i' A
- GamepadStateProcess;手柄状态处理+ x, [6 y" r. a8 W% D! c
- LDX #$018 @. E6 U+ g* k% d% l( L
- GamepadStateSave;手柄状态保存8 Q2 Y7 C" G8 _" ~# m4 |6 ?
- LDA <Gamepad_0_Value,X
f' w( C D( {( g5 g - TAY
( ^' Q* e/ J) i6 T- h- H - EOR <Gamepad_Temp,X
7 M- t/ Z" a2 g: M [0 N - AND <Gamepad_0_Value,X
8 A" {. u3 B, _% l( E! F3 o7 [4 y) Z9 Y - STA <Gamepad_Once,X9 d; P: _( N, T* U$ D8 R
- STY <Gamepad_Keep,X
' O( Y; e! O$ ]# `' T0 c - STY <Gamepad_Temp,X8 K8 P& U+ F. _/ |
- DEX3 A% p" ?9 n; K: J
- BPL GamepadStateSave
* _1 d! |5 j; \5 h1 z - RTS1 d, [6 q4 f+ X9 R$ M- R4 e Z
- # e6 c& L' L0 x1 Z, V
- GamepadDatacan;手柄数据扫描
, Y$ j+ g7 ^ g/ g2 b( w5 F5 R$ ? - LDX #$01: g4 n/ n6 P0 M/ V* ]+ Z& F
- STX $4016
3 b8 r# s2 g" y, z+ b. S - DEX
6 U5 G' C# T! Y) _6 { [ - STX $4016$ c6 L# z' H i
- LDY #$08
* `* K2 G; V5 ^8 ]2 o - GamepadPortScan;手柄端口扫描
* l/ b( q3 \9 f* _! m. e - LDA $4016
1 C4 H$ W5 b3 X6 [! K7 { - STA <Gamepad_Port_Value
1 k& T* t! {) V$ G" G: J( x5 o - LSR A
) B" y0 E; ]7 ^ - ORA <Gamepad_Port_Value
8 ~- b: S0 j x+ i4 J6 @% T$ s - LSR A
5 d+ w/ ]3 }0 w) _ - ROL <Gamepad_0_Value; K9 K: O" Y1 B, e5 H& j) w( K( n
- LDA $4017
8 K5 e! h0 I3 Q3 m% t - STA <Gamepad_Port_Value- Z+ n( c0 f7 e6 d& c' e9 {0 @9 F
- LSR A
7 ?8 e0 K% L% |5 x; m. ` _ b - ORA <Gamepad_Port_Value% l- [$ H- W, V8 b/ V+ I* t
- LSR A9 H, `$ A+ j7 F9 ^; q; l
- ROL <Gamepad_1_Value3 [. u1 E3 i7 N6 j" m& m
- DEY
% E( `" n% ?: ^' q$ a1 A - BNE GamepadPortScan' ]) w d! j: t/ K4 k9 u& ]
- RTS
' K7 W0 Y v) @3 A t - ' L( A+ b0 z! i: Z
- ;==================================================$ ?: z1 B: |# {0 |
- ;PPU处理
0 D4 d. U7 i3 U! g7 T - PPU_Process: M5 Q3 S& k* y. B4 x
- LDA #$00, j# V% z% k7 m
- STA PPU_MASK
. v! z7 s* Y+ d g. `# Y8 Z - % F5 G7 t- c. A4 e# N( e, Y" B# B3 L
- BIT PPU_STATUS( `" _7 Y x9 F* |1 V. Y, o* v. K8 N
- LDA #$20
+ ~. L* o# J: H( l. u+ N9 A - STA PPU_ADDRESS/ H+ }2 g" i2 N g
- LDA #$00
, I4 B8 y$ T# v3 L' p - STA PPU_ADDRESS# z3 T0 K" q# |% [2 n
-
0 @2 s7 K! D& s: l6 I- R9 X+ z - STA PPU_SCROLL4 J- m, o+ e- P9 L6 ~, L
- STA PPU_SCROLL
7 h" c9 w/ s8 H( v: X h* c6 O -
2 f1 I, j+ o1 W - LDA PPU_Msak_Buf
! t" z, v( W) B8 g4 `* C! M - STA PPU_MASK% F, \5 _& w- I' Q3 x8 i5 W$ l
j) t7 r8 p$ A# }5 M- RTS
0 z. K& v; V# Y1 A -
) G2 J# A* L8 d - ;==============================
# T. e$ o2 h* C) ~ \9 B6 B - Time_For_Vblank;延时等待! N; K9 P3 H5 l1 g0 r
- LDA PPU_STATUS
# J$ J+ |8 u; k7 u7 f7 ?6 I - BPL Time_For_Vblank5 N" m, T7 o; o7 O- c" d
- RTS
2 R3 x8 T$ k0 q3 Z -
6 p3 q2 x5 z, p' w# V" B/ o9 n - ;==================================================; c" S! o' k+ W9 E
- ;初始化MMC5* f% L8 e& f# H4 C Q1 Q
- Init_MMC5! n; ?: i* W( v: ?
3 d9 Q( s$ T0 {) S D+ ~3 s( n- ;设置一下6000-7FFF的RAM
6 h* R8 l a. {# @% m7 I' q - LDA #$00
5 x, L6 q! D R" {7 \* K/ T - STA MMC5_PRG_BANK_6000
- H& K$ O. d# x -
# U# p! T6 [/ ?* H/ V - ;开启 PRG RAM 写入
0 l# _: x$ ?: F - LDA #$020 O7 B. R3 A/ q/ e7 R/ M R
- STA MMC5_PRG_RAM_PROTECT_13 \5 A9 @! h w( V0 D9 g
- LDA #$01# D* b. i) u4 q
- STA MMC5_PRG_RAM_PROTECT_2
/ Q- t0 N& j5 k; y - 5 K3 @# P; Z+ {! O* {/ ~
- ;启用 1KB 扩展RAM ($5C00-$5FFF)& t9 X0 `6 ~3 d4 v
- LDA #$02
2 }) `( e3 v, i5 I% m8 k - STA MMC5_EX_RAM_MODE
( b0 U9 x, b+ e9 X/ R - 4 E# g5 Z2 f# h+ w1 w
- ;设置 CHR6 S: F. `! G( _# _* y/ ?2 N
- LDA #$009 {1 V6 g$ c/ v/ x5 Y
- STA MMC5_CHR_BANK_0000: `# T) x# a8 n
- LDA #$01# W$ y9 k4 C5 T& L( L
- STA MMC5_CHR_BANK_0400
2 p# F* A2 w, s9 } _9 i - LDA #$02) Z! V8 u$ }. j4 |- w
- STA MMC5_CHR_BANK_0800 z5 T( a* }, Q# e7 \0 x3 ^- l% s+ W; h# F
- LDA #$03
, G$ _0 b4 B4 n# z Z; t* p - STA MMC5_CHR_BANK_0C003 U5 w- S) ?- b6 R- `
- LDA #$048 Z } H* A3 R
- STA MMC5_CHR_BANK_1000* m/ y! h, x" R }" Z# w9 i
- LDA #$05
& H* F* O A, ~3 r* Y1 s: z; Y - STA MMC5_CHR_BANK_14006 C! z1 E# [; h
- LDA #$06
2 `# A5 l) T( C - STA MMC5_CHR_BANK_1800' m9 O* R3 B6 W. e
- LDA #$075 s) \1 U$ c y1 q8 W: p2 Q
- STA MMC5_CHR_BANK_1C009 D5 I0 | v2 [8 H
- 5 B& v, W% R5 _) j) t
- ;设置屏幕镜像& `7 q1 F X* ~, m
- LDA #$50
: \( B( ~2 C) k' Q2 Q" Y! E7 X$ w; ? - STA MMC5_NT_MAPPING
* C0 n( n6 ?9 U+ R - ! S& m [4 {* k9 N
- ;禁用IRQ
9 i; D9 b# s! P7 n - LDA #$00
& p* L# A+ \0 \/ C$ g3 k - STA MMC5_IRQ_SCAN_CMP
( ]1 x( n: K! I: C% Z2 @ - STA MMC5_IRQ_STATUS( B# s( d/ ^3 f( c" F* {4 ^
-
. L a! ]4 W$ ~: G1 t9 O - RTS4 ^8 d5 q- F1 w) G2 h6 q) g
-
- p8 L- h9 R \+ h+ j& I - ;==================================================. F, t; }- V" t( O' c
- ;重置中断处理3 @; M' e: f; p5 ]/ h
- ResetProgram
# g0 [) `) }& |1 |: L' I5 P; D - SEI: z1 u. }3 j: q2 k9 u5 h
- CLD
$ N# Z" q6 u; p+ t1 D: B' ~. U* W - LDA #$00, w( S: E2 ^4 G6 Q# V1 }+ b
- STA PPU_CTRL; u2 Q/ K) X2 G/ K* D
- STA PPU_MASK6 V7 Y) |6 j' F/ g/ L: i8 `+ R1 P
- STA PPU_STATUS" v3 B4 |9 h# S* C
- STA JOY2_FRAME4 c k. E) z8 y! h; M0 Y* B7 Q
- STA APU_STATUS( q9 U) g4 D. _5 B) v) u
-
7 `' G4 a- M b - LDA #$C0
6 L0 j- G% }7 d% Q - STA JOY2_FRAME/ N* J8 m5 ?2 Y( |9 y
- 7 S6 q. L3 g/ T) B, T: S
- ;等待vblank0 R, X$ M7 {' s3 W
- LDX #$028 ?8 ^/ G! h! q( f8 l4 Z3 R, T$ G
- Vblank_Wait_1
' q8 }( V8 K$ B: { - BIT PPU_STATUS {* N Y% k9 X9 j& s3 I9 d
- BPL Vblank_Wait_1
( l$ x# Z3 Y: @' t; \# z - Vblank_Wait_2" [8 V5 m) M7 h( Y' J1 N- G3 D! t
- BIT PPU_STATUS
4 @. f. ^# {4 X- G2 h) G - BMI Vblank_Wait_2, F; G8 r) s1 b. B& u6 q5 N0 o
- DEX
( x. \" a+ ]- J6 f! S( P - BNE Vblank_Wait_1
( K& f) G' }( h0 r9 C, C" F -
+ U2 T9 \2 B+ k* n7 @ - LDX #$FF2 t n- r6 g. V7 m
- TXS
5 C# ]" |: K$ j, E" n% F0 P -
* _/ C0 X) m0 ]- u) B" Q1 O4 a' ` - ;初始化MMC5
3 G) {( y$ @* r' b1 ?9 K1 t, G: S - JSR Init_MMC52 @- ]( y- X% {9 g
-
& v& n4 N+ {* d6 K+ T" ?! h - ;==============================$ m( z( I. U9 T' B6 A' Z. V
- ;RAM初始化
0 d. v& J# X9 r) e7 o - Nes_Ram_Init" h' [: A) _/ m! S
- LDY #$00
4 T0 k1 J {" P9 v7 Z% S! w3 c - LDX #$08- c8 ?. N b0 d U8 @9 C
- LDA #$009 Z- f6 r/ r$ g; z2 }, I g) Q
- STA <$003 z! j: G6 c+ q# i
- STA <$01
5 m2 a) K p# H7 H) h - Nes_Ram_Init_Write
% `$ C2 Z& z {# x5 F4 ]+ Q - STA [$00],Y
' [8 [% j0 ~/ u* i9 F* g - INY* {* f$ U6 O' z) w- ~. e8 ^
- BNE Nes_Ram_Init_Write% |: F+ D/ b# h; P4 r! b, R
- INC <$01! Q) e( ~' Y F9 ]2 c o3 Y
- DEX
1 k4 Y) s- q' Y+ G6 R% n - BNE Nes_Ram_Init_Write) s3 s( `* j5 E+ P/ p
- ' j: e, j/ y4 ]- `. q; O8 E
- ;初始化命名表: d& a) {* n7 G+ |$ Z0 {/ A+ F, d
- JSR Init_Name_Table
# p3 I! ~2 `2 S: g -
/ q' g2 {4 C( n c! V8 k, r - ;初始化调色板* t( ?7 C$ G6 b/ C& R+ _
- JSR Init_Palette3 m5 T. O6 s7 C1 j! B W! w% `
-
" o' b3 z8 A) }8 C - ;初始化命名表属性" G0 Q j, I. C/ J7 |$ ?3 ^1 Q
- JSR Init_NameTable_Attributes
5 Y. Z$ Y, n. q& n% W( c h8 b -
2 ?" Z4 k1 N. I; W5 t- y7 [ - ;初始化精灵内存6 C' i K5 o1 t/ y4 |; a- I
- JSR Init_OAM_Ram
& Q0 _3 M1 u8 r$ ?* g' [1 o: R/ z -
# [ e5 `! I- o. \2 m% E - ;在屏幕上写点东西
/ j1 Z U) d" O* r/ S& F8 l0 A - JSR Init_Name_Table_Text
: ]& K7 z. x, i1 ^ -
. ]4 a' ^# L/ l( [0 d - JSR Time_For_Vblank
4 S+ A ^7 Y9 l4 f7 E/ u1 N - ;开启PPU控制
( `- g( V% P9 V8 r( {: v3 y/ ] - LDA #$88' u) v9 F/ {0 l$ T/ ~- u2 p
- STA PPU_Ctrl_Buf
& v( T) ?# q" V) M0 m - STA PPU_CTRL. c% P/ \2 x. y& m( q* K, {( o
-
- O' e/ A4 D6 B& C/ N; c7 W: `2 l - ;开启PPU显示
o# f) o" H; Q3 r1 I( J, z - LDA #$1E4 A" v- ^" p5 j* i: Y! D
- STA PPU_Msak_Buf5 Q# |. w/ D" P% r4 I
-
* W0 W2 D: A) X* z% [0 E1 \3 m - CLI9 U3 u0 y/ W: @( }
- JMP Loop9 a6 U" L3 X0 H9 _
- 1 F' e1 b! ]5 }. C- @2 ]
- ;==============================6 B4 O0 H1 k7 g! Y
- ;死循环, 等待NMI中断
: M" ?( n7 _1 N. j# w/ x, X - Loop* ]' l' K' ]7 C8 e3 b0 T* y9 p
- JMP Loop8 i6 x$ _" Q: v" }5 z4 d$ `
! c/ j+ `! Q u1 }- ;==================================================
$ Z6 U. }: ]8 Y! l+ [: B, u( w - ;NMI中断处理
0 ~ L- _$ E' B1 R" Y9 B - NmiProgram
. o' ?" P+ n0 [9 l; S - PHA5 J, ?4 F: x; y* y& O$ g
- TXA
2 d) ?/ D% Q) ]! m) j7 _0 C - PHA- P8 ]! s7 X2 R3 u" ~
- TYA
/ I. ?" S2 I v0 w$ b - PHA' \4 |* k! u+ p! Q* a
- 5 {5 H5 }7 d) V4 s# J
- BIT PPU_STATUS
. w1 p) Q; F" P8 L8 }5 u - , u- }9 a6 f$ d# l; a' l: G
- ;启动IRQ中断, 第16条扫描线触发( Y6 a( |/ U: @* @4 ?* f+ [9 O
- LDA #16
, X/ a! y( T4 g, h - STA MMC5_IRQ_SCAN_CMP
8 @, M7 n- z/ d0 p4 U - LDA #$80
Y- e$ ?8 P1 x* e8 s o - STA MMC5_IRQ_STATUS
- B. _, |- V: H$ w1 d# [& H, g$ F - CLI9 E. a7 S) ]0 ^) E1 \- i
- , U8 ^$ G! N5 v' }
- ;关闭PPU控制3 H9 T" Y4 _' Z6 Q$ @1 e
- LDA #$00
6 s3 {9 V3 T7 n - STA PPU_CTRL
6 O' l a0 C. M3 ` -
! T, Q- {0 v! U- O6 E9 D h# A - ;处理PPU3 h0 i6 Y: @# ]9 Y2 g+ g( }+ R4 u5 ]
- JSR PPU_Process
# c+ Z9 }5 y; w: n -
& ~( _, s: B& C s% V5 |3 A s - ;开启PPU控制
3 Q6 [6 s( |) m2 w5 P( G - LDA PPU_Ctrl_Buf5 H0 D1 {! C& c6 o6 b9 t
- STA PPU_CTRL0 L( p( g& J) _' l H6 b; D
-
4 }& J- l" I( F1 o e* p; i - ;手柄处理
0 Y6 w4 G3 ]' K7 W# g. L8 c# H: \ - JSR GamepadProcess- {, x0 Y; O: q4 y; a
- $ L( T0 N. S/ E# ^* t) A3 I
- LDA #$00, s- b2 D8 C. [* O
- STA IRQ_Index
, W3 c* Y7 L/ }# u+ o; E8 |* T2 s - 2 r3 v4 E1 x2 R
- PLA) u$ v8 ]4 \2 P2 X8 I! K( u5 C
- TAY* O; D. h3 i6 e% @4 {0 g3 A
- PLA
) F% u: {& Q$ m: i+ V - TAX
m- S$ a( d6 f9 j& h - PLA7 C; q5 s0 r) R- i
- RTI
+ `0 _, P1 N4 r' H( [4 s+ Q
0 y; s& @3 W1 j! n. Q, p- ;==================================================# a5 ?4 J6 S& Z% p% ?
- ;IRQ中断处理
l+ V$ l. d5 p! B( V F, n - IrqProgram
7 ?4 g4 S1 L" M, g0 X! P! Z - PHA. |/ i& V. l; x
- TXA
. s. [1 Y( b2 F/ }( [: Y - PHA8 `# E% p# L" }/ G" P1 X
- TYA# u) @: x2 U6 X
- PHA3 g9 x! A# d# W% X( o
- % o7 B$ e/ ^, c, n3 Z
- ;确认IRQ: w; b" s% l' T0 Z
- LDA MMC5_IRQ_STATUS4 A2 f* K: \% }1 t
- . s; O4 T2 Q( A. ^
- ;允许下个IRQ触发. [' O9 p- l d2 x- U4 a
- LDA #$801 x* j/ Q+ A# P: [# ~
- STA MMC5_IRQ_STATUS! W4 o0 q% N7 x
- # Z# b2 G/ l. R0 k: o
- ;IRQ处理, 每隔16条扫描线触发4 L( M1 i# v% h3 V: F+ a5 v) C
- LDA <IRQ_Index% h! s' T3 x3 `1 z1 s7 O
- CLC
5 C8 V2 n V- \$ l5 }5 U2 s - ADC #$02- @8 s& i) C8 p
- ASL A( R0 h+ P1 `* Y& N, o
- ASL A
) Y6 |( ?0 P& [ - ASL A
" k% _, q; y% G# P: H; t - ASL A
3 E# k u* C( r& } - STA MMC5_IRQ_SCAN_CMP4 [# t8 |5 g" e1 k( E
- % x" H* ]. Q t
- LDA <IRQ_Index3 n ?/ E9 T: }8 Z
- BNE * + 41 q5 G- ~7 B& d1 X% a& d
- INC <PPU_Scroll_H+ U2 b; a0 O3 A. h, |( B6 {
-
( U6 m4 V9 }) @ }, d9 ^& b - ;设置屏幕滚动" a8 \* z/ Z4 Y6 N
- LDA <IRQ_Index0 d+ r! G7 R# c7 f) `' n
- AND #$01
2 T! J+ h* q) [1 U - BEQ Irq_Scroll_Right
* Q- C3 F& @ ]% X: v5 x
$ S) ?( i+ z e- Irq_Scroll_Left
0 U. T( v( ~2 v' c$ W - BIT PPU_STATUS$ G6 G/ i, J, r+ j' V0 B6 }
- LDA <PPU_Scroll_H
" O+ @4 j7 H5 r5 E! |# B3 m - STA PPU_SCROLL9 y- B% x& ]6 g1 @2 T& z8 w
- STA PPU_SCROLL
1 i: p4 M4 u# y5 S6 f - JMP Irq_Scroll_Over2 s/ W, T, @3 C4 \$ h+ f
- s N& r( G7 A, ~; y9 A$ L8 m
- Irq_Scroll_Right& I ` g* D* b! `5 W1 ~4 o- q4 `% C1 E
- SEC# p2 k6 E) R6 O. q2 ?% C( K
- SBC <PPU_Scroll_H7 E; G3 i U% a, e% a
- STA PPU_SCROLL
# T$ I$ Q! R( N - STA PPU_SCROLL8 p- V5 O; \8 b+ |: _+ ]& i+ d
- Irq_Scroll_Over' ~- s9 j$ A6 J7 Z. E
- 6 D4 `0 z+ T0 ~. `! z: E' F9 `' N$ {
- INC <IRQ_Index
3 S- l. y7 c; n' H0 p - * o% T) v) E7 s9 B; q& v! `6 G1 g
- LDA <IRQ_Index
/ t2 @' s1 A6 {) F& L - CMP #14, @3 C3 ~0 d1 l4 c! X# J8 x
- BCC * + 5/ G8 A; [' C; I3 c
- ;关闭IRQ0 v+ P! m( |( {9 C* V7 R
- LDA #$00
7 ~" B# _1 ]! b - STA MMC5_IRQ_STATUS# c% ?4 I: P% I: @0 B# X
-
, I" a- [3 J& T+ P - IrqProgramEnd# k7 \& y1 _% M' M5 m# J# r) k
- PLA
+ W$ T; W7 a) b# X4 ]! |4 i - TAY8 w( H6 }& `+ i) x0 ^. y9 P
- PLA
( v: M5 L- {" R% q - TAX3 h& w# Z0 K1 \# `# B2 B$ ?+ o9 _( s
- PLA" \2 l7 r) k/ [( t: Z" a0 Y
- RTI
; t d+ d- d1 P! q9 K+ r- G; E! g - " |6 [3 R2 Z- }" }
- ;==================================================
" K% r" G7 T: Y% \; Q - ;中断表
" ^* {* W& x, U- A8 o8 [! u/ \/ s - .ORG $FFFA* ]) K) b0 G- `+ g
- .WORD NmiProgram; o6 l: M% m# J) r- L9 e
- .WORD ResetProgram i: U9 X1 ~0 g
- .WORD IrqProgram
复制代码
% x) V1 M5 ] j1 @- H4 h+ J |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|