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