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