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