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