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