|
- ;[FC][Mapper19 IRQ]5 e. Y, {0 e; e/ U( G
- ;FlameCyclone 20230710
5 w' N+ }; J) I
# w3 v& l+ \, m- ;文件头
# w5 y. }; c* l+ u: ] - ;======================================================================/ K, o N) B5 q% L9 i" l, F
- .INESPRG 4 ;16KB PRG 数量
6 i b w* T! F$ m! d7 \ - .INESCHR 1 ;8KB CHR 数量" E# W; o4 H& J/ p# g* \" y: I
- .INESMAP 19 ;mapper 19
4 t X/ h3 \/ b. J' a0 ^1 @2 h - .INESMIR 1 ;命名表镜像 0水平 1垂直, |# h% u0 q, g u, q8 c8 I
7 ^# Q; D5 ^' N7 u- ;必要条件" S/ `* T% H( R# v' k! P+ a
- ;1.持有CHR ROM2 g$ e' H7 g5 d% o7 e v" d" u
- ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
4 p, @8 ~2 Z4 ` - ;3.精灵内存(OAM)不为空
+ Q/ d6 x, z0 u$ h1 t. B. n9 t& {& h
) v7 f; s l* b7 _- ;==================================================
2 T4 _9 @* A6 j" H - ;NES端口常量
% {1 z# _# ]5 }* I' q( ? - PPU_CTRL = $2000 ;PPU控制寄存器
9 j+ A- F5 \# L! J! F - PPU_MASK = $2001 ;PPU掩码寄存器& O0 n& _( G1 J9 ?5 `5 M
- PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位2 u9 w0 ~( b/ K
- PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1* f3 R0 t' L% M. t) C+ }) D& T, T
- PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加17 `5 U) ~" {+ J2 Q( B' {
- PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 . p" Z4 r# V+ Y. U% K$ Y+ c- K
- PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加1 H7 C$ T" W5 L0 ?+ h( T
- PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 5 E1 q+ a6 V8 \5 V1 a
- OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
3 S& S3 f* |1 o - APU_STATUS = $4015 ;声音通道切换6 y: \: u* \ r4 K9 N
- JOY1_FRAME = $4016 ;手柄1 + 选通2 i k; X, B% b4 A9 j
- JOY2_FRAME = $4017 ;手柄2 + 选通* s6 {" C, }" Z
4 X6 }: `8 ^1 |( [: p" k6 v* z( B- ;==================================================4 E- }/ g+ N) G6 Y
- ;MAPPER 19端口常量: p% Y z5 K7 }
- M19_CHR_0000 = $8000( v7 N! \# n$ ?
- M19_CHR_0400 = $88000 q5 p$ _; f/ u, V+ s* F1 e& u
- M19_CHR_0800 = $9000* X5 R9 ]" Z9 M, z2 }
- M19_CHR_0C00 = $9800- |* ?* c$ Z. g
- M19_CHR_1000 = $A0009 z' K1 t# M" V
- M19_CHR_1400 = $A800
6 D% u' V! b, q- i# G& d - M19_CHR_1800 = $B0002 u& [( W- S; M
- M19_CHR_1C00 = $B800
4 A! i- J b/ |, | - M19_NT_2000 = $C000 S! G; X; B9 I3 @$ }/ @
- M19_NT_2400 = $C800& I% b! t8 g+ f
- M19_NT_2800 = $D0003 [+ p0 _, D# m5 [& r0 J( W ^
- M19_NT_2C00 = $D8006 W" `7 O8 ?% V6 W ]
- M19_PRG_8000 = $E000
& N6 t$ ] x4 c( ~# x& i - M19_PRG_A000 = $E8003 f c) \' U( o0 L
- M19_PRG_C000 = $F0001 N% T3 I9 j' q, ?. C) J! v9 ?' n
- M19_IRQ_COUNT_L = $50009 N( B8 C. W, g, ^
- M19_IRQ_COUNT_H = $5800: x2 L* c8 {# A# J
, n% u: I! A* q0 c5 ~! {- ;==================================================
- ]0 ]1 t2 g8 y9 d* c" Y% [ - ;程序块配置
& O( C0 M1 E3 |/ _4 C2 j - BANK_DATA_MASK = $071 N2 F m3 M% }' j
- ;--------------------------------------------------& y% ~/ j! C# A3 M
- RESET_BANK = $07; q! S- b* j4 {2 P. T
- RESET_ADDR = $FC001 |3 K+ {0 C9 |0 i) A0 ~
" q* H) j' b: e6 J6 q/ ~- ;==================================================
# x2 H5 M) T4 [- | - ;图像块配置! b' n/ Z+ Q6 j) ]( i5 e
- CHR_DATA_BANK = $08# C6 ]3 d7 S) |* I- t% N
) O! Q; S* V1 ?0 C& H- ;==================================================/ l, [" K$ p- {- a6 E! h
- ;零页内存地址配置/ V9 \* X, F, o7 J: o5 `
- Use_Ram_Addr = $80
* y' s7 M; t% t( M - PPU_Ctrl_Buf = Use_Ram_Addr
9 s- X; `1 v/ ~7 C6 H ~ - PPU_Msak_Buf = PPU_Ctrl_Buf + $01) \$ j! M' z4 @1 G
- PPU_Scroll_H = PPU_Msak_Buf + $01
, x. D8 k" S, b5 P - PPU_Scroll_V = PPU_Scroll_H + $01$ {; p2 C' h& o+ y7 R
- FC_Data_L = PPU_Scroll_V + $01) r6 K8 N% p8 v' l
- FC_Data_H = FC_Data_L + $01
B6 ~6 T6 W; x - FC_Data_Buf = FC_Data_H + $01
4 p+ b9 h0 Y+ |( k! v - ;==================================================/ S; l+ p3 s7 `, J2 Y5 q
8 O, D/ S+ L8 _2 S; c) m- GAMEPAD_MERGE_FLAG = $04: S5 b( a6 d$ q9 l
" N3 k; U7 g% a/ |, }- Gamepad_Keep = FC_Data_Buf + 1
1 l! s3 _! p. @$ {+ A2 R - Gamepad_Once = Gamepad_Keep + 2. ? Z Z- |+ f4 u7 G
- Gamepad_Temp = Gamepad_Once + 2# N& B& ~) W3 A; }
- . p& T; I( q3 d
- Gamepad_0_State = Gamepad_Temp + 2
/ T% f/ O. k. M; ?, c$ n' ` D - Gamepad_1_State = Gamepad_0_State + 1
2 @; C) t* [5 V0 u( c - Gamepad_0_Value = Gamepad_1_State + 19 p- z* y0 X s: @: y
- Gamepad_1_Value = Gamepad_0_Value + 1
4 r) D" Q& C" v k U1 O7 n - Gamepad_Port_Value = Gamepad_1_Value + 1/ E* i# k! ]5 P2 `: g
- Gamepad_Merge = Gamepad_Port_Value + 1
3 ^7 b6 C; b) X \4 X: X8 w
2 i: E; C3 |3 Q5 c) [2 k8 X- ;==================================================
& w9 K2 Q7 N# E0 Y" ]. e" R1 d - IRQ_Index = Gamepad_Merge + $01: P( H% T1 h% L, ^* ?
- ;==================================================
+ u! p9 I1 E8 [/ ^0 k/ ]* N
b% ?# Z$ I& U- ;CHR图形数据. Z8 O: ^1 E L, n0 E, z
- ;==================================================
1 f0 E1 L5 D9 M, J* x6 T9 R | - .BANK CHR_DATA_BANK. U2 U9 K; G% K0 {2 m$ Z
- .INCBIN "chr_bank/chr_data.chr"( C+ W" Q' o! v; T" P* _' [
- $ T2 n# y# B1 g+ a' i1 u& y5 A$ Z
- .BANK RESET_BANK & BANK_DATA_MASK: e2 \- s T, r) j) S5 q7 L d- W! `
- .ORG RESET_ADDR6 b T, _" ~1 E9 l; G/ H; _0 W
- $ I) c+ G f% `% Q
- ;--------------------------------------------------
( Q- n0 X- Z P8 J - Attributes_Data3 p0 R. a+ k, B' g5 \
- ;命名表属性* A% _0 V3 Z, }) h& F
- .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
$ g/ i' u% A1 g7 C+ A: O- t; ]3 h7 W* G - .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA$ S& Q+ f. k& o3 ?- [, Q) o
- .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
0 m8 L+ @' `7 C) z6 q" m; _ - .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$555 ]# R5 I( A, l% k
- ;-------------------------------------------------- x) V+ j" |1 s
- ;调色板数据
7 g4 j; q' m# G5 L, v - Palette_Data$ H# ~8 ^ x5 m( e1 N0 [/ W
- .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F7 Q) }* V* `! R/ ^- C# o
- .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F1 k5 a0 x' ~/ O0 M$ ^) U( F1 Z
- / R. o9 i8 D/ H
- ;==================================================: x" ?: q8 w( p' P
- ;命名表初始化
6 o3 ?$ t8 {& P5 e - Init_Name_Table) e( s3 G" F, @- h% Q
- LDA #$20
! h7 r! j. i" b# G# N& m8 _# T - STA PPU_ADDRESS
9 v* u. t) P* t+ k5 W - LDA #$00
1 T3 j2 |1 }! e; Y' a - STA PPU_ADDRESS, y [: k9 h7 `2 R- k1 w
- LDA #$00
, ~1 I: [0 U) P+ y" E) P6 s - LDY #$00
" n* S0 p- b! ` - LDX #$10/ Y1 w9 x# C* ~1 j3 Z+ a2 e
- Init_Name_Table_Write* u$ `1 [5 J3 N
- STA PPU_DATA
) v) C- f8 P A% j0 X' n - INY) j5 N+ L& r1 E
- BNE Init_Name_Table_Write7 F7 N, f9 N( ?: k5 s1 K: A1 v
- DEX* d% m9 m. p9 B8 v8 d
- BNE Init_Name_Table_Write! ~9 E6 B$ N2 O3 w; p0 n+ {" p
- RTS
6 l2 V% b3 \1 q6 { - / s" U* W6 H2 w! f; u( [, o; o4 B( a
- ;==================================================
% G( @5 [% a- t; j1 x - ;调色板初始化
+ l6 ~& R" S/ ^# E& ^ - Init_Palette
; j& |- N" J7 D6 w - BIT PPU_STATUS7 n7 v7 y% Z7 ?# t
- LDA #$3F2 [' S: a! g A$ i
- STA PPU_ADDRESS
) A7 Y5 A) v3 C! |7 f; ?" N. ` - LDA #$00
! n- J. L7 }: n4 B - STA PPU_ADDRESS0 ^0 P- g9 o/ i0 _1 ?, q/ ]* l; C
- LDX #$00& m/ e4 S7 S; ]& y
- Init_Palette_Write
$ _$ A! t1 v E) P& T: B - LDA Palette_Data,X- O% I# e2 ]1 b' Y+ D5 v) B8 {
- STA PPU_DATA2 t7 \" n5 x* b% n, m
- INX# T: m3 H- t6 k# X
- CPX #$20
& J8 v9 | L6 e# b' a( ~ - BCC Init_Palette_Write
9 u$ E1 {) |5 e/ \$ V, n - RTS
" y; g Q) o5 L. G6 G - " e( d6 [! H1 O [
- ;==================================================
+ Y. l; E& @2 M1 g0 T8 P - ;设置命名表属性( I# |; }# W' {7 e* J! t: L
- Init_NameTable_Attributes
( r9 k; M5 O/ y8 S m9 v - BIT PPU_STATUS5 S) v0 S7 p+ z
- LDA #$23
) m8 J# C' q) l& D, c - STA PPU_ADDRESS3 N5 d/ @ i5 @- V ? E
- LDA #$C0& k3 H' t4 ^/ y. A# k" H" ] I
- STA PPU_ADDRESS) G7 y! y {$ y7 E0 ]! O) Z# J" E
- LDX #$00# T! y' F; H0 j6 u, e2 D% }+ g
- Init_NameTable_Attributes_Write
; Y! [9 d1 m0 `& `$ d - LDA Attributes_Data,X- N+ m' I3 n0 W C
- STA PPU_DATA6 C: j$ z$ G2 O5 X# E
- INX9 c: J) V/ W5 r o
- CPX #$402 ?' L ~. q: c9 n& u( ?" W
- BCC Init_NameTable_Attributes_Write) `& Q7 E* p) P: t4 U( }, P
- RTS4 W6 N5 w# x' x2 r0 V& r6 l. c2 L" D
- 5 U1 K" w/ A' K8 p- C% V
- ;==================================================
& T, ~$ S1 `3 C; c0 Q - ;初始化命名表文本- d; N* \1 G0 E9 V. {; r
- Init_Name_Table_Text7 w- e4 k- F% L! A1 e4 U2 K
- BIT PPU_STATUS' b6 B l. W, ]1 I. V- `' {
- LDA #$201 y A r) d4 M2 _
- STA PPU_ADDRESS
% x* A5 o" D) d# i - LDA #$00/ C& N" ?4 s. C& I0 [
- STA PPU_ADDRESS0 h- ~8 \4 C& ` S( ^" I
- LDA #$00; T8 i5 ^( F1 R; h
- STA FC_Data_Buf3 B) l6 i( W0 e M2 P$ g
- LDY #30
( ^+ G# ~5 y) F2 e4 E - Init_Name_Table_Text_Write) x+ D0 `" h" O: m! G. M
- LDX #32
$ r5 Y: k/ U3 z; j& P! R. u3 ` - Init_Name_Table_Text_Write_Char- R. _# h/ B" S6 f4 p1 V
- LDA #'0'
8 j" C+ B6 P/ J - CLC
; P2 d0 L5 g& i; V - ADC FC_Data_Buf) Z/ E5 M. D* C9 V& Y
- STA PPU_DATA
2 S, h1 h5 N8 ]+ u# V7 V% o* ]! q - DEX d/ k3 d6 H& b) ^% _9 `4 ~3 V
- LDA #$143 o' ]( U$ R$ ~8 M9 B% ~5 `
- STA PPU_DATA
1 C' t6 G \- x# g; @+ ] - DEX
+ t* \4 f4 k* D& v) I4 Q r* g - BNE Init_Name_Table_Text_Write_Char
# d3 Y/ \. X0 ~, m' T) i+ X - INC FC_Data_Buf/ ^9 _+ ?# u* ?
- DEY" B9 V5 b$ q# t8 B$ r
- BNE Init_Name_Table_Text_Write0 y* i6 \* J1 K9 P* y& n
- RTS& b4 v) P6 L2 M/ j- R& w1 _" {3 H5 i
2 L: H1 e) V' m" H1 S- ;==============================
7 m3 q0 k4 ~* G* q! y/ T$ j4 } - Init_OAM_Ram;初始化精灵内存 ?: _( r' t* |* J* C* o! Y2 f
- LDX #$00
5 x& n% b" b5 \ - LDA #$00
- l3 e4 v# t- M7 j6 P2 m- U( n9 q& {2 k - STA PPU_OAM_ADDR
! [9 N% Q$ g, d! t - LDA #$F8
) n7 F* ^5 j$ \+ G! t0 t0 a0 O - Init_OAM_Ram_Write6 s: z3 k4 l- `, G/ p* l1 z r" _
- STA PPU_OAM_DATA
! o1 o0 C! w5 l - INX
$ n% D4 {. c: c/ `% E1 M - BNE Init_OAM_Ram_Write
* g/ P" s* R. p( N( I - RTS6 Y$ Y6 _; M0 [* \0 ~9 U
-
* A% P( s6 L; C+ h1 N - GamepadProcess;手柄处理/ O$ P- O t5 U$ f
- JSR GamepadDatacan
$ a2 a4 f7 J3 g( { - LDA <Gamepad_0_Value
5 \! \% g) ?% t5 P; ] - STA <Gamepad_0_State
8 R- M V; L. W% d/ @8 f4 f - LDA <Gamepad_1_Value
2 A9 }- F7 u# n; D5 T) @ - STA <Gamepad_1_State
' B; J3 A( B7 {" w3 P - JSR GamepadDatacan
* l; t T; B/ d3 ] H - LDX #$01
6 D3 m( ~$ ?3 `4 t o - GamepadMergeCheck;合并手柄输入检查
9 _ R8 O& |* ]) |" V - LDA <Gamepad_0_Value,X7 B; x' `. i. v9 }& z" w" z
- CMP <Gamepad_0_State,X4 N" z0 I. C+ f5 z$ f1 L+ x' J1 D
- BEQ GamepadMergeInput1 ?5 O! B" `% U7 W% V
- LDA <Gamepad_Temp,X: f B* R! E+ E1 i
- STA <Gamepad_0_Value,X
- S/ w4 Y$ H6 z# U4 J+ X, n4 m - GamepadMergeInput;合并手柄输入& r! n+ z* C% U3 |4 U+ K
- DEX
7 q/ x5 }" }* b8 J0 _ - BPL GamepadMergeCheck, w, S+ n9 c M( p2 }+ U/ f
- LDA <Gamepad_Merge0 \+ @$ d/ j7 A0 H! W
- AND #GAMEPAD_MERGE_FLAG- G4 i; Z1 Z1 P) Z3 X5 C
- BNE GamepadStateProcess
4 x3 x% ^5 m8 X y3 E! e$ H - LDA <Gamepad_0_Value
5 S: `" Y: g* E. c* a2 V! b3 j* ~ - ORA <Gamepad_1_Value
2 N! G$ I9 a& W6 E$ r7 L% x - STA <Gamepad_0_Value! p& H1 X+ j$ s/ j( }
- GamepadStateProcess;手柄状态处理
Y4 e0 F3 K/ l& x, t: c - LDX #$01
# i8 J! G% w0 G4 V7 H: E - GamepadStateSave;手柄状态保存& B; z' }. ~6 S8 T4 ]6 O
- LDA <Gamepad_0_Value,X
6 w5 ]+ M$ {* ?% N( s - TAY4 F, ^8 Z* J G# B4 L4 n7 C
- EOR <Gamepad_Temp,X
' M3 K! ?, U$ [$ {. q7 m - AND <Gamepad_0_Value,X' d: N0 z* ]! x0 f" x
- STA <Gamepad_Once,X
* j. l# o5 j: ?- C; d" N - STY <Gamepad_Keep,X/ F2 }' ?3 @- h+ @
- STY <Gamepad_Temp,X
' o1 N+ Z( b1 f" x: S- m - DEX
, q7 M, V/ L' t0 T0 c- L: P - BPL GamepadStateSave
/ d- E' I% o' ^ - RTS- _* K a3 s$ U& z
0 g! A0 j1 ~% v' A9 E6 H* U% n. }- GamepadDatacan;手柄数据扫描# W# r8 q7 C- H
- LDX #$01
8 s% w! r% J s8 I k/ S% a - STX $4016* M( e7 L' V0 Q+ E J! d
- DEX- u6 P; d. c8 c' [, z( e1 y
- STX $4016( ]1 }5 j5 M, L6 b i
- LDY #$08
0 w+ ?4 S4 V% h; _1 X0 q - GamepadPortScan;手柄端口扫描, Y; d8 w8 S5 n4 ]0 ~; K
- LDA $4016
h; \- C u! F G6 ] - STA <Gamepad_Port_Value
; j# m. i9 F# V1 ~2 J ^# q7 r - LSR A$ d; Y" l$ e& e$ M
- ORA <Gamepad_Port_Value
" C; Q- v+ }7 i' L0 W1 ]' z( ? - LSR A
& P- o# r( _# H* {9 ? - ROL <Gamepad_0_Value+ P" l% T' {* a6 a4 K5 w
- LDA $4017! d( N, r6 t. B# \
- STA <Gamepad_Port_Value
) @$ C/ u! c7 |" ?5 y8 P - LSR A* m5 u8 k5 Y% f& z5 N$ e1 {
- ORA <Gamepad_Port_Value4 ~! j% \& w1 R- g4 e" H5 ^
- LSR A& W7 z7 q) i" O- l1 D
- ROL <Gamepad_1_Value$ v- f: N/ Y3 a3 f0 F4 H+ |! u5 B U
- DEY" s( i) I8 X+ E! R" Q7 R0 I, ?0 Y
- BNE GamepadPortScan
l, K) R3 {4 p* T0 E y2 D0 E - RTS
3 K: t0 I& D2 ~$ x -
$ J4 D k) p3 m2 ] S - ;==================================================# E9 T! Z4 u# g
- ;PPU处理4 c2 s5 w6 y! z: z$ }2 K' {
- PPU_Process
3 m" S* K8 q# z$ J+ G5 c - LDA #$001 k0 T( Y4 c& u' G7 O! Q6 l
- STA PPU_MASK
, n5 N& Z. H E. x X. A/ G - % h( s; ?6 \( e$ } H4 s" c
- BIT PPU_STATUS
7 l* C8 Z) }7 s2 B/ A: r; Y* }9 G8 O - LDA #$209 [( W/ @8 I8 j6 p. ~2 Q M1 j
- STA PPU_ADDRESS# w6 R' G9 a, `" z0 _0 |1 f6 M
- LDA #$006 @7 U9 u/ r& l! D5 ?
- STA PPU_ADDRESS# j6 N5 n7 C( }$ {) ]! J
- " _+ p2 d, F( z$ v) I; p$ _
- STA PPU_SCROLL
' y: M: l$ _ O0 N( S/ O1 P5 @1 q - STA PPU_SCROLL: j9 F2 J9 Q/ u1 F: f
- ) p/ h' L, d$ A- M
- LDA PPU_Msak_Buf9 C/ z, \4 {3 y6 y' |' z) B
- STA PPU_MASK
/ q7 E+ \) i: q) ^/ ^" l$ F - ; _& b6 V6 p& W
- RTS4 ^! Z0 U9 E# s
- + t0 s3 F/ o5 T
- ;==============================* J+ O/ F. @ `# m4 l& s
- Time_For_Vblank;延时等待: @" k, N2 F8 D% v0 ?1 @" ]" q1 D& ^
- LDA PPU_STATUS
6 a( X: _! o0 T& ?3 `) Q1 Z$ K) p - BPL Time_For_Vblank
8 o3 T! Y# ^8 f8 I4 m# d - RTS( a$ b2 @3 a& T! A
- / W+ s) ], C/ o+ r
- ;==============================
% y ?( F4 r- |# G. F - ;初始化MAPPER197 v% P. G& a) S2 c% e
- Init_Mapper19$ y o: y, r8 T4 i$ ~2 |* q
- LDA #$001 s# ?4 U) {( O6 J; S
- STA M19_CHR_0000
, n( J1 h/ v8 r2 \% i1 d/ E - LDA #$01# B6 R$ v8 n1 j) g# \/ a
- STA M19_CHR_0400
Z. j3 z* K* }5 w2 J. p& l - LDA #$02
: B. H2 b7 I! f$ b5 u - STA M19_CHR_08003 w9 k/ j- T) X/ D1 L, @% Z
- LDA #$03
) T/ B) l& J3 v8 n: V# `& Z6 w - STA M19_CHR_0C00
; v5 j; Q" Q/ a# r! t - LDA #$04
0 \9 c2 l( M- U1 y9 a x) K - STA M19_CHR_1000$ S7 _# Q- D' [( F* q6 S6 ]* x
- LDA #$05
/ Q6 Q+ i( n: J! O - STA M19_CHR_1400
' Y* E2 x9 |5 m- j+ B - LDA #$06
+ ?2 D5 g; ~3 g% |$ d - STA M19_CHR_1800
8 ^! Y- E2 I% [! ~6 e" t: i - LDA #$07
! k4 G- H$ E( Y* F) t: m) d: A - STA M19_CHR_1C00
3 M2 W, w$ J9 T5 n4 R5 w4 @7 ? -
3 H( E" d! z) B' b+ X" H! v! W - ;禁用IRQ
7 Y0 a; [7 r# X) F8 f - LDA M19_IRQ_COUNT_H$ V$ z6 r' O: d
- AND #$7F( M- j/ H2 T" U# |$ k
- STA M19_IRQ_COUNT_H8 S3 n( m" ~- T: Q( U# t; L* \
-
# i5 c6 x4 G# D: _ - ;命名表
0 U( d9 E& r: d- S: X3 w: V - LDA #$E02 V) d6 D* P7 |3 E) J
- STA M19_NT_2000
5 E: J1 _) y% U% |/ Y" U - STA M19_NT_2400
/ [. n. |$ N" }4 `; k% N2 W# ^ - 6 N. C* Z9 h0 [% `
- ;命名表6 b/ T8 Q6 H# D4 u& c1 r
- LDA #$E1
- Y2 f4 v2 ?/ H2 k - STA M19_NT_2800- Y( \! r1 a' ?
- STA M19_NT_2C00
4 C2 t5 C) Z* U" S* r* \ -
8 Y+ ~/ B+ \0 b' c" M: l: `( O - RTS
2 w: M+ d7 o# s& Z) @- y' L5 t -
2 [1 `1 |4 _6 d! c; ]$ f; ^ - ;==================================================0 j2 H) o) c% G; q& R4 q8 e. m
- ;重置中断处理
1 |2 ^8 f0 Y' r# Z5 z8 P( e' z3 Q - ResetProgram2 {8 `8 s. D# l) t
- SEI7 H" e7 R+ h+ U) ]
- CLD
5 x& G6 E! e* b. T0 u - LDA #$00
) o9 o# y' H- t. g: J - STA PPU_CTRL
& }9 J3 U3 G7 g. W& J - STA PPU_MASK* E3 s# g, X9 v! J1 @3 t3 d; W: e
- STA PPU_STATUS$ ~% O- J; W, ?
- STA JOY2_FRAME- c, L& G0 w9 W5 z' _
- STA APU_STATUS; l0 r, q9 L, B" x. v
- $ h2 ?5 t5 l" X8 |
- LDA #$C0
9 n$ _/ s, S$ `8 f - STA JOY2_FRAME7 @* C' g' s) w7 V
-
& h4 k" p4 [! ?( ~" O) x( D% y: Y - ;等待vblank
4 k0 ]* W; V1 w1 A( I& ?" a ] - LDX #$02
0 X. X C( q7 y( d, s& |0 g - Vblank_Wait_14 x0 o2 f' {3 O7 ^
- BIT PPU_STATUS) U, Y+ a( ?7 D1 X/ w( y
- BPL Vblank_Wait_1
* C. X/ S, ]2 X+ v0 X - Vblank_Wait_2, n1 Z/ a5 h: F7 m! y
- BIT PPU_STATUS
2 q% z5 F4 a6 q* r5 x; e - BMI Vblank_Wait_2* |2 J6 Q8 Y5 i, ~( j
- DEX, b# l2 @5 p7 ~4 r
- BNE Vblank_Wait_12 i1 u- \4 h- D+ _. T+ B
-
) w3 V+ w1 N1 Z$ l4 L; @ - LDX #$FF
" b& q! L* c" F, f" Z7 j - TXS
" G' f% p, ^: s; w9 _8 L -
# F- K9 d5 ]6 r3 _& p+ P/ d - ;初始化MAPPER19
) S" Q! l! E, S# y - JSR Init_Mapper19
. ]' ~0 H m3 j) ]# c( M -
- u) a% h4 T3 W - ;==============================2 S- {% d0 q/ t+ H5 {& F- t) F2 `
- ;RAM初始化! {7 |" y9 R/ r- C9 E7 c
- Nes_Ram_Init% b; {8 ^2 P# h i) f4 y1 }
- LDY #$00, t& a% c: L# H/ m( O8 x
- LDX #$08
. o" n0 w3 \4 Y" h2 H - LDA #$00* r3 o( j3 q! S
- STA <$00& {; T- \# M# O Q6 A
- STA <$01) A/ g+ x1 m' `7 L; t' n1 p
- Nes_Ram_Init_Write! T7 L5 E, P& H0 Z2 p# H' O
- STA [$00],Y
% j( ~# ^, r, _% z. N7 f - INY
9 y( w! m4 R5 k3 e- f) ]# f - BNE Nes_Ram_Init_Write
4 ], H! u% N6 L5 s - INC <$011 \+ X+ u. \2 J! S
- DEX* o! M% v& F) P/ g# C
- BNE Nes_Ram_Init_Write
( z0 J! [7 @$ k2 R# { - b( Q" R8 _: H( e7 z# g2 o
- ;初始化命名表 m) B1 m9 u0 n
- JSR Init_Name_Table
! B' C( v2 ^' j5 e: |% X8 G - % j' k( p+ O* r
- ;初始化调色板4 v8 w/ N! O8 e! k P
- JSR Init_Palette% ^: q2 g j E+ y
- & n6 d. G# }# i
- ;初始化命名表属性
5 U! n3 @4 T' r' v - JSR Init_NameTable_Attributes
% u7 y/ V' g' I4 D -
. i$ x0 N: B3 i) l9 N - ;初始化精灵内存
5 n% b# R W$ n/ _ - JSR Init_OAM_Ram
% F( z8 X+ K5 i# s -
. g9 r, x% Q& r' y9 @ J - ;在屏幕上写点东西1 N( ?% U3 `$ z- V+ D
- JSR Init_Name_Table_Text
5 W+ ^ \4 a: q" x8 W - ) S" H0 c# T# t% g3 {2 ^
- JSR Time_For_Vblank9 J5 h7 W& A( b% y2 A! |. b2 Y" N
- ;开启PPU控制9 y" ^; e( i4 {" w
- LDA #$A81 i$ c; }0 F- B3 _9 |! j
- STA PPU_Ctrl_Buf" ^* k8 F- Y M/ u3 `; {5 O( a
- STA PPU_CTRL
/ o* T) `7 f1 D. n- b2 @, M -
# i( N( ]9 Z( n, q2 w; P - ;开启PPU显示
0 u: u# `) c4 c9 N - LDA #$1E
) k, a( l9 M/ o8 e q - STA PPU_Msak_Buf, f7 P$ `2 u2 y8 t# z# E4 k. q0 ?
-
5 F9 H. R2 p& t2 e1 C, ` - CLI7 ]/ Q8 w( j0 O4 o
- JMP Loop" [; X) ?! _+ K
-
0 z! J l: ?/ }( c2 f0 b - ;==============================
. U3 [+ v/ [- g) q* W - ;死循环, 等待NMI中断
& f: p% T+ E% ?" N* T - Loop! l9 U0 p E$ b* m+ C2 k- c, l
- JMP Loop
" e8 B/ c8 N, z$ W4 m - 5 V: E& a" T5 r/ a
- ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967" [1 K9 A) j5 |# c( l: c2 P# R
3 n8 j! X4 }! b$ M. }- ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)
$ b' }: D' U: d/ J. d - BEGIN_LINE_CYCLES_START = 32768 - (4103)% n. _5 U3 q4 p) _7 M8 h" J
- ;==================================================1 I0 B$ e" W! U8 o2 m U' t' d
- ;NMI中断处理4 U; S! p" Z9 Q" O2 i8 T4 i6 m
- NmiProgram4 U5 g( V& G/ _+ h' l
- PHA0 k; v* t& i- e; X! T) b1 v
- TXA
! n! q( n& \" q$ X1 Y, _ - PHA
L1 p9 ?# _0 | - TYA0 j" j9 O1 r* H1 ?# x& N
- PHA# K0 h8 g7 {2 Q
-
% A* X- Y0 f' S - BIT PPU_STATUS
; d2 D0 E) x# H0 z2 J - $ J) R4 `0 I! b. u% P$ Q
- LDA #$00
$ G7 r2 |/ P/ u/ M: P - STA IRQ_Index
/ e- V! B+ ~; H1 P2 ?( B; a - $ g: T- R4 T+ w5 ]0 t/ J
- ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动* @ m( I+ v+ F$ K3 c4 L7 Q) H
- LDA #LOW(BEGIN_LINE_CYCLES_START)
9 n/ l- c- [! h9 O1 Y5 Q - STA M19_IRQ_COUNT_L
* {4 [% o3 q: d6 b8 ] - LDA #HIGH(BEGIN_LINE_CYCLES_START)" h6 C5 }8 A/ g( b; O
- ORA #$80
) X0 \2 d+ M( k e+ ~! q! @ - STA M19_IRQ_COUNT_H* b3 n& G" M' D- x
- CLI
" r T1 P, L. D - - ^$ ~6 K! U7 y0 b' q1 p
- ;关闭PPU控制
- T5 y+ w6 j! s, L - LDA #$004 e5 q# f! S; `5 }" w
- STA PPU_CTRL: g! `% C1 n/ s2 D# N& z6 w
-
% @: Q# B* N4 q9 U# @' I( K - ;处理PPU% _ D. `4 A% K
- JSR PPU_Process
" Z" p5 s# `- H/ R9 P -
' s& j% }! H1 x& g - ;开启PPU控制
; ]7 U1 }$ v/ p; Z - LDA PPU_Ctrl_Buf
. ?/ L! I- d; I K# Z# L. m+ i' g - STA PPU_CTRL
9 x+ S. A1 S2 x! r7 E4 u; C3 t6 V - ' m8 o4 X/ P, ~* Y9 c! z
- ;手柄处理
& L- h7 R5 ]' s7 f4 q - JSR GamepadProcess
( U2 L8 J8 t) T. c7 s5 g -
) Z0 b" V2 ^$ H2 v - LDA #$006 C5 N. q0 Z4 ?5 V" H, n2 m3 A
- STA IRQ_Index* E g9 A8 ]( Q& e9 v) c% ~
-
A. J C, M! b& k - PLA
2 }8 s2 ]' a2 U. S6 X! k: x; k - TAY
3 j( f" ?! G+ X7 S# | - PLA+ I3 t: ?" H9 J( A- l A
- TAX
, N1 \6 G) q. q1 o# x* J* K - PLA( @0 t. F1 I, h
- RTI0 Z. u5 @8 B9 y/ s* `, A
7 d( @! A' H! \( q3 [/ v- ;每行扫描线113.679 p% y, I' L# g. _5 l
- ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)+ ~8 @3 A* T' y' Y' h+ H3 p
- BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
( G* }4 n) i" B* r7 p5 D0 A - ;==================================================; L* U7 b8 ~0 B0 ]: L
- ;IRQ中断处理
' n7 X( q6 ^4 e5 w" F - IrqProgram
" y* A8 k- i. T - PHA
& n6 j" n! z1 | - TXA0 l; x" |1 M$ M/ [
- PHA, \9 o3 B" @- d3 e/ W x& _5 Z2 p
- TYA
( k5 w' K/ ` m/ N5 M. @$ o6 o" d - PHA
0 n) r1 t6 g+ V# i% V - ' x$ V% ~, `6 u4 P5 F; b
- ;16条扫描线后触发IRQ
1 H& ~# p: ]! T; W$ M - LDA #LOW(BEGIN_LINE_CYCLES)
) V8 {( H. z" i - STA M19_IRQ_COUNT_L2 z0 R( \. J( B2 Y0 a$ b, J5 q' [
- LDA #HIGH(BEGIN_LINE_CYCLES)0 \" N; l' `3 T' K8 h/ f- F8 a) ?
- ORA #$80; R4 x5 |' }! S- k: D
- STA M19_IRQ_COUNT_H& e+ i5 T% ~& P) R* y1 \5 T( q
-
3 e$ M: m) u0 i - LDA <IRQ_Index
) q9 C5 t; ~' ~* g5 G3 H% A0 T - BNE * + 48 e2 f5 E1 ~/ N/ T
- INC <PPU_Scroll_H
# d1 f. o t) z' ?% d _ -
; a+ L J6 F0 T. ]3 L5 P7 W% ?8 _ - ;设置屏幕滚动
3 n# ~ I0 w* p* H. a C& q6 k) C - LDA <IRQ_Index
. O; y0 O1 b4 _" R4 m- K* Y - AND #$016 ~( b: Q* \1 S4 _ `# j b
- BEQ Irq_Scroll_Right
6 X7 H) P: B, P6 Z) b$ `0 R$ l
0 c% c9 C) k/ r4 c6 h8 g- Irq_Scroll_Left
4 _$ I1 H* r' x - BIT PPU_STATUS u; ]: z6 R4 Z
- LDA <PPU_Scroll_H! ~! F" i! N+ o4 x' X: |, n: e
- STA PPU_SCROLL. m0 q; J W, k2 U5 [
- STA PPU_SCROLL/ t$ a h9 o9 z5 ?
- JMP Irq_Scroll_Over
% j' r, n% f2 B+ p2 e/ e7 } -
- \3 Q) b$ v, j i) x - Irq_Scroll_Right# c) L5 o$ n& [' R9 {4 t
- SEC+ d+ W. p0 w- G# O# c5 e2 h
- SBC <PPU_Scroll_H
* s# r7 c; A3 b1 D - STA PPU_SCROLL1 d/ j k( C$ F7 e
- STA PPU_SCROLL& l9 l6 [+ `: F m
- Irq_Scroll_Over: W* h I" f5 r
- 5 ~7 t% A6 V2 l2 _$ {: ~
- INC <IRQ_Index( ]0 m) }9 ~0 `2 @( l% Q- I% Z: P/ V7 R& A
- 8 g+ C8 g; _) a- i+ }
- LDA <IRQ_Index
4 K# b- S0 M6 {% Q, S - CMP #14
" S: o- c1 ^. V - BCC * + 10$ [9 Q% O% v# b- f/ [0 X% h
- LDA #$00
3 V' h1 e5 j& e- t1 _ - STA M19_IRQ_COUNT_L
: C# h, c9 b1 _9 g6 {- P9 j - STA M19_IRQ_COUNT_H, h0 ~6 o {) `) }
-
& z) F% N4 i- t: X' {) E$ @ - IrqProgramEnd8 k6 m( I& a1 ] E: [. D9 Y
- PLA
# Z' O4 l5 w, z4 }7 ~: f: e3 k - TAY
4 g6 g3 r2 r3 g# C/ ~ - PLA }2 {8 J8 @. H2 z5 x; D
- TAX0 t. }6 ?, f7 j$ ]- ]! z8 `
- PLA
) A3 D( y) p1 I1 [& u8 M9 B - RTI
2 t. L. w6 ]7 B* X0 Z6 f: P- v, Z - ) Z R4 u; X! c e+ R4 u- q
- ;==================================================
& a+ S) b% @; f - ;中断表0 c: Y/ k* n0 Q2 C4 {9 n
- .ORG $FFFA
* O5 w& B1 ~1 e- J! v- [ i- w - .WORD NmiProgram, `7 s0 _$ K8 z6 I; S
- .WORD ResetProgram* L, ~8 z" Z* z, `9 N; X! `, H
- .WORD IrqProgram
复制代码
& i" V+ K6 G" t% i. z |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|