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