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