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