|
- [code];[FC音乐][MMC3 IRQ]
a1 W% D% ~! W - ;FlameCyclone 20230710
2 n$ {" }7 C# ?, l" V, \% u) _0 V
" N4 Q" F9 A- [# h V6 y4 F0 I- h- ;文件头1 y, {6 k( w1 q) d9 Z' G2 R
- ;======================================================================
" U6 X1 i( c8 p6 R- m- h1 V+ P5 U - .INESPRG 4 ;16KB PRG 数量% |6 I/ ~6 a! V# H9 t8 f" ~
- .INESCHR 1 ;8KB CHR 数量
1 H! o9 I! T! [; w F( M - .INESMAP 4 ;mapper 42 E0 R g: A9 J" \0 D3 i" |
- .INESMIR 1 ;命名表镜像 0水平 1垂直$ L0 k8 Z; \) Y2 T( C: O( K3 o
- $ R2 X, ~2 U: ?! @5 `
- ;必要条件! A1 V" I0 g# p4 g# O
- ;1.持有CHR ROM
3 i- n" J) Y4 z7 ]( U; k - ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$10003 x( D" k z1 x; H
- ;3.精灵内存(OAM)不为空
: X- a4 V3 v( i z: R8 l% f! m
5 ?7 @% k7 w, c" I0 Z0 f- ;==================================================) u& K& T# V9 x. k$ l
- ;NES端口常量+ G6 ~& G1 F" A' U+ x' n
- PPU_CTRL = $2000 ;PPU控制寄存器
. b6 r, C6 j; m - PPU_MASK = $2001 ;PPU掩码寄存器9 @2 c$ M+ n% X- H8 C
- PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
8 j3 k. W/ P+ L- q0 ~ - PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
1 `6 o& X$ M, ]" m7 s1 J - PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1 Z! q6 A% ^ X$ C1 O9 T0 N
- PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 2 y' P) \0 t! W
- PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
8 @/ R$ i7 I4 L( g - PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
, E, E/ y: K+ c2 y$ r - OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
& w6 M" l. w2 s" H5 O' b& Y - APU_STATUS = $4015 ;声音通道切换
" X$ S" {$ }- g& A1 E' P' W - JOY1_FRAME = $4016 ;手柄1 + 选通$ w- g8 [3 _8 h& {: k# A3 W
- JOY2_FRAME = $4017 ;手柄2 + 选通& |) P+ o, f2 Y( L2 e
' l# d8 Q4 r2 s9 S+ c- ;==================================================
) x- `; D2 t+ [9 { | - ;MMC3端口常量
1 W8 l( ~8 D; ` - MMC3_BANK_CTRL = $8000
S6 X1 a6 v( E+ O% }7 G - MMC3_BANK_DATA = $8001
0 o5 R9 v5 Z% e+ _: O+ m6 k - MMC3_MIRRORING = $A000& g% I8 [$ p! O2 t; Q! V8 L
- MMC3_PRG_RAM_PROTECT = $A001( J. J2 p0 Q: g
- MMC3_IRQ_LATCH = $C000
; B/ U- ?0 Q! F; X - MMC3_IRQ_RELOAD = $C001
' P( o. m3 U5 g; u3 t1 |* K7 A4 a) i - MMC3_IRQ_DISABLE = $E000/ G5 t8 \. m# X7 H W% g
- MMC3_IRQ_ENABLE = $E0012 V) t0 V! z, j& [5 c+ O% ?
" S: G* w- O' R3 z I0 q ?- ;==================================================
7 Q) E/ ^/ P1 c2 c' i( S2 f% G - ;程序块配置
1 |, X6 u. S( a% R - BANK_DATA_MASK = $07
- t+ g. M1 H+ y% i& T - ;--------------------------------------------------% e! M9 T. L0 ^1 |
- RESET_BANK = $07) q3 p2 \) t! R( A }, I
- RESET_ADDR = $FC00
" }9 M) w; p! K) T) |" U8 F - 9 Z: k# n+ h2 M
- ;==================================================
/ o2 `- R. m( s; _ - ;图像块配置: d+ O1 Q, ?! P* P: \5 }
- CHR_DATA_BANK = $084 l- U5 y u' `3 l9 z5 @6 x
- ; l5 h" n& ?9 Z! Q& j5 F2 G0 b) {
- ;==================================================
k) c! u1 x. t7 R - ;零页内存地址配置! }2 H# q+ i2 A' }
- Use_Ram_Addr = $80& d1 i# u/ t. }$ t A. ?) C) q
- PPU_Ctrl_Buf = Use_Ram_Addr8 [) y: S4 K2 ^
- PPU_Msak_Buf = PPU_Ctrl_Buf + $01' t* g. s; w1 u; ?. i
- PPU_Scroll_H = PPU_Msak_Buf + $01
. x8 R: s4 ?7 v6 E$ p0 h8 w2 R - PPU_Scroll_V = PPU_Scroll_H + $01
3 t+ K' L- k2 R - FC_Data_L = PPU_Scroll_V + $019 Q# A2 Z. }/ I! }8 G
- FC_Data_H = FC_Data_L + $01
9 H; ^2 z& E9 \+ h+ o - FC_Data_Buf = FC_Data_H + $015 s/ g! R4 G$ x
- ;==================================================2 B; k, B: @ q% z3 E
- X( j$ p9 }# v) m6 O& D. e
- GAMEPAD_MERGE_FLAG = $04
& D0 H1 E" D9 \* V! V - 3 d& A7 k3 U* ^- L- B
- Gamepad_Keep = FC_Data_Buf + 1
1 C8 j; w5 X- C2 G - Gamepad_Once = Gamepad_Keep + 27 z/ D( y; x4 ]: _9 q6 k
- Gamepad_Temp = Gamepad_Once + 27 T! f! i3 J, n. t4 ~- }5 E) H
-
% s3 i& l+ d c) s4 r5 u( a - Gamepad_0_State = Gamepad_Temp + 2# ~. j/ W1 C: N; Q- d
- Gamepad_1_State = Gamepad_0_State + 1
/ d. V$ ]3 m% Q0 }# D6 X - Gamepad_0_Value = Gamepad_1_State + 1; J& @$ ^4 \7 T
- Gamepad_1_Value = Gamepad_0_Value + 1 _; w0 w' Y+ l' `+ l: l
- Gamepad_Port_Value = Gamepad_1_Value + 1% n ^# q4 }- l0 j2 J9 w( l
- Gamepad_Merge = Gamepad_Port_Value + 1
' E# l+ s0 S0 A3 X1 }+ y( ^
1 R- C" P$ M2 _$ n' U- ;==================================================
* n. ^# B9 a- T( C - IRQ_Index = Gamepad_Merge + $013 m" ?8 n: f7 M) P5 H9 U
- ;==================================================
9 B$ q$ d5 l' z5 |% W; y% ` - , m4 \1 m4 k/ q ?3 ]& s9 Y
- ;CHR图形数据# l7 U0 G: V/ R: F+ k4 N* X
- ;==================================================
0 X! d& z' @& @/ y5 b; z8 P - .BANK CHR_DATA_BANK0 _3 q) j; M/ t3 H& \
- .INCBIN "chr_bank/chr_data.chr"
, O- U# S: J- D/ k* k/ @ -
6 S( }; w$ `' p; V% u - .BANK RESET_BANK & BANK_DATA_MASK! @3 o" ~6 P Q* k& d" I A9 W i
- .ORG RESET_ADDR% V, L4 l$ E! G; T5 L% e
- 9 ?$ ~6 ]! W$ }* _0 o
- ;--------------------------------------------------
; P3 I! H/ }1 H8 P! }! ~ - Attributes_Data
1 P7 [, }" U: s. r4 H - ;命名表属性
2 ?, m+ ]: j6 p! R/ w) @' g4 _. c9 @ - .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$007 g' O5 R/ e" K5 g$ R( i9 ?
- .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
6 `* K, v( i. \$ u$ W - .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA" E: A0 X$ f# X/ O
- .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55& u9 _$ {2 F# ]% a# z$ C6 m
- ;--------------------------------------------------+ N1 m6 B+ c; C0 N2 r; C1 W
- ;调色板数据
& i. l# C1 f9 r" l4 a2 }9 W } - Palette_Data& C1 N8 t" @) \. s" f- O
- .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F/ E F) |' [6 M+ X
- .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F9 P3 \1 ?- G6 l" D
) W. \4 x8 Z5 c4 _- ;==================================================
# t" S; f7 V' P - ;命名表初始化
+ M4 z1 _5 {6 i9 V! g" m0 p - Init_Name_Table, S5 {# z6 K5 S F# i# U
- LDA #$20
. @" x! u7 Q8 w7 \- g# d& A6 V - STA PPU_ADDRESS& \; T' J/ a; d4 w6 w( H) Q
- LDA #$00
) T/ `- P* F4 o6 J% }$ J! y3 H - STA PPU_ADDRESS
. R# R. H9 e) b- K - LDA #$00
2 F( B: j6 t8 y: s - LDY #$007 f7 q9 {4 Y4 o1 K/ j" ~! x
- LDX #$10
- n- \% X9 o4 H% q - Init_Name_Table_Write
6 I: K/ D- w% P( q5 M - STA PPU_DATA
0 A# O: C M* D1 M - INY
) W" s! k/ L$ {- P" c* N) E - BNE Init_Name_Table_Write8 Q7 ~2 d: o* w& p: f3 Q
- DEX
9 p4 b6 V' X& X2 Z! h- @ - BNE Init_Name_Table_Write! G$ l5 X7 @( E1 U& i8 X6 c/ C
- RTS( m8 F+ U% f" k/ |
-
4 Z, F" ]: C0 ]( f3 E - ;==================================================
+ @7 _9 A% [; \5 F O1 z - ;调色板初始化
6 e# ]) L2 G4 R7 R - Init_Palette! ]2 k1 S2 @+ v. Y
- BIT PPU_STATUS i! W0 h7 ^% S8 U4 G8 y7 |! {- ~
- LDA #$3F
8 F8 V8 \( J; F* ] - STA PPU_ADDRESS- I" W5 A# V7 b
- LDA #$00, V3 N3 B- A# P
- STA PPU_ADDRESS
& A N/ ~% M& w0 r. Q% j, b7 w - LDX #$008 E8 n* `/ @7 d/ U/ h( \
- Init_Palette_Write
& n0 B5 Y1 x8 C8 f6 a - LDA Palette_Data,X) l F. {) ^2 E
- STA PPU_DATA/ V1 \' V5 p, _" X, n' \
- INX' p/ k. x$ E$ f
- CPX #$20
, o) [# [. j+ Z5 @ - BCC Init_Palette_Write
+ U: T' G. l B8 t6 ^/ x - RTS
. @+ l2 e. z! [& E - ( k6 h7 `0 M+ {8 H
- ;==================================================- J5 a" }" e. P$ }% l1 v
- ;设置命名表属性: r( q" p0 h. \" w8 x# l8 ^ M9 c
- Init_NameTable_Attributes2 n9 l1 ?7 B# T: b
- BIT PPU_STATUS
" ]3 G/ S4 s$ J& W0 ~# j! E& x - LDA #$23
- h' D+ S/ X+ N$ D - STA PPU_ADDRESS4 F0 j6 F. d( [/ x W
- LDA #$C0
9 e$ Q* e3 N" t3 n - STA PPU_ADDRESS/ d7 i2 ^7 o2 a' b6 @" n" ]' i1 X$ G
- LDX #$007 S; E8 J. D# A5 y2 N1 g
- Init_NameTable_Attributes_Write1 C! C, u7 c# s' ^8 S
- LDA Attributes_Data,X
4 \' p1 Z( H3 a- M2 W$ `- Z+ | - STA PPU_DATA
3 I9 V* u2 g' Z9 z: _+ b9 { - INX3 w# ~: y! n8 F+ ^! e$ g
- CPX #$405 d. k+ e9 y. n
- BCC Init_NameTable_Attributes_Write
# H. @# U) f& G# F" B4 e5 A - RTS
4 p& G }( [3 y+ O* X
; k0 {3 s H) W1 @' S- ;==================================================" Y+ \" R4 E9 }2 B* `" L, Y
- ;初始化命名表文本
3 G/ Y* w3 o- z+ @7 N8 U - Init_Name_Table_Text% ^0 }" u+ z7 ]6 Y) E
- BIT PPU_STATUS2 `3 k# x6 ^) E& t( C; f+ t
- LDA #$20
9 [6 n; r+ d8 K5 W K - STA PPU_ADDRESS
1 P! }6 N9 ~- s% G& c - LDA #$00
( X) ?/ ^0 \% V v$ ^& m% ]$ | - STA PPU_ADDRESS. @) H5 p0 r2 I, J% E" j( D9 J, V E
- LDA #$00
& `2 _ _8 ^; a C: M2 ~* w - STA FC_Data_Buf
* m( j r5 J/ {. v6 u# | - LDY #308 D& ]; R+ e; x8 {' C( ~, T
- Init_Name_Table_Text_Write
. ?1 `' T; ~9 Z3 S: ?/ r3 M - LDX #32/ ~" s L7 h2 c/ N4 T. `) j
- Init_Name_Table_Text_Write_Char
1 w2 p2 z& w2 p, _: Q; w - LDA #'0'
% E3 `6 p* s! k1 e. d# a - CLC- U' Q, t8 W" y4 ] u) b
- ADC FC_Data_Buf
" n7 o. K/ _7 ^# N8 e - STA PPU_DATA
4 O4 F8 Q+ ?' ?# \ - DEX
7 i* _( v+ w* f' x, ~ m9 j - LDA #$14
, V3 F' d6 [: ?: s - STA PPU_DATA& a* s. U/ Q# z- n4 r
- DEX
3 c, z4 w |1 n - BNE Init_Name_Table_Text_Write_Char
, E# v! T! r/ F( m$ F1 J - INC FC_Data_Buf7 z3 K7 g; Z% G; a. j' S) @4 L
- DEY8 |& P9 a: L8 W
- BNE Init_Name_Table_Text_Write
' U; ~* c. Y% }4 B- g& R' I& ? - RTS
- V. e; ^& j! `' l - / d+ @% r1 x+ F1 o
- ;==============================/ v# c) V3 Q8 [$ S
- Init_OAM_Ram;初始化精灵内存
- n1 @% }8 I* n, ]8 p t - LDX #$001 A' i$ h- ~, R7 L% d6 g
- LDA #$005 K$ ^5 t6 u5 U/ \7 M) }
- STA PPU_OAM_ADDR5 m" F' t' a2 g) J
- LDA #$F8
1 [2 B, z' H* m! q& N, e6 D- ]% v - Init_OAM_Ram_Write
$ w2 m3 W s. O) s8 c% K$ H, Z2 G - STA PPU_OAM_DATA5 _! d0 E2 r' c
- INX- B6 }/ Y0 P' B* q; E# R
- BNE Init_OAM_Ram_Write( N# _9 B0 i& |) [) D. h4 b
- RTS
: P% [* g0 Y" r -
- S7 x5 ^2 c* {$ P6 ` - GamepadProcess;手柄处理
$ \6 U! G9 c9 F - JSR GamepadDatacan
. H. z& y; p( v6 }1 v/ N - LDA <Gamepad_0_Value' v7 _. K- s6 t7 M' R1 k
- STA <Gamepad_0_State' j6 B6 S% A" h" Z* Z; k0 j1 J! W
- LDA <Gamepad_1_Value; u% j0 C }% g3 F8 r) M
- STA <Gamepad_1_State4 d: F8 q& W3 G/ j7 @% A- Z- z
- JSR GamepadDatacan4 ]9 D4 ?$ t; j% w: L+ k. |! d& e
- LDX #$01
8 l# K3 u9 z% _, ?8 T: j - GamepadMergeCheck;合并手柄输入检查# S4 y: l, T ?8 r8 l
- LDA <Gamepad_0_Value,X* p6 n9 [6 V) y% g* \* N
- CMP <Gamepad_0_State,X
8 Z, y: L6 y1 a - BEQ GamepadMergeInput$ k( n" j/ {+ u" z+ B
- LDA <Gamepad_Temp,X
% G9 ?9 d# ]5 P: ^ - STA <Gamepad_0_Value,X
7 E0 {4 ?3 q' Y3 m8 e' z+ S - GamepadMergeInput;合并手柄输入5 {5 B9 L0 G4 y+ L" W
- DEX
" [ T# \5 p& H( {; @, e - BPL GamepadMergeCheck# _' w5 j) P' ]; U$ m3 K
- LDA <Gamepad_Merge* J8 ^8 z# G/ z3 _& O; ^
- AND #GAMEPAD_MERGE_FLAG8 F# M2 P9 h5 o+ M% `, D
- BNE GamepadStateProcess/ `# H% A+ h" y5 B! s) N
- LDA <Gamepad_0_Value# r/ ` B& l# x
- ORA <Gamepad_1_Value
. t, y* W6 c" j3 L. A, k" d - STA <Gamepad_0_Value( I2 L0 q, |+ Z( D8 [4 a
- GamepadStateProcess;手柄状态处理
' S0 I, C. g' |! L - LDX #$01, p+ n* l/ R# O+ ?4 e
- GamepadStateSave;手柄状态保存
$ ?9 y& z2 I$ H" t* R0 _ - LDA <Gamepad_0_Value,X
+ l0 b/ M" A* h- m0 Z - TAY
/ Z; f6 G/ i# q; `% o# K" S - EOR <Gamepad_Temp,X
: |# ]9 E. l; C3 w* z6 W - AND <Gamepad_0_Value,X. U0 P" A( L) {, Z
- STA <Gamepad_Once,X* x; q8 c2 I3 O2 D5 f
- STY <Gamepad_Keep,X; f* M; L: A; I& }( O7 N
- STY <Gamepad_Temp,X& g. A8 x, y6 R* p# n
- DEX" W( r/ k8 v! O# G5 W% z, w7 p
- BPL GamepadStateSave7 C" ?; F7 Y! ^1 z
- RTS: y# L" E3 e5 t0 M& K
8 q# j- i* }( U/ z* j" v- GamepadDatacan;手柄数据扫描
4 b0 m3 R% [( ~! { - LDX #$018 O9 E, Q2 t( w+ g8 G; x" x" S
- STX $4016" v- D3 q; c$ T7 e, D7 Z7 z
- DEX
/ W9 g- c5 u& @0 F; ^- c& ` - STX $4016! k% f/ D- i. F# b
- LDY #$08
" J, c5 E; f6 M - GamepadPortScan;手柄端口扫描
* |) l- {; J1 i" n - LDA $4016
2 z: _/ {. u8 z, p6 a - STA <Gamepad_Port_Value0 O% X% W! O' t' ^# u: o! c! ]& }! e
- LSR A
) L% ~; j: q8 o' q6 @ - ORA <Gamepad_Port_Value5 t6 D+ E; l2 \3 J7 o7 m
- LSR A1 N' i1 e3 ]7 p& ~
- ROL <Gamepad_0_Value! B; z- F# y, E2 r; a8 d
- LDA $4017
4 m3 t# i: }& i9 T - STA <Gamepad_Port_Value
2 }0 ]% ?" }, B4 a( } - LSR A2 z) _" i$ q+ x- H6 W
- ORA <Gamepad_Port_Value
4 q/ ^. w$ b. u! h: N - LSR A* V2 K2 Z& \2 E$ C" z- B
- ROL <Gamepad_1_Value
$ Z9 e0 [5 G5 q, j - DEY
; f$ ]! e2 w' J( |# U" t. J - BNE GamepadPortScan. Y- u4 Q+ }9 l0 A4 [+ u/ r$ W
- RTS
8 E3 h5 s L& `5 b -
$ C1 L- c& |; M @ J" p% [, j) u - ;==================================================
& k1 k* f* f2 t, F! p6 s - ;PPU处理
9 S6 S4 O- ?" s9 ]( s2 h3 ]0 ] - PPU_Process
2 Y& V$ M$ x( Z- t - LDA #$006 ]- H: Q: E# L e* L6 e7 y
- STA PPU_MASK
0 m: P* N4 l. h7 o1 A -
( c* K2 g7 W# ~# ]. y - BIT PPU_STATUS* [# z9 C6 o# d* o$ l
- LDA #$20
% D" Z" a- Q- \1 X - STA PPU_ADDRESS
( R: i1 [- g4 C. V( F$ ^) A) f - LDA #$00
+ m: y! W& X. {7 i - STA PPU_ADDRESS& d- P' y# k( [/ i
-
2 R ]5 ^6 j( O. J+ J5 j - STA PPU_SCROLL' q y% `- J- A5 }; Q
- STA PPU_SCROLL8 B8 X' V" n' U8 g. `3 `
-
# r) r, n& J7 h8 J' j$ _" o b! ] - LDA PPU_Msak_Buf
6 n+ s$ H) t3 ^' A% o; m - STA PPU_MASK g1 B9 g3 w1 z
- " G' W3 E4 @2 T' A& N* I8 P6 r
- RTS5 a _( W: g, v7 O4 R3 i
-
* Y6 c* `$ U2 `& h - ;==============================
6 F' u' K8 o" k( K- { - Time_For_Vblank;延时等待0 Z' ?; e6 }1 B' z; ^/ j+ }
- LDA PPU_STATUS& \/ J* m, o$ k
- BPL Time_For_Vblank z& ]; ~# Z0 u, S4 X- T9 W' Y \
- RTS
; q# F( l1 C: o+ j - + ^! X& c! f Q$ B( ^
- ;==================================================
; f0 R3 W7 ]# W% ^* X8 ^ - ;初始化MMC3
- \. ~; @5 H" t: X( q - Init_MMC3% ]" r1 {( w* R" E
- STA MMC3_IRQ_DISABLE# \' f Q6 h0 ~" N
- 0 A( S4 H. \. `: p
- ;设置MMC3水平镜像
3 ?& p; H3 C5 w9 j; v: _ - LDA #$014 y+ N0 p3 C) t2 f
- STA MMC3_MIRRORING8 W2 ~! x- g1 T% b* H2 l
-
5 d4 _# ^8 i: `4 {! i1 ^ - LDX #$05
+ Y w7 y# J g k* u - Init_MMC3_Chr_Bank_Write* n* m+ i, r% k6 |8 q
- STX MMC3_BANK_CTRL; P- p; U$ e% f
- LDA MMC3_Chr_Bank_Data,X( y2 @! Y+ R0 M: U+ _" \( E
- STA MMC3_BANK_DATA
6 w& [8 q; z- E! f - DEX0 y s9 @! M* ? W+ U
- BPL Init_MMC3_Chr_Bank_Write
& v3 e+ k/ Y& j! @ - RTS1 {+ D! [ Z( ]8 ?$ M( C' }3 \$ b
- ;--------------------------------------------------
: N) r0 W( ^! }/ Q! ]* E; F - MMC3_Chr_Bank_Data
7 M; Y, j) ]: E+ A* T' W. S$ d2 h4 I - .DB $00,$02,$04,$05,$06,$079 e/ U$ @; X! I6 x/ a' M5 o
- ' `5 w7 D/ @6 Y3 X9 C* ~" t
- ;==================================================
- w# ~- p( d" G- p1 p - ;重置中断处理
5 s5 x) o' G& @) n' P1 v# M - ResetProgram" |3 Q4 t( \. l$ C# B" U
- SEI
) P& x/ y) p+ t7 }- w1 R - CLD( S5 W" q2 n% a# p& z
- LDA #$00
1 m- l% }0 [ e$ J - STA PPU_CTRL" x* e( [ e$ J# o
- STA PPU_MASK" L+ H5 m* P6 F- W v
- STA PPU_STATUS2 R5 d4 y/ z6 O* C5 H, O
- STA JOY2_FRAME% s! F' a; \: O% q2 E' ^8 [# d
- STA APU_STATUS
3 n* p7 @" L3 m5 g- U7 @ - 6 A& l( a7 r9 f& s! r
- LDA #$C0* `) K& \6 x1 Q. Y
- STA JOY2_FRAME
9 L1 }6 `' f9 N S' [ - 3 @/ M8 z; F9 B2 e. K ^# N, m
- ;等待vblank
( }& o; r& N# O/ ~) G - LDX #$021 H$ l- N, \9 `1 P4 c$ N1 B( ^ S
- Vblank_Wait_1
+ h3 a6 b, F& O& j8 m2 o7 c - BIT PPU_STATUS5 H% _4 f# n2 |' r: T$ f
- BPL Vblank_Wait_1
; p$ I5 w8 Q, T - Vblank_Wait_21 T; w6 m. r7 m7 f5 J
- BIT PPU_STATUS
5 m0 _" {/ f6 ^- ~" O' y - BMI Vblank_Wait_23 M7 o( B7 R5 U2 C4 N# l4 E
- DEX, ^7 B5 d6 T7 Y( @- I
- BNE Vblank_Wait_12 ]# `' @' A% r* j2 B" D/ M
-
8 k' {/ {; Y. q, w - LDX #$FF
3 t, G2 m! v+ C- X& s - TXS. p5 p) |) @4 ?5 q9 {' g
-
3 q6 V O5 l- M* C8 ] - ;初始化MMC37 U6 e! g! J# N) O
- JSR Init_MMC3' \5 u# u- L& l& x7 D
- 0 Q( t2 o' Y* I. H2 {& P; Q/ n
- ;==============================; k p6 a P1 o7 Q. I; Z6 f
- ;RAM初始化
! x1 n8 V" g+ a" M" |" D; ~ - Nes_Ram_Init
$ P5 s* [5 h7 l; p/ m( ?: | - LDY #$00
, F R* J# p, ?1 Z& B+ ^( K - LDX #$08
q' q6 R" ^) Q) X: Z - LDA #$00
) I' o) e# s% Z - STA <$00) u6 m7 m. A. l6 h6 b% k; {2 G
- STA <$01
+ Q- t0 Y' Z- a! a, _5 M - Nes_Ram_Init_Write
! s$ s" V9 g8 o, t" K - STA [$00],Y5 {2 j* @. E. C
- INY
! _1 t) V8 x8 k6 B/ Q2 K5 a8 n* d - BNE Nes_Ram_Init_Write
4 a! R5 b3 P! U, ` - INC <$01
! X0 O1 p' y, B/ S2 T6 [7 S - DEX8 q: ^# K8 ^8 R0 J
- BNE Nes_Ram_Init_Write
2 c9 W0 K. H) l$ B [ -
: Y% m/ U g8 r0 @, `5 }) U - ;初始化命名表
7 }, D! P2 {) L* k2 o9 ^ W4 L - JSR Init_Name_Table
~8 F' L. @* V5 a) ^% f3 f -
4 `- x. E8 X/ U - ;初始化调色板5 Z2 Z6 m+ ?2 T$ c4 M1 ], i! Y0 J' J5 s
- JSR Init_Palette4 k( I+ F/ H9 R6 P& q( ~
-
3 l8 ]6 d2 z5 Z' A. v2 R% ]' i - ;初始化命名表属性
: E+ u1 V# b0 W0 {. c4 W j - JSR Init_NameTable_Attributes
( ^/ k7 [5 }, X. P -
- i% [( t: o3 Q0 g- M/ J* g$ P9 b - ;初始化精灵内存
. y2 {' Z/ v/ c) y& i" b( H/ O - JSR Init_OAM_Ram
: h# Z) o2 C( O2 q" }7 O+ j -
: B+ ]0 Y, O" \$ c9 t' R - ;在屏幕上写点东西
9 D7 [; n1 v5 w) \+ S3 h* x - JSR Init_Name_Table_Text
4 M, u. ]' O, @) _$ B - 7 q5 N, c8 `) v, }* v( V
- JSR Time_For_Vblank' p, _% s9 v, g( f# s
- ;开启PPU控制
1 H- E- t+ y1 v8 q8 w* T/ }# `# v - LDA #$A8
1 L3 Q, W& V! m0 d - STA PPU_Ctrl_Buf6 o J1 n4 ^" N. U
- STA PPU_CTRL4 n, u6 F9 i9 S9 w, ]
-
6 c2 `; U- I% x# S - ;开启PPU显示% ] w1 y) x$ K5 g% I& Z
- LDA #$1E8 {1 ^& d& Q. J1 E4 [3 K- d
- STA PPU_Msak_Buf7 X4 N5 H- W- ~: @" L. m' U S
-
& B; g- k- R; L% C8 { - CLI% F# O+ @7 F/ U! S* h* E* l
- JMP Loop
; q, Q, m2 N) d4 B$ ] -
- ^6 ^1 P/ M8 B - ;==============================" |* \7 U+ ~! q4 @- T' N
- ;死循环, 等待NMI中断
' s7 _- I/ d( x- l4 H - Loop
" v: [ v+ C) R' Q& H# B - JMP Loop
- b# D4 Q3 R, D+ q9 E - $ t- ?! f) {/ {2 X
- ;==================================================" b! r& T5 g& \* q: Z ?. F n1 i5 E
- ;NMI中断处理
+ ?2 W9 ~4 w: s# V- [8 F - NmiProgram
5 h I/ {% i: ]' m/ D e - PHA3 s' L' ~0 `# ]+ m
- TXA
4 {+ T \6 A# y0 [, {: @* t3 ?- n! O - PHA
( S1 a) t' [4 t, K1 }6 a3 d - TYA
: X8 ]9 _7 ^% G$ X9 e; Y) W - PHA
2 K" a- ?& u, }. u' [( m -
/ o5 h. c0 z/ M6 i5 h/ t. b - BIT PPU_STATUS! p9 `2 k/ O2 h+ u% U7 N
-
" W) B1 {& e( Y - ;关闭PPU控制
# k0 k+ G( o8 z4 C% g) [ - LDA #$00
1 U3 W3 \9 ^( u" |# J - STA PPU_CTRL; v* d; a, ~0 n2 [$ B
- ( u& Q1 _: Z5 t% p
- ;处理PPU! ^6 X4 L5 m" k
- JSR PPU_Process4 ]/ ~( r+ P* F8 n/ k
-
: m, g! i$ T1 s1 g& P - ;开启PPU控制1 b- u0 A" R$ `5 ^! o
- LDA PPU_Ctrl_Buf6 s* [4 m4 D( N8 _
- STA PPU_CTRL
3 ]) b1 F3 Q' ` u - " [/ N3 W% }) `: t4 D2 ~4 W2 ~
- ;手柄处理
5 E# k! V% x& }6 X. _- B - JSR GamepadProcess, r x; h' @5 y5 n' ~
- " s$ X7 b" E; x1 I
- LDA #$00" J3 [8 \6 I/ P6 ]# [8 }5 d
- STA IRQ_Index
8 _0 E3 t, e7 z% s' f) \) I+ O" B -
. z! o4 U: R8 H: C$ O - ;启动IRQ中断, 第15条扫描线触发, W& z; J1 N9 m( v) j. ?
- LDA #15 + 17 p. N" W4 s/ B( q
- STA MMC3_IRQ_LATCH# M$ R2 V% ` X! e6 e( B
- STA MMC3_IRQ_RELOAD0 u& @9 y1 i! o0 x
- STA MMC3_IRQ_ENABLE
* C# y+ N) ~' \) S% z, d4 n - CLI
: T5 W3 `, l7 O' ` -
. y( r: j4 Y4 _ - PLA& w' N. U4 a. v* }
- TAY
( B4 w+ u: j/ ~$ m2 O - PLA! u- H8 N# O* u2 Y" T9 D" M# V
- TAX, P, L9 O7 f! E/ y* e- q/ G8 v
- PLA
# b! |& r. \! x - RTI
& Y/ J9 L3 W* Y v - 4 \: S3 u( o1 i% l1 t" a7 [
- ;==================================================
6 t5 D+ e* K1 b( g0 p% [$ F - ;IRQ中断处理
# Q, `0 i( J% C# X6 }- | - IrqProgram" ?) P2 p5 ~4 T7 C7 h. J9 u
- PHA
, {& J* H, ~2 h3 k( U - TXA
" Y9 \, f# O' B2 h) ~) Z - PHA+ A* l$ C1 f8 N8 s& v
- TYA
% a; {4 p& \9 i, i" M3 k3 \+ o - PHA0 b# E9 M8 \: o/ n. ?. q- q0 o
- 5 t6 J5 I' a) Q0 L/ [6 _, g
- ;关闭IRQ
( f5 Q: R3 G$ g* d. b# }0 Y - STA MMC3_IRQ_DISABLE
" j- S, w' M$ e* J( z$ ~! s8 H - : I$ W4 X, K/ G9 o; m/ {
- ;允许下个IRQ触发
# x( A ?( f1 j& v: T! ] - STA MMC3_IRQ_ENABLE$ _5 o& d: P2 g" _5 _
-
9 D( \# n; e9 e6 L5 f - ;IRQ处理, 15线后继续触发* p' b7 x3 s9 B9 J, V" P: v1 F4 D
- LDA #158 c/ ]' c8 Q- @ B+ q
- STA MMC3_IRQ_LATCH
, k! U& V+ E) i. O5 g! m# |" O -
G6 |; y4 q, w - LDA <IRQ_Index e% q0 s( X' C l8 `
- BNE * + 4
' F' ?* m4 ] H" i& O' u9 f% k# {8 y- ] - INC <PPU_Scroll_H! _3 `8 z6 A0 b% y$ w; J
- % v' w% a5 ^- x7 n! }1 }
- ;设置屏幕滚动
# G0 {& H7 ^; ]! R9 x- g9 B8 t - LDA <IRQ_Index/ r% @5 A+ ?& M2 {! m7 G* I- r- f
- AND #$019 s) d4 ?1 x( N( O& p
- BEQ Irq_Scroll_Right
# ? o+ l, R$ m, P) w) g, ? f
' h( Y* G4 v) v( U( _+ c4 K* q% b- Irq_Scroll_Left
3 b5 f( K3 j U/ t' } - BIT PPU_STATUS( @9 m( {; [% L5 m
- LDA <PPU_Scroll_H
- X* V- s2 b- I! u7 g - STA PPU_SCROLL. X% ^5 L/ t& x1 F1 w g( ~& ?
- STA PPU_SCROLL3 ^6 @+ ^7 j. I i4 R7 l9 a6 e
- JMP Irq_Scroll_Over
) w; o2 n! T3 {9 y -
, C! }) i8 @- R; H7 u - Irq_Scroll_Right7 n$ ~4 t! q1 t3 V y5 ~& X
- SEC( Y2 }6 [. ?' A) q! l
- SBC <PPU_Scroll_H5 i* h" ~8 s6 _* {9 X0 i" y# f
- STA PPU_SCROLL
0 Y c& A+ z" A$ v7 R - STA PPU_SCROLL
% t8 u! ~9 u H8 l* X1 Z8 G - Irq_Scroll_Over* l# X b+ R p& \/ v# ^
-
- R6 `7 c& M6 i0 F- ?( ] - INC <IRQ_Index) _( G: @' y2 q. [- j0 i5 c
-
, `! h7 j1 O& W* Z, k - LDA <IRQ_Index) Z* _/ t V4 \
- CMP #14
8 C6 Z+ h7 v$ q2 b m A. m - BCC * + 5
9 y) I6 F' C8 |8 E3 J - ;关闭IRQ
, Y |; V( g/ S. M - STA MMC3_IRQ_DISABLE) S% c7 ?6 y- E
- " K& |2 Z8 t) E+ Q4 {% A
- IrqProgramEnd
+ S3 |/ X% F2 x/ O3 M; g! h1 } - PLA" y3 S8 P$ J9 `: D) `
- TAY& F% g" b1 p8 h; d5 n( c! O, u+ p
- PLA& z8 E8 B0 w9 r" {( _
- TAX
8 P3 { @, O9 D) k1 K0 i( z - PLA6 ]3 e# L3 B' \0 ^5 C
- RTI
6 V. W0 O) f9 H" Z! s1 p) _! ` - + h, @* k9 G8 e, S# @1 e1 N
- ;==================================================
" u% q0 ?, g+ ~ k - ;中断表
1 q6 T2 T$ I' v2 k3 {9 R - .ORG $FFFA
' g3 Y1 ~3 [* W( J3 { - .WORD NmiProgram
6 h) o Y; U5 j% Y - .WORD ResetProgram' m0 x4 J- s6 M0 B* U
- .WORD IrqProgram
复制代码 [/code]5 I h2 z- r" J0 b! q( G
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|