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