|
- ;[FC][Mapper19 IRQ]2 [4 ?8 p* U6 ^, z0 h& P8 K5 v
- ;FlameCyclone 20230710
. b( U8 _/ u7 k: q - / @# b, Z, a" e
- ;文件头3 G u- @* k- m2 N, ]; s9 H$ ~0 e
- ;======================================================================+ {! D6 l" B' O2 {7 h; C
- .INESPRG 4 ;16KB PRG 数量
! o' O' z& z6 P6 J4 B - .INESCHR 1 ;8KB CHR 数量
* ?# R% R. T, V& o - .INESMAP 19 ;mapper 197 E V# U2 Z2 W+ M1 J+ N
- .INESMIR 1 ;命名表镜像 0水平 1垂直
: ^' \6 ]" c2 z! I0 W, k - a: b S: c. j# `0 c" b# z4 F! H
- ;必要条件! i8 Z; E2 G9 p: e3 |% b1 k/ L
- ;1.持有CHR ROM
) {4 f+ Z3 | e" r# P0 x& p, @ - ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
) D7 i4 h; m' @# @8 ^; w A$ v/ | - ;3.精灵内存(OAM)不为空
' X5 b3 ]! e2 z4 O* s) p! u - : @. z3 p6 ^8 }% Y& T- i( L
- ;==================================================4 L" }& n# l6 f! M$ q% P
- ;NES端口常量/ p) `0 |, F4 `" g0 k2 @
- PPU_CTRL = $2000 ;PPU控制寄存器
2 ~$ R. g% Z: ]; f S' G - PPU_MASK = $2001 ;PPU掩码寄存器
X0 G' f. g9 h$ B2 S m - PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位" t8 G4 l' `. t8 z! d
- PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1- H: F3 n- L% P+ k5 M
- PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
5 @& S; i6 d& h6 w+ _9 G - PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 8 v" a' [7 D: v5 o! e9 R
- PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加# |* _! ^( r* w" }0 ^- T8 ~( o" q1 E
- PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
2 q( F9 W" A( z, p0 u7 I2 t4 e8 n, L - OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存/ z: Q8 m. F& x7 n
- APU_STATUS = $4015 ;声音通道切换
7 e. S1 u4 R H. v0 k& @+ ]; f) }$ [ - JOY1_FRAME = $4016 ;手柄1 + 选通
% f/ x+ f- Q" L1 o - JOY2_FRAME = $4017 ;手柄2 + 选通
1 j" Y O, }/ D - ) ?5 x# J. X6 O9 X" P9 S9 g
- ;==================================================
; [# K% S, w3 W: o( K6 H! W" G( O l - ;MAPPER 19端口常量
1 ^) N. w5 h$ t2 }% S - M19_CHR_0000 = $8000
9 ~: F) ?4 l- ]- H' O - M19_CHR_0400 = $8800; b m' I8 C" E/ G
- M19_CHR_0800 = $9000
7 b- l: A, C) n - M19_CHR_0C00 = $98007 m7 _- g- [, _1 z& @* e
- M19_CHR_1000 = $A000
$ M. X8 }# q- K8 v1 |, N1 l - M19_CHR_1400 = $A800) K) {) K; {; v* m( B# m- U
- M19_CHR_1800 = $B000
9 [! N1 q e& K! G - M19_CHR_1C00 = $B800! i6 t' l7 z. N& D/ t* |) |0 \
- M19_NT_2000 = $C000
- a6 t6 ~1 \" {' b6 v6 @ - M19_NT_2400 = $C800
+ q; A3 b5 P$ q - M19_NT_2800 = $D000# L' W2 D; n O$ F* e
- M19_NT_2C00 = $D800
) j1 {7 ^" p& l- d- U - M19_PRG_8000 = $E000# @8 V6 z" [ l5 Y+ M. I3 e
- M19_PRG_A000 = $E800# `! e2 c, P! g" n. q
- M19_PRG_C000 = $F000
/ n- _3 ~: q: D) C% Z, _7 |2 d( X - M19_IRQ_COUNT_L = $50003 t& M0 P7 j4 j( F: p/ |2 r0 Q) j
- M19_IRQ_COUNT_H = $5800
% q. ^ w, [9 T- a7 ?7 P. } - & b9 N, m- M0 s) c* `# @) k0 J1 A
- ;==================================================
' `& q. U8 o# I' f4 E' v - ;程序块配置% `& d: l m7 a5 L, y
- BANK_DATA_MASK = $079 F8 a9 X0 ~ v9 `
- ;--------------------------------------------------: L# O* Q7 F7 a8 H$ S, m& b* @
- RESET_BANK = $07: k! N( d) b* v$ Y8 _3 A( z
- RESET_ADDR = $FC00
! c: l) G8 e! ?% ?& n$ ^0 | - % T, c d6 h# v* J3 t: u; }) f
- ;==================================================7 T) c' Q& o1 V
- ;图像块配置9 O2 Z# a: E! g9 L" G
- CHR_DATA_BANK = $08" [( N* c; J! ?# P( k
' T7 L' Q% p- a+ J8 S$ P- ;==================================================
% B, u& \; s: s/ `8 M+ O& o/ F - ;零页内存地址配置
1 \: `" f( u5 ?1 y$ M [, j3 t S - Use_Ram_Addr = $80
6 a5 z- I: R4 Z - PPU_Ctrl_Buf = Use_Ram_Addr0 B; m) j3 f b* u
- PPU_Msak_Buf = PPU_Ctrl_Buf + $01
: L9 }* e2 _1 Q2 [; `. ? - PPU_Scroll_H = PPU_Msak_Buf + $01 ^. w8 @& D4 s* R
- PPU_Scroll_V = PPU_Scroll_H + $01
7 F7 ~) m8 `( `6 I - FC_Data_L = PPU_Scroll_V + $01$ G5 }8 U, Z+ S, ?
- FC_Data_H = FC_Data_L + $01! ~7 W: N6 K; o7 g! a5 m
- FC_Data_Buf = FC_Data_H + $01
5 r @$ C# p q' X5 }, K' i. T" _ - ;==================================================
# H- j& e2 e9 N/ P. m
) {8 l; o: Z8 f# H- GAMEPAD_MERGE_FLAG = $04$ x& _/ n/ h) R* c3 P6 N3 `
0 j( U8 K, b t- Gamepad_Keep = FC_Data_Buf + 1" `* @$ }, n( C1 P7 K
- Gamepad_Once = Gamepad_Keep + 2
5 f4 l: o h2 a. s/ R - Gamepad_Temp = Gamepad_Once + 2
: t( N( e3 `# v4 ~ - 5 q5 S: q2 ~: ~2 l" T4 K' I9 h
- Gamepad_0_State = Gamepad_Temp + 2: B; w B2 e/ @. n4 M. j
- Gamepad_1_State = Gamepad_0_State + 1( g" I5 d2 X- {% u5 K
- Gamepad_0_Value = Gamepad_1_State + 19 x8 t9 o4 M' |5 `1 t
- Gamepad_1_Value = Gamepad_0_Value + 1
/ U3 v$ Z7 X3 U: E% F - Gamepad_Port_Value = Gamepad_1_Value + 1
) S* G$ n) P, J$ T - Gamepad_Merge = Gamepad_Port_Value + 12 p- E& p0 ^7 K4 y6 _
/ E0 @5 a+ N- P0 h! v3 Y- ;==================================================
, n- W, X; _' s) ^" f5 A5 i - IRQ_Index = Gamepad_Merge + $01. Q4 u) m" c8 o5 o- c
- ;==================================================% p) d m) i1 ?6 a8 M
- 3 _/ H }3 p8 Q, Y! t
- ;CHR图形数据
' D1 p' I! v/ a* u2 e - ;==================================================
( A! L; Z3 N) z e* U - .BANK CHR_DATA_BANK
; a6 z% ?1 r( @7 Y3 y - .INCBIN "chr_bank/chr_data.chr"
$ e$ d9 p( ^% N8 D - + V+ i% Q7 J( s6 b2 T
- .BANK RESET_BANK & BANK_DATA_MASK! d0 T r. Y+ I4 B& K
- .ORG RESET_ADDR
8 u5 K/ x7 Z% r( N; W# ^ - 8 w: s; `6 G+ D- \6 U0 b
- ;--------------------------------------------------% S8 g" y1 }0 E$ ~6 o+ ^# W
- Attributes_Data* i. V& p1 r& T3 t
- ;命名表属性
* r/ [- a2 b, w' M# d5 s" F" ? - .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
% c# x& ^: H2 E/ x5 { - .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
$ u. J( n z4 z- ^: Y - .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA: _- ?7 p1 Q$ M8 _
- .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$550 ^5 L& k/ a( U; [/ @9 C4 I
- ;--------------------------------------------------( u8 j3 w' ]8 k' E( I
- ;调色板数据
/ B5 M* t5 F: f5 }* i5 [ - Palette_Data @ `, l2 y( @6 |
- .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
1 [3 {' G @: o9 D* I1 c - .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
. m* ?% M$ B9 c
7 K$ d/ G6 g3 f ]4 Q- ;==================================================
5 O5 a8 {9 W9 }4 ^, w9 d/ f - ;命名表初始化) P5 o9 ` o e) h3 P. I
- Init_Name_Table
8 N4 I7 R8 i4 u8 E! {# J - LDA #$20
4 S! d0 e; r; s( x* Y - STA PPU_ADDRESS( @3 f6 q2 `- ?+ Z
- LDA #$00
3 J, t! N' f3 o2 r( I7 O - STA PPU_ADDRESS
" u; H5 r4 ?% m; r - LDA #$00
: t- F% @2 Q- Q - LDY #$00! H/ ~6 |4 d- w$ Y, g7 f* z
- LDX #$102 [0 p. `" {% ?5 C9 r
- Init_Name_Table_Write3 P9 p* L9 a W4 ~+ _4 Q
- STA PPU_DATA. ]- L J2 E# |+ @" a- \
- INY/ C0 s- q% F8 u, \% U! n
- BNE Init_Name_Table_Write
' A; U ?: y2 j6 b3 N - DEX
9 |( i( {# E7 @! d4 ?& i+ i( _ - BNE Init_Name_Table_Write2 b p+ d' ?9 Z
- RTS) O, R# u" B, P
- $ R: }7 ~- s& K& c2 X7 _/ C
- ;==================================================0 x9 a' T& d( S1 y/ u5 I
- ;调色板初始化( r( d; e: Z4 S( {. r7 p
- Init_Palette: ~# ^9 q6 v3 Y2 z/ p" j! B
- BIT PPU_STATUS
, W7 J" F$ _2 j. x0 C9 R - LDA #$3F
) t' H( M1 ~+ S: a3 V - STA PPU_ADDRESS
$ `% y2 l, F4 ~4 E* Q - LDA #$00
# j1 c" N G' ] - STA PPU_ADDRESS
- `1 [' ^: O1 c% x2 x# _1 j( { - LDX #$00* S% r5 j; v# Z8 O8 U
- Init_Palette_Write
; C \( F: Y/ M: o% x - LDA Palette_Data,X
+ e- J; L `( j, ^& @" w - STA PPU_DATA
2 M+ M' t; E/ P/ m - INX1 ^& X4 y; Z$ N. d( M6 x: [
- CPX #$20. n: T1 e0 K% H. P
- BCC Init_Palette_Write
2 N! t( ?, q2 t* F6 r - RTS
! p( F' q- I( t _+ L' ] - 9 a( v K3 n! Q0 i0 W0 }- O. P8 _
- ;==================================================
) u! @9 W( v1 g# L( j( g2 h - ;设置命名表属性
6 l z" D- E H: t2 r - Init_NameTable_Attributes. ~; Z! f2 E- v( u
- BIT PPU_STATUS
1 {7 N" I7 s4 p% X6 L# @7 R - LDA #$23
; H& q) C4 m, q1 d+ g/ z; z - STA PPU_ADDRESS9 `5 e2 B2 L: i3 c/ f) v& r$ ~4 ]. Z& P
- LDA #$C0
$ j; T7 i5 x- f ]* ?! r& E - STA PPU_ADDRESS. h2 ~$ ]' B K- G* H8 `' C* C
- LDX #$00
& i1 k5 H4 ^$ ?5 g" f) r - Init_NameTable_Attributes_Write0 \) U$ z: t% Q! C( M
- LDA Attributes_Data,X
1 \% n4 v' I0 o% o. _. H - STA PPU_DATA
$ y r- L# e. Q- |+ i$ I F5 p - INX5 K. [; w2 H. t5 x
- CPX #$407 \1 H7 _# @& k
- BCC Init_NameTable_Attributes_Write4 K+ e3 N' V+ V2 j! u
- RTS
/ c8 Y* l; L# _4 o D
- x. B$ V5 _) f& z& K( Z5 Z- ;==================================================+ d! q3 s; y! W: K# U$ `5 C
- ;初始化命名表文本 f0 G' O6 z/ y% b W- r* u! K5 c
- Init_Name_Table_Text
2 S# e7 S3 _$ `% b - BIT PPU_STATUS
8 p, C, K: U* `8 p5 A5 t* f' a - LDA #$203 W8 j2 S2 u3 y; J! e3 Y9 G2 Y
- STA PPU_ADDRESS
- C E" M$ N7 V2 c- {' r) H - LDA #$00
. M- R4 K0 z5 X- {. B - STA PPU_ADDRESS
' F7 I" W9 U0 B+ W9 p( Q - LDA #$00' I( x2 B. J- m" p5 E
- STA FC_Data_Buf$ B/ E' N7 {0 `
- LDY #30
+ b1 p$ y1 l M, a - Init_Name_Table_Text_Write, x5 ~; x5 H- D$ @6 n
- LDX #32
! \3 |% G8 D2 V0 V6 e A2 o5 ? - Init_Name_Table_Text_Write_Char
" p* Z! {* Y) s - LDA #'0'3 M+ U5 a! o; r4 |9 U( ?
- CLC. G, ]$ S! o6 u+ A* W! `
- ADC FC_Data_Buf2 t" ]$ u. W8 v
- STA PPU_DATA
4 p+ {- f. d/ ~. g - DEX
# n2 n2 T/ k- w% _' i/ s- ~' r - LDA #$14+ Z3 n. _: |: \) l2 E
- STA PPU_DATA4 d4 m2 `# B4 c5 L2 p2 s
- DEX; Y6 b, p0 n4 r ]+ @
- BNE Init_Name_Table_Text_Write_Char
5 N0 h1 n* ?7 W- Y/ g: f - INC FC_Data_Buf, P) h+ z% N ?" A: Z" l9 M
- DEY
& W1 t2 X5 T" u$ S - BNE Init_Name_Table_Text_Write# Y$ ~' `+ Z: _# P, ]8 C
- RTS7 e4 B7 t: u3 P7 ^
' r- G& e) d$ m/ t# ?2 ]- ;==============================
9 C2 s( b2 n1 T( _6 e' U - Init_OAM_Ram;初始化精灵内存: T% ? a7 n X
- LDX #$00
- ~% }" |, q# A; N) h7 i L - LDA #$00( m5 H" o. M2 G8 m N4 x
- STA PPU_OAM_ADDR
8 r3 L4 B; a" M; h" ] - LDA #$F8
{2 v6 I. }$ c6 `! w% F$ x7 H - Init_OAM_Ram_Write
) Q: I, @+ z# S9 K - STA PPU_OAM_DATA$ l( t% e* e- {9 O9 K# V$ V
- INX6 x% o% u7 j$ E5 N: q
- BNE Init_OAM_Ram_Write
v1 s- K2 ]2 F - RTS
6 m2 X6 v, d8 n7 j) G6 f7 e& {" c -
9 s4 D$ v; t8 @/ h - GamepadProcess;手柄处理
2 f$ ?7 r g5 M; F. p9 w - JSR GamepadDatacan |5 e. R7 N( U( R( p4 a
- LDA <Gamepad_0_Value Q( |# v+ Z5 a* W
- STA <Gamepad_0_State7 B( e) A( T( P W4 W
- LDA <Gamepad_1_Value: l F& ~$ W; Q& w; B% e
- STA <Gamepad_1_State, E/ v' d" H( _
- JSR GamepadDatacan- W9 B( G! G# f! @) t
- LDX #$01+ t3 r. }, M. g* K% n4 Q2 T1 L; Z
- GamepadMergeCheck;合并手柄输入检查
$ W' @$ ?; c" T. G/ ` - LDA <Gamepad_0_Value,X
% c, a" t; Q* R3 w - CMP <Gamepad_0_State,X
" z4 M- E5 a: T - BEQ GamepadMergeInput
2 |% P `" ?- q$ n0 E8 H - LDA <Gamepad_Temp,X, }" S7 K$ ?) Z+ m+ p
- STA <Gamepad_0_Value,X( ~4 m9 \" S- e$ C
- GamepadMergeInput;合并手柄输入- Y9 M: t, \( ~/ q3 W( p9 J
- DEX" a0 I; J9 x% p B" M7 c
- BPL GamepadMergeCheck
; o3 n8 q! B9 `& O% h - LDA <Gamepad_Merge# Y) ^, b* H7 ]* ?
- AND #GAMEPAD_MERGE_FLAG2 Z: F4 y$ I# D" h
- BNE GamepadStateProcess
) v- i( z; l) t* f5 `, ~& N2 N - LDA <Gamepad_0_Value" Z8 H* L; ^3 B6 m1 K
- ORA <Gamepad_1_Value
7 T2 C/ n3 e" D! } - STA <Gamepad_0_Value
9 R- J1 C5 l* r* G7 P" l2 I - GamepadStateProcess;手柄状态处理
$ G0 h/ S2 m0 [' ]8 q! l+ O; e* D - LDX #$01+ v( y" q! n' k! x w
- GamepadStateSave;手柄状态保存
8 u3 i3 |* ?( K9 W6 B: J - LDA <Gamepad_0_Value,X
: I- s- n% W$ `# R8 Y! w) U5 j# s - TAY1 Q! s, X4 M6 N S5 [; W5 V# q
- EOR <Gamepad_Temp,X
& Z5 B/ E! B; i* D - AND <Gamepad_0_Value,X
. ?- Q' @0 G; C - STA <Gamepad_Once,X: w* k' {* }0 ~- x7 s
- STY <Gamepad_Keep,X
* x M5 A0 p, m% D1 j" k - STY <Gamepad_Temp,X2 y% _/ O, K; B: e" K" v" p1 r
- DEX
% a" j4 R; ^; c+ D" e3 g - BPL GamepadStateSave
4 H9 B% x" ~5 O- `1 l - RTS. T" ] `8 V) H0 X1 n
/ _% O& F% l# Y0 O- GamepadDatacan;手柄数据扫描# B' o! n1 s, F D0 _
- LDX #$01
# d' _% o' H5 D0 Q3 J* D# R( f' P - STX $4016# ]. U( W' L2 u+ P4 h5 }* s
- DEX7 H* h; S: {) @
- STX $4016
9 J+ s$ `" M* \& V. P - LDY #$08* n0 G! U6 Y. F
- GamepadPortScan;手柄端口扫描+ l3 X' B# _$ k2 Z5 E$ T/ I2 V) k
- LDA $4016: L1 {. B4 R$ i; j' h- r
- STA <Gamepad_Port_Value
5 O- I$ x! G* X) T2 x3 J9 _7 R: c - LSR A
' o2 e! d, A; U6 O - ORA <Gamepad_Port_Value8 v+ U8 i+ e) u! r2 |8 F8 g
- LSR A
* |9 Z4 F' S) K- X% ^9 B/ e7 ^ - ROL <Gamepad_0_Value' O7 _' R" R6 ]2 q
- LDA $4017 E1 R4 R( M# s5 o" l8 M
- STA <Gamepad_Port_Value2 D/ t$ F! K- j; \; n$ @
- LSR A
! U( _% k9 S, ^3 |5 G - ORA <Gamepad_Port_Value
( K' E5 U: g. H5 P) y" K - LSR A
1 [3 X$ ~9 Z! k - ROL <Gamepad_1_Value
* j/ m' w$ Z2 [; h( T - DEY7 _5 Y4 S9 \0 O% I
- BNE GamepadPortScan$ T8 N/ U/ h6 ~. V4 C. X
- RTS
4 n' D% ] c: _9 Q1 ` -
9 C) a T5 _- @+ R: {4 _, p' ~ - ;==================================================
7 d% f' u b) t. g - ;PPU处理
/ u' Y8 E1 m+ P9 `% w. } - PPU_Process
# G2 M/ S5 ]0 F; O% p - LDA #$00
/ f2 q7 C# f9 m; c1 Z" U! K - STA PPU_MASK
9 l Y2 z& f* ^6 D( V2 c* V -
$ m. |' z" v" O9 A# h" L - BIT PPU_STATUS8 Z4 r' C/ D& s% h4 ^2 H
- LDA #$20
$ T" G/ Q+ c# v! {/ {1 B - STA PPU_ADDRESS' \# z% j- P) ~; y! m3 ^
- LDA #$00
7 [+ p! v% Y4 D5 H, L5 E - STA PPU_ADDRESS% u) K$ {$ V9 H5 P4 {, Y
-
& Q( l9 N- W8 |% i$ e - STA PPU_SCROLL4 y$ ]! o* c2 ]% k) h) U( [6 H
- STA PPU_SCROLL
4 {& I! ~* g2 a3 V% l4 S$ r - . S- a' R8 Y H3 M6 h8 `
- LDA PPU_Msak_Buf2 g2 c! \& D9 N$ y% `* h( P) x
- STA PPU_MASK
3 G" B3 x# D4 ?2 N3 ^7 F7 k' N- S
2 `& d% d; x8 I- RTS
. e5 o) F) O Y4 N1 R0 N - 1 F, k0 c9 }6 r+ P3 U2 ^9 E
- ;==============================' @% s# {* Z8 w% Z9 `) h9 M
- Time_For_Vblank;延时等待
2 V1 g! ]5 J& ]" C" B- [9 G - LDA PPU_STATUS. s; r- G6 ?! Z6 V s
- BPL Time_For_Vblank
' b5 E% J0 H& C/ ~) j - RTS& t/ {+ g7 x4 \. `9 I
- ' u, z! E" s2 m. s7 ^. d% Y i9 E
- ;==============================5 X3 @' S0 f6 D8 P3 l# B( j
- ;初始化MAPPER192 I8 F3 {3 ?. `* N" S) r D: Y7 q
- Init_Mapper19
( A- w | A/ y; C - LDA #$00
) U% g6 g) {( G% K6 t+ g! J! G - STA M19_CHR_00005 X& h# U" J+ H
- LDA #$01
; C2 b( u' @6 E/ M3 @. Z/ I4 V - STA M19_CHR_04003 r+ q3 l6 K; M5 o3 ^8 \8 O# ~8 y
- LDA #$02% J0 |8 Q& d" W1 U0 }
- STA M19_CHR_0800
" T% h+ _. ?! M. Q+ s" X - LDA #$03
: K4 g: c2 z! f - STA M19_CHR_0C008 _2 P- ~' r7 f& e1 m" b6 \
- LDA #$04
# v+ R& |1 R& H' k - STA M19_CHR_10001 f: t- X# J: f
- LDA #$05
: Y; G1 s' B- P7 C' L6 j! Q - STA M19_CHR_14008 ]0 P! g: N V1 Q, o8 _
- LDA #$06
! F" L6 M3 F9 ^* P. } - STA M19_CHR_1800
2 \$ T( m, e- @) p/ M, a - LDA #$07$ v% U- v8 Y: p5 y' S; v
- STA M19_CHR_1C00
4 Z0 m1 g/ X: G+ e/ w- u - 9 `/ W( M5 C) ?/ E* [9 P. F$ n
- ;禁用IRQ1 G; \8 V$ D% t. {2 H
- LDA M19_IRQ_COUNT_H
0 o$ C% g4 _( Q6 ?: k+ { i# n - AND #$7F [/ x6 l/ q$ q5 B3 @8 M: @' H
- STA M19_IRQ_COUNT_H4 N" m) R$ U( E
- ) o0 J4 c) a: H4 x( F+ T; ?
- ;命名表
1 t6 b3 h5 I& T8 c# x7 g) {/ J - LDA #$E01 X1 }3 S( p5 s$ n \0 b
- STA M19_NT_2000
% t4 ^, [; _. Z - STA M19_NT_2400% E! V- i' ?' n' S0 a: Z& E
-
0 B8 a5 D6 ^# G3 d; Y6 H - ;命名表6 t4 b2 {: v: p. ~
- LDA #$E1
* B" Q$ }6 y& ] V: J - STA M19_NT_2800
# O( ]9 h6 O0 m) N3 _+ u }# N - STA M19_NT_2C008 I2 G# t. F" h0 j
- & J& T2 B- I- I& v) _. w; c2 D
- RTS
3 f# `5 D/ a7 ~5 C; G: R& e' k7 z -
# R: i1 E8 Y) m, f4 @ - ;================================================== r7 D# Q9 | y% C8 \7 @/ O. N
- ;重置中断处理/ E9 Y- L8 {( Z( X( w1 `. b
- ResetProgram
# w$ O& m8 [" V w- ?% g, t' m. W - SEI0 X7 X& h* {4 H& _
- CLD6 {& y' g( E5 j9 A+ X3 A
- LDA #$00
: d0 `8 c1 T% P8 y - STA PPU_CTRL+ f4 v/ J3 u; H: _
- STA PPU_MASK R4 e" Y/ l8 C
- STA PPU_STATUS
9 t9 |+ W ]7 H# g - STA JOY2_FRAME
9 [- u2 D0 Y6 ]" Y7 [ - STA APU_STATUS6 C! @1 ]8 u, J
-
/ m! i, {/ v* I" j) m) W - LDA #$C0/ _. S' s, e( h9 p
- STA JOY2_FRAME ]: U' N; |5 L" a; b2 \: @' B+ Q
-
% O1 @3 j$ Y. t3 i - ;等待vblank
- V! D, J4 G8 e1 S: c- h - LDX #$02
7 t5 w- I# U5 D+ u7 T1 G7 S- v - Vblank_Wait_1( W) _5 V7 E( C+ C6 I( J
- BIT PPU_STATUS* U( k7 j% x: m9 b: ?. {3 S1 z, @! Y
- BPL Vblank_Wait_1
1 U' K, f3 R4 G8 h5 ?) f0 b. J2 r - Vblank_Wait_23 k& d \8 e7 F
- BIT PPU_STATUS
! ]$ M1 e6 \+ m5 `6 \$ L - BMI Vblank_Wait_2, o6 I9 O7 C/ l! A# b0 i
- DEX
+ ]* e% O4 e- e- G2 g - BNE Vblank_Wait_1: u e+ t1 K* L' z2 @
-
: b1 ^# g! y2 p) |1 w - LDX #$FF
5 e J% V& e1 V) e. c7 ] m1 c - TXS
5 q* a. D: ^. v- P% e4 D -
9 [4 l. Z f% ^& c - ;初始化MAPPER19 p& x# k# D# w0 m$ ?6 j6 s6 Z
- JSR Init_Mapper19
- W! {8 \' {6 H4 z3 K7 E. r - $ m: r8 Z. t5 m4 t# i: S
- ;==============================
/ y# _ x; _/ E: t6 R- |5 ` - ;RAM初始化$ T) H) a, `0 b
- Nes_Ram_Init
6 E, _% h) X& g. t8 Y9 V - LDY #$00$ G2 e5 S; H+ l
- LDX #$08
4 |" o$ m3 s) U" T0 ] - LDA #$00
& B( {- H0 J% S( R) \+ x - STA <$00
# w9 ?* p% H) o - STA <$016 u* _( b7 G/ K$ ~) g, H
- Nes_Ram_Init_Write
) }" Y9 V7 o) c) w/ n& v* h - STA [$00],Y- ^) q5 L, Y# W8 ~* Q- l
- INY
5 o8 [- A! j9 K6 S& x5 d) ^ - BNE Nes_Ram_Init_Write$ d: s+ [5 \! \9 e7 Q
- INC <$01+ ?+ Y4 J, x' y3 j' i6 X& P
- DEX0 D3 \8 e& }3 E* O
- BNE Nes_Ram_Init_Write
0 r8 y6 d/ _$ ~4 t( X& W/ x: L -
7 A2 W6 b% W# c$ X) a* q0 W' Z - ;初始化命名表1 C u' f/ a; H4 h
- JSR Init_Name_Table
, h! P; w ]4 r - ( D# `' _6 ]" u# E' H
- ;初始化调色板
3 G8 j) ?, A1 J* c% B# ?) V - JSR Init_Palette
# z7 ?3 r2 ^& `* ~, ]$ g -
! o, \; q f. \# y y - ;初始化命名表属性
H) g. o3 L: p' K0 h Z - JSR Init_NameTable_Attributes# P& W1 @* a; }# d
-
" ?7 z5 i. T4 ^- f9 z - ;初始化精灵内存4 ?! _( I5 w3 m# o$ g: s& L
- JSR Init_OAM_Ram8 V% A5 N0 p7 w% w
- ! Q4 T' X% _' S0 V; g
- ;在屏幕上写点东西
/ L1 R8 ~( i/ G9 _: d: @ - JSR Init_Name_Table_Text
/ n, m1 C! }4 j6 f- A4 r0 O - 8 t( h/ ]9 o- N8 H" d+ Y
- JSR Time_For_Vblank* P. y( t: E+ v: V: O
- ;开启PPU控制
4 l* m: A8 |% a - LDA #$A81 V9 m* e. q k$ F8 h8 P; B
- STA PPU_Ctrl_Buf
* f$ N8 h3 A6 F- W2 O7 Q - STA PPU_CTRL
9 [& n- w, S0 M+ W1 B/ H9 N! h. ~ - ) v! f$ W: c N& e% V" a2 r3 b
- ;开启PPU显示' o& t; n+ l" v/ k8 p8 B* w
- LDA #$1E
* |! q: F$ m% C+ o* p - STA PPU_Msak_Buf
X& d5 ~ b% O - 3 R9 V9 b) n. S7 Q( [
- CLI
* A- ]3 g( g9 z' Q& V - JMP Loop* |! b$ K4 Y" y. g/ K
- ' F9 W' _- _, b& Z- N8 K
- ;==============================
6 \7 e- X6 }! r! i; b6 m4 a - ;死循环, 等待NMI中断
: ~. R4 e; V; `6 y+ ]/ E9 S% e - Loop
6 m+ D+ s$ ? W# u" @ - JMP Loop. ~( Y3 V' I, y6 C0 Q& p; T
- ) O+ m6 R/ G2 v" K
- ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967 r, ^1 W; e: n: L
- 8 x0 @) ? o' ^0 X' N
- ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)3 `9 C8 Z W% O3 p5 B
- BEGIN_LINE_CYCLES_START = 32768 - (4103)
, }2 e, M" p0 M: D - ;==================================================) G7 H; _. {1 n3 S, G: H* A
- ;NMI中断处理
b1 |! \* [" W - NmiProgram
: W$ f, `/ p) y- j - PHA0 y M7 i4 |/ ?/ x
- TXA& Y4 k+ }& \( o5 o
- PHA7 R! O" h! {1 Y5 Z7 I9 Y2 L
- TYA$ E) [* v6 @ E
- PHA
$ @1 s6 s% ~! p - ( I" A9 M y- P% w4 _& ~
- BIT PPU_STATUS) |/ a {* x8 v' v7 I' P
- / p7 K) E7 U& }/ r. g' V5 J$ l
- LDA #$00
( q2 G! S9 e ?: O7 l1 \+ p - STA IRQ_Index
) F, y3 X" U R2 R -
+ x4 E6 t' e1 k6 i! g - ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动! p' k8 G$ [' a, P. f; R2 {
- LDA #LOW(BEGIN_LINE_CYCLES_START)# C' k6 u0 i- N4 @, R9 Q& H5 p. X' `
- STA M19_IRQ_COUNT_L- |! A- o" a* h
- LDA #HIGH(BEGIN_LINE_CYCLES_START)
`' U0 f8 J6 w+ f! j - ORA #$80
3 N, r, H% J9 x" f - STA M19_IRQ_COUNT_H. M2 |0 H2 u& m% {+ l8 H9 E5 E. B
- CLI
, G8 ?; t3 `+ K, q( X4 Y - ; a X9 a8 x+ X/ d6 Y( m& K P
- ;关闭PPU控制
9 R" M2 B- v6 R( C3 d - LDA #$00) Q# q! P2 L- _$ K, B$ y
- STA PPU_CTRL" Y8 ~( h/ n; C
- . v% G2 {" u. C a" X, f2 `7 s
- ;处理PPU
% Z! Q$ f# P$ m" v5 M4 M( r - JSR PPU_Process' u$ E$ V3 t H
- " p" ]/ M9 Z. S ^% @
- ;开启PPU控制. H- t y8 Z# I. n9 \- s
- LDA PPU_Ctrl_Buf0 y" m: C" l' A4 o" V4 W
- STA PPU_CTRL4 i. Y I, M! Z# t
- 7 G" `9 O3 M. s% n
- ;手柄处理( r, m0 M( w7 r6 h4 A5 ~; Q
- JSR GamepadProcess3 ` D' s% o. y' Z8 x- X& Q1 w
-
/ O! z& E* M$ e3 { U# R - LDA #$00
* i, ` J& R* P - STA IRQ_Index
9 {+ i' @4 o! Z: E6 i1 h2 o -
- M7 M; t6 l, p) i: ~& L - PLA( l/ g+ ?% a, Y) W1 _8 L
- TAY
. Y R9 p2 Z$ |$ z - PLA7 j0 H5 D; W0 N5 d: V: a, c
- TAX. Q k" W4 z4 X& Y2 g0 d
- PLA
% \" g. F7 h0 Y - RTI* p4 |% u- t/ M( z9 z. t8 w
: j7 o; u* l4 I8 k- ;每行扫描线113.67
: M# r! j1 @: ?7 p - ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)
& x& ^( T6 b, c - BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 71 U9 t. r+ E& S5 s0 ^2 M) k# ?
- ;==================================================
( Z" A/ N" b8 u0 g6 n6 e - ;IRQ中断处理8 ~. `1 V: W- b# b9 {: J
- IrqProgram
* m x+ \% h- Z* U - PHA
1 A+ f& D; X# V - TXA h5 ]: Y/ X$ C. y0 C
- PHA6 T6 J: t3 H o+ a
- TYA9 E* i3 }( O6 E8 f) F) }
- PHA
/ y7 m/ n4 O" U6 {- s6 S -
7 G" Z" G1 d; c6 P' [2 M - ;16条扫描线后触发IRQ) K7 L$ x% n2 Y* e6 K( L F( E
- LDA #LOW(BEGIN_LINE_CYCLES)
& y) N( `. E8 B7 l/ j. } - STA M19_IRQ_COUNT_L
8 R+ X! ]$ m9 m' B$ f6 n- u) ~ - LDA #HIGH(BEGIN_LINE_CYCLES)/ y1 K7 L `+ E6 w$ \# l ^/ j+ Q( q
- ORA #$80
7 @8 T5 j0 J) e. e' F9 a' D6 m - STA M19_IRQ_COUNT_H
* t# l: ^: N5 V% p. ^( v -
7 V8 D9 X+ Q+ j9 A - LDA <IRQ_Index
5 v5 C! h0 N" |! M9 X7 w - BNE * + 4, ^3 Y# m9 i8 V" i+ A' g$ b. m$ X# E
- INC <PPU_Scroll_H
: ~% R# p- j) d -
+ V. ^' X! x7 J+ A3 G } - ;设置屏幕滚动& M c! P! G6 I, @- T0 x
- LDA <IRQ_Index
1 s4 ^2 D' Y( l {' {5 p9 K - AND #$01% ~/ Z; O- t8 ^& L' m
- BEQ Irq_Scroll_Right& J5 ^9 `1 w- b: F& Q; ^% u: ^ t
- K2 c4 E' E/ P a+ x5 H
- Irq_Scroll_Left
! u4 Q4 z( W# I7 g& \ - BIT PPU_STATUS8 z! W+ b6 t# m4 n- `4 W
- LDA <PPU_Scroll_H; M& A8 T* f9 E! C9 ~
- STA PPU_SCROLL
9 b& i, A: y; g - STA PPU_SCROLL6 V5 _/ s: c- Z' Z- g" k! @5 b" j
- JMP Irq_Scroll_Over
( N) q, u0 c/ q) {& G I8 B - - H8 ?7 H, v1 t3 N5 Y
- Irq_Scroll_Right
* B% r# A' f* {! n/ z* z& q - SEC
1 t: W0 s, K2 s. W8 `. F - SBC <PPU_Scroll_H, b5 P/ ?: r0 J/ @# }
- STA PPU_SCROLL
; P4 [* v x6 C - STA PPU_SCROLL$ }7 N# k* r5 H8 I9 I$ z
- Irq_Scroll_Over
2 y" J; H. k3 J6 {( Z8 Y - 4 O1 d" T, Y; ?: o
- INC <IRQ_Index1 {7 `+ k: A3 {. `% `5 e. F- @
- 9 R8 s. O$ {# H
- LDA <IRQ_Index
; S+ D% \( |0 ~3 {/ p# b* Y( e - CMP #14& v& J) G4 y: V3 } ^# _ F/ E, G' U
- BCC * + 10
9 y N; l* d# p; t8 ^ - LDA #$00
5 E! F8 ~9 `1 t; i: x. l - STA M19_IRQ_COUNT_L3 C \6 H* F1 @- f2 ^+ `+ p% o
- STA M19_IRQ_COUNT_H# t% q5 w" ]& I& { o" s
- ! t `! E: R0 h* b
- IrqProgramEnd' a8 [1 p: o5 I2 [7 A
- PLA
8 s" H+ }2 u5 g" q- Y+ }! J - TAY
5 e" M9 M) V$ P - PLA
) j8 G5 N/ m6 V* h B" w6 k7 H - TAX
# u3 A @+ {+ W# t( } - PLA
# s5 g( B" v" P1 y: K/ ]1 U' W0 X - RTI
8 ]' a% n! W* t -
7 g& f" d* s* J5 Q7 ?8 q9 l, X - ;==================================================: V$ [) E# `5 S! |; c; D
- ;中断表
9 ]- L& Y( Z! o' L# K% @* p, O - .ORG $FFFA
& q& l5 d! u8 Q% e- Y/ Y7 C - .WORD NmiProgram
1 d+ N; W% z4 Z5 @& z - .WORD ResetProgram
. w0 X6 Z* V- I8 G- J/ ~1 c - .WORD IrqProgram
复制代码
0 p' d. C5 X3 M) a |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|