|
- ;[FC][Mapper19 IRQ]1 I$ J) n( ?0 R& H
- ;FlameCyclone 20230710- y3 [9 @1 Q3 ^) y$ c5 \0 a7 p
% x5 T' Q4 F; [7 U3 ?- ;文件头
; |8 M m6 x+ e3 n( t# e - ;======================================================================, z! o9 i" L7 k1 L* k- B
- .INESPRG 4 ;16KB PRG 数量) {" r. ], M) K& b
- .INESCHR 1 ;8KB CHR 数量
3 h1 |. p2 I8 |! R' H! P - .INESMAP 19 ;mapper 19) [- r: w- ^( D# U0 B B
- .INESMIR 1 ;命名表镜像 0水平 1垂直
0 y* \) h6 L! {/ N$ f* ?" g - " u8 K2 `) E5 ]- x
- ;必要条件
, u% X' l f& w) i4 S2 @ - ;1.持有CHR ROM
" t# x3 M5 B7 F" m9 R - ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
! ^/ l# ^( V# |+ B# ^9 \ - ;3.精灵内存(OAM)不为空
: C) Z. [9 _. w
' O- y- w% B; v5 |1 K c( ]- ;==================================================
1 w+ P+ ^' s! g/ _- ? - ;NES端口常量
: |: l' ~! s+ L& V$ x2 _$ }5 ? - PPU_CTRL = $2000 ;PPU控制寄存器
3 r, \# p2 }5 h# J - PPU_MASK = $2001 ;PPU掩码寄存器1 t' y w* h3 i: I4 ]
- PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
6 D: i# j! \$ j8 f7 ~2 T- |* e - PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加12 P5 ^/ e+ s9 `; y, E
- PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
- p# u! _- q# o! y A - PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 ) d2 N+ U" R9 t0 K3 R0 E, J
- PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
5 ^; Q; e- M: G7 Z) V6 j7 P, t# W - PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 ! V3 a- F# h) j2 ^+ O
- OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存3 R" x0 b) [% E5 i4 G; I- u/ w7 A
- APU_STATUS = $4015 ;声音通道切换
" E8 G3 Q/ @6 L - JOY1_FRAME = $4016 ;手柄1 + 选通" A3 v2 y1 t" W" e
- JOY2_FRAME = $4017 ;手柄2 + 选通
x' {) j" Z* y( T, G* D- B
( o' m" g i! T- ;==================================================
* ^+ Z6 E Z6 t$ l$ Q+ V. u - ;MAPPER 19端口常量
& _9 u7 @. d( K) ^6 j, B - M19_CHR_0000 = $8000
% M9 T+ `7 t$ J. J# h" f - M19_CHR_0400 = $88007 K/ t! V/ c; k# v' q/ S3 d
- M19_CHR_0800 = $9000; M7 y7 s' }3 O$ y
- M19_CHR_0C00 = $98007 \2 J& L# ~9 d, b4 D
- M19_CHR_1000 = $A000
; D7 Z0 t( }& Z, s$ A - M19_CHR_1400 = $A800
1 ~+ H6 J' f t* l& E( y - M19_CHR_1800 = $B000
* Y3 J* l1 e) }. S - M19_CHR_1C00 = $B800
. \8 J6 c; Z1 f6 z/ \9 t - M19_NT_2000 = $C0008 y: V1 W6 _8 ?$ a: R
- M19_NT_2400 = $C8008 n' s, [' G) i2 B/ H& x
- M19_NT_2800 = $D000
. \7 E) r) R9 L& Z# k; U9 M. h - M19_NT_2C00 = $D800; [* ]$ d5 p- a- {6 ]. M
- M19_PRG_8000 = $E000, p5 S8 Q9 k. h3 Z
- M19_PRG_A000 = $E800
' Q( j" b( M- v7 g9 P$ b# Y: k - M19_PRG_C000 = $F0005 h+ x' }) n" z- {* m
- M19_IRQ_COUNT_L = $5000& ?2 n$ a" J4 _# Q1 q6 ]* F
- M19_IRQ_COUNT_H = $58001 G# x$ I( F: } v& E
8 d% V: c3 G7 l" L G4 K- b! f/ |- ;==================================================
* d5 [3 W2 t3 x - ;程序块配置" V- z9 `) d5 E2 n s# ?3 m
- BANK_DATA_MASK = $07
( V9 p9 ?' B$ b8 ~7 r - ;--------------------------------------------------
9 ^5 O$ a) @6 ^0 o2 t1 q - RESET_BANK = $07
1 c6 d. l$ b, ~* w6 C) x# L - RESET_ADDR = $FC00* k- a# w" o. s& T, J; e: H
- 9 P8 v' k% o9 S$ ~3 D' w/ Q
- ;==================================================. n/ G5 j! Q4 h8 x' W) J
- ;图像块配置: S0 F6 O/ j4 m! n0 K' ]* b
- CHR_DATA_BANK = $08
/ t2 g" Z3 J: d% ?$ _ - : Y+ ^9 @3 A. q. K" r7 l
- ;==================================================
: e( T! g( @6 W$ v5 L: F - ;零页内存地址配置! ?) N' R/ K/ ?7 r
- Use_Ram_Addr = $80
, I" I. c) {' t - PPU_Ctrl_Buf = Use_Ram_Addr
' ?8 ^/ z1 V6 F" @ - PPU_Msak_Buf = PPU_Ctrl_Buf + $016 H6 X; K1 D$ t! E) S+ g V3 q' ^
- PPU_Scroll_H = PPU_Msak_Buf + $01
, m# O7 }; R& `4 z# w, j - PPU_Scroll_V = PPU_Scroll_H + $01
+ g' h2 Y3 H* Q }1 U1 L* x - FC_Data_L = PPU_Scroll_V + $01% D1 W( {) C) P# h1 s1 G8 W
- FC_Data_H = FC_Data_L + $01
: O, g N f% i) @! B; Y - FC_Data_Buf = FC_Data_H + $01& _- }5 Y* P6 G
- ;==================================================5 {0 B! _+ m' l1 {' l# p+ l
- ( x9 M" L- z' V6 O6 s5 {
- GAMEPAD_MERGE_FLAG = $04
; p* j+ N; q; o3 R7 O
0 J) n7 R+ p4 V; w9 V- Gamepad_Keep = FC_Data_Buf + 1
" _: z, _* h' T* Y - Gamepad_Once = Gamepad_Keep + 2* {- u4 |* u: z4 I; K8 L+ n/ y
- Gamepad_Temp = Gamepad_Once + 2' O- x2 F3 [6 h+ @: ]3 t
- , B4 B: [8 p: d+ l @' E* ~0 o2 n0 y- b
- Gamepad_0_State = Gamepad_Temp + 20 O7 t8 s+ @0 T) u
- Gamepad_1_State = Gamepad_0_State + 1
/ V3 L. f# x6 }- F; `7 v/ N7 B6 w - Gamepad_0_Value = Gamepad_1_State + 1. `3 o5 J( y' U$ A( p; E
- Gamepad_1_Value = Gamepad_0_Value + 11 b( Z& k& G- l' ~/ B& _5 n
- Gamepad_Port_Value = Gamepad_1_Value + 10 G: D2 L0 u* C- K7 g' x8 ?. s1 U
- Gamepad_Merge = Gamepad_Port_Value + 1
" d) q- k- z. g, ~# Z( ~: Q) }& j
( ?. E' e+ Y, J4 P6 r5 H0 }# f# x- ;==================================================
/ t/ o' h' n) g" v$ r+ g8 p - IRQ_Index = Gamepad_Merge + $01* h4 O8 G! l% `+ b
- ;==================================================, [9 Y2 B- s M# Z' e9 E% L
- b2 ]) h, Z' }# g- ;CHR图形数据
- ]/ j4 |" d* M/ K, e0 v, \2 x0 |* Y - ;==================================================
v' l. U& _ B2 s4 l2 ] - .BANK CHR_DATA_BANK. _6 b% u" U: Y1 ~) u7 M& j W
- .INCBIN "chr_bank/chr_data.chr"5 V3 h, _. |$ G/ H1 q
-
+ S3 x/ e+ W. h: L8 N - .BANK RESET_BANK & BANK_DATA_MASK
5 B. \. C, w4 E8 W1 O" e* i% E - .ORG RESET_ADDR
; Y" P# x, r7 o) ^( v# M$ D - % D @4 f9 [; k' |) [
- ;--------------------------------------------------
0 {6 k6 X }! g3 ^, m# ^ - Attributes_Data. @/ |/ h, c- T& h& G, M% N
- ;命名表属性
9 i0 {+ H" ?! o! v - .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$005 i+ ?8 r% G; t! [% D3 V
- .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
; P9 i* s9 \! U9 H+ F - .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
+ ^( V, V! U+ ^7 h1 A' M+ {- k - .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55) D2 V# f! H6 n0 k5 f
- ;--------------------------------------------------6 G) ]0 R U7 N# p
- ;调色板数据
, G$ K4 [2 e& W5 g4 r. w$ V - Palette_Data
! P* W; |. Y3 a% } - .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F6 g' c" t5 E; B0 J2 k1 [% F
- .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F( |" l4 k+ J" M' ?2 l7 D# q
9 I; h# Z: J Q: m1 X) {) K4 a7 ^& M- ;==================================================
! t4 Y8 i2 _% X" ]3 r5 o: N - ;命名表初始化5 k- ?1 A! j2 ?/ d9 H+ D0 {1 @4 C
- Init_Name_Table
) U7 i3 J2 {7 S# ] - LDA #$206 x9 E% S6 \, N3 W7 ?. _5 m6 x6 Q; I
- STA PPU_ADDRESS
& U3 C5 h% O3 ^* ^; d: Q* v1 t( Y - LDA #$00
# O) k; q9 _5 }0 d# Y% X$ Z5 P) q - STA PPU_ADDRESS
2 t* e' r" R9 n u - LDA #$00) I1 L- B3 U# {# M
- LDY #$00& ~/ ~4 s$ m( O# y# c6 {
- LDX #$10
3 d2 R& @$ B/ ?7 C3 D - Init_Name_Table_Write
% D8 q0 p) A; P, ` - STA PPU_DATA
6 b; I# V" S- V' p' x; e, I7 n - INY
5 G5 M( |& z: o - BNE Init_Name_Table_Write$ j: O) \5 ~7 s
- DEX
" q$ n/ {! a. R- S - BNE Init_Name_Table_Write7 S& C& P: r# f9 h5 h* \
- RTS
9 c2 t4 U9 E/ x! d& E -
. ?" R3 o& A/ _9 L+ T+ e, } - ;==================================================
: P8 |$ F! C n - ;调色板初始化
) B, f/ H0 k9 N. n! r - Init_Palette3 l9 S! V' U$ {* b; S
- BIT PPU_STATUS/ z% l8 \$ M4 [, R- X9 W! r
- LDA #$3F7 P4 J& x" t2 g; i) A$ z5 O! c
- STA PPU_ADDRESS4 y7 e4 e! s% v3 z% s; M8 h: a& F
- LDA #$00
, G1 W W5 K9 b, m$ } - STA PPU_ADDRESS
1 d3 k$ V- I: }# R, d - LDX #$00
0 W8 Y, c4 ^3 i+ g0 }+ l - Init_Palette_Write
3 m! r( o! f0 I' y) x" X2 j - LDA Palette_Data,X v- j7 z9 s6 x& K$ l+ H# B
- STA PPU_DATA
' f3 h& u! p+ f# N" Q - INX
! @9 x2 \' N# a# D2 u - CPX #$208 ^7 F1 p* E& X
- BCC Init_Palette_Write
! |& Z9 U/ t( {' l" F% D - RTS
) J- Y t' U, D - & F( w* @1 N: u( z& ]
- ;==================================================1 D) V$ d( o8 [" k6 n0 \
- ;设置命名表属性
( j# [, M' V; U2 \ - Init_NameTable_Attributes9 ~( ~. w+ P8 t8 {7 Y
- BIT PPU_STATUS) ^9 b6 T1 b8 z) K4 N% i( b
- LDA #$23
2 n' z- a* l/ J: e8 c9 q - STA PPU_ADDRESS
" G6 G+ @2 G6 ]8 T' K/ i - LDA #$C0
; u( m* ?+ d: [" k9 @ - STA PPU_ADDRESS
( w7 | `0 B* [4 I; \7 o - LDX #$006 `# T" w U, I
- Init_NameTable_Attributes_Write
9 I: M# D1 ^3 T) y c - LDA Attributes_Data,X) ~6 P* t& m6 K4 ?6 y$ Y
- STA PPU_DATA% i+ u3 L# d/ w' {7 H+ g9 x5 i
- INX
k0 b; z: @% }. L" Y - CPX #$40. \ o3 v* I+ B2 e0 X
- BCC Init_NameTable_Attributes_Write
: a$ j# L( G7 i g% T - RTS
1 X ]: e& S4 h6 y" d9 {1 H6 V
! w }+ |, S( c2 z0 u; X& b$ H7 H- ;==================================================6 M. e& _: F( m# p' c0 }
- ;初始化命名表文本
! l8 A- D r9 b& E# ^- G$ J3 P - Init_Name_Table_Text w: }) N p2 F+ i
- BIT PPU_STATUS
$ L9 ^- R1 Z( |$ c5 l' `7 n - LDA #$20
" @$ k- i2 Q& h$ D4 [& x2 E) x - STA PPU_ADDRESS
* p. s1 X& n n* | - LDA #$008 w0 V: p+ ^8 x4 q4 @
- STA PPU_ADDRESS2 g0 Y( M& i- l, y
- LDA #$00! C# S3 h8 u2 W) i% u
- STA FC_Data_Buf
# M% H0 {: A7 ~ - LDY #30/ x+ X/ R. l8 ?2 R: q; O6 q8 u
- Init_Name_Table_Text_Write/ ~- C$ P1 i" V# c
- LDX #326 x l4 j e: G9 e
- Init_Name_Table_Text_Write_Char
4 X7 `; j& Y6 a - LDA #'0'
) Q& M6 P! G8 c8 ~3 v# B - CLC
8 R& h5 Y: N6 T/ X. C+ T( r- D - ADC FC_Data_Buf
# v5 |! ?9 m7 D6 U5 T6 ~$ V - STA PPU_DATA
$ f' q0 s8 b( k9 y - DEX
6 l" Z4 O8 \1 e" ^ D - LDA #$14+ k0 z) u, F; o' b3 f9 n2 h6 |
- STA PPU_DATA
* s2 J# F2 ~7 W - DEX7 \' w9 [3 y% h3 q
- BNE Init_Name_Table_Text_Write_Char
: E* K' N. r* i/ E5 ] - INC FC_Data_Buf
1 W" R* _: J0 y - DEY4 Y$ n% D/ k7 G2 |! h1 o, z9 W
- BNE Init_Name_Table_Text_Write
0 R! c8 E5 k* W% u - RTS
" b* K: C0 B' g" `4 p - , K+ _' w# k# t
- ;==============================
: I4 [: u4 C0 l; L7 C5 X - Init_OAM_Ram;初始化精灵内存3 p2 b/ L6 \6 k7 H4 C. b" y
- LDX #$00& \4 y" I5 H; X' b
- LDA #$00
: j0 z. M6 }7 v; G - STA PPU_OAM_ADDR! p! J- P) R8 N4 M. R7 R9 N3 q
- LDA #$F82 Q- g$ F2 \( n" x
- Init_OAM_Ram_Write
# o0 Q$ |, D3 i - STA PPU_OAM_DATA2 z& {3 z& E: ^2 E5 l; f2 E# o
- INX3 T- \; V& z/ @5 c: j
- BNE Init_OAM_Ram_Write1 W l4 v, C+ i9 `1 T
- RTS
. G2 H/ H9 s | -
' f1 o; ` T1 f. }! c - GamepadProcess;手柄处理
1 n6 N5 A. K1 t8 Q* H - JSR GamepadDatacan
# P) P0 |8 ?& a9 ?4 C - LDA <Gamepad_0_Value
# [$ w9 ?) H/ H9 y; r- {' r - STA <Gamepad_0_State
. i( J8 Q$ l( o: [3 r4 ~ - LDA <Gamepad_1_Value! {4 v* j, L. O6 W4 w0 g( ^& o9 B6 y
- STA <Gamepad_1_State& K W& y; r, i/ I
- JSR GamepadDatacan
0 H- E, I- O- t9 L - LDX #$01' _3 U0 z2 a6 [* D3 M# H; y
- GamepadMergeCheck;合并手柄输入检查
6 h4 G; w. b$ m& S ^, d - LDA <Gamepad_0_Value,X" R! B+ y6 {) h* N
- CMP <Gamepad_0_State,X8 s5 S( F% }5 k% ]
- BEQ GamepadMergeInput
- {; {5 R* w3 q- g) B) [ - LDA <Gamepad_Temp,X) W+ g4 ?+ W) ]! t) w5 Q4 D
- STA <Gamepad_0_Value,X
2 H/ G* |! M; G - GamepadMergeInput;合并手柄输入
" P5 `5 d* N1 b# ]. H% z - DEX0 K# _# E5 e3 h6 W5 @3 y- v
- BPL GamepadMergeCheck; j* ]: W; O/ f" F% z- Y
- LDA <Gamepad_Merge
9 F) x, e1 x3 ]9 E8 O4 e - AND #GAMEPAD_MERGE_FLAG
6 p# f6 R6 ?8 J/ E' @! i3 m - BNE GamepadStateProcess
- Q. }" ]' J$ |% A& A( ] - LDA <Gamepad_0_Value4 \1 N: Q$ ~4 b: U+ e
- ORA <Gamepad_1_Value
+ e# F/ \% ~ X9 j+ C! C - STA <Gamepad_0_Value
5 j9 p) b( q! _& e" T3 w) u( ^ - GamepadStateProcess;手柄状态处理
+ }2 s' e5 l. N% K4 [ - LDX #$01
8 f8 [! R+ \* Y& B) x - GamepadStateSave;手柄状态保存
0 ?" s. i+ ?4 Y - LDA <Gamepad_0_Value,X
8 T5 F) O1 j, m - TAY
2 q( Z0 i$ h1 G' E. ], w - EOR <Gamepad_Temp,X1 P$ M' n! M- P2 t5 S
- AND <Gamepad_0_Value,X
0 \9 O7 e9 e. l- @& J - STA <Gamepad_Once,X
( D' ?; C# o( {+ I - STY <Gamepad_Keep,X b0 j$ ]) z' E, ?8 l
- STY <Gamepad_Temp,X
4 }$ _# k6 k& V( o( T* q - DEX X* H. r' M8 n8 j& a, ]* q
- BPL GamepadStateSave$ `6 J- X% L0 N- H
- RTS9 ]0 T# F3 W; A9 Q# ]. V+ p
" r8 b9 j# p0 W2 P5 K$ @" B- GamepadDatacan;手柄数据扫描; ?% ~( t0 Z9 g4 q0 t
- LDX #$01
# m/ i( K/ V6 ~0 ~ - STX $4016
F' [# U9 `6 D& c+ ]1 D* @! L+ E - DEX7 K7 t0 w, r/ X0 k! v
- STX $4016* p2 c3 f6 O$ m/ s" ]$ O
- LDY #$081 k" N1 v) G! u& e$ A# ]( t
- GamepadPortScan;手柄端口扫描1 i" m; h v& H& p
- LDA $4016
/ S- E7 Q* u6 M: E8 R9 i - STA <Gamepad_Port_Value: D! p+ r4 E5 U: D( k
- LSR A' N: O& g b- n& c% r( s7 g2 c
- ORA <Gamepad_Port_Value
3 k2 l$ R; b4 U* b w7 |" V - LSR A: ^3 a/ z+ T/ u" ~( j& `, p& [! N
- ROL <Gamepad_0_Value
6 }0 \! g) f+ E" Y - LDA $4017
% K8 Q5 B7 w' i1 R7 l - STA <Gamepad_Port_Value
4 T$ H6 x3 _' l4 a - LSR A4 L- R3 J8 v ]" W
- ORA <Gamepad_Port_Value
% @0 V. Q" d# Q7 U/ q/ Y - LSR A7 d u1 g: e9 H4 z% f$ P
- ROL <Gamepad_1_Value
7 i& h, j; Y9 W9 t+ {5 `. n4 r. N X - DEY
6 Y; C: Q! M( z+ N8 e - BNE GamepadPortScan. O5 T/ r1 }( D
- RTS
3 a7 G6 W2 d! G* g0 J4 L -
M; H- w% q0 M1 Y$ C. s - ;==================================================$ Q( a4 j1 L- K- Q: b3 N4 w" M
- ;PPU处理
3 A. I% v& q/ w5 _) M* e! d6 F - PPU_Process
. q4 d- s8 w! j1 Q' A - LDA #$00
. _4 P+ M" v- c/ h$ K" I& x - STA PPU_MASK# m- S% s' W+ ~1 Z. x6 K8 }
- # s' `: y n1 Z5 O$ h
- BIT PPU_STATUS2 j% T5 v+ I% N$ T' i D6 D
- LDA #$20
; O6 V! X- S F H - STA PPU_ADDRESS* x3 s/ ~' X% o5 K7 t
- LDA #$00
5 S3 r" g; ]/ C8 A% j - STA PPU_ADDRESS
3 _4 ^( W+ L4 I, | - 0 |* ]! V( ?$ d3 P, }
- STA PPU_SCROLL
! b1 r8 K& k% a9 L9 { - STA PPU_SCROLL
0 i8 |4 [* A1 \3 l1 F2 g( Y. C - 3 C. e0 S) v7 P2 q- X$ N7 ]
- LDA PPU_Msak_Buf2 ?! X' p* W( u% z7 S& S' Q7 _+ m% o
- STA PPU_MASK5 ?$ H2 ~) t3 z; ^ T
- ; O4 d# H1 p b4 ^; N% ]: Z9 g, Q* x
- RTS8 j$ l. d0 ~+ C& u
- 4 a3 Z+ u: g+ s2 K l2 E+ M0 o0 \
- ;==============================7 f3 b( s7 o# }1 n( k" K; M
- Time_For_Vblank;延时等待
, B$ h3 |/ ?# ? w - LDA PPU_STATUS: t, Q2 c/ Q7 `+ C6 c- X9 J
- BPL Time_For_Vblank
+ g, a5 q3 }9 j/ ] - RTS- X; ^# q- U' L& G( U
-
6 K. G/ c8 ? w* [$ o - ;==============================
1 l. e7 n- ]6 y; z1 }* J - ;初始化MAPPER194 Y3 X+ P" d' x' P$ i l- Q" t
- Init_Mapper19
% h# U6 k+ N9 ?. a- |+ d4 i* w - LDA #$00& I# ~: B+ i8 w2 e! j r. Q7 Y( R
- STA M19_CHR_0000# ?% A' q" Q) X1 l- i- D F
- LDA #$01
3 L" d& g# w+ `# U! d' E - STA M19_CHR_0400' Q! K3 J& P- P1 o* O0 L- |4 ?
- LDA #$022 O1 s) |% o! r# E0 C$ o
- STA M19_CHR_0800
" _7 N0 a7 K& Z0 ^0 L+ \ - LDA #$032 }# x' R" Q; F7 r, k9 c
- STA M19_CHR_0C00: m2 S( _6 ]% O. Q& X* R
- LDA #$04; ~: ?. o6 t1 o, o7 O# Z
- STA M19_CHR_1000
% P( r2 ?. S+ y. k o$ L3 a/ n - LDA #$05# Z5 r* j: B; g# P1 b% c% i3 g
- STA M19_CHR_1400
0 D% t N: F& i# ]* [# l - LDA #$06) d% q- Q/ m5 s; F% u( ]* _8 Q
- STA M19_CHR_1800
( \5 u/ N1 @3 ?' |4 C1 i) a - LDA #$07
: ]0 m# F( P9 A, m - STA M19_CHR_1C00* L+ C+ j r' a8 a, G# [
- 6 k9 Q) K+ b& k% A H5 n# S8 ?6 _
- ;禁用IRQ2 a9 u0 L2 d" V7 c9 C- ?
- LDA M19_IRQ_COUNT_H
6 }9 Q& a; ]/ [ - AND #$7F. P1 G* I* U7 y" }7 J& s
- STA M19_IRQ_COUNT_H& G; I' V0 C, W. d+ ^
- 8 f- r5 n5 R+ R& i; F
- ;命名表
4 k% i( X8 w/ [0 C2 V - LDA #$E0& r0 Q; X3 m% q$ U0 ~7 S3 W! E/ R X
- STA M19_NT_2000% D' q2 v7 o4 V- o5 `7 |; f1 c: N
- STA M19_NT_2400
! }, B: L& k' ^1 T2 j -
8 h, ~" x' l2 P - ;命名表8 Y/ b( m T& p0 p' M) Q- M6 |
- LDA #$E1
& [9 D5 R5 e( m - STA M19_NT_28000 j7 i* U8 c( |5 d! H+ _
- STA M19_NT_2C00, n+ K4 ^& f! C% x6 M/ s! I
- ) `/ i3 X, O8 n) \) @
- RTS6 P B* _7 R( m. }5 J
- n2 w& U- [/ p& k7 Y/ a0 F* S
- ;==================================================4 I- d) m* ]4 ?0 R2 F/ D
- ;重置中断处理9 \( m. z: m( E9 M4 w
- ResetProgram4 U% ?7 G2 e! T3 m4 L
- SEI( {+ {( w, b2 ]8 E8 [
- CLD) r) h! {4 [% O! |4 a) _+ V: V
- LDA #$00
, A6 L1 M* L" W- Z% d - STA PPU_CTRL
2 W) k' k2 w! y3 T% g$ v - STA PPU_MASK V. v$ _' ?9 K* D9 o }
- STA PPU_STATUS& i" Q( p* p; R
- STA JOY2_FRAME9 M) A3 j* i; E( j1 ?0 U
- STA APU_STATUS/ ^2 g, U4 ^# n8 w
- , U' {' e1 @" \8 v9 J2 S
- LDA #$C0
- ]4 K3 `" q# c. _. x - STA JOY2_FRAME C1 P& x: h' y v( g* n
- 6 k1 K6 D' F- F+ O: Z% ]% R
- ;等待vblank
$ W$ L7 b" n2 Y4 r+ O* W - LDX #$02
* G( j$ U y, g- [ - Vblank_Wait_1
3 c2 k2 e# f$ H( ?& d, D J0 ^ - BIT PPU_STATUS
5 h, t5 x/ B7 h; m/ e( T& Z - BPL Vblank_Wait_1
) w" L, T/ n% r) k8 J, O* w - Vblank_Wait_24 M! D5 B( @1 b4 R, Y! h7 t9 r. {
- BIT PPU_STATUS# r! f* p9 j& a8 t9 F
- BMI Vblank_Wait_2
- O' e% @, n, W% t5 W - DEX
$ j4 C7 ]/ Y( b0 `5 F8 q- V' ? - BNE Vblank_Wait_1- l4 S, c) {1 L3 h1 o) W/ }' u3 R) W. c
- 2 `; ~+ w( L6 k( X9 _" I! |
- LDX #$FF
& D/ I9 E% E/ Z& z - TXS3 Y- ~! g, W q
-
& r: ?( C6 e5 u* O8 m! A* R - ;初始化MAPPER198 T9 y4 v+ @' F G* H, Z
- JSR Init_Mapper19
4 N0 L Q9 r! q L: ` ^ -
4 ]% D( l5 w5 R; N6 @3 O- p# \# E - ;==============================; K) F2 o; _+ ^, @7 [
- ;RAM初始化7 ~; o. Z3 U! ]0 X9 x: y, L( }
- Nes_Ram_Init0 |; ]8 t1 T1 ?( o
- LDY #$00) a! z$ D) J! Y# W
- LDX #$08( I. J, {; G. w/ s& m
- LDA #$005 m- P A( a9 K2 K0 C6 S7 k. a4 k* y
- STA <$00/ A0 t7 ?9 D' J, d; y2 L l+ W* r1 T a
- STA <$01
- O: |$ V# |! K - Nes_Ram_Init_Write
; A2 P E3 S I- s - STA [$00],Y
m' A! J `$ C% U! D - INY& f+ m( r/ L0 j' u, o8 e7 ^
- BNE Nes_Ram_Init_Write% o: Z8 E% P- K- p; {. E6 L3 B/ k9 j
- INC <$015 @7 P% U. h" F# r& e
- DEX( L! F. y( B; E# R3 |
- BNE Nes_Ram_Init_Write0 P% N$ ^: C$ X8 q1 K
-
6 W* s5 P! j2 E; O - ;初始化命名表
% H9 G, C; J, k" P! v+ N+ l9 W - JSR Init_Name_Table
( Q4 ~. I& N) N& p -
' s: I5 Y0 K+ K - ;初始化调色板
$ Q" c+ X$ o% S/ Z( ~ - JSR Init_Palette
0 f {$ M {4 `6 p -
* S8 p5 R, _: e9 @+ p) e7 S - ;初始化命名表属性8 _ ?; W. j0 {( _- ^: i& a! w0 c
- JSR Init_NameTable_Attributes; v! Z& |* Y$ g$ D S i
-
" q5 t! H: g& R0 [ - ;初始化精灵内存
* P \4 g5 t8 Y4 w6 i, F( A! p1 p - JSR Init_OAM_Ram' |1 {. R+ q2 J8 N& N0 g$ ~
- $ q% @# v9 B, k; o8 M
- ;在屏幕上写点东西9 V- D: r, D, Z$ V) M& ~9 {
- JSR Init_Name_Table_Text( L! j3 U4 U2 W7 B. d% |3 l5 C
- $ U( q: ?* X5 J, Q. J
- JSR Time_For_Vblank* A7 c5 L0 M1 Y* K' o
- ;开启PPU控制
. e4 E- s( e: | ]( a- c2 M - LDA #$A8* E0 l% B# ~2 {% n# o& g* g
- STA PPU_Ctrl_Buf
$ x6 M2 E n# {$ n; R6 m - STA PPU_CTRL
; {+ h) |* |5 I; o' X: y -
% @& Y/ X) }* E9 Q8 |) B) Y - ;开启PPU显示
5 U4 r6 U. U( w4 p/ d$ | - LDA #$1E8 U1 w0 U" ]! _7 h. {+ U& v( E
- STA PPU_Msak_Buf7 |2 a0 D0 Q# g7 r' z) s2 a
- # j5 n1 n0 W; i7 Y' E6 _2 k
- CLI$ v4 Q+ \: `9 Y) V8 q1 u
- JMP Loop
/ J! K9 j! ]0 F( }4 J - 2 l& l) h( z+ {6 r! S) e' H
- ;==============================" Y, f1 V* i X2 X" c7 A1 d/ S8 K
- ;死循环, 等待NMI中断1 d u9 N* j8 C( s0 r% z
- Loop
- T% X9 W; X+ V7 Q: @ - JMP Loop
$ k: a' F: V E& t3 w+ b" h9 {' F) M
* M4 _5 Q- G5 G$ l! X) _+ z: } B- ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967- S2 N3 q2 O) r$ m* ?
6 E/ ?3 b$ E4 x. n4 u" Y* B- ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)
! o0 F8 j( B! s( M2 ~, c3 D - BEGIN_LINE_CYCLES_START = 32768 - (4103)( |& j M4 y0 V7 d/ ]6 q
- ;==================================================2 V- w* u" K1 ~2 h2 e# X8 z( x& E4 B
- ;NMI中断处理; }0 L# V- M) S' q* h1 J
- NmiProgram
# G. V. M2 x" I0 m; y4 b- u - PHA X" Z. y5 @8 B7 G
- TXA
: ~5 t: C/ r9 {! ~2 W - PHA6 A& O- I* B0 _
- TYA
1 Q7 O0 ]) R; m5 o) |5 Z - PHA9 x8 x5 G; i8 j8 n% w) J0 k
- + g; t# d+ o- j/ k2 o! z
- BIT PPU_STATUS) P7 a' m, y1 Q, r" {; w
- / G$ k1 ~+ `& y4 T$ M- f
- LDA #$00' f) ?# t2 {% W# x% r& U
- STA IRQ_Index4 n+ y5 h9 S2 r
-
! X6 W# S5 X2 p4 d* {. L, I - ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
+ G6 v; ^. p4 ^- T3 i, d( Z - LDA #LOW(BEGIN_LINE_CYCLES_START)) |# k) b: S _ I" j# o5 j
- STA M19_IRQ_COUNT_L% R) k5 ]4 V/ F8 S# v
- LDA #HIGH(BEGIN_LINE_CYCLES_START)
; [# t! w7 h F; s' ]3 i - ORA #$80
7 E1 Z6 t' k+ n - STA M19_IRQ_COUNT_H
: P/ L6 B& e, N* s$ D7 k& S, q0 g - CLI* d! o& ]: d3 p
- 9 v6 ]0 J8 b: ^8 G
- ;关闭PPU控制
& c# `* {' I! ]$ E - LDA #$00" B4 g, ]& U% V& c( a# s3 B$ ?
- STA PPU_CTRL; r: L+ n+ I9 s) ?4 Q# c4 l& x* \
- * X |4 |- f: S+ M$ }2 R% R1 v) D
- ;处理PPU d/ n. [) I: b3 g8 v
- JSR PPU_Process" N/ p0 w0 C9 ?0 \
-
C+ V" K8 [) E: q# ? - ;开启PPU控制
) ~8 Q: E% s) D) h) z3 R1 ? - LDA PPU_Ctrl_Buf
% D4 ]1 P( t5 u M3 V# x4 x6 P4 @" v4 Q - STA PPU_CTRL$ e$ L0 |# |7 v' R1 N" s
- $ _: h `- h: n' a' x- h7 Q9 g
- ;手柄处理
3 s; X# n! ?3 i, D' I - JSR GamepadProcess
4 c8 Q) s! q5 [/ ` -
$ R( a& O9 `3 d, s! Z( d - LDA #$00
, O9 G9 W: m" G5 `; K# k - STA IRQ_Index) M- b! h j6 r- `" Z4 z
- 0 q; y s2 c- l1 B
- PLA0 e; W3 ^8 Z2 e
- TAY/ n l: |! q- J, c X
- PLA% P' U, t# ~5 I
- TAX
- o! P9 W9 n* f) Z/ A - PLA
: p' n0 P- e4 e - RTI
8 H r3 p) s1 ^4 K - - @1 i8 H( H3 Q% U
- ;每行扫描线113.67# s2 i& S/ K" T/ {1 `- J
- ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)
2 L5 a3 N7 K3 [5 V, n) D. } - BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7' e+ \" j/ E& r4 O
- ;==================================================
( ~3 h) m+ o5 E- z9 P" O X - ;IRQ中断处理* |% d' |3 F2 Y; Q+ y' i
- IrqProgram
; O" W; f% {& U/ O; k) Y; F - PHA
4 Y. p' {- c7 G% t' w& t" C3 E - TXA7 c' m6 D+ j& F
- PHA
% Q+ G0 D2 d8 @ - TYA; v- e2 @! W$ P: v% x/ x( b
- PHA6 L3 ~0 s1 @- [( a V( h$ `
-
R- P' H, J) T; y - ;16条扫描线后触发IRQ
9 l) C B% v" ^& u - LDA #LOW(BEGIN_LINE_CYCLES)* Y% ]5 d, {3 u* s# e2 |: `
- STA M19_IRQ_COUNT_L
& Z, w2 \3 A/ o - LDA #HIGH(BEGIN_LINE_CYCLES)* g' _) k4 m# B) D
- ORA #$801 L9 ^, T0 v F1 K9 b% g
- STA M19_IRQ_COUNT_H
3 ~! S- H; m1 x& S( u0 @. E - 4 v$ |8 \/ A5 _. G8 u1 L
- LDA <IRQ_Index# i3 f) k/ h$ x( S5 M) \
- BNE * + 48 S: F( }$ v: z; X+ p" ^
- INC <PPU_Scroll_H
# r$ Y' j6 ?1 s: x -
7 Q* V4 U8 s: s - ;设置屏幕滚动
( R( D) P0 v) } - LDA <IRQ_Index
& Q' P8 Q8 I6 e e& y; _) v - AND #$01
5 I$ ~5 y& b$ B3 A/ H - BEQ Irq_Scroll_Right
* h5 S$ Q4 x2 O4 S. x
6 E" M2 ?) \+ X4 C- W0 R. u+ O9 B- Irq_Scroll_Left
; V# y* {' j8 ]8 F: {7 E, z7 f - BIT PPU_STATUS
. H9 t3 u' K$ e* G$ v2 C! v9 x - LDA <PPU_Scroll_H& D- A, {% Z( G- g# O8 {
- STA PPU_SCROLL" Q( X9 a y) C' S- E
- STA PPU_SCROLL- e6 W/ O2 o! A; h' l
- JMP Irq_Scroll_Over$ {5 Z) a, j. R2 d
- * M6 q# L o2 d" V
- Irq_Scroll_Right+ o* k$ F- }% c! e# \" f! q/ Z
- SEC5 B7 ?; w! z% l+ ]4 Z
- SBC <PPU_Scroll_H
" Y: R0 Q( A" ~# @3 C - STA PPU_SCROLL6 H+ f% k) ~. v* A! \- p
- STA PPU_SCROLL
. k/ \* m- b% C6 V8 K& l - Irq_Scroll_Over+ N! ?$ F% u1 a; g
-
6 ~- q3 q6 x, _& |' j- E' z# c - INC <IRQ_Index5 \- B( v( p- D4 A& X9 \ U Y
-
' N0 T& ]: p& C6 T6 w7 J - LDA <IRQ_Index" l: o* |- n1 t, B
- CMP #14
8 ` j3 j. Q3 w - BCC * + 10& X; E: h) c2 j# j
- LDA #$00
4 D% P3 h8 e( _7 u& z T! y1 ~) i - STA M19_IRQ_COUNT_L& a3 @! @" g9 q
- STA M19_IRQ_COUNT_H: U2 w. c, ~/ ` `. ?# q( X$ V9 e f* e
- + N) N: m, m( H# U+ {
- IrqProgramEnd$ D3 o7 I* A+ [3 A1 T
- PLA) @ Y' F! M; D! c% o: ]
- TAY
, {: k+ F8 E& U, [( A9 n - PLA j% Q, e8 Z9 r: A0 |6 Y9 o
- TAX
0 L8 q/ v! k8 X$ B& H8 x% S - PLA
4 L6 c" q( `/ Y9 D4 Z4 u2 u - RTI
: c) M8 R4 s6 ` i0 u - 0 d5 e) g/ u5 D, E( h: O4 S$ s
- ;==================================================
3 r7 V e7 F, b1 }. b - ;中断表 Z! m0 E: |, ^) x1 f9 k0 o7 P
- .ORG $FFFA2 Z! g1 |* n; @
- .WORD NmiProgram
+ ^& O# V" \- v; Y - .WORD ResetProgram
( z! {% S" {" r5 p3 {1 ]. r* x. ? - .WORD IrqProgram
复制代码 1 h, h' X* r; K6 h7 M
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|