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