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