|
|
- ;[FC][Mapper19 IRQ]
3 ^' o9 G# h$ d; l; b, @( R - ;FlameCyclone 20230710. ?' L$ B' r2 h% R
! L1 T; [9 k/ Q0 ?- ;文件头
; `! F6 @) Y7 z: O - ;======================================================================% o' e5 ], j; P; \: l0 F1 Q
- .INESPRG 4 ;16KB PRG 数量
# ]" ]* @& U8 ?9 f - .INESCHR 1 ;8KB CHR 数量
0 h; R: W: u( B; \" e6 x - .INESMAP 19 ;mapper 19
3 r, G; j4 k3 K0 h) u! ?& d - .INESMIR 1 ;命名表镜像 0水平 1垂直
5 l# j0 H; n# K# t5 ^8 T9 C4 m4 D - 6 F4 F6 A9 T5 t" u6 y7 u) ~) m
- ;必要条件
* N9 g8 [- y) r' f7 z0 N- {. F9 M- L/ O - ;1.持有CHR ROM
4 j1 |) d5 p$ |( o - ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
) p% E+ j M6 V4 [; P - ;3.精灵内存(OAM)不为空8 N8 H [ Y; B0 j$ u( ]3 L/ o. u
- / {3 f" H4 B( a% w y( a6 J
- ;==================================================
* H* V: f% C% O0 L& Q2 j. l - ;NES端口常量* D$ C2 g( i+ n A$ [$ F
- PPU_CTRL = $2000 ;PPU控制寄存器/ z5 r/ b7 K0 k8 U; J6 Z; r+ A. w
- PPU_MASK = $2001 ;PPU掩码寄存器
7 a- l) R" _) L% H6 r( s - PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位- I, p& v7 q& m% j y
- PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
T7 y L0 V& h0 M* X2 h$ e - PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1& a2 f' A8 P5 E! D, S5 r
- PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
* A" V& u8 E+ i1 E - PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加6 b: Z9 U2 a2 K! z, n# p/ j
- PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 - ^) q: U) _" G, [
- OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
3 ?9 [+ C" g; e4 E# \ - APU_STATUS = $4015 ;声音通道切换
' x2 F. T2 V% N, F0 A3 ? Q - JOY1_FRAME = $4016 ;手柄1 + 选通7 D. R) w, m2 e d: C
- JOY2_FRAME = $4017 ;手柄2 + 选通
* R# e4 t$ m# E3 a7 k; m- h - * U, U: \6 P, ~+ s- g- T$ }
- ;==================================================
z( u! l8 r2 x! k, B5 x - ;MAPPER 19端口常量
# L3 X1 b _7 b# U* O- L. Q; f M - M19_CHR_0000 = $8000
" i8 u. F: o/ o# z& A6 a! ^) d - M19_CHR_0400 = $8800
2 C+ I* L3 q$ S0 w) N+ r5 A - M19_CHR_0800 = $9000
6 E. y! D2 b+ g6 k& e9 H6 I' a6 i - M19_CHR_0C00 = $9800' C3 G' r2 M8 s
- M19_CHR_1000 = $A000
6 B9 O1 E8 m' a J2 j' p; k# S9 o - M19_CHR_1400 = $A800
3 w1 \" \: H9 ?7 T: e - M19_CHR_1800 = $B000# h/ z8 [' Z/ p( O0 Z4 V& {1 C
- M19_CHR_1C00 = $B800
0 ^' B1 C( ^* ` - M19_NT_2000 = $C000
+ e3 x0 K" z; e; I: p2 o - M19_NT_2400 = $C8004 S5 ]) \* V2 E" u8 B
- M19_NT_2800 = $D000
9 S$ F+ @: t& K6 ^ - M19_NT_2C00 = $D800
, J) O3 {7 E$ n& E. [: l0 b - M19_PRG_8000 = $E0009 z; y5 c4 X: J9 Y# `4 t, s- L2 P
- M19_PRG_A000 = $E800( J( V r j+ X3 ?! F) V. E
- M19_PRG_C000 = $F0002 K6 a1 r1 Q; ^
- M19_IRQ_COUNT_L = $5000- b( x& B) c3 d& B: i" a
- M19_IRQ_COUNT_H = $58008 S# N) v2 b' R
$ S; N6 n+ m+ U# v- ;==================================================2 T3 g0 l% o% B& `9 H
- ;程序块配置
2 }! U2 |/ |) o& V, \4 N - BANK_DATA_MASK = $071 ~) b8 G8 J' s/ n4 G) g
- ;--------------------------------------------------
+ {- m. r$ v/ p4 u - RESET_BANK = $07
+ y8 C& Z; C; C; j# f - RESET_ADDR = $FC00/ N V4 \4 r7 F, v5 f0 n
- ! C. }/ q5 c9 d z: T# u
- ;==================================================. Q% u% O) w, t! x1 Y
- ;图像块配置) Y6 g6 q+ T5 ]3 Z! N8 S. o& B
- CHR_DATA_BANK = $086 @! {+ C3 c. [0 u
- ) l! [% Z: u# J+ D
- ;==================================================7 K1 v9 a$ \6 T; i# v+ L: R6 O
- ;零页内存地址配置
. w9 C$ l2 Z7 Q2 {9 @) T. v+ w% f5 O - Use_Ram_Addr = $80
& |. A* y! ]( h, w) z - PPU_Ctrl_Buf = Use_Ram_Addr
3 G, `$ O, d5 E0 a7 Y: C - PPU_Msak_Buf = PPU_Ctrl_Buf + $01% d( E( F+ Q: g2 c* r- d
- PPU_Scroll_H = PPU_Msak_Buf + $01
5 ]5 M9 @; V+ k5 z% Y - PPU_Scroll_V = PPU_Scroll_H + $013 Q" A2 Z8 I( B/ o1 j! U8 ~
- FC_Data_L = PPU_Scroll_V + $01
8 E$ e! Q" E- Q$ K: O - FC_Data_H = FC_Data_L + $01- r6 |8 ~" \5 q+ |) w( h7 K: ?
- FC_Data_Buf = FC_Data_H + $01
! K) P; j. n2 L4 I - ;==================================================9 U" Y6 ]- o; q( c3 q
6 }) O: V$ V" Z- GAMEPAD_MERGE_FLAG = $04
5 w! {5 Q; t$ _+ D - ; F6 ?( X3 d" m0 I% p& [
- Gamepad_Keep = FC_Data_Buf + 1
/ e: m9 h* k5 ?' B+ \! @) j - Gamepad_Once = Gamepad_Keep + 2) f4 c- z+ l: e! j
- Gamepad_Temp = Gamepad_Once + 2
' B4 _; Q; u, U* X' D - " l+ X) k2 l* O$ \* f
- Gamepad_0_State = Gamepad_Temp + 27 G+ v. |; s; ^ A2 U: k, u* v
- Gamepad_1_State = Gamepad_0_State + 18 r4 t8 z9 G9 t: \& l8 F8 P
- Gamepad_0_Value = Gamepad_1_State + 1
2 K' z" f$ |* U( f" B3 p/ n - Gamepad_1_Value = Gamepad_0_Value + 1
0 @* z" F0 t6 r. J - Gamepad_Port_Value = Gamepad_1_Value + 1
6 z8 E5 N3 L1 T8 r- m7 n - Gamepad_Merge = Gamepad_Port_Value + 1
' Q6 T8 s: D; v. A$ e" v - 0 { p$ C$ [. s9 o0 n
- ;==================================================
9 C0 [- T3 J( B& H4 i! x3 x - IRQ_Index = Gamepad_Merge + $01
( s# \( U3 {1 s i; r* ] - ;==================================================
W( e2 ^$ w0 @& p) V' B5 \ - , n6 G* ?) ^; t* x* B F
- ;CHR图形数据
( Z: ?* h: @& S* G* @# { - ;==================================================; B* f" i; d+ T: l5 T+ v& y3 X
- .BANK CHR_DATA_BANK# A2 o- I" ^6 k& Y1 B8 S# p
- .INCBIN "chr_bank/chr_data.chr"
8 c+ F' \6 y* x! H; y - 9 T4 _) U. N) U! J) ~! ?
- .BANK RESET_BANK & BANK_DATA_MASK
+ q/ @' F- s- g0 Z; F) L! U$ G - .ORG RESET_ADDR
: b% H6 b* M7 U( X - 3 g: d& p( L+ y P, [" y
- ;--------------------------------------------------
: s5 z$ E0 u X0 n8 U - Attributes_Data
/ E. K1 \- y% \2 D* l) S - ;命名表属性
+ [7 I; T F5 y' d7 g - .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
6 a6 q! L' J4 J, k. N - .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
8 s7 f* v0 U: [ - .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
, q, b; Y/ W. N/ x( U# {$ K6 H - .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$551 N. P1 a. I7 I4 W
- ;--------------------------------------------------
$ s8 s; d$ ]/ }) k0 x' u - ;调色板数据2 M0 Q; i W3 b# Y& o
- Palette_Data
7 T4 R1 p3 k h' Z6 } @; q% I - .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F5 [# P. d7 f+ ~: e7 d1 p
- .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
3 i( E: u3 S0 D \5 P# T: B: N- k - 2 K" `+ n: L+ t
- ;==================================================5 a0 u! u/ D8 B0 V. ` y
- ;命名表初始化
' ^5 a9 ?) C x1 b7 L - Init_Name_Table1 e9 c: {9 \* U* F- J2 Y6 E
- LDA #$20
& W' y Y4 z0 q0 v - STA PPU_ADDRESS
( s, h3 p" ^9 _; c2 O+ u- R; O0 o2 L - LDA #$00" Z% k& I0 k) y5 I3 p
- STA PPU_ADDRESS
' e% `, P3 d& M( x$ Y7 l6 U( t - LDA #$00$ ^; R) q- T8 H6 ^! E- X `
- LDY #$00
) B' P/ U- l# {) }% ^4 | - LDX #$101 Z- {- y) p9 y: p2 k
- Init_Name_Table_Write' N. l: T, A8 I P$ P" i) _
- STA PPU_DATA
1 g$ i' w4 S5 h3 ] - INY& j# Y) y: ` n1 g
- BNE Init_Name_Table_Write
( a0 N0 m& U0 u: H' A - DEX
' N# [$ t; { V" u - BNE Init_Name_Table_Write; I9 b {% V$ ]4 x" }" R, ~7 @. B
- RTS
7 W- r K }2 X4 t3 A -
. g& l2 w: F0 G2 j5 H ^9 l - ;==================================================
9 o) S3 j: a8 Y! X - ;调色板初始化3 p4 f: B+ P; Q/ ?3 e* e1 ?9 D
- Init_Palette
- O& B! K& t) Y' c7 y - BIT PPU_STATUS
" ^7 N8 j# |. C9 F - LDA #$3F2 O5 l9 A: k0 v# ]1 L# V
- STA PPU_ADDRESS5 B* F+ _) l5 k+ r% }% ?! E# q" t3 u
- LDA #$00
l, b1 Q; g; }) J' P. ?( L - STA PPU_ADDRESS
4 W5 _, d: E1 M l4 ~ - LDX #$00
) d! q. c) `; v, p) E1 ~ - Init_Palette_Write. d/ A& B2 A7 r3 D
- LDA Palette_Data,X' D( {) T( Q+ Q! D& P" V7 K
- STA PPU_DATA4 ^8 Q9 h9 {. W2 O5 Q8 H
- INX
w/ C9 ?0 \! }0 Z" O3 X4 ` - CPX #$20
- F7 D9 r* M( a, F+ g - BCC Init_Palette_Write
# O, R3 n/ L! T9 J, {' ^ - RTS
9 m8 N- q; R: l3 }2 w) u -
3 l3 S( z7 [/ L; c3 n - ;==================================================4 b1 D" Q( N' r3 ^9 s
- ;设置命名表属性8 P2 Z( z! l' g/ L, d4 w
- Init_NameTable_Attributes
x8 ` y) C, Z) f S - BIT PPU_STATUS
: y" u; i# L& m) K9 r0 B - LDA #$23: E7 n1 q: s Z0 m
- STA PPU_ADDRESS! G# M0 j# r- X" C; P3 w
- LDA #$C0$ P+ [' z z5 i
- STA PPU_ADDRESS G$ a3 u" @+ c
- LDX #$006 O" ]1 ^1 a/ z/ F8 P
- Init_NameTable_Attributes_Write9 d( e1 u% ?$ l0 f. R* U8 t+ G
- LDA Attributes_Data,X0 ~) S3 f A9 X+ G8 m$ N. L+ c
- STA PPU_DATA
' [6 T5 ]7 h R G& P0 ^ - INX# T3 r1 E7 k3 ^7 @
- CPX #$40
9 g6 K0 y4 z1 R2 b - BCC Init_NameTable_Attributes_Write
) G) ^) q" X& {3 R U. t - RTS1 B4 r7 o+ s1 b
- & ^: C u2 q. |
- ;==================================================( k. `8 n1 r8 S2 r, a) o
- ;初始化命名表文本1 H; }9 D5 D3 \! v
- Init_Name_Table_Text
( G5 s' B$ D% ?) A# R4 c3 ~1 { - BIT PPU_STATUS
8 b0 H9 ?" x8 z @ - LDA #$208 v( e) b* @# ?; ~
- STA PPU_ADDRESS
& I4 L; |8 Y+ B' l: k# t5 H - LDA #$002 Y M: a% ]. I7 p6 S! o
- STA PPU_ADDRESS; R [0 A0 @4 U6 M" |
- LDA #$00
) B0 S Q# |% E/ u - STA FC_Data_Buf
- B" O- d3 x; C, N' m3 N) D c& w - LDY #303 H5 @. ^ t" ?! N0 {
- Init_Name_Table_Text_Write/ L6 u6 |0 a1 }* Q
- LDX #32
* `1 p+ R5 w% a. ~7 f! _ - Init_Name_Table_Text_Write_Char: M7 q0 B7 V: J+ N7 o
- LDA #'0'1 G) |1 k% m4 n/ s& | V$ b
- CLC
2 y! Y! W$ P* n" }) @, L - ADC FC_Data_Buf
: @2 v2 w. D( m' ^9 m5 u+ s - STA PPU_DATA$ r5 `% l- r' Z
- DEX, T5 G0 s* Z% Q& `
- LDA #$14
8 q5 v% ?% \) P' G, [ - STA PPU_DATA8 q: r) R$ Y0 q, s
- DEX: D8 Q, f4 ~( G
- BNE Init_Name_Table_Text_Write_Char& T; _& X6 j+ e4 f& W: L
- INC FC_Data_Buf L9 B! u/ T4 U: ~3 _* G. b
- DEY
! q2 J; f- f, k6 X - BNE Init_Name_Table_Text_Write8 }; B4 I+ q/ `
- RTS
+ m2 P; W3 P; ~, R, h
! Y& ]1 f# d" [; u. ?- ;==============================5 }. j! f9 B4 s% A! L
- Init_OAM_Ram;初始化精灵内存
- Q( R# M1 `/ f( c - LDX #$00
+ P" L& k, a: R1 V0 D/ g - LDA #$00
( L! P; S% v. [, r1 W7 N - STA PPU_OAM_ADDR
! p& ?" C1 t( N) J9 _; J; U - LDA #$F8
; b; l; x+ R; @( K+ h* A+ c, p- K1 t7 h - Init_OAM_Ram_Write0 J/ u$ }: @" w& k u O; \
- STA PPU_OAM_DATA( r Z, @. a' y0 j0 U
- INX& X0 q3 [3 a3 I& F) p! ?) u; l7 Q- Z
- BNE Init_OAM_Ram_Write9 i1 Z) e1 t5 w, i0 V
- RTS4 z8 ~" [$ t3 F( U5 y! [1 X
-
~6 o/ M$ ?! M4 j1 N - GamepadProcess;手柄处理+ B* k& { P6 `9 d3 O3 L
- JSR GamepadDatacan
! P4 H& ^ u& X& |# ? - LDA <Gamepad_0_Value
8 i' `* `0 c( h; _4 l - STA <Gamepad_0_State4 {* ]2 A7 |" J3 p- B) @) t
- LDA <Gamepad_1_Value; b1 U( Y/ e* B8 C2 V n
- STA <Gamepad_1_State- \2 i, z. |- {( g
- JSR GamepadDatacan
/ ?) G- z$ Q% n% j+ f* a# A! Q - LDX #$013 y# i% {1 j/ X2 U& ?
- GamepadMergeCheck;合并手柄输入检查
3 X6 z. z1 y, X2 H. R" h- _) N - LDA <Gamepad_0_Value,X
( a" S- O( ^& G. f4 r/ E# Q - CMP <Gamepad_0_State,X
$ {5 w0 s h; t; @# f X - BEQ GamepadMergeInput
% B3 p0 |, ~0 [% H4 f: ^ - LDA <Gamepad_Temp,X6 `7 ^% o5 q% b$ |8 l
- STA <Gamepad_0_Value,X6 W, N v! C6 ` s, I1 x
- GamepadMergeInput;合并手柄输入* c% v2 X" B8 n
- DEX5 x5 j& @5 e. p3 `% y
- BPL GamepadMergeCheck
5 a' L% n: _9 D1 b - LDA <Gamepad_Merge
N6 d6 r$ X$ }7 ? - AND #GAMEPAD_MERGE_FLAG
! W+ C6 Y1 ], ~4 d: F* G- ]* l - BNE GamepadStateProcess
/ @% I; v+ Y6 \" y- e/ @ - LDA <Gamepad_0_Value
& ]/ ?8 ~& b3 L' P - ORA <Gamepad_1_Value5 i4 g% x3 w2 d/ L; C1 S. O* I6 p2 ~$ x
- STA <Gamepad_0_Value
; D' b3 P. V# [! l# r* u - GamepadStateProcess;手柄状态处理
8 C* ]; d1 a' b" V# l- a - LDX #$01
8 n( J5 W' o+ I& L6 A$ D% @1 p! [ - GamepadStateSave;手柄状态保存
# C8 [# }2 ]" F" Z7 v# U) Q - LDA <Gamepad_0_Value,X
2 s! [: p' N6 E+ a+ _ - TAY# C- W+ }4 ?& N9 y9 U
- EOR <Gamepad_Temp,X( L6 r+ G+ m& B8 G- j& w9 P
- AND <Gamepad_0_Value,X
+ K" y8 y/ C8 k' m2 i4 _ - STA <Gamepad_Once,X5 J2 }, K& b5 D; [% x2 W7 i
- STY <Gamepad_Keep,X8 J$ A$ S5 r# U {: E
- STY <Gamepad_Temp,X; k# q: Z* f: Q+ I
- DEX7 B* ~: ]: ?% p: u2 [) C
- BPL GamepadStateSave3 i- O8 @/ o) Y( I3 R: X( P
- RTS
. t% X8 H6 D+ ~4 I+ f6 Y - ?+ Q c' ?* n+ D9 f) z
- GamepadDatacan;手柄数据扫描
" f. E* Z4 B- U" L - LDX #$01
' U4 z' T" p4 }' w5 d- Z! N4 U. M - STX $4016 o, c8 k# i7 K1 s% r
- DEX5 E2 `; V8 a3 L; e1 T2 f
- STX $4016
! E5 N, R" m, s* l$ e4 [ - LDY #$08# y4 t$ m. f9 n% u& C
- GamepadPortScan;手柄端口扫描& ?$ }6 A, P3 T1 a- Z( u
- LDA $4016" ^- ^, ~. f+ N) h0 d
- STA <Gamepad_Port_Value4 z0 ]9 Y Y2 _5 T
- LSR A+ k( g, t, y# q2 w/ e$ M! A
- ORA <Gamepad_Port_Value) W$ B. Z. d& H* Q" S8 s/ F
- LSR A
8 O4 z. k! Q* }5 k/ Z+ j/ g - ROL <Gamepad_0_Value2 \8 t% z% E' L% c7 v p
- LDA $40170 R9 m7 U3 y* M1 Y
- STA <Gamepad_Port_Value7 b/ X% _! u& O2 `- x I
- LSR A
) X! z# [/ E; ^ - ORA <Gamepad_Port_Value
7 L5 N" \* q3 N4 N* m; u - LSR A- b! x. t6 ]! V& F% r* T* n
- ROL <Gamepad_1_Value& t( J# V9 h: R3 o/ K g! N) k2 b
- DEY6 q& ^: `+ a' `0 s
- BNE GamepadPortScan
: ~' k( T: L; |! l$ s* c - RTS
2 Q( T g( f ~8 f1 f- ` - ! F* m: p! w. o" ^( ~0 f
- ;==================================================( p- P# p( c/ `- k: T0 ?/ B' e
- ;PPU处理
& Q9 s9 L! W+ o& g. i$ G: f! C - PPU_Process+ ~/ `% [( G+ X' L
- LDA #$00
P$ [7 P/ F: [7 x. a" a - STA PPU_MASK$ [5 F3 ^9 R/ n& l
-
; C' V/ o3 F+ Q1 E! m7 u# P - BIT PPU_STATUS
/ g* M) N1 i$ J4 h - LDA #$20
, L: R* ?! y6 U$ H( ] - STA PPU_ADDRESS
- {0 ]9 f) b! f5 L1 m2 Z8 }1 b - LDA #$001 p/ ^. |- ^6 h5 L' x
- STA PPU_ADDRESS
7 c& x' w1 T, g - % \. T. @& g) A
- STA PPU_SCROLL. b' B) C2 G5 e* z4 k: y* Y& Q) v! h" W
- STA PPU_SCROLL6 {3 C) f. ]; a+ H' A# K) ]- K, h
-
5 V: d9 x% M7 P' j! E& e - LDA PPU_Msak_Buf2 h& U9 N) y2 Q/ l% z4 ]
- STA PPU_MASK
. \( J& d! J! i( I
$ }, t, y' G6 E3 ~5 Y- RTS
" K3 u9 k% U. O5 C - ! ^+ ]- E! v, B% m0 F
- ;==============================
: y9 Y" H3 L& l3 c - Time_For_Vblank;延时等待
W' i4 |4 |5 W - LDA PPU_STATUS
" t& F4 e/ i+ Q- j5 t - BPL Time_For_Vblank
9 ]0 i7 R5 ^) p! T6 m/ Y4 f6 x3 a - RTS5 T; ]9 O% B, S$ m& T* N) j
-
+ o+ L- i4 H8 A9 K! X# G* F9 j7 j% y - ;==============================
; }: k: ?: x4 C4 e' Y2 x" x) k* J - ;初始化MAPPER19
; V a, p% U% u5 G7 k6 d& a* g - Init_Mapper19
! c' j) Z7 x" Z8 t) K' ~2 v- r - LDA #$00- q$ J, ]$ }7 z2 g, _
- STA M19_CHR_0000$ f. B4 k1 @! S9 _7 Z3 b' |
- LDA #$01. L! a0 M6 }: v$ c6 _8 m% x
- STA M19_CHR_0400
# H& `+ r p5 j3 l, j H+ n. D, A; u - LDA #$02/ i1 n2 A3 l q/ L" s
- STA M19_CHR_0800! g1 O9 A' F6 a( {
- LDA #$036 p D0 B8 h, q8 O1 _) e7 C
- STA M19_CHR_0C00* l& g: n8 H0 t2 r f
- LDA #$04
7 N* Q9 W7 ]3 U& Y! X% \5 J+ Q: V - STA M19_CHR_10006 o: _8 o, \3 i N) D- @5 V
- LDA #$05
. U' m' _3 H) W' S - STA M19_CHR_14008 q0 l; z& O# a
- LDA #$06
$ N/ Y3 o7 i: c) p) o" M" C. b - STA M19_CHR_1800
5 q. P% O# h8 u5 {2 y* c - LDA #$07: j6 r! v$ F; Y' R" |. F
- STA M19_CHR_1C005 `8 J, _7 l3 D
-
- T" \( A( m0 S$ U8 L8 s; X - ;禁用IRQ
0 S, A; j x$ R& c7 v# ?& O - LDA M19_IRQ_COUNT_H, L1 s* h3 D/ K( X' S' u. P
- AND #$7F
, j N. Z$ G! S! n* a% ^3 g# H - STA M19_IRQ_COUNT_H
$ w% ] E9 G& X! ~6 D1 v6 }- m) h! q - : j2 U. A( I5 x! C
- ;命名表
( ~' m9 q0 j4 M; d) U; d, A - LDA #$E04 j* f$ e4 q' I' S: g
- STA M19_NT_2000
3 P2 {& L; Z' S% F S: J( S - STA M19_NT_2400
: g% f) p' i& a7 B+ e - # y! S% M. k; W1 k5 n
- ;命名表3 K: h B D( ]3 u/ g! P0 }- K* N# z
- LDA #$E1) ^& r( B7 k) p6 p9 W+ H6 X
- STA M19_NT_2800
4 b8 y; z, ]6 [8 m4 C - STA M19_NT_2C00( t4 p, o8 i& u* M n
- / P4 Q% Y) N. a0 a5 a) w
- RTS" X) Q# U2 _+ N3 p
- ; R/ e& v/ B6 H P
- ;==================================================
3 O9 ~ V S/ | - ;重置中断处理
& ~9 L' `% k3 y6 { - ResetProgram
0 f. `- C# s; ?* p - SEI
- R6 v2 k) @6 }; g, O! W - CLD3 ~2 a2 S* U' U( I% _1 d
- LDA #$002 O; @- H. w0 E# X2 W! Y' g$ _
- STA PPU_CTRL
$ w) U% @0 L* x( T - STA PPU_MASK( ?1 Y, L: r: [: ~2 F
- STA PPU_STATUS; e( y9 M3 ]* w$ y7 D8 r' O$ Q+ ~
- STA JOY2_FRAME
! I! H( d' G9 w' S - STA APU_STATUS
# V- q8 R, ~/ j4 k/ g - 9 o7 q8 m! f G z% B! U2 E$ P
- LDA #$C0
/ N0 u! h1 z8 c! i1 K$ u, ~" J5 c - STA JOY2_FRAME
1 L5 Z# i, [6 v( m) c. R -
" a8 L2 O1 e5 p' H; W4 L - ;等待vblank, ^* A0 Z7 ^; R6 U
- LDX #$02) ~; z/ t& W. [' H$ J/ [) x% W
- Vblank_Wait_14 x3 \; U4 p1 C. G
- BIT PPU_STATUS( L# y3 d/ @, _) Q2 @3 n, @
- BPL Vblank_Wait_1
; Q+ N- Z/ M) [! R# ~( ?2 B - Vblank_Wait_2
/ @; l& m+ o; O+ Y* q - BIT PPU_STATUS
5 e: I! i% ?# U7 e - BMI Vblank_Wait_26 h" t8 w9 L! h H8 n
- DEX
! j# m- W) j! `" \+ v - BNE Vblank_Wait_1
: f6 z- U! G5 w# I8 a" v2 S -
& j1 e* s* `7 P4 a - LDX #$FF& d" w x; j9 [3 n- d) U
- TXS( ^1 ~7 F0 }. Q
- - K+ K y/ j% W
- ;初始化MAPPER19
+ b5 A( }; G6 h+ }4 K( T - JSR Init_Mapper19* w2 v* w9 L6 I' U( X* s' X
- : y; X& _. o3 W3 j t
- ;==============================1 ?' T. {& ?# ]' d4 P
- ;RAM初始化
3 w# ?9 Q# G o7 v2 Y+ t. b - Nes_Ram_Init
1 d2 d8 @3 ? g) G! h - LDY #$00
: d/ Y$ B i* {+ ~( w/ d - LDX #$08
4 W) | @% U( u1 h% W/ w - LDA #$00: z& G0 z+ R" M1 m; N4 H
- STA <$00% ], f2 G9 _1 Q
- STA <$01+ w( x" \$ O8 l8 e4 a
- Nes_Ram_Init_Write6 o- s0 D; ?/ p
- STA [$00],Y
3 C( r1 j; j2 C1 E# @; b: Y3 X - INY
, D G8 H! X6 j: a - BNE Nes_Ram_Init_Write
% M7 }2 q$ J* z1 N V4 m3 d - INC <$01% I8 K1 }6 `% L, B6 B; j2 R V
- DEX9 e( E$ A5 }" j5 s
- BNE Nes_Ram_Init_Write' v. C$ ^# D$ j$ ]* s0 j+ F
- 7 s" `- r0 T. }9 O
- ;初始化命名表
4 T0 o! w3 \& a7 O9 V* w7 M! o - JSR Init_Name_Table- f J. ~5 U( j1 K9 B
-
4 I2 b% z( z5 Y& t: f: c - ;初始化调色板
; w' f# v" G' y0 N- ]" o' x& o - JSR Init_Palette
% ^( h* c6 a6 q! _6 V# ?0 t -
7 f- |8 b; ]3 U6 j - ;初始化命名表属性8 b* r4 K- y( k3 C
- JSR Init_NameTable_Attributes
* O9 x' w! r# [! G- S -
6 c. p: w+ U4 A' C - ;初始化精灵内存) Q7 ^ S3 k- P- D8 j
- JSR Init_OAM_Ram
/ G2 w6 J, t2 G# O -
/ `# Q3 C t, C+ o - ;在屏幕上写点东西) M! b) l% n X& i
- JSR Init_Name_Table_Text$ L; x$ b! w6 T. y; n0 Y
- " r4 |7 O9 U) R) ?
- JSR Time_For_Vblank
/ f2 x6 h4 e& {; j9 X - ;开启PPU控制) O# Z/ J$ i. E# B* C4 t4 V
- LDA #$A8
, |. Z9 w2 B+ H) {) }3 D* u- H - STA PPU_Ctrl_Buf
, k- Z4 h* @ W0 a( ~ - STA PPU_CTRL
. a S8 ^; |8 X& { - % X- a* a' g% x
- ;开启PPU显示
+ d$ D1 `) z) M6 W y - LDA #$1E
. m' T, r% S$ i( { - STA PPU_Msak_Buf
$ E. Q5 c, t& J7 ?/ h$ J - ( ^; S! B3 X7 F0 n7 H
- CLI( `- j# ?" N+ U3 U: L! P
- JMP Loop
, ~6 G3 i, j3 G -
+ h. v2 n+ _0 ]: v - ;==============================! g. a z1 I, p7 R4 {
- ;死循环, 等待NMI中断5 r6 H' Q' R8 A3 W( i
- Loop
2 o2 }, e6 y, r& c - JMP Loop3 a5 B2 i+ W( M2 w
- - n8 I4 z, |' E
- ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967
# f; h4 x+ D3 l! a2 }# m. S: w - 6 J, ~4 @( |3 n0 A$ K, Z! ?4 H
- ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)
9 M ?8 V9 t( i - BEGIN_LINE_CYCLES_START = 32768 - (4103)6 q) R9 l6 j& c: ]
- ;==================================================% g" d* y- G) `0 I( _
- ;NMI中断处理% \; T9 V% m3 x' r0 C7 Q5 }! t
- NmiProgram
+ ~! o- H- T: P4 t( p N# [ - PHA6 w* S. Q- `: ^
- TXA
; P; ?# Z; r- k! D# g3 W - PHA. [* U7 s2 G8 d- c
- TYA
& y( w+ u; @- T w3 {/ ` - PHA' k& ?+ j3 h4 N5 h( J; A: e
-
' \" u! Z( `8 P& v - BIT PPU_STATUS
6 O1 V# a% j& A: q; a6 K4 s - 7 X% E M3 o) o- M$ C
- LDA #$00
3 q2 U3 | ?- ` - STA IRQ_Index% o; j6 [" s- D
- 7 a3 s( e4 q3 Q' \& s4 y
- ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动" w' F g5 s8 L5 ?: Z+ t
- LDA #LOW(BEGIN_LINE_CYCLES_START)
% f" C& w% Q& ^ - STA M19_IRQ_COUNT_L
3 _/ Z& `- T" {, z" S/ C* y - LDA #HIGH(BEGIN_LINE_CYCLES_START)) N. d/ s' G9 z4 y
- ORA #$80
2 ^" ^& V3 L6 R2 ^- Y' X/ u1 q - STA M19_IRQ_COUNT_H
* O( D7 |2 d7 q1 `$ K% ]8 o9 W - CLI; s G% W$ ?8 H1 V* _
- U. }! I; y: V9 ?6 }
- ;关闭PPU控制" Y0 W+ V4 }! i
- LDA #$00
5 P6 n# p W) Z$ @ P+ H - STA PPU_CTRL
4 |" G5 F9 x5 D/ t2 E -
; d3 J, T% Y* t! b2 a - ;处理PPU% X3 A! F! O. c2 H) b z4 g
- JSR PPU_Process
0 }5 k9 S8 x2 U - & Z9 p) U/ @( k1 V6 Q
- ;开启PPU控制! C2 S; t5 d" c) m+ i" ?2 j
- LDA PPU_Ctrl_Buf6 q ?: T0 i7 O( k% [! F+ O
- STA PPU_CTRL
S9 K2 Q3 J& O3 ^. ^ - , n+ y. T' L ]% F
- ;手柄处理
; Q6 [. X1 a5 E) {5 g) d - JSR GamepadProcess
* m+ ^& @7 v, \3 F6 o2 {' n9 v - 6 i' P& A3 R' C9 D
- LDA #$00
! B j; u. Q0 ?6 \ - STA IRQ_Index h' ?* c2 A1 ?
- ) ~# \. \3 g( h8 q/ D1 v9 x
- PLA2 l6 Q5 m. v2 w8 M1 I: N/ ]
- TAY
& {7 Z+ c# N* z Z2 \* a - PLA
0 h: o. b' D4 R# ^ - TAX& Z( v% D3 `9 O# h l [
- PLA
0 ~3 E# o( F& T - RTI J9 c, Q M9 V' L
& @) }: l* n [/ ?" C T- ;每行扫描线113.67
9 m% k4 J; y) }" } - ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)9 ~7 p* O2 i3 `% o
- BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
( }% K) A. r2 O& [ - ;==================================================" X1 X: X/ Y" ]* O2 Z, L% w; B
- ;IRQ中断处理( s% e4 v- A# z- ~. o4 y
- IrqProgram" {2 Y8 Y. E" H2 C& X
- PHA
& S. I2 O w6 q7 r7 ?8 ?( V2 L0 Z - TXA
, Z- m- g3 {2 W5 O4 { B - PHA
; ~7 i! `& z3 g9 i) M1 s - TYA! C" E1 w) M, H; a0 v9 l4 }' ~
- PHA
6 k6 A6 u8 T- f, u1 v; `5 k' e -
3 D; J5 h) K- _" M6 }, |# ~' n6 U - ;16条扫描线后触发IRQ8 j F/ ^2 C% h
- LDA #LOW(BEGIN_LINE_CYCLES)1 v+ I. S9 T( N; g# v* B
- STA M19_IRQ_COUNT_L
9 W7 t" c' Z! w5 t3 k - LDA #HIGH(BEGIN_LINE_CYCLES)
( \2 c5 |5 s1 C4 M" K - ORA #$80
- \& k5 Y x% T% ]8 B# R% ]) k - STA M19_IRQ_COUNT_H) Y2 ]3 F8 e2 t1 o/ Z4 S
- - f+ S4 |( T$ ~* Z
- LDA <IRQ_Index, s' F) ]0 f8 L( h: j2 H) T" R f& g
- BNE * + 4
6 W l# R: P- V0 E0 D$ P2 L - INC <PPU_Scroll_H
* _" I9 ]: c) v+ e - / d K! r# g: F$ m3 Y! u
- ;设置屏幕滚动
! X S( M7 A3 A. o3 I- }6 Z - LDA <IRQ_Index9 ?/ p5 C" U( z% u4 L2 N) }, ^$ Z
- AND #$01. k" F+ u' O! H) X' E% p
- BEQ Irq_Scroll_Right
1 ~$ Z3 a! n" ~+ q, F
) R2 R ?8 V5 L q- Irq_Scroll_Left8 U; B9 F4 W+ @. P/ m: B! H* x
- BIT PPU_STATUS% T5 b/ F" z: k* E* i
- LDA <PPU_Scroll_H, y9 W/ D4 V% W5 b. W- J9 H! W. Q
- STA PPU_SCROLL
) y7 S9 F, X+ K9 m - STA PPU_SCROLL; l$ h7 s' z$ e: R
- JMP Irq_Scroll_Over9 i& |+ Y/ S1 K. R5 k& @
- : N4 Z& H$ j- g# F) ^. }
- Irq_Scroll_Right6 s) U+ \" v. U8 e) Z5 p4 ]
- SEC
% k6 P# e' k9 j0 t - SBC <PPU_Scroll_H
8 [$ X0 W& G0 B0 w+ y8 B7 T4 M. w - STA PPU_SCROLL
% x5 z- v$ `/ r n" d l1 l8 x+ o$ C4 l& p - STA PPU_SCROLL
+ v6 p$ y; O9 E4 G) X0 z: k - Irq_Scroll_Over h% B7 _# ^4 X6 [. D [( k% J
-
& Y+ |; Q: V ?0 X4 z: | - INC <IRQ_Index
4 r3 [+ |: I2 H$ S; V -
5 l1 J$ U M5 L8 r' I - LDA <IRQ_Index8 z0 {& e; B$ `9 G B! v' G# U7 w
- CMP #14: L: z/ Z0 d* d5 G4 f1 Z# e/ G
- BCC * + 10
) [$ V! E# p. g" V- { - LDA #$00
" ^1 }* ^# Q& k& T5 j- }( C7 k - STA M19_IRQ_COUNT_L" F( I c& K k9 C& d+ A1 x( U, U4 ?
- STA M19_IRQ_COUNT_H
( \3 a- F/ w5 s9 L% Z4 B - & p# I) @! |* |
- IrqProgramEnd
+ x/ J$ W t. a! _- h4 Z9 w3 c6 a( ] - PLA/ J: o K# [/ g3 t5 ?
- TAY
W. k! a) U# o( V; T, h( K - PLA9 c% S8 C) j% d
- TAX
* J9 h5 Z& M3 R( x! b - PLA5 V1 b+ p" u; E
- RTI
4 C! k; q3 b3 } - 2 c0 }% @% I8 [8 g) X1 t
- ;==================================================
/ _6 R6 m: z2 I) _1 T1 P B - ;中断表
5 ~5 y( i: S% c& Z) ] - .ORG $FFFA
; @4 Q J, l; b& }; X# }+ U4 H - .WORD NmiProgram
+ y! r! y% ?3 b5 Z q. \ - .WORD ResetProgram
`3 `6 p2 Z$ `. P - .WORD IrqProgram
复制代码 ( V7 w) ]; ^6 |. U h C+ n% z
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|