|
|
- [code];[FC音乐][MMC3 IRQ]
+ U( u: x7 @, N. p% Q2 V - ;FlameCyclone 20230710
3 }2 `$ _/ N5 t3 h - ( R+ G7 ^) b( f H/ Z
- ;文件头3 v. ?# K; B1 I. G S
- ;======================================================================
, \. N; Z8 @6 ] - .INESPRG 4 ;16KB PRG 数量
5 Y- G# ~$ ?, m5 t7 ]) |3 a6 ? - .INESCHR 1 ;8KB CHR 数量
( E' `) V7 l5 z3 K3 ]" K- ^3 p4 w/ V) B - .INESMAP 4 ;mapper 4
( r0 d$ d' x9 J V4 g$ | u - .INESMIR 1 ;命名表镜像 0水平 1垂直* M) Q! ]4 t9 u
: D, \% m) N0 p" v. V- ;必要条件
" W- H! ?1 D* `( w - ;1.持有CHR ROM Z& r2 l0 h, n D `0 t
- ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
& T: v; [' m) e( s - ;3.精灵内存(OAM)不为空
/ H' l3 ?" x. g& y
. h/ J" D, p$ u- ;==================================================5 v$ [! d( M/ ^
- ;NES端口常量! G+ d( U2 F) V& D. n3 E
- PPU_CTRL = $2000 ;PPU控制寄存器9 V+ v) @! |; s) W% m
- PPU_MASK = $2001 ;PPU掩码寄存器+ B9 K- k, L1 R9 [) l W8 l
- PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位2 P" e" l' @3 L" W; d" O' H8 J; ?" b+ o. `
- PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
* G1 B2 I- X$ g' X( X3 X# R - PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
7 D, |# K9 F/ o, b - PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 2 A& x4 ?' j9 X( s4 ]" G
- PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加& p% b* q8 R2 a
- PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
8 ]2 t: J7 Q8 e0 K* ?) [1 N - OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
7 J8 T: p5 L" B - APU_STATUS = $4015 ;声音通道切换8 P. e( O0 c+ p1 A& Y
- JOY1_FRAME = $4016 ;手柄1 + 选通* a4 v! n' W: E* x$ L
- JOY2_FRAME = $4017 ;手柄2 + 选通: O' \9 E; i/ |3 |
- ( A, p' f* k1 k. Z. T
- ;==================================================
5 }+ U7 {0 x" s" F! h - ;MMC3端口常量4 U1 L' E/ l( l+ n, y) q9 V
- MMC3_BANK_CTRL = $80006 Z) K' X5 `9 @ y9 m/ ~
- MMC3_BANK_DATA = $8001
* C7 } h" \, ~4 D3 |* s: W" D - MMC3_MIRRORING = $A000# [+ }# M+ z0 V$ ~
- MMC3_PRG_RAM_PROTECT = $A001
. ^ N6 a o) c% d1 L% x - MMC3_IRQ_LATCH = $C000
) \) C8 J2 w" j7 E - MMC3_IRQ_RELOAD = $C001
$ L" l( o r' D/ |/ Y - MMC3_IRQ_DISABLE = $E000* P' A' D8 x" ]! x2 E- }& r( a
- MMC3_IRQ_ENABLE = $E001% r6 m' c9 J& Y
- # t" ]8 t$ T$ y D3 U( y1 L
- ;==================================================# l& ^% \' v, L9 x5 P
- ;程序块配置
+ S1 C! L) Z7 s, k5 V( T$ T0 I - BANK_DATA_MASK = $07( y8 g0 ]' W/ ~
- ;--------------------------------------------------* O* j u9 B0 h
- RESET_BANK = $07
6 l* q: u- ]) k y% [9 b1 F' a* w x - RESET_ADDR = $FC00
( ~( J+ M; H7 ~+ u2 F* ?
4 O) X. B% T& T8 A' ^3 b. C- ;==================================================
; k$ R2 B8 v0 B' l# ? - ;图像块配置: e4 s0 I6 ?* U
- CHR_DATA_BANK = $087 E. N7 q' x, E# v6 A
- + a1 X, b( }% q9 e: |3 b; W
- ;==================================================
$ c! x' S8 W7 X+ A3 Q( W! ^; r - ;零页内存地址配置
: z9 {; |% v3 v7 s& Z( N - Use_Ram_Addr = $80 _4 w: P& u! P# M
- PPU_Ctrl_Buf = Use_Ram_Addr
1 k% e& u$ K+ p5 ?+ ~ @3 k) S - PPU_Msak_Buf = PPU_Ctrl_Buf + $01# ^/ m0 N' A' x! U7 { A
- PPU_Scroll_H = PPU_Msak_Buf + $01
, ?( f6 z6 M) z; l - PPU_Scroll_V = PPU_Scroll_H + $01
- q- @) x: f0 W" \ - FC_Data_L = PPU_Scroll_V + $01
5 M) y; h {$ s5 Q - FC_Data_H = FC_Data_L + $01# `5 M1 l9 A4 o
- FC_Data_Buf = FC_Data_H + $01
8 _/ h( e6 i' R9 }6 s# R - ;==================================================
! u& V& y5 O: q; i4 j6 g
3 m7 c# X, V2 ?) e% ?) k- `4 a$ I- GAMEPAD_MERGE_FLAG = $04
: c% n& r4 D( D
6 J+ M" D) s9 [8 x+ I- Gamepad_Keep = FC_Data_Buf + 1
: w: k. U) p3 H9 t/ r+ p/ E - Gamepad_Once = Gamepad_Keep + 2- }5 S1 A7 {, j& R$ \
- Gamepad_Temp = Gamepad_Once + 28 K1 P/ Q: `" T( ]! L
-
# w1 a5 z4 k9 C1 j: `9 c+ U - Gamepad_0_State = Gamepad_Temp + 2
1 U9 f% P. [( L& |: g$ S - Gamepad_1_State = Gamepad_0_State + 1
. S. F8 O$ s! p B: a/ q; K - Gamepad_0_Value = Gamepad_1_State + 1" e+ }; c2 ~) _. a( [1 ^' F! ]4 r
- Gamepad_1_Value = Gamepad_0_Value + 1
% u+ B* R3 l' F6 ? - Gamepad_Port_Value = Gamepad_1_Value + 1
1 T( \* U9 t+ {6 r4 j) ]* r1 E - Gamepad_Merge = Gamepad_Port_Value + 14 E) `( a0 ~+ K' e, s
- 1 t. ^- V: u8 _; {4 X# `
- ;==================================================9 f4 G8 h- [7 m$ N4 l" A2 s8 N
- IRQ_Index = Gamepad_Merge + $01) O0 ~* v; \$ Y6 M3 o
- ;==================================================6 K. }* U! r2 P0 ]5 h+ R% X
0 J7 m( ?( x5 S' ]4 j- ;CHR图形数据
7 L& A" G% H( F& H/ q: K - ;==================================================, u L& b; R* ?+ R: z9 v+ Q- |
- .BANK CHR_DATA_BANK
7 A, t0 R/ u- T6 g% g - .INCBIN "chr_bank/chr_data.chr"
) e' ^6 c% b) x% D7 n -
3 o0 j) K, m8 n- b" |7 W - .BANK RESET_BANK & BANK_DATA_MASK+ W3 j! I) d3 Q6 q
- .ORG RESET_ADDR
" F* e! L4 K( N6 ?8 b6 h -
+ H* p2 z2 @* \+ u+ d+ ?% K - ;--------------------------------------------------
. A% Z# \( R) E1 e D+ j4 V$ | - Attributes_Data
G0 G5 v3 ?7 W2 e0 j1 ` - ;命名表属性
4 x! n" G/ y: D! A, E - .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$009 @1 z; Z- q; ~* T" [* b
- .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
' w Z5 S2 f% Y4 b- t3 K a - .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
: P8 v- @. z2 k" d3 I3 E - .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$556 C. \! o1 S; F: l$ q9 U
- ;--------------------------------------------------
/ ^) Y* m/ H F6 S1 W0 J) | - ;调色板数据
# d" O6 i& f6 y! A2 c' v - Palette_Data
- o5 v- C' w5 L9 U/ T - .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
. k& y( y$ C9 w; T; `8 u8 U# c - .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F3 Q) ?8 @5 W1 K @/ C& U/ t
- 1 c7 M- J/ q4 e
- ;==================================================
9 F3 V6 Z0 `6 F, s& L - ;命名表初始化
7 }. l( k) W' o: H" g2 o& U - Init_Name_Table1 K4 o7 p$ e0 k
- LDA #$20
! Q& l7 {0 B9 L+ s - STA PPU_ADDRESS! h* C0 i0 \9 @7 S% g
- LDA #$008 I* g- f! z( I7 y- w
- STA PPU_ADDRESS' ]: L' }1 E) U1 l* k9 R- n
- LDA #$00. O; \+ X# N4 X7 t% x! e
- LDY #$00$ J- V F/ g' p2 w4 a
- LDX #$10) C# Y2 I2 B& \4 M" q8 g
- Init_Name_Table_Write9 B" u' A) @* O( ~0 l/ V% n
- STA PPU_DATA0 Y. x' ?. \: g& d. O
- INY
6 y! v# V8 R( @+ U0 V, C8 h - BNE Init_Name_Table_Write5 K' c& B8 x: e+ D5 |
- DEX( v7 G% l3 A& `7 y% w
- BNE Init_Name_Table_Write' R' y% ~( r& Z% D2 K
- RTS
/ r9 D6 r) W+ J5 r' X* c - 7 {9 @8 B9 y6 A" y s! R+ `* r; G W {
- ;==================================================1 ?2 G V2 T/ S' p7 V6 d
- ;调色板初始化
! h* I0 o5 `) { - Init_Palette
, L1 E% V) I) q% W! K7 j - BIT PPU_STATUS
$ d2 F$ F, X/ C" d4 B1 A$ r, A5 T5 L, w - LDA #$3F8 o* V* K2 N# Q8 u1 |- r$ E
- STA PPU_ADDRESS4 k) H/ G2 N2 W9 S8 c% u% k/ q
- LDA #$00
/ @1 E$ l$ ]9 k# N0 }; c' w - STA PPU_ADDRESS
9 W6 }# O0 J# m7 h - LDX #$004 V, P1 ]6 @% Z+ I Z2 ?1 n4 z
- Init_Palette_Write
( ], ?( {( p7 u - LDA Palette_Data,X
5 z# U S, r* g } - STA PPU_DATA- y* K. f5 y. W! x. E0 ?
- INX o4 M* u! X5 L3 g
- CPX #$200 y7 H% A' j# i1 s" e$ n9 O
- BCC Init_Palette_Write$ e1 n, F5 O8 j% D( j
- RTS( M( V+ y& |. d; P3 r5 l W
-
0 O8 T7 G( H/ ?4 h' ~' S0 L% _ - ;==================================================
8 C$ k+ |) i& ]( Q - ;设置命名表属性
0 [8 O) w7 F& B1 q# u6 Q - Init_NameTable_Attributes
& B2 Z" y0 B5 H" T! ]8 p/ x9 [ - BIT PPU_STATUS# w2 j" F; A9 \. x* V8 ^
- LDA #$23, i$ A+ i" `/ J( P) w
- STA PPU_ADDRESS V+ a4 v# m% E7 l7 ?" \
- LDA #$C0! F; _" X$ E7 G' D
- STA PPU_ADDRESS
* z8 A7 r& N N, v* ]! h - LDX #$00
/ ^+ `" O& v- {! y - Init_NameTable_Attributes_Write* L/ S: V) F) o% z
- LDA Attributes_Data,X
1 s' {) T' `+ }/ E - STA PPU_DATA
! E4 S1 H' R$ h/ ^3 m0 } - INX1 Y& m' m3 R" M; l5 m% K0 _ N, g
- CPX #$40
% r6 A. T6 ~8 S+ A5 s - BCC Init_NameTable_Attributes_Write
' w/ k% d. N8 [ }9 P7 F- |5 l% [ - RTS& J/ `$ {( e5 J+ P( D1 ]8 E' k
- 2 d5 P6 D% R* {, J2 M
- ;==================================================
$ c% d5 \( ?+ K2 C6 q - ;初始化命名表文本 T* r2 D2 N6 b( Q0 S
- Init_Name_Table_Text+ F! q1 B) P9 o0 z3 R3 j- {/ H3 h
- BIT PPU_STATUS: U1 u) I( \8 ^
- LDA #$20 ]6 F \. S. }" @4 a6 W* T
- STA PPU_ADDRESS
& Q4 d, y$ ?% R& k5 w - LDA #$00% p; D7 p# z- L" Y \; [ I
- STA PPU_ADDRESS
8 r5 N+ C9 x8 _' n/ R5 w8 Z - LDA #$00
! D% L! K% K6 K$ `, G) p" w - STA FC_Data_Buf
' C7 q& v/ K$ g6 K. u - LDY #30# `8 M) T% C& K2 z: }0 x
- Init_Name_Table_Text_Write
- b/ p- T/ }' x - LDX #32
7 ]( \4 ^4 b" r. J* R - Init_Name_Table_Text_Write_Char
& C3 S1 P* y p7 ]5 _( T1 r) z - LDA #'0'- t: O" O: x. N7 c- {5 s0 H
- CLC' }* M* v L( `" f
- ADC FC_Data_Buf
1 {! v8 G* B& }: t" s' m - STA PPU_DATA
: K; a9 f6 `4 `- _ - DEX
4 g5 S1 ^* n8 S$ @ - LDA #$14
$ k) r9 b1 L1 h1 U1 S4 `1 @ - STA PPU_DATA
; u+ j D1 u l6 x t3 E/ J - DEX
8 R' m$ e( h2 [( l - BNE Init_Name_Table_Text_Write_Char
1 k' z0 r8 b* ^1 m% Y - INC FC_Data_Buf4 r( h% e/ {1 v: q' u! u' S
- DEY
; N. I7 o$ ~$ q7 c) z - BNE Init_Name_Table_Text_Write
$ `- \8 P+ Q6 S9 G, }5 ~ - RTS
9 Y4 b8 l$ x( M9 ` |) D! c3 ^
/ t2 w! q9 P9 c3 O- ;============================== J e: \6 G2 l8 y- t/ X' q
- Init_OAM_Ram;初始化精灵内存- h( i0 M0 z% p3 ]4 O
- LDX #$00% F, q' e7 Z% J S) _" }( ?
- LDA #$00) Y, L& V8 x* Z6 G
- STA PPU_OAM_ADDR
& F, o: d7 f# N. Z1 N - LDA #$F8: A$ |+ P7 l! [, c: a
- Init_OAM_Ram_Write
; k* m$ c, O2 X - STA PPU_OAM_DATA
/ v* `/ ], v/ H0 z% E - INX6 A8 m }* W M5 n8 w; w
- BNE Init_OAM_Ram_Write
2 e0 [4 S* w$ c3 ^; D - RTS# W0 e1 |# h: o7 v& ^
- , l: ^3 M4 V- |- `. `
- GamepadProcess;手柄处理: D' Z# `& T# X% ], o
- JSR GamepadDatacan
/ f3 u! v0 @+ ~ \" i - LDA <Gamepad_0_Value/ B8 r+ T. L( n3 m$ ?
- STA <Gamepad_0_State t- [' H' W7 A
- LDA <Gamepad_1_Value9 A; y, j0 V- A: F
- STA <Gamepad_1_State
+ Q, `% k8 {% ^1 G - JSR GamepadDatacan7 w- O& @- h) U% A! G1 a
- LDX #$01
; [. ]7 ?5 B: \4 J8 O6 ? - GamepadMergeCheck;合并手柄输入检查+ C! |3 v( H, p- z; k; L
- LDA <Gamepad_0_Value,X
# t1 q( b9 ?0 O - CMP <Gamepad_0_State,X
( y7 }2 M0 `5 b1 P- M - BEQ GamepadMergeInput
+ n# [& |5 x; Q( j: z$ i! \: w6 C - LDA <Gamepad_Temp,X
& h0 Z# y& ^' f9 U% J: x9 h) Z1 p2 B/ M - STA <Gamepad_0_Value,X
; m3 a" U$ ^8 W$ R% x: L0 W' t - GamepadMergeInput;合并手柄输入
) ^8 {6 [# H) Q2 ]& C B% p" g% Y - DEX4 G( S) Y3 r. a# F6 R0 _
- BPL GamepadMergeCheck" Q0 x1 {# N) N( o
- LDA <Gamepad_Merge
3 ]% \! s0 p5 B6 O# Q- g, {" S - AND #GAMEPAD_MERGE_FLAG, q+ \& I: `+ A
- BNE GamepadStateProcess8 @ ~# w7 K9 m* w5 h' m9 B
- LDA <Gamepad_0_Value; C5 R. X; x& e
- ORA <Gamepad_1_Value
3 v U( M" n( H7 f - STA <Gamepad_0_Value( {; A- ?2 t# b' n
- GamepadStateProcess;手柄状态处理
; s& u! x8 H. V8 _/ m - LDX #$01
5 M2 M) T% Q8 x2 Q5 X( N - GamepadStateSave;手柄状态保存
Z5 i1 `2 X3 V% H - LDA <Gamepad_0_Value,X, V. a3 R/ w0 }( H
- TAY" z' ]& C+ k5 _4 A
- EOR <Gamepad_Temp,X; G0 W0 S O+ D! V5 ?
- AND <Gamepad_0_Value,X
9 _* E+ V" P/ l* ^1 O! I, b - STA <Gamepad_Once,X2 q& @$ h6 a. f2 c" `/ j. d
- STY <Gamepad_Keep,X' ~$ c r# o, X, |5 j
- STY <Gamepad_Temp,X
* T3 V0 x$ J+ Z- d: i7 M7 h1 q0 x" r - DEX
0 X e1 n! L# l" m, w, A - BPL GamepadStateSave9 ]; v) q+ Y# {2 \" y7 C% o
- RTS1 V& \; x& k( J# G o7 {. t
- i; p" |; r5 h! f# L2 ^9 m$ d# l
- GamepadDatacan;手柄数据扫描
1 Z' Q! h. b6 S0 Z9 A& Z - LDX #$01
5 y" K/ b+ H0 w% l6 N - STX $40164 \: V1 z) { {6 [# u
- DEX
% A4 p; r4 a1 B5 Q7 \" Y - STX $4016
8 c( F' t" ?1 ?3 J! Y6 N1 v- r - LDY #$08
: ?2 r1 a* G, _+ T: s. X - GamepadPortScan;手柄端口扫描
! N* ]* M3 H) ~1 j/ g8 y - LDA $4016; B% e- e3 p3 U
- STA <Gamepad_Port_Value% t7 d( c. W7 J1 u6 t
- LSR A l5 R2 c& m0 y F H8 ]. w7 m7 F
- ORA <Gamepad_Port_Value, _7 o6 e1 W' q6 Q0 D. S. D# O
- LSR A: ]) W% L5 z& w) ^; n' e
- ROL <Gamepad_0_Value- O: z a% c8 q
- LDA $40175 Q1 d/ v9 G+ Z" {
- STA <Gamepad_Port_Value
! G: q) l9 M1 `* d* Z* d& M - LSR A
0 A9 `/ y% ` q& ^6 Q* s - ORA <Gamepad_Port_Value
* S& e2 Y7 C& ?! c - LSR A
8 D% p' l! _( a7 W. o - ROL <Gamepad_1_Value/ L/ a0 c% Z; y. M0 t4 |& J
- DEY1 ^, v2 v/ s6 i& _, J) W K8 K
- BNE GamepadPortScan: J2 m1 @( _; S1 G2 c0 e: k; j4 A& e
- RTS: Z }$ h `; t
-
5 J# Y4 Q) h# ` - ;==================================================
0 U4 `' e) r) v {+ O( \: ~ - ;PPU处理
: d, E3 c* o# z# L# j1 b - PPU_Process
0 P$ p' m' j) { h - LDA #$00
0 k8 Q3 f) Y# @# p" l. |, H- ] \! p - STA PPU_MASK
0 Z& d) L# Q( T( X" N - + z! W& i. _' d" O9 [8 x
- BIT PPU_STATUS7 f$ L+ Y8 c# o$ z
- LDA #$20) m! ~) H% e( C0 B, B0 s# G
- STA PPU_ADDRESS
# @- ]: n5 S1 C% W - LDA #$00! e" l9 h% I" S' ?& k2 r4 Z
- STA PPU_ADDRESS& U1 U7 o" s1 |; t" ?* c* v
- * V h3 t5 p1 ?! \3 T0 {! K9 C
- STA PPU_SCROLL5 G' u9 _# v/ y" y& i
- STA PPU_SCROLL
) X, T" A: T0 a, G - * }4 W# I- H; O0 L7 f. a
- LDA PPU_Msak_Buf& e7 E+ g# D! y( M* I/ s
- STA PPU_MASK
0 s( S* @+ \) a5 g4 i: [
a1 b' Z( k% N) j- RTS F% d& W4 N/ P9 h$ n, M
- 5 j" ?1 J8 g$ B! S. W6 p
- ;==============================
/ `+ L+ h, P& S! t3 E4 h C - Time_For_Vblank;延时等待
0 _( X' i; t$ u \! Q( |9 R1 v3 K - LDA PPU_STATUS
% h% x8 {; s: x1 `) h - BPL Time_For_Vblank9 }& q% v* j; I5 g7 I
- RTS
8 {7 ~ W6 }- Q* Z6 y1 K' M6 W - 1 f4 ?, A9 k- f5 T
- ;==================================================
4 K% }- _) i C3 m4 ~" V: F - ;初始化MMC3
- I7 T/ z; _5 p+ w- P - Init_MMC3
P4 e) h. a# E# ?6 E9 P# G - STA MMC3_IRQ_DISABLE
4 }! y6 ]/ n7 z' J: H - ' ]/ c. I; F4 S- L* u+ g3 f7 k+ X
- ;设置MMC3水平镜像0 }: L4 w3 q/ }4 E
- LDA #$01
: j! p7 b3 w$ E) W k$ e6 n - STA MMC3_MIRRORING
$ ]. h& t9 N. n9 p! v3 L2 u) I- s -
, t- R$ F. G( } - LDX #$05
3 y, C1 y8 t% y3 P - Init_MMC3_Chr_Bank_Write
: o" ?4 [. X3 M4 s- [% M - STX MMC3_BANK_CTRL
! E% ^- z, G# e; `/ B - LDA MMC3_Chr_Bank_Data,X
8 z M1 l$ C$ b% D2 h+ a - STA MMC3_BANK_DATA
7 h6 \, L, {0 p" U8 z! _ - DEX
# n; S4 p' f5 I/ g - BPL Init_MMC3_Chr_Bank_Write2 g F5 F- i" V8 G) t+ L
- RTS
' L1 `& ~+ x7 W - ;--------------------------------------------------4 K3 T! E+ I* Y; m4 n0 p
- MMC3_Chr_Bank_Data
- T; Z- q' U, \; s1 N/ i }2 J - .DB $00,$02,$04,$05,$06,$07
3 S2 e1 R: p i+ h/ i0 r
! U1 l' [7 k2 b$ o+ u& p- ;==================================================
3 A/ e- O8 X2 s: k2 S8 k0 H - ;重置中断处理
7 ?2 Z% ?1 n& R2 D - ResetProgram# s& L: ^( w1 P) i; g* w2 P* ]
- SEI" W. D/ F1 N- u% z
- CLD" ^0 N' C, ?1 e' X" g7 v
- LDA #$00
/ q( V9 ]- n/ F3 Q0 T - STA PPU_CTRL
: ]- a2 _/ {' n6 T& H# P. Z - STA PPU_MASK' G' w' l: V& u+ @
- STA PPU_STATUS2 z' |, J- ]- _. I1 S- x
- STA JOY2_FRAME' E7 w- d( ~5 ]5 X: x1 @
- STA APU_STATUS5 e/ H" j0 X' Y+ O
- 4 }0 c) X ^5 ^* a7 M: ]# V
- LDA #$C0
; g5 G0 w, Y* \, X% _/ t - STA JOY2_FRAME- Q2 F4 V6 X0 W% n' [, k
- : r+ p6 T) k/ C( l( x/ w0 }
- ;等待vblank9 A; {" V3 T% N* x+ t. W: c1 r4 f
- LDX #$02
9 C# o, W" W( d2 u7 T# D' v - Vblank_Wait_1, w* Y" |$ l. m+ c
- BIT PPU_STATUS" O) B4 X: K' m) B8 H
- BPL Vblank_Wait_1
/ h6 j, u Z& N1 Q- d - Vblank_Wait_2' u" V8 ]' K6 Y8 F; B* z6 K
- BIT PPU_STATUS
* m/ [3 t2 a$ `1 W4 w( R) v - BMI Vblank_Wait_2
' _7 Q+ {! f1 X6 J0 O" ? - DEX
4 S" K8 ]( L3 |. J2 j9 d* h9 \ - BNE Vblank_Wait_1# a' N, Z! h+ P ~
-
- X/ Y2 \; l1 ^. S l - LDX #$FF
# o8 V- j, W2 B. _- X - TXS6 ?5 }8 c) ^6 _4 |2 I7 X$ F! J, L
-
+ x- a6 @ q) D. J; { - ;初始化MMC3
0 r9 Z4 F$ L" e& V0 @ - JSR Init_MMC3
; u* @! X+ p) B4 @% b9 W - : \& V" J; z% w0 D( v7 ?7 n/ r
- ;==============================9 w5 h$ |5 i6 ?
- ;RAM初始化: S2 @& S6 z& P+ \" u* y
- Nes_Ram_Init
6 W, p: [) n9 p/ q) ~$ J1 F$ b. [' E - LDY #$007 m( \; \, D' m {4 M) d1 @
- LDX #$08
# D+ y4 V J5 i8 f9 \: |! ?4 b8 i0 Q - LDA #$00/ j4 o6 P2 L- P0 |
- STA <$007 w3 r7 \1 t9 r7 p. k% F; h
- STA <$014 h& \* D/ `1 N* D! ?
- Nes_Ram_Init_Write+ L7 A5 e* O" ~* T; [' d9 D
- STA [$00],Y* g7 S# L* Z+ a" k; a
- INY
& ^) E- Z% X3 Z3 t, g- K - BNE Nes_Ram_Init_Write- L" c9 I$ R# V7 C' U
- INC <$01
& Z4 d7 `5 j" P" j7 y% [* Z4 L - DEX; }, r7 N# |, k) p8 ^
- BNE Nes_Ram_Init_Write
, u7 V7 s1 d8 Q- {3 I6 R! q - 1 m; U8 X- `' r0 |2 P$ Z3 b& p
- ;初始化命名表$ r" d* o2 t7 E6 P& s& f
- JSR Init_Name_Table
$ p- M* N7 s2 q9 M$ k. U3 V! J6 h -
7 U2 d7 h$ y, y5 `* ~ - ;初始化调色板
7 `/ @5 |' _7 \' h5 l - JSR Init_Palette
3 b1 Z: v9 C/ ]7 ^+ x! h! a0 e9 p - 2 C6 W" V6 X5 r, a9 F3 R- L
- ;初始化命名表属性
9 T: @5 i/ N% h - JSR Init_NameTable_Attributes
; m* Q0 {5 _; s5 L: o. v - 4 W: [ S' ?8 ^. @4 b, v- S8 b
- ;初始化精灵内存& u3 L/ I6 L! {4 o2 o M
- JSR Init_OAM_Ram
( V9 O4 X4 C5 x$ J - 6 C( {, O i, X. M2 i
- ;在屏幕上写点东西0 b4 ?) j! a5 M& A9 h. ?1 S
- JSR Init_Name_Table_Text
/ D( W+ ~* x& l+ [% } -
0 R; n+ W* H. `5 H" v - JSR Time_For_Vblank
: [2 N3 m% W9 y9 | - ;开启PPU控制
6 r# l/ w# D$ D4 ] - LDA #$A8- }% g2 i0 j6 ^5 K
- STA PPU_Ctrl_Buf
* N# `, I6 I' W# O( F - STA PPU_CTRL: Z% ?2 P( D- {0 U. P
- 8 Z3 ~$ s& ^* o/ n
- ;开启PPU显示8 f! }+ r( a& F3 X- K- E+ F
- LDA #$1E" s0 i4 z. r. h. {' f8 ?( O
- STA PPU_Msak_Buf
7 c6 A6 `. @# @" ^7 ` -
9 I5 {5 q; }. \9 C9 A - CLI8 Y" m' X& G+ |% n: y% }, W
- JMP Loop& ?/ l: v" S+ f1 x
- ' } v1 d: o9 O/ q z
- ;==============================+ K K$ z9 ^3 Q! Z" g" o
- ;死循环, 等待NMI中断
" l& Z3 \5 D' F" z/ l' W8 e - Loop
! w- M, Y/ R$ n/ T - JMP Loop/ w$ ^' q- g" g E2 P
; R8 T3 D- P- d* B3 d- ;==================================================
3 z, B* D5 Z# a/ z. O1 D' ~2 s2 O# r - ;NMI中断处理
3 S. J# E8 [, B - NmiProgram9 G& ]' r# g, r; z, J
- PHA E5 S( ?6 Q8 a/ R* W
- TXA
+ F! T' h! `1 o - PHA
; }' _$ u4 r5 W4 A$ U5 n - TYA! q% s6 G+ t/ k$ v( X1 D5 v. f
- PHA
( M9 q# g0 n0 _: I& p4 c - 2 H6 U1 C1 ]* U, F0 J' n, ~. \
- BIT PPU_STATUS" b4 m4 r V" A4 N# n
-
- x" q4 V" w/ u, I- Q" R - ;关闭PPU控制# D3 S! D& o3 k4 W9 b+ p) Q! O
- LDA #$00
3 a$ g1 C" h' l, `5 D - STA PPU_CTRL$ o3 |. v1 _' C# j, x/ Y: W
- % S+ I5 S5 G& Q1 E5 r
- ;处理PPU3 N7 ~% G) P& p1 E' O$ I
- JSR PPU_Process
) w5 s9 X! Y2 V' V - 8 |* m7 u4 Y+ i/ U
- ;开启PPU控制
( a9 M& M6 d& B - LDA PPU_Ctrl_Buf
7 o9 ^! K8 `4 }) E - STA PPU_CTRL
" I2 ?5 V9 _5 B% P( s: T -
, h' s1 m# s! ]0 ]. n* \! K) e - ;手柄处理. y8 ]3 P O0 ~: G4 m( t
- JSR GamepadProcess8 X) P6 m/ R- F; X/ @; M1 k& n5 v
-
5 c+ t) R/ A& C* \ - LDA #$008 V: ] V3 A, E( p( N. @/ t" y
- STA IRQ_Index
/ c% o/ ] K+ c* x O2 p( o4 X - , |; b0 @; s4 K8 |. Q% M
- ;启动IRQ中断, 第15条扫描线触发6 j$ U8 ]3 a3 C- t# W1 O: K0 N
- LDA #15 + 1
0 S) b' X7 Q2 [. \ - STA MMC3_IRQ_LATCH$ S, r. F' n6 ]6 M" l9 o, v
- STA MMC3_IRQ_RELOAD! Q# W( A+ r: t( T, B# f% L% c" W
- STA MMC3_IRQ_ENABLE9 {4 o9 ]0 [$ p/ v9 B6 Y' f
- CLI- r( Q9 m/ t+ C' p2 O
- : Q% M w: Q8 j) C. c2 {& m% W
- PLA3 W$ V6 l% k' C6 L- {
- TAY
# T/ k8 z$ h% A( j& X - PLA
0 V% `1 h C, R [- d - TAX
$ W* K" n- W: o% l& A' J - PLA
0 k$ z! X- K9 ]/ h3 A+ b7 j - RTI
- b' S" G5 _0 m% [$ F5 y; b
2 a& }& v/ |( M) ?3 o0 H- ;==================================================
5 A4 r9 s7 N t) J - ;IRQ中断处理$ i7 v- W, N% ]
- IrqProgram" ?1 i" d$ G# M5 N, R
- PHA
; B9 i. U/ }9 K! w - TXA u2 r' V/ n$ p6 ^
- PHA% a) ~7 W! l7 b
- TYA
9 j* B1 y: u8 a - PHA
8 I1 X" a, k) A# K# n - % w& g5 Q: E$ d3 M7 U% f
- ;关闭IRQ
- G5 T# R0 l8 S! C w - STA MMC3_IRQ_DISABLE
|. G! n2 ~% K6 t- p; o - $ o- |0 ^+ @$ F
- ;允许下个IRQ触发6 l# r+ G4 p0 h! _
- STA MMC3_IRQ_ENABLE ~ s5 b M1 C |% o2 }
-
6 [( v" S2 X; ]( E( Q- k( \ @9 n - ;IRQ处理, 15线后继续触发
7 U' G- J$ t. n( u4 F, R - LDA #15- M, U, @7 A4 A. S, ^
- STA MMC3_IRQ_LATCH. u- a' D+ p6 a1 i2 ]5 c
-
; B( Q6 H) l( R' p' Z- j - LDA <IRQ_Index* O$ _! L7 m0 }1 W4 A2 z1 E c9 d8 k; P
- BNE * + 4
8 c1 O* R, }0 Q& S' n W ] J( V - INC <PPU_Scroll_H6 D# H- Y% g* B3 ~. R" x
-
# A, k6 ~+ L6 s2 V - ;设置屏幕滚动
+ Y. j; d/ U/ K) f7 d - LDA <IRQ_Index# I, {2 m5 [' \
- AND #$01% g M* V( n9 R* C% h
- BEQ Irq_Scroll_Right( B ~5 @% _0 a5 @
* {3 Y; F8 b; X3 g1 x$ G0 M- Irq_Scroll_Left9 }0 |: \9 z: d# f3 O' c
- BIT PPU_STATUS
3 w4 i/ k9 m0 \5 b" ^% m4 j - LDA <PPU_Scroll_H
, v7 h$ R, M/ j- `" Z - STA PPU_SCROLL
7 f7 N3 X. N" e( B* S - STA PPU_SCROLL
0 z! h, {( V# O; x- P8 X$ ` - JMP Irq_Scroll_Over
f+ V7 U/ n! x5 j& s) Z -
/ B4 X; o. ^2 |4 a, u - Irq_Scroll_Right
0 C5 Z* M3 f# `) d! q" B. a8 B - SEC0 T1 ~& P9 o7 t5 @
- SBC <PPU_Scroll_H4 @! F2 D/ x' C+ W7 f% }2 q9 ]& d4 E
- STA PPU_SCROLL2 f, K" N! t: {$ |
- STA PPU_SCROLL
/ i2 a7 p$ c9 {4 B9 @ U. Z o - Irq_Scroll_Over" v# T0 V3 j2 _3 W6 _
- % _. u& f) P9 [/ h& s' H, e4 ?
- INC <IRQ_Index
1 E3 H* \9 p* q1 @, D* D2 w! x5 T -
- P$ j! h }1 Y9 p1 j5 p' O( M - LDA <IRQ_Index
: w! |7 }8 b2 W% M( g" _ - CMP #14
* m6 B2 [2 p/ R/ W* _4 u! d - BCC * + 5. d: m; ~; L; ?; P! v6 J9 W2 e
- ;关闭IRQ' V$ Q/ h, \+ d9 n$ o
- STA MMC3_IRQ_DISABLE
) n+ d# F) Z; Q( i) {1 a -
3 ^% Y* {' A" ]" d9 R - IrqProgramEnd
' I' d* l" g, O, ^+ t. Z! @ - PLA
$ {$ }8 o1 s5 X* ^' m, x- z% [; n' K - TAY
2 B; f. K: Z2 N9 f* e8 x - PLA
8 T; i i% c8 X+ l8 V4 l, B - TAX
$ o Y1 X0 ~6 @ - PLA
n# w Y" w. H - RTI# }& [* A& N. o, ~9 _0 C1 c* H
- 9 k# n: i! t$ U, h5 q6 W+ N
- ;==================================================0 L; ]$ g }, z O3 V# `% ?
- ;中断表; f* d0 Z: {, i) |7 Q
- .ORG $FFFA) _! ~4 _ _! Y" \9 }3 q9 }
- .WORD NmiProgram
9 y# f D. a1 e$ G# J1 n: M% w - .WORD ResetProgram
+ u$ p# b6 [: r0 @5 ?' n - .WORD IrqProgram
复制代码 [/code]1 Y1 m9 j% F! L; b: I g! g0 f/ D
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|