|
|
- ;[FC][Mapper19 IRQ]/ P X& k# z! c8 S R6 k, d
- ;FlameCyclone 20230710" s* t/ `5 D8 a y$ v- q* A3 O
4 l) G2 ]) v g- @* M0 y2 q+ F- ;文件头
# ^) @$ l5 o* {& X - ;======================================================================
0 d; M; Y8 N: a5 w* T, y - .INESPRG 4 ;16KB PRG 数量0 w7 g6 @+ _8 f& m
- .INESCHR 1 ;8KB CHR 数量+ k7 u: \6 d4 r# n3 A4 d
- .INESMAP 19 ;mapper 19
: }2 ?( H/ o" Q7 o+ _0 N - .INESMIR 1 ;命名表镜像 0水平 1垂直1 ^ G- L' ~. Q, I; W
- " p( I/ e! m( r( T' k
- ;必要条件! t6 i Y3 v4 R0 E6 Z! Z1 {
- ;1.持有CHR ROM: P9 `, v! x( B0 b" f+ u0 D
- ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
% ]1 v( h3 W# W - ;3.精灵内存(OAM)不为空2 y$ s7 I! Q: r/ E5 a- U
- 1 N; L; w% y$ f5 l( ~
- ;==================================================
0 q3 H4 R! N; k2 I9 y; i1 I - ;NES端口常量" }7 v6 a2 K2 a
- PPU_CTRL = $2000 ;PPU控制寄存器0 E$ Q8 F; N' }& K
- PPU_MASK = $2001 ;PPU掩码寄存器
; ?# d/ C8 ]" b0 s - PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
* X, l6 j4 r( s. {" U) M! H - PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
' H: _" t, y( U7 `# R+ L3 B - PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加18 N, I& B8 d% D* S/ r2 d, g
- PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 5 d. }7 k* I. p- T8 Q& ~
- PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加+ d; j- X5 @' o! @# h6 f E
- PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
% H# P# p& j- W+ S) U8 y - OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存3 q! ~- G; W& N1 h9 [ a. |3 ~
- APU_STATUS = $4015 ;声音通道切换2 t z0 d5 `- O
- JOY1_FRAME = $4016 ;手柄1 + 选通
+ S) b/ D3 K( |9 l( C& _6 p - JOY2_FRAME = $4017 ;手柄2 + 选通2 c( h' y8 i) s8 J- C
) V2 t! u, e, t- ;==================================================
4 i) D3 }2 {2 r - ;MAPPER 19端口常量+ n: _: s8 w. C1 A7 Y
- M19_CHR_0000 = $80002 T* X$ T" I0 U' O- B' t+ R3 V
- M19_CHR_0400 = $8800( d7 g* Z- v2 ^- L$ |0 _
- M19_CHR_0800 = $9000
( G- a. }3 ], w( m$ | - M19_CHR_0C00 = $9800
$ `- G. I5 H# f b% J1 W - M19_CHR_1000 = $A000
9 Q* F1 W% f6 I* v - M19_CHR_1400 = $A800
4 O- j" S* R/ _5 U) b1 n5 D$ \ - M19_CHR_1800 = $B000
9 H8 U6 j+ x: u. L3 D3 n, I - M19_CHR_1C00 = $B800
/ B, j5 @" B8 j0 f. t- y* | - M19_NT_2000 = $C000& u; U3 u* U- G, q' [3 o
- M19_NT_2400 = $C800
# }( ] k+ c; z" f2 B2 _ - M19_NT_2800 = $D0001 \0 G$ O3 ]2 o+ Q$ c) }( z
- M19_NT_2C00 = $D800
' G' r' p3 F: v' S - M19_PRG_8000 = $E000
/ j1 s5 ~+ y }6 ~' c+ U" @ - M19_PRG_A000 = $E800
5 g+ l7 v' n* n; k( Z& ]6 n - M19_PRG_C000 = $F000& I' F- p+ u% k6 p2 }
- M19_IRQ_COUNT_L = $50004 q* k& s j2 d- F% j2 u1 x
- M19_IRQ_COUNT_H = $58009 ^/ e" J2 F3 f) v
5 z8 T4 N# m" `7 F$ R- ;==================================================5 [/ w9 w' Q9 c" ^
- ;程序块配置1 l/ r# G! B& V& k% g& d) G
- BANK_DATA_MASK = $07) _% H9 O# n; F& z5 G, M
- ;--------------------------------------------------
- E6 J! f3 \! H- C# g, |5 |9 s - RESET_BANK = $07& b; S2 Y1 L) k% n2 F4 y( i |
- RESET_ADDR = $FC00. d( E2 v/ \$ d$ M6 x0 w0 U; S
- - ?: _" s/ t5 R9 }* J/ Z* `
- ;==================================================
5 V v' C/ M% i" } - ;图像块配置7 p/ `- N) z2 n, m* E& o/ g/ Q* N7 [
- CHR_DATA_BANK = $08! B+ o, h+ v& c
- * r8 H/ c5 H( k0 y, a( v; y& A
- ;==================================================( y& I( [7 F. z; j! j
- ;零页内存地址配置
7 {- o; J' [9 k6 j* P - Use_Ram_Addr = $80
- d' u, A9 E8 _ - PPU_Ctrl_Buf = Use_Ram_Addr
, _; B X6 y. ]/ y+ m; k - PPU_Msak_Buf = PPU_Ctrl_Buf + $01
1 B, `# G: z5 F5 ~1 J( q - PPU_Scroll_H = PPU_Msak_Buf + $010 f! p4 t$ d" Z- R8 }& ?* b: f
- PPU_Scroll_V = PPU_Scroll_H + $01) n# L+ G1 N8 z
- FC_Data_L = PPU_Scroll_V + $017 m2 S$ @) W3 S3 p9 P! W
- FC_Data_H = FC_Data_L + $01( G7 s% C0 Z; }( s. q- g
- FC_Data_Buf = FC_Data_H + $011 I8 p, [2 l+ O% Y7 n
- ;==================================================
% U3 C9 }, R# h0 T% q4 r) N& t0 a4 k; K- J - 1 Z8 y/ h; w4 `
- GAMEPAD_MERGE_FLAG = $040 N' L/ |5 a$ D4 [
8 E% k5 r8 U; Z- Gamepad_Keep = FC_Data_Buf + 1- q9 a* m, j( E3 ]
- Gamepad_Once = Gamepad_Keep + 2
" t4 W D Q9 E A8 V' q9 W! t% t - Gamepad_Temp = Gamepad_Once + 2
* \( [, h& \5 v' t- A K -
/ s, \. K1 ?8 [ - Gamepad_0_State = Gamepad_Temp + 2
/ q5 w. r- ~9 X% E ` - Gamepad_1_State = Gamepad_0_State + 18 u' t% B1 u! _1 `% } R+ b- C
- Gamepad_0_Value = Gamepad_1_State + 1
+ x5 c, Q# i4 S& ^) Y - Gamepad_1_Value = Gamepad_0_Value + 1
0 |/ w& G% L1 r! {5 } - Gamepad_Port_Value = Gamepad_1_Value + 15 S6 O) r: A f$ _% `
- Gamepad_Merge = Gamepad_Port_Value + 15 e- e8 ^, H/ g7 q5 |/ P* X
9 n, x9 j, C. q8 g% Z* @! S- ;==================================================: x* z, q. n% c$ H5 Z3 Y1 C
- IRQ_Index = Gamepad_Merge + $01
% R5 a6 ^8 L$ V - ;==================================================; {/ K7 i: G3 }, ?- p" k6 W$ O/ s
- 9 c% {. F7 F2 \0 Y/ C- f/ o
- ;CHR图形数据; c+ g, N0 V5 r. A; ~
- ;==================================================
" {: i0 g% ]+ y7 u - .BANK CHR_DATA_BANK
( I; N. L/ e" J* _0 O - .INCBIN "chr_bank/chr_data.chr"+ F( b5 m! w& U- _+ X7 ~0 m1 n
-
; W- s) P- O3 Q2 z8 V$ {6 c6 c% J - .BANK RESET_BANK & BANK_DATA_MASK2 G8 M4 {4 Z- Q9 ]( s
- .ORG RESET_ADDR7 w# ~; f7 I$ ?2 _1 i$ R# N6 l
-
: [7 w$ S- s/ _$ P6 F& T - ;--------------------------------------------------; ]' v ]9 A2 V) ^$ t" C$ B, N
- Attributes_Data
5 ?# N& E, R: T; |: l - ;命名表属性
6 s6 E4 a" }7 x1 `6 s - .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ R0 l+ {* H( X# j, x& u, X - .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA6 V) M9 g8 @3 j- L* S/ @
- .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
I$ S+ }# t9 L, m: v! K - .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
+ w% y) ^' N5 t! a - ;--------------------------------------------------
* D* A3 f( U: Z& {! d4 i H) s4 D - ;调色板数据2 F# s4 U3 C2 a5 y; B2 K) b
- Palette_Data( w( M( l0 n" ~% }+ p4 v# s
- .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F. P& K5 \( e- [. r& f
- .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
, F4 O, K9 r& X# E( B+ z9 v6 \
3 F. ?' G$ x, d1 S" O+ g9 M2 w- ;==================================================
; h7 M& S$ H9 k& s - ;命名表初始化$ P" {. ~8 D7 b/ H: ]* N
- Init_Name_Table( Z0 T" R# o/ k: w
- LDA #$20
( j; F& G/ f: ~" q - STA PPU_ADDRESS6 ^% ~2 b( h9 k- T% |
- LDA #$00
' B8 j( y! r2 w - STA PPU_ADDRESS
0 `7 s$ B; B: u; H - LDA #$00
' h) W6 V7 Y3 K. r. h - LDY #$00
t2 S# d1 }) k$ K) L- H5 i8 v - LDX #$10
" G; ~4 R0 g) Z/ G+ ?% l$ l - Init_Name_Table_Write
" a' _0 s" ?& E+ E - STA PPU_DATA
$ t H& j5 n C - INY4 H c4 v) o6 A1 ]
- BNE Init_Name_Table_Write
! Q. G) l9 d+ `4 f7 Q - DEX6 s" r/ k5 P t0 |! _7 Q
- BNE Init_Name_Table_Write
8 a; r. z" v0 c* B - RTS
( `& L- m* z) B% H Q# [. u - # e% B; k$ V3 t) {1 Z" }( v; L
- ;==================================================3 B$ y: t( J! {+ ]% |: f) t: ?
- ;调色板初始化
: ]5 q$ f) x9 r$ \0 P6 ^6 [4 A - Init_Palette0 x9 G7 r5 \' e* S; S
- BIT PPU_STATUS
P3 d1 V/ T! O$ d3 H2 a* ^& i" y - LDA #$3F
0 H& W! {1 M! v$ o0 ` - STA PPU_ADDRESS" M7 v' P% G7 t
- LDA #$00/ M$ a' |! O( S
- STA PPU_ADDRESS
|; S5 X- h2 s7 u& b# T% r0 L# h - LDX #$00: y8 a, [; {& v5 s- ~) s
- Init_Palette_Write
/ P$ D8 [" h6 ` - LDA Palette_Data,X" ~- x" l& I2 f' t4 i! Y6 D. p. ?
- STA PPU_DATA
; c$ C2 Y9 Q. w9 U$ p/ | - INX
* [% g% i( _7 F% s6 e1 n& u3 V - CPX #$203 q2 H# @: X0 a/ ~
- BCC Init_Palette_Write y% q: p( f( S' X
- RTS
& j/ J, S" a8 K( u( | - " L5 @* w8 U8 ~$ z
- ;==================================================
! y( B, K: V0 Q - ;设置命名表属性+ P' y. F8 W* @
- Init_NameTable_Attributes
% O: y8 Y, h* A+ z& [ - BIT PPU_STATUS6 U ]1 B6 @5 Q9 Y$ Y0 b
- LDA #$23
: I) D- w1 r7 G8 R, A - STA PPU_ADDRESS, _4 a1 |$ y, Z/ S! G, U
- LDA #$C0
# n* p' D: Q+ p M - STA PPU_ADDRESS) }/ }& v F! h; d
- LDX #$00/ y' l" V% u7 f6 c5 l, F+ D3 f! a
- Init_NameTable_Attributes_Write
+ i4 a% y0 V* z) F9 T ~8 `% T - LDA Attributes_Data,X
+ d- E) p+ s& n0 F9 j q) @7 C - STA PPU_DATA: h2 ^" C) o y2 }: j8 C, E$ T
- INX: Q2 u ?6 i6 m+ E( E
- CPX #$40
2 D. R' q/ Y6 E% s - BCC Init_NameTable_Attributes_Write! `% a9 H6 P" Y; v0 S8 M6 |
- RTS
5 s" t9 d& @2 A7 k* x3 t - 3 w$ e0 o9 E4 I6 X; F
- ;==================================================
; U- d$ P4 v% [ G5 ~/ Z _) k- K - ;初始化命名表文本
7 S' j9 O) a! F; s4 V5 a - Init_Name_Table_Text
8 p" W3 ?( w u+ V. G6 U; O' L - BIT PPU_STATUS \* _4 {! x3 a( L/ z
- LDA #$20: B; U9 _' d+ @
- STA PPU_ADDRESS
1 K7 X: I) a& q) H: f! _0 j - LDA #$00
% I v/ z& b# N9 F: ]2 C - STA PPU_ADDRESS
# d3 L1 a2 l' j! E( `5 D - LDA #$00
0 D% V) s3 h: {9 H/ v* h - STA FC_Data_Buf
9 @ s! t( m( `7 Q - LDY #30
5 j3 w( n- T! t/ }" ] - Init_Name_Table_Text_Write4 @* r+ p+ u" I- z
- LDX #32
# B! l, @# p P) Y - Init_Name_Table_Text_Write_Char" l X7 k3 ^6 j" C; t
- LDA #'0': x& }4 w; g) O4 h+ W
- CLC+ C5 u4 F! }" F- s
- ADC FC_Data_Buf) o% e: g7 }/ C D; q2 T* A0 ]
- STA PPU_DATA
9 W5 O3 D; b4 |# n; t) B - DEX
* z/ X) P3 e# Q - LDA #$14
5 Z/ y" w3 ~1 X% \( \# @ - STA PPU_DATA
, b4 c+ M/ c7 ?# [& U - DEX1 |7 ~" L7 L4 I/ g# b8 {' ~2 m
- BNE Init_Name_Table_Text_Write_Char1 `9 N& T+ a4 @/ o/ S# {7 o; J. q! r
- INC FC_Data_Buf
" D3 I# `! }# [8 ~$ D - DEY
) G3 h+ V- S% L4 f - BNE Init_Name_Table_Text_Write
# X9 O+ P9 n9 ]3 x( Z3 B( i/ y, `. z - RTS4 |* _+ ^* H% r( _
- : F* b* H/ o* U; w: h! C) P
- ;==============================
: g) a" B0 Y& G- a* C/ F - Init_OAM_Ram;初始化精灵内存
7 S, y6 J" x: @ - LDX #$00; E$ c ~& R. `
- LDA #$00$ J) v k }1 }* z) u
- STA PPU_OAM_ADDR& T3 l/ y( z1 g9 X+ R% @
- LDA #$F8
) v1 {# y+ ^. [+ ]+ c! _/ E - Init_OAM_Ram_Write
* E9 G* y) B3 m' m - STA PPU_OAM_DATA
; c: u; Y0 L! u# a o6 V$ w i - INX
# A7 I2 Q& T8 C W" q2 b - BNE Init_OAM_Ram_Write
4 B0 j; e1 C: w) z' w- M0 t - RTS
5 z8 `! o S, x -
1 \$ M; n9 L( `6 S& x) }. O$ n - GamepadProcess;手柄处理7 F: O: | n$ q3 o0 F
- JSR GamepadDatacan# o) b3 `5 e6 R: n% i
- LDA <Gamepad_0_Value
- {5 l0 `/ f7 \, z( F - STA <Gamepad_0_State
! @% X) K" I4 y, K; N5 q* c% g - LDA <Gamepad_1_Value' C1 ]! O8 O7 y( g/ a6 k+ L+ }
- STA <Gamepad_1_State
- a1 i& L7 }1 Q0 R1 C$ f* Q; v d - JSR GamepadDatacan E9 \1 W: j1 L: |# ^4 L( M
- LDX #$01
; G* D/ N) H2 ?8 z D" Z - GamepadMergeCheck;合并手柄输入检查
8 _# `" N' f& _5 M( j" Z) A, U; A' E - LDA <Gamepad_0_Value,X9 `. X! N4 n* f5 u, U; _5 r
- CMP <Gamepad_0_State,X J1 c# {6 g; G2 W! q
- BEQ GamepadMergeInput0 M8 T5 m1 H" c/ G* |7 l4 ?
- LDA <Gamepad_Temp,X
7 J5 i- o" g8 @2 |) X - STA <Gamepad_0_Value,X9 w, C; |: D+ n/ }" Z
- GamepadMergeInput;合并手柄输入& b- Z* q" r. P0 F" }9 [
- DEX
7 ?5 r& l0 Y6 R - BPL GamepadMergeCheck7 R. G* H; w# }8 y5 }/ i
- LDA <Gamepad_Merge# ]% Y" U5 A% @. n- t9 M# c
- AND #GAMEPAD_MERGE_FLAG& M2 J2 [5 }' d& D4 |7 w k
- BNE GamepadStateProcess3 Q/ `' P6 _% `- o0 c' W
- LDA <Gamepad_0_Value
) b% o+ m% Y' f% K/ e0 I0 x6 S6 B" [1 i - ORA <Gamepad_1_Value# Z6 n2 B# J% Z( F/ t2 E$ R
- STA <Gamepad_0_Value
* V, @5 [ S; v7 [' L; C - GamepadStateProcess;手柄状态处理3 o3 [7 }" j! T6 t7 v% v$ T% l/ v
- LDX #$01
- i1 z: X/ o% N6 j - GamepadStateSave;手柄状态保存
7 |" w# p, y7 v2 v: M - LDA <Gamepad_0_Value,X
% F5 B9 `+ d$ j0 C+ d4 t" Q" k: b - TAY% F" C ~- x* k3 x7 y- j4 _
- EOR <Gamepad_Temp,X$ A; c% O. }: j: y) ~- W
- AND <Gamepad_0_Value,X7 I/ O" ], i1 U& r
- STA <Gamepad_Once,X* q0 o1 g H" n) c
- STY <Gamepad_Keep,X
" |& g6 [* z0 L( R f- L - STY <Gamepad_Temp,X8 u3 c- ?% g$ q* G
- DEX
: C! V$ a$ A# Q0 R$ f - BPL GamepadStateSave* o6 W, S- p! f: B" L X) F4 y
- RTS
- d. O8 W5 }" }# ^3 Y
5 w8 a1 G, Z. R" W, n8 w0 ~1 r- GamepadDatacan;手柄数据扫描
0 l; m" `" T- c, ^8 J - LDX #$01
% B& ]( n m/ y, P+ U! z7 H - STX $4016- r" E" p( n+ ^. z3 m4 Z
- DEX
, ~7 r; k& I0 R$ f - STX $4016
% |2 X. `) J: t# W - LDY #$08
9 ?2 t$ }/ ~* u; x1 X4 O/ k+ ` - GamepadPortScan;手柄端口扫描
0 k+ {2 u' `+ s( m- M2 g* k& A - LDA $4016
6 u& `: Y D- ?1 d; e( s - STA <Gamepad_Port_Value
- t4 e4 a9 z$ Z# \4 r" I1 J - LSR A
7 G' l6 M- L! ~8 q" j - ORA <Gamepad_Port_Value- ]. L8 T$ C4 t5 }3 \ \
- LSR A
5 j* {" Q4 z% a* _" c - ROL <Gamepad_0_Value
4 [: r. }1 Q* `; X0 f% T7 S - LDA $4017! X# ?2 i6 B, M) E+ S
- STA <Gamepad_Port_Value
% U2 \5 U+ {$ t; I$ j5 Z2 b - LSR A) q9 R& \3 u9 Q1 a- e- _
- ORA <Gamepad_Port_Value
+ Y) ] P# D$ _& `5 H - LSR A
$ Y; H: B4 b; I: N - ROL <Gamepad_1_Value6 O. X5 K- l1 u
- DEY; \1 Y8 X8 h( b/ [8 E
- BNE GamepadPortScan
: M' r# I5 f& s* m% ` e/ H8 o3 Q - RTS
3 T( ~* O5 S; l. ~ g - ; d6 x% ?: j( I; K2 Z/ \
- ;==================================================
- A0 e1 N+ x; N4 h5 A8 `8 D& E% A! s5 ~ - ;PPU处理
& D! p. y/ _- W2 M" U; \ - PPU_Process
( ]! D& H x/ o/ u - LDA #$00
- o& M% F& o- D* L' M$ J2 H* p - STA PPU_MASK
2 @7 ^# ]/ {; g3 n - / ~ ~3 J3 P/ ~- d* }
- BIT PPU_STATUS
* h7 F# y# t7 J6 |# v! ] e9 { - LDA #$20
+ ?& C9 e( h$ ]! F7 `4 E9 B - STA PPU_ADDRESS
* ^- a) b4 ?! f# z - LDA #$00
, u6 V) k# q% ]# D - STA PPU_ADDRESS* Y6 B1 r8 p' L" B/ \" L7 \; g5 L' ]
- 0 }3 Q; P e9 T
- STA PPU_SCROLL! v4 O+ n. J2 R2 R7 X0 [2 y6 s
- STA PPU_SCROLL' ]+ {) V o: Q8 P
-
' \( u) D) I1 ?; [, u - LDA PPU_Msak_Buf5 c8 Q! P* n( V8 P; @- t
- STA PPU_MASK
# B" m* z* I* y0 P9 h w1 X4 U - " e! P, ~( R5 b- a$ \' M5 c" O! N
- RTS
& u/ G' T5 C. P4 w F - . M, |$ e% k1 b- z: E) P
- ;==============================
# Q. q) r9 ]3 W4 N; e7 @ - Time_For_Vblank;延时等待
) E! i( |6 o5 T4 _* r - LDA PPU_STATUS
5 e( s- h1 X6 p+ } - BPL Time_For_Vblank( K# T j( s0 f$ ?5 F
- RTS9 ^4 g* w( ]' A/ r. q+ {
-
' E. K1 o. o$ t3 q# E - ;==============================
8 b3 K$ m, k3 r - ;初始化MAPPER19* z; P, y6 v: {# k
- Init_Mapper19- J- I; l7 b3 `8 N8 D/ D
- LDA #$00
! o- I% w5 I x6 X0 G9 r - STA M19_CHR_0000
1 k- G+ o* g7 s6 K1 S - LDA #$01+ [ d$ m/ B0 j- D5 ?
- STA M19_CHR_0400
6 H+ e' k" I; D - LDA #$027 B; K1 ]: ?" s7 E6 v
- STA M19_CHR_0800
, e# k* p( u h, v - LDA #$030 u7 E2 ~; q6 d2 }7 B) W- f: h
- STA M19_CHR_0C00+ n8 h# ]$ R& ^9 e) R1 s, Q. T( Q
- LDA #$04
( R5 k- T; V. n3 ]3 E' s - STA M19_CHR_1000
; K. L! A5 n1 D# g# [ - LDA #$05
8 }. V: a- r5 ]4 ? - STA M19_CHR_14007 c1 w; P5 [, T! P3 o, a# F/ o
- LDA #$061 s3 D( i& {% z3 H! S
- STA M19_CHR_18007 p& W# _; \; s. l
- LDA #$07* Q& N, M5 s- D% S* u8 K
- STA M19_CHR_1C00
* B& B5 w, d. F1 p- | |* Z: J -
& V+ s) v) D- o9 q. p( [ - ;禁用IRQ& Q8 m1 t4 `, L7 x" B8 l9 q3 E
- LDA M19_IRQ_COUNT_H
1 y1 O5 y# { \* X! _ - AND #$7F
$ `1 x' K% i. F$ }& a- V - STA M19_IRQ_COUNT_H* W8 |5 W' x" z) H
- 9 I+ A$ [$ S3 U- k$ [: k# X* F
- ;命名表% f" X- i0 a! O& A- F. N
- LDA #$E07 h ], A6 [, J
- STA M19_NT_2000
* s) y- n) @% u/ {2 b+ h8 i- i - STA M19_NT_2400
) R% b% a, j1 Z9 ^: K - . A2 ^4 n1 h0 F+ h8 C4 U
- ;命名表; A8 `/ f& O- \# o
- LDA #$E13 y& @, w5 c; ~- f" Z
- STA M19_NT_28007 V. \. f* R, z, v. j$ `
- STA M19_NT_2C00) p% b" D1 ]$ {! A
-
& b5 s! T7 {" X# {) o - RTS
X u8 m5 b0 W: ^6 |' j -
6 i4 b, z \+ A - ;==================================================
+ i0 [, ^9 t: ^4 K" b - ;重置中断处理5 {. j: Q8 w* ^+ L# o, \
- ResetProgram( X$ O& K# X3 P. v/ o
- SEI
6 P, E- Z+ C& m7 p! k8 k9 Z - CLD
' b# D6 |' i! M# X- j' R/ e - LDA #$00
; S. n a# T1 t5 L4 n - STA PPU_CTRL
3 F/ S/ y+ K7 R$ A5 i G$ W - STA PPU_MASK- W4 b. V2 ?6 v6 E! P, s" o
- STA PPU_STATUS# r4 x1 ]6 ~: I5 f, S1 ]3 A; H
- STA JOY2_FRAME
# k! Y6 Q* M( l2 i4 A/ Y8 r6 V - STA APU_STATUS+ Z; d/ _( ^2 ]# `$ j: C8 S: i' J
-
8 V. J$ \+ m. _8 i - LDA #$C0+ k8 {+ Q/ g/ M- }' \2 n* Y
- STA JOY2_FRAME) B5 r$ y# b) `: z7 b7 }& X$ b
- ; I4 h6 I4 N; H5 ] _4 ]! q
- ;等待vblank
" _# c6 K% a& C# t4 `/ X0 f - LDX #$02
1 q) @# w/ x$ z% n7 }2 v0 } m8 o2 n - Vblank_Wait_1
6 L, t, N$ f: v - BIT PPU_STATUS1 t3 t9 o4 b3 D% l `
- BPL Vblank_Wait_1
8 V' {. e0 q9 `# U. j- V9 z - Vblank_Wait_2
7 c) T* n: i, m - BIT PPU_STATUS' Q7 U i/ `; m7 o( N1 L, B
- BMI Vblank_Wait_2* X! l1 Y# m8 P7 Z7 {' n
- DEX# _" O, S$ C [0 p/ D% S# W
- BNE Vblank_Wait_19 k' x+ n- W$ z" J0 s/ S
- ' ^+ F& y2 T/ X
- LDX #$FF3 c5 [; f0 X8 N$ S: Q
- TXS
# a6 F$ l1 {# Z9 S -
! A# l& A/ k3 R! V$ U' t, t- v- Q" R - ;初始化MAPPER19
( w) l) A/ u' u8 }8 N - JSR Init_Mapper19
2 Z, f9 S( I2 f: J4 J3 v - 9 {+ ~" d3 G/ Z2 T- V# t, F& u; E
- ;==============================
, I! c @1 U- g - ;RAM初始化
2 l& N( ?5 t5 z" C - Nes_Ram_Init
6 ?0 l- ?/ N+ j/ ~" M5 q+ K, c' l' ` - LDY #$00% ]3 C7 e* ]9 P- A6 I' |! C9 T
- LDX #$08
" ^# ]% j" {$ O - LDA #$00* `8 ]& e* o q: m3 `! Q, F8 ]
- STA <$00
9 j* V7 b* {1 n/ S( E' L8 T8 P - STA <$01( h! _% b9 K6 b+ B$ _# ?
- Nes_Ram_Init_Write
2 i# u T( u. P - STA [$00],Y
% h' f/ s( U: f! p9 w - INY
) m) O* C% d0 ^) l - BNE Nes_Ram_Init_Write# K3 o" _* ~; e( m+ ^0 n9 f J
- INC <$016 `: i+ f/ ~- s4 I2 }4 M
- DEX
' m/ w/ c, {! Z7 a T - BNE Nes_Ram_Init_Write- [; c) X6 b% j4 B8 \' b2 z
- 3 a& f! q, k) {: D- [& i
- ;初始化命名表- u T) D; t9 Q; L6 `9 v
- JSR Init_Name_Table5 v0 H, r# Q+ K5 k* z' o' w
- ; Y1 x( X8 J! H- n
- ;初始化调色板
" |+ s' h4 ?9 S0 b - JSR Init_Palette/ _" H, J1 w& R# i( u8 E' h' x
- ' H1 V/ n* g9 _( p# p m' {9 ~
- ;初始化命名表属性
1 A6 C& o" V; Y0 G8 B( C' g. Q4 `6 f - JSR Init_NameTable_Attributes
7 g2 V' r3 F( ^- M3 P -
+ q9 e8 Z+ D5 V6 I2 U0 x! P - ;初始化精灵内存7 m3 g$ m0 @$ B3 W9 ?1 Q3 K1 N" m0 G
- JSR Init_OAM_Ram! e# r% f, |6 I$ b: e
-
3 S& g5 w) P3 N& }1 E1 g9 f - ;在屏幕上写点东西
& P* T/ P( {2 j - JSR Init_Name_Table_Text' o1 e; I) p$ o0 d z
-
1 A3 Q; J* L9 w0 Q - JSR Time_For_Vblank+ m/ _0 [) B7 b
- ;开启PPU控制
8 c, X( B" y P* {: L - LDA #$A8
, t+ q! j9 f: J6 u. b& o - STA PPU_Ctrl_Buf) ~8 Q1 ?7 n+ e: s/ q
- STA PPU_CTRL* `4 l0 N/ h f, Q
- 1 @$ l4 ]- ^4 p: Z) s" e1 V
- ;开启PPU显示
0 Z2 m, F! R. P! E/ X - LDA #$1E! p! R% R, l9 W. z3 a
- STA PPU_Msak_Buf$ P4 \( i2 R$ Q1 i2 `6 W
-
, b- O# O# V W3 @2 H/ A; f6 d - CLI
& B: o0 [, z0 o! _. f. O - JMP Loop
4 c# S# C; |, A( k4 X. x! [ - ' d. E0 D! ^% G1 z( f/ }# E# B
- ;==============================- M) v4 I# I; |
- ;死循环, 等待NMI中断0 n% ~6 j4 p2 Q5 |' S, d
- Loop+ T- U: c, K# _: M* N( S
- JMP Loop! ?2 ~! ?" i7 y$ T; J
5 _5 n- ^5 H$ |8 O' r3 B- ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967) b% V' a& g# o/ j% t& E. {/ U: H
?3 }/ {9 l3 Z( e7 A- ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)/ o" V/ \: f9 t3 i* M+ s8 V
- BEGIN_LINE_CYCLES_START = 32768 - (4103). b" |7 s& w5 W; o! p; }, z
- ;==================================================
( j$ `) [" k" M" m2 Y2 T' N2 i6 J. n - ;NMI中断处理
# n) d/ t6 u/ K - NmiProgram% E# @% E* N4 F* |
- PHA* |9 h5 T W$ o2 N# f5 @
- TXA W8 Q! r' `6 D% u9 R
- PHA
5 q! X5 Y) g" O, n: @6 u7 | - TYA
8 S6 f# G4 I8 _9 ~) Y9 F - PHA5 ~; M% {; K& h2 f* e3 w
-
2 o% }% O4 A" o; V! `' \ - BIT PPU_STATUS
. |9 m. m. c6 M [, _ -
" R" ~5 u% o9 M; u4 v1 ?, f5 N - LDA #$00
1 f: v4 o$ r; F8 t6 ~& i - STA IRQ_Index
8 x3 e% z8 ^; k( f% k* i( X+ W Y -
% Z: h& S. y3 J - ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
: q+ G0 H* }% i2 L0 s, ` y% Z - LDA #LOW(BEGIN_LINE_CYCLES_START)
3 M8 v' y k7 _/ e W - STA M19_IRQ_COUNT_L& u* v3 g- l, [# ~8 }- J9 o0 z' |
- LDA #HIGH(BEGIN_LINE_CYCLES_START)
( Y3 r* ^2 N2 y5 N9 Z* Y3 ? - ORA #$80
7 D$ |# y9 b, A6 ?* z/ b) d9 G - STA M19_IRQ_COUNT_H
0 L9 E7 Y1 X' S9 Q" M - CLI
. ?4 T' e, h5 `' L- }+ x -
' O& ?6 N9 w7 L9 B9 ~1 ~ - ;关闭PPU控制
% X: i. w' l. P - LDA #$00' D' @, t- y; m! R, i B
- STA PPU_CTRL
5 X c% L7 c& W - * I p8 V* t( f2 A, K
- ;处理PPU7 _. U( l5 s! { t d* Q+ p) a
- JSR PPU_Process
$ l/ j0 r% _9 i* H4 v. {- C0 W -
+ s B0 j: g* T' X9 ~ - ;开启PPU控制
. w7 X9 A$ G; A" B/ g: |/ d' r - LDA PPU_Ctrl_Buf
( u4 [8 v A' P7 f# C( l) f - STA PPU_CTRL
0 s+ u8 k5 w) y7 C; n. R - ' N' y9 o) ]4 a. F/ T
- ;手柄处理
7 N# f3 p+ W( h - JSR GamepadProcess# s( {* ?3 X& U9 r+ J* ?
- 0 I, Y) Y4 p5 s
- LDA #$00
# j* k. N0 t A1 }7 J" J+ p. j8 S - STA IRQ_Index# p$ p. t" r2 T, H# A
-
, L8 U' k2 }8 C$ p+ H - PLA
; ^' ?8 @# X' h* U& a - TAY
3 R+ y4 k1 a8 v! N - PLA
% t0 V8 f' ?; b/ c - TAX
. A o) B9 W; F/ } - PLA
5 Q* n$ }$ J: n E - RTI F! K2 C! t' u% h
- & u0 y2 W. L9 C& y! V1 R
- ;每行扫描线113.670 _' S9 S) f9 Y3 g/ a
- ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)( \% B+ I4 S% p+ p; V
- BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7. |' J- B. i7 i- E# x
- ;==================================================1 ^2 [ R1 n0 o- k! f
- ;IRQ中断处理
( f& H6 y6 c% \/ C - IrqProgram, X V8 r1 C5 L# H) A' \8 r/ l
- PHA
7 s$ K$ f5 b6 r) S9 x2 Y d - TXA
9 h B/ e. u7 z# Y: @ - PHA6 b( k! H7 a/ e; Q& m
- TYA/ {1 ?+ x4 b; x, k5 A1 F% R m
- PHA
6 q0 }( R3 d2 a& `- W( }( L" F - : a1 ` \ U! P" }8 S. N2 o! N& j# R
- ;16条扫描线后触发IRQ, m+ O; w c' D4 @1 V
- LDA #LOW(BEGIN_LINE_CYCLES)
- L$ d% @, A1 Z4 E* ^/ y) u0 a - STA M19_IRQ_COUNT_L1 U: [8 } ?6 Y. V; T; I2 ]
- LDA #HIGH(BEGIN_LINE_CYCLES)
" w( n% g7 q& e: P. q7 q - ORA #$802 _+ b r: S: A, @" s
- STA M19_IRQ_COUNT_H
a* q1 _8 R" _' t -
+ U6 a8 q+ v% x9 e: H$ p - LDA <IRQ_Index
- \( r7 d7 L% P. O1 f8 b8 E# o - BNE * + 4( O3 ?: F' x% C% ]
- INC <PPU_Scroll_H4 i% M% e2 p: [! O0 |8 f% m
-
+ l2 I0 z* p M7 L+ U V - ;设置屏幕滚动$ [" j% h# V4 L( _- E# n
- LDA <IRQ_Index
% P X% N2 B# z# H! d& ^7 Y5 K" O - AND #$01/ d9 m. F$ g) ]
- BEQ Irq_Scroll_Right3 U! O3 S9 X6 U, R/ u# n, {" @
- 1 r# x! q3 ]3 f$ `
- Irq_Scroll_Left+ [8 Q% n5 F2 h
- BIT PPU_STATUS; r, `) i0 C0 L, O% D
- LDA <PPU_Scroll_H
% A M4 g7 R1 U ^; ^! K - STA PPU_SCROLL9 J( z* X. o" p( _8 t P
- STA PPU_SCROLL' y5 D8 C8 T: j' D
- JMP Irq_Scroll_Over4 W1 B, B% `* w2 p; |
-
- V9 z4 E; V3 S, ~1 W1 t - Irq_Scroll_Right
1 B' }; Z8 R) j* B! m" t3 g - SEC' B* g: c4 {& B: P6 r
- SBC <PPU_Scroll_H' z. c: R' c* J" F
- STA PPU_SCROLL( b6 z+ H" y0 r Y
- STA PPU_SCROLL
, ] I. s% s% }: @* ] - Irq_Scroll_Over
" `) r! _% n/ _& d - 3 s0 F' g6 i: W' A( |" @" |8 m3 y
- INC <IRQ_Index) m5 a* ~; B* D* ~6 R3 W7 Z# |
- 0 o' B& k" y4 }4 s* W! u G: Q u
- LDA <IRQ_Index
- q& e9 N5 X. i! G - CMP #14' B" h0 x0 A) R/ i1 Z/ {5 p# J8 {
- BCC * + 10
# R9 w( C. X5 W! {2 `, A+ ~& i - LDA #$00$ N& x+ G9 _& x. g% |9 o
- STA M19_IRQ_COUNT_L
- `* T$ b# @! I0 X* R. m - STA M19_IRQ_COUNT_H7 D: m: L6 u; x# w* i; a
-
1 g: G1 i( T& d8 K) K5 H - IrqProgramEnd
6 M' K" [' s- }: e; T - PLA- M7 Z$ _- r- s6 \) [
- TAY
: e9 q) J5 z, x- M7 O - PLA; v: ~! s- v2 T
- TAX
) C! B1 o! Q! n* k C, B1 m - PLA4 M- y; p5 p* |5 V, \
- RTI
; K. R: o' F6 Y1 C. { -
" e& _$ G3 o+ p: u* y" h \7 P/ k - ;==================================================$ B& x9 ]& c" q% u: y6 ~
- ;中断表) j2 O Y3 x5 I, h+ Y, F4 m9 g
- .ORG $FFFA
; e5 v4 W" O; F1 ` - .WORD NmiProgram M, {3 h9 K& |2 q( u
- .WORD ResetProgram/ {! u, |/ Q4 ?( V
- .WORD IrqProgram
复制代码 9 Y% @1 N8 v0 S: |
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|