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