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