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