|
|
- ;[FC][Mapper19 IRQ]: e" O# x% e- o% W
- ;FlameCyclone 202307106 I' [! N. R3 u
- ( K% m& Y9 N) s9 e1 E! K: M
- ;文件头
( n- J7 F; i7 p8 D& Q - ;======================================================================- y, ?; Z! k: A4 l$ x( \( y7 q# f
- .INESPRG 4 ;16KB PRG 数量3 h# v8 Y0 w7 j7 ?, S
- .INESCHR 1 ;8KB CHR 数量3 K4 a8 P3 ^) S* O" [, \4 z3 o# p
- .INESMAP 19 ;mapper 19! e0 J. {8 J' H$ \
- .INESMIR 1 ;命名表镜像 0水平 1垂直
6 g7 R. ? x) B' k. [9 z - " e3 j2 m! ]3 D7 j* K- `+ P K
- ;必要条件 u: _$ c& Y% s/ e4 ] k4 L
- ;1.持有CHR ROM. `& }1 D. f* d N: |# j
- ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$10000 |7 z# p! c! F% h/ d& G6 c' I
- ;3.精灵内存(OAM)不为空
1 ~$ n0 R/ S- k* Q2 s( N - 5 Q1 t) w* R: v* A _- N) w
- ;==================================================; y# U/ K6 K d# J9 u. C8 b6 A
- ;NES端口常量
: p. @' Y) |9 \2 P: u0 f4 Q9 y6 _0 { - PPU_CTRL = $2000 ;PPU控制寄存器0 Y0 b1 n. u* ]- O
- PPU_MASK = $2001 ;PPU掩码寄存器' U {% C0 ?/ A! `$ ]. p
- PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
3 E+ o8 L/ P! c, s# a) j( C n - PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
! O% p( V4 E& |% n& I - PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
3 w- v2 Q7 o1 I0 A; E, R - PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
4 ^& @$ g' E+ q3 n5 ^ - PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
& y% p: o5 U* |! L3 A* F* N. J0 _ - PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 6 J, R- ?, Q" `% F4 `+ w7 e
- OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
( R- G0 q6 Z6 n- E - APU_STATUS = $4015 ;声音通道切换
0 t3 `5 P" F% f. ? v' i% [ - JOY1_FRAME = $4016 ;手柄1 + 选通# f: }* w* t; p4 ]( z% `
- JOY2_FRAME = $4017 ;手柄2 + 选通
+ J7 r/ h- |0 |! \: V: S* w - . Z* G( C: I. [& A( }6 k
- ;==================================================
! u( V- K+ Z0 [ I1 Y* _ - ;MAPPER 19端口常量
* d0 {: z4 m4 N- j$ {5 L" y: y - M19_CHR_0000 = $8000* ^ w( W& l5 ^% ~ r
- M19_CHR_0400 = $8800 T" [/ S- ^3 h* ?6 A9 D
- M19_CHR_0800 = $9000
9 n/ o2 }! a! s5 N2 Q4 n) j - M19_CHR_0C00 = $9800
1 ^1 r9 C) h' u$ P - M19_CHR_1000 = $A000 X \! g- q* K. V2 g- j2 P5 c
- M19_CHR_1400 = $A800
7 t$ Z- N' F, f# ^# v - M19_CHR_1800 = $B000/ h( q# J8 f% N# a( C! A( C l
- M19_CHR_1C00 = $B800
' y E2 w8 D8 H. y5 M7 N2 J: B2 w - M19_NT_2000 = $C000
1 W6 I4 x- @ ?8 L. `/ S - M19_NT_2400 = $C800% _' E' J c% W; \) Z9 Z5 A
- M19_NT_2800 = $D000; t% q+ n/ h0 d" C( d
- M19_NT_2C00 = $D800
5 J3 B" A* J1 [, q0 f% s - M19_PRG_8000 = $E000
2 I1 o9 G/ O' B3 f4 S+ N - M19_PRG_A000 = $E8003 W$ @+ @, Z+ ?9 z' ?- v7 z
- M19_PRG_C000 = $F000 |4 J d, d$ S* n& ~/ S+ R
- M19_IRQ_COUNT_L = $5000
5 H3 ^' }1 l& Y5 R$ w. |' [* W$ Y - M19_IRQ_COUNT_H = $5800" P# l+ G' Y' s. S' Z G0 i; W
M# K" @$ h2 I0 @5 e5 _- ;==================================================: D0 ~3 w5 e, v* i4 u6 m4 W" s
- ;程序块配置8 f4 H: B! ]5 n( T! c, z
- BANK_DATA_MASK = $07
$ X+ Y: [2 Y& R( n% X6 | - ;--------------------------------------------------
* r/ I* c) s9 l# J; b3 F1 o - RESET_BANK = $07
+ `; {" j7 M+ |7 C7 T - RESET_ADDR = $FC00& ^; ~- f$ w8 r
- 5 J* I! g: i( r, e. ?
- ;==================================================
8 `2 P" h( Z; L8 K - ;图像块配置- i2 a; H" v4 G/ d+ T, u
- CHR_DATA_BANK = $08
0 [# g& }! K4 `1 k/ [& b - 1 Y& v8 {2 x: P# d5 w8 ^/ h
- ;==================================================
- d5 i8 @: \9 k9 L: g0 U - ;零页内存地址配置
3 L4 R1 }" P* ^* Q0 C - Use_Ram_Addr = $80
% F* L9 v+ V- p& J - PPU_Ctrl_Buf = Use_Ram_Addr7 e c( `3 |& H, f& {
- PPU_Msak_Buf = PPU_Ctrl_Buf + $01
6 @7 M. e, W$ d8 ] u6 F - PPU_Scroll_H = PPU_Msak_Buf + $01! {) B; Q# K" X2 {0 R# Y/ D
- PPU_Scroll_V = PPU_Scroll_H + $01! n) g' b9 e5 s- c9 O9 V. W
- FC_Data_L = PPU_Scroll_V + $01
' @, I& G8 a/ z7 U4 o" I - FC_Data_H = FC_Data_L + $010 D8 m% f5 W( n
- FC_Data_Buf = FC_Data_H + $01
+ {# w& ~7 B1 w - ;==================================================
6 r6 v( Q9 K1 F5 {" N+ D
# `6 ]$ O8 j( I. M- GAMEPAD_MERGE_FLAG = $04" P9 G) s, ?: }$ p( {' Z4 W6 x s
- + H2 A" o/ g& V: w N
- Gamepad_Keep = FC_Data_Buf + 1
( s( H, J' u" o1 `; \1 A( ^- j - Gamepad_Once = Gamepad_Keep + 2( a( n4 q! z4 U$ R1 Y
- Gamepad_Temp = Gamepad_Once + 2
9 j9 i/ D( _. Q9 f. j - ) ?$ Q; @, W9 M! E8 i% c
- Gamepad_0_State = Gamepad_Temp + 2
& Y7 y) l$ m U3 j- i - Gamepad_1_State = Gamepad_0_State + 1
. l- n f, N$ G9 k - Gamepad_0_Value = Gamepad_1_State + 13 O% U- w( J o. E4 e9 l
- Gamepad_1_Value = Gamepad_0_Value + 1
, I' B- b% ?0 z+ E, W/ D+ }$ \ - Gamepad_Port_Value = Gamepad_1_Value + 1
# I+ b# ]! W6 F, J0 P - Gamepad_Merge = Gamepad_Port_Value + 1* a* g( _) e: J5 b) c0 i# c
0 n A% \6 x9 F, ^- ;==================================================
2 x' `8 U5 G: K( C% R( G - IRQ_Index = Gamepad_Merge + $018 `( D' |% g) b- Y, ?$ c" t
- ;==================================================& w+ H3 r/ N$ R. w9 X1 V
- Y! _& O% C$ j: _ ]
- ;CHR图形数据
9 J# S6 O$ w; \6 d) W i - ;==================================================! b/ ^2 R: w/ A; D/ b9 Y$ O
- .BANK CHR_DATA_BANK
5 h9 l6 Z2 g& y7 x, \# T$ I1 G - .INCBIN "chr_bank/chr_data.chr"* _: `- u* f" @5 e2 u6 N0 R8 Q; B* I
-
: |! Y, W8 A; z- \- q - .BANK RESET_BANK & BANK_DATA_MASK
9 s, o- H0 j+ p8 B, j& U5 s% Z7 k - .ORG RESET_ADDR; b) ?) K% h, M# h# D( S
- ) d3 q# [2 z6 i, [5 V& y/ x7 k
- ;--------------------------------------------------
4 U9 V4 v0 Y* ]% ] S( L& P& [% \ - Attributes_Data- P2 Y s1 p( V5 a" N, {' c
- ;命名表属性" q- C+ N& h# [- z( B6 y5 t) p
- .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
% A( i7 l0 U$ O! @7 p d* L - .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
& i5 ?7 T+ ^! d1 q2 M% |5 T - .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA! Z. W3 ]% |/ R3 |
- .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
) T" w. ^4 g: S$ ?1 V( N6 R - ;--------------------------------------------------
+ M$ y5 O, J" {% I$ x! a - ;调色板数据
# r5 d1 ~! c5 b Q1 t1 Y - Palette_Data
% A) D3 V+ r ^6 Z- b9 y0 g: N - .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F$ y0 ^) p' I! s' k7 ~( C/ V
- .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F8 i9 o0 s% k$ j0 Z* K5 m
. x" b, e1 e; q; u) C$ d- ;==================================================
. O# L* e" k1 W( ^+ i% e - ;命名表初始化
$ `+ {$ c2 y; M- s8 E6 ?: w - Init_Name_Table
3 K1 j9 _4 T2 A& ?1 ]/ E. k - LDA #$20- ]2 q, f. {- |' o: s5 [) K+ l
- STA PPU_ADDRESS6 q( E! @2 b6 S# U4 ~ c& |
- LDA #$00
4 M/ A6 F, X6 |( p5 P/ M0 O6 K - STA PPU_ADDRESS% v' N- J/ ^# Z0 I$ o
- LDA #$00
( e/ G- V+ b' G y - LDY #$002 B$ ?2 s4 A* F! U! E
- LDX #$10
0 g& [5 [( e" y+ g5 H' p8 ` - Init_Name_Table_Write3 N; O$ r1 b; }; O" ~, P. A
- STA PPU_DATA4 j! F' L6 Y0 m' ]5 t7 o, g
- INY
+ v& o7 ?% M' ^5 x- ?6 Q7 S - BNE Init_Name_Table_Write
) s: [4 S5 b) { - DEX. U& X* i6 [8 o( d9 I
- BNE Init_Name_Table_Write7 ^% d. ^6 W9 Y' Y
- RTS
3 [) ^: F$ |- h- o3 y% \8 ? -
# n6 l6 H7 _9 U: u+ e - ;==================================================
~0 c5 v# b7 V$ E5 l( H: V - ;调色板初始化* @0 b5 X3 D2 r O3 H l9 p
- Init_Palette9 h w7 N# R! A3 L1 k0 j
- BIT PPU_STATUS
6 d" J3 U' r- A+ C8 \) e' L. M - LDA #$3F* O% Y) k8 x! |
- STA PPU_ADDRESS( u9 ~1 z8 [( p B8 R4 q
- LDA #$00
& z% y, F7 }+ k6 S, J! h - STA PPU_ADDRESS6 y( \: p3 ? p: E
- LDX #$00% b& a: `5 I: Z( u1 `4 d8 u
- Init_Palette_Write: j, t8 G/ x0 S$ A$ J5 z
- LDA Palette_Data,X2 M0 i" i! O. S0 ?; _
- STA PPU_DATA
' S: W+ E5 E$ m) f \& {! i" ~1 P3 c - INX
9 h, d* r% E7 ~. v, f - CPX #$20
5 ~: X, J0 F8 B - BCC Init_Palette_Write$ T9 v8 J' d# A
- RTS
) p1 |( H; O- M# z+ { a, W -
9 p1 h/ y! t! f( j: m - ;================================================== ?) O3 s5 N5 \" d( I8 N3 x
- ;设置命名表属性
: J5 e! D9 F) r f - Init_NameTable_Attributes9 x& _. O0 v0 [3 C
- BIT PPU_STATUS
2 B% |1 ?, i& N - LDA #$23
7 ^7 R/ B+ r7 ?' |8 H" Z - STA PPU_ADDRESS, I; u3 \) I$ R! i A- |: l
- LDA #$C0/ p0 }! _& {/ a0 E7 h4 I" K
- STA PPU_ADDRESS1 A. i6 x( J- W6 T
- LDX #$00! ^- C5 |$ N1 Q0 f1 u+ b
- Init_NameTable_Attributes_Write
1 `% ]& V* f* ] P) J; r) k- U' Z - LDA Attributes_Data,X
$ {0 P7 R# G/ V5 o: i - STA PPU_DATA/ a1 [3 y6 {& O2 X' `" T+ s+ P$ y
- INX
8 z$ |3 g9 R! {* x! k; X. n5 _, P% Q - CPX #$40
; b- ~5 f( y% f/ z" k x+ ` - BCC Init_NameTable_Attributes_Write
. ~* ~# S- \! b9 H' G0 x - RTS
! H8 k# U2 ~4 m
" M# c5 e: G# b7 G# a& V/ m" P8 Y- ;==================================================
+ z+ X1 ]8 _8 v( _6 P4 j6 |3 u - ;初始化命名表文本+ R. Z9 B4 o. T) K0 m
- Init_Name_Table_Text
* `, ]- O- b0 @7 @ - BIT PPU_STATUS
) {2 P h8 X6 i8 \, o+ ~ - LDA #$20
3 l& `, u% G' Y - STA PPU_ADDRESS0 u# I4 z2 |" T7 G0 G- n
- LDA #$00
! ~5 W( f4 E3 v* l - STA PPU_ADDRESS) h, m L6 c# j
- LDA #$00
. r% M; @9 I) \* }3 i( H. c - STA FC_Data_Buf
% [' R- N. c& r - LDY #30$ w& |# Q/ v$ k( l& R& \* b: n/ u( x# P
- Init_Name_Table_Text_Write
2 z+ |& m% G' p - LDX #32
$ }5 _! o9 R" e+ C - Init_Name_Table_Text_Write_Char
% f( r4 q4 z0 I6 p3 l- Q - LDA #'0'" ]9 i1 b' D7 ^
- CLC
1 r3 D5 r! m. o: r - ADC FC_Data_Buf. x5 O1 P- S# e' E: h# I2 ^; |" N
- STA PPU_DATA( u+ @, F, m+ ~- ^: k
- DEX
4 e9 d2 y5 ?3 V7 O4 i - LDA #$14/ ?; @# ?2 j- R( i6 L* L6 p
- STA PPU_DATA7 s- _- y) o y: O3 { o
- DEX8 b4 `7 g* A5 e; ]& V/ ]
- BNE Init_Name_Table_Text_Write_Char
9 W; W" Z9 z3 x- o4 X - INC FC_Data_Buf7 x( H9 w% L5 z
- DEY( a/ v! {% X2 c
- BNE Init_Name_Table_Text_Write
" G. ^& j3 y# |+ B; R9 W0 l - RTS
* H( G7 ^8 r# V d: X/ n: r: j( d - 8 d1 U7 g# _/ ]6 Q5 E) M
- ;==============================
U* H; [3 p5 k7 W2 A5 x2 N - Init_OAM_Ram;初始化精灵内存; c, w. [7 ?, R* ?
- LDX #$00
2 K( n- [3 c% f. j - LDA #$00# F# z Q8 V: o# }4 j6 m
- STA PPU_OAM_ADDR2 A6 _- i; r/ x% {. W$ J
- LDA #$F8
. E7 v& H1 m6 K& l z' o! [ - Init_OAM_Ram_Write
. L$ M. h) E0 F - STA PPU_OAM_DATA& n3 Z6 v7 V: Q2 w5 J; O' N# n: x! w* x
- INX
0 P2 I7 ~; k. W4 r7 ?; `4 {6 D& q: I - BNE Init_OAM_Ram_Write+ C0 J2 }/ G/ T; X9 B4 Q
- RTS, ~& T' A5 q/ M, p a
-
* E6 P9 A: a" o9 u1 I W i7 ~ - GamepadProcess;手柄处理: ]8 |4 J: V+ X u
- JSR GamepadDatacan' j3 o9 q1 _/ W% y6 U, _# }8 t2 _& d
- LDA <Gamepad_0_Value
: @/ u& g0 z, V, k - STA <Gamepad_0_State6 { _# {9 F; C
- LDA <Gamepad_1_Value
7 y* ~9 z0 s: ~* H% ?, L, Y - STA <Gamepad_1_State
: O5 z( P1 b$ ~ - JSR GamepadDatacan* e/ E! A0 t# \% ~4 t
- LDX #$01, f* c( H. R5 m: v
- GamepadMergeCheck;合并手柄输入检查
0 Z/ Q: V$ |0 \8 B9 o9 N5 p$ h - LDA <Gamepad_0_Value,X
# a1 z: P: o/ Z; s# J3 t# D - CMP <Gamepad_0_State,X
, ^2 F6 @7 s8 j3 F) h( u/ c4 d6 s$ B9 r - BEQ GamepadMergeInput
6 S' Q& {& e, i - LDA <Gamepad_Temp,X3 c/ W9 G4 E3 u7 U( _8 K
- STA <Gamepad_0_Value,X* ]& q' [9 a+ z; v8 Y* x
- GamepadMergeInput;合并手柄输入
/ L; X6 R, s C& \. O - DEX2 h* ~, T# T9 Y T6 p
- BPL GamepadMergeCheck
( N* t) [! S( o/ C - LDA <Gamepad_Merge' p8 o5 f* Z: K5 p! q L4 O
- AND #GAMEPAD_MERGE_FLAG
' w" T4 T @) G- ?8 Z - BNE GamepadStateProcess
. w2 a" `; J; s( I8 k - LDA <Gamepad_0_Value7 f f L9 ~3 ?; U3 \" H. W: D
- ORA <Gamepad_1_Value
% V* H9 w# \ m o3 q% G - STA <Gamepad_0_Value" O0 q" f7 M% q3 b8 e+ H4 O' ?
- GamepadStateProcess;手柄状态处理
* o1 E1 F6 R. ~$ ^. O$ A! t - LDX #$01
) y9 ~5 p4 R% r% y - GamepadStateSave;手柄状态保存* n- v" G' S) X2 s2 V1 P
- LDA <Gamepad_0_Value,X
5 P2 ~7 q% k) T& P) g1 a - TAY
. v$ V$ G9 \+ e# S7 C - EOR <Gamepad_Temp,X
/ M- @2 V9 k3 h1 e9 r4 {- o - AND <Gamepad_0_Value,X5 j0 ~' e& \; H/ ` Z+ n
- STA <Gamepad_Once,X
. r& }9 b/ L# U' G. C - STY <Gamepad_Keep,X L1 F1 w& g( M; r: j9 }
- STY <Gamepad_Temp,X5 B' z% K0 `7 Q D9 ]
- DEX7 c' n; |" C" b# b
- BPL GamepadStateSave
" w1 e- E& g y, g3 n) D! Y0 i - RTS' R, x/ V) |+ f, H$ M7 Y }( q
- : Z3 @/ d+ y) B- U! v0 p3 L
- GamepadDatacan;手柄数据扫描2 ?7 z0 c( _/ A3 O: q. |* m+ c( w, k
- LDX #$01
$ `7 i0 L& Z6 d4 H' [+ L) M - STX $4016
/ s$ @0 a0 c" Z) O+ J7 W5 O - DEX6 C5 O( E6 ~, D' Z3 W3 W( C& X; W
- STX $4016
* n* T, t* @6 c! ~ - LDY #$08% T7 ~) X7 O$ @2 S4 Z2 \
- GamepadPortScan;手柄端口扫描
* g+ g. S; p+ f+ L0 g/ \ - LDA $4016# N+ r5 F6 w; ^
- STA <Gamepad_Port_Value
8 W% q+ B# B! i4 U( ] - LSR A' w' `# a6 w1 X2 P7 F" N* \( o
- ORA <Gamepad_Port_Value
" U, w5 ]! @% _0 H( p - LSR A& F& ^' [9 C1 W9 s& a- v
- ROL <Gamepad_0_Value
; L A. n" h, r5 l' d4 W6 O, a4 R3 Y - LDA $4017
8 E" j% u3 N2 K" t; @% v+ @& L- d2 b3 L - STA <Gamepad_Port_Value$ ?- i. N7 z2 X$ O$ s+ f- u
- LSR A
V, Z4 R! E t9 ^) M+ O4 M - ORA <Gamepad_Port_Value) h+ y- \( z* Z# T3 k+ @
- LSR A
" r. c T+ y1 i1 q$ i- H/ B - ROL <Gamepad_1_Value
: y. s& c8 m! o- e. A9 d - DEY+ e+ x- J" B6 x1 o
- BNE GamepadPortScan
+ B, g3 k# H$ L' l$ n2 q - RTS. {) ?; a9 p/ j6 u; p
- 6 P5 B7 A0 h* [( s
- ;==================================================
" ~. _5 K3 f M0 X - ;PPU处理6 v) b( V. b/ ]4 H9 I
- PPU_Process$ L7 ?5 i. m# U8 i
- LDA #$00
& G7 k' ~9 }4 g' J6 V: `# [7 ? - STA PPU_MASK
# n7 l" C. W: ^7 I4 |6 U* g. N. u -
) E; p3 N& g8 H6 V' h( r - BIT PPU_STATUS
- D5 B" o" [" X7 v* I0 o! l( y% Q3 I* e - LDA #$20- I6 ?7 e R% T0 Y7 C
- STA PPU_ADDRESS: R% Z, X) a/ d
- LDA #$00
$ q3 |: p; v( p+ Y3 h2 j( |9 N - STA PPU_ADDRESS
# A- g: p8 ]! x: d$ _/ y# C - ( I1 M: [& |$ N, n
- STA PPU_SCROLL
" c) S( n, r" w* j. v - STA PPU_SCROLL
0 T; T g* a8 t! R -
" e: v& y. `$ ]; { Y4 d& x - LDA PPU_Msak_Buf N" t# t; }8 U9 L1 h) s ?
- STA PPU_MASK; ?* K0 s& M& l" D# S
- 9 ^7 ^* } u, m
- RTS
) G0 b' o% L K4 |/ @7 w - 8 E7 t7 `0 |/ B" B1 s4 X4 x
- ;==============================
( A6 }/ O, ]+ G1 Z& ] - Time_For_Vblank;延时等待
) E" `8 C' ?4 K- I1 j9 e' | - LDA PPU_STATUS) M% ~ w# L/ c; b
- BPL Time_For_Vblank1 `+ f9 f" l7 R
- RTS% s Q/ n( w( Z/ I( w Z/ X# V
-
. c _1 l! }* u9 P; I6 b! V - ;==============================7 q; ~1 h. U y1 R* T
- ;初始化MAPPER190 z/ ~& W% t/ J
- Init_Mapper195 ?0 ?* d% \8 D4 C/ T0 t" B7 F1 u
- LDA #$00
# k' C) ]8 K$ m2 N$ R - STA M19_CHR_0000
# x4 ?" [+ p$ R8 t - LDA #$01
" B# o* K# n+ Z - STA M19_CHR_04002 [5 K( Q# Y8 s* x( Q3 \% f
- LDA #$02( f! f/ E. k% c- T4 j. n. M
- STA M19_CHR_0800 {- G2 B, `7 W+ k; U
- LDA #$039 k% s1 V. l# N" D% o
- STA M19_CHR_0C00) A% d9 \$ V1 G2 k9 ^# c% C9 @( n
- LDA #$04
1 D9 X) _: Z, o6 b& p+ u - STA M19_CHR_1000
) i; l3 B% i" x) U - LDA #$05# d9 z' [) i9 n- D
- STA M19_CHR_1400
4 E" |: l N. W, [0 \7 c* C" f+ c - LDA #$06
! b1 s: O4 C" \& t. T - STA M19_CHR_1800
5 }: G4 a) d- L - LDA #$075 g9 p9 P: X2 c1 G# c
- STA M19_CHR_1C00
* n! P; G5 X/ s! z5 d5 ]% d -
" ]1 a4 ]4 t ^% @8 N - ;禁用IRQ' o8 s5 K5 k6 t
- LDA M19_IRQ_COUNT_H
9 f# D' d, H/ H& q& G8 i: l - AND #$7F( B# c8 l! ^( p* ?$ ?
- STA M19_IRQ_COUNT_H7 Q& }3 [- R" h# w
-
& k/ r4 b* V8 v - ;命名表' \. r. ~7 _1 G/ y! A. D1 h2 H
- LDA #$E0
+ `1 o8 H) [4 J2 _5 ^+ ` - STA M19_NT_2000
; j0 i) i9 M: u, a - STA M19_NT_24007 ]! ^* l0 Q0 @9 f
-
6 t: I8 K/ q& ~0 V - ;命名表
5 f% g' x/ w6 F - LDA #$E1
; r" l w$ w! ~3 A - STA M19_NT_2800
5 _$ ^9 \- i- M9 z0 [ - STA M19_NT_2C00: s- B" Z& A5 Z' b2 z) w
-
7 Z! U4 `0 z9 m; Z" J+ t9 ]0 W - RTS' y3 {2 P: z- N( h: N
- 7 P' ^) p8 P1 L) W9 X
- ;==================================================
# P2 l! ~: H6 S& c& @ I - ;重置中断处理
1 s, Y2 {7 h- G; G; _# G. x$ o# r2 a* B - ResetProgram
. T x5 S C- x( y" U - SEI# c2 b# [7 S; s# X
- CLD8 e9 a6 b8 ? c& {# h/ x9 X
- LDA #$00
% ]# W# A" m Q8 U. o. b, ^ - STA PPU_CTRL
. N5 s, a2 u, o* [0 l5 l - STA PPU_MASK
: J. T. d! _: c5 {! c% m - STA PPU_STATUS
! U" ]- u! h( m2 U - STA JOY2_FRAME
3 l+ u5 R5 j) i - STA APU_STATUS
7 Z9 O& ^8 T+ X' |) [- W - : V2 D0 l3 R1 o% h& A" Q
- LDA #$C0
1 O$ w. z, N! a( S. |' J- ^ - STA JOY2_FRAME
4 {+ [$ S% V3 p) } -
u: h' v3 H) i4 W - ;等待vblank
& {6 ?7 }) E' F( J$ J5 @ - LDX #$02
* Z9 w' n% L0 r1 _# { - Vblank_Wait_1" |. D+ F8 ^. V
- BIT PPU_STATUS5 e5 Z$ V3 D& ~" r+ t3 K
- BPL Vblank_Wait_1
( }5 F3 \& N2 G6 ^4 j# I Y - Vblank_Wait_2
' g6 j; t" x: I, ] - BIT PPU_STATUS
" f8 z; V0 `8 C; z( ]/ Y5 Y# b7 w - BMI Vblank_Wait_2; Q: _/ x; `! U, M5 F ^! d
- DEX! T4 @# D0 X) ^; @
- BNE Vblank_Wait_1( T/ @9 N, b. R
- # F6 U4 p; T" J Z$ T L
- LDX #$FF
. d e. V" T8 i& w - TXS+ C8 G' ]0 i' }
- 9 b0 T d+ W9 B
- ;初始化MAPPER19
4 f8 j, ^- K% p* ? ] - JSR Init_Mapper19
+ ^8 Z' Q C1 {) [( p -
" p- l7 ]- j) ?/ n0 Q - ;==============================
# f5 ?/ f2 i2 V, V$ P* |* k8 n - ;RAM初始化
3 `. t) W% s2 Y" B - Nes_Ram_Init1 p1 \6 V6 S+ }
- LDY #$001 {% X* C! g5 l& t
- LDX #$08# k, ]3 H3 A5 l, \ } b+ @
- LDA #$000 a5 n) d$ R* n7 Q: E4 P
- STA <$00
/ Z0 [9 R* q0 y/ g2 I; F$ \ - STA <$01
8 v$ r2 @2 Z. B: q" }/ V# z - Nes_Ram_Init_Write
6 g+ O4 L' Z0 d k - STA [$00],Y
4 L3 I1 g/ Q) w4 Y8 u - INY) E7 ^* z( D3 |6 ^
- BNE Nes_Ram_Init_Write
( |3 |! Q* d. { - INC <$017 B# d$ B7 Q% T4 ]9 F& l9 ]
- DEX
) I' ~ u e2 E: c1 R0 b7 I - BNE Nes_Ram_Init_Write8 j. n) m, e" `
- + R4 T" d& R0 _. [6 V5 y
- ;初始化命名表, G6 s2 |2 T4 [ I, U$ V3 J: k
- JSR Init_Name_Table
2 \+ U( k7 J* P - * E" O" c! E/ W8 V) ]# \
- ;初始化调色板* E" |' P) y/ Y3 H8 s% v3 L
- JSR Init_Palette- U" }& i2 K: f9 c: [! V! O
-
3 A5 Q+ A K7 t, q, A9 l$ | H - ;初始化命名表属性, w9 e+ Q$ u/ E0 j: r2 C
- JSR Init_NameTable_Attributes
- m3 Z9 B" A) W, ]9 X* d -
; R1 a. m4 P' |/ T2 p) p - ;初始化精灵内存
- Z+ J$ T7 v- R1 |+ M. F& N2 t, I& d - JSR Init_OAM_Ram
; t- }' f. F0 Y+ r j# y# D0 N - 3 D+ p& I1 {( p' B6 [% O
- ;在屏幕上写点东西$ a' o0 G8 i( l4 I6 _
- JSR Init_Name_Table_Text' }) I: \( J/ W0 x" g/ `
- ! _ k1 T' g4 E0 [, p
- JSR Time_For_Vblank2 ?. [; t9 A3 N4 d% e. E1 N7 I
- ;开启PPU控制5 X/ `1 T% w1 S7 X
- LDA #$A8
; O! o8 D/ f# C$ `( } - STA PPU_Ctrl_Buf9 J1 `$ R% ^: r. V, b+ j% @+ r
- STA PPU_CTRL
$ V' x- O' L$ `! S) i -
3 u7 ?+ c$ _( J1 |3 V - ;开启PPU显示
# \: \2 F' l- L3 `, Q - LDA #$1E; e1 j6 q2 d5 n" j+ d
- STA PPU_Msak_Buf" W. l: e* c6 M/ L" ?$ s
- 1 B. `- ^7 ?) \7 d0 _% v( \/ j; O) X
- CLI Z% E( X& W& j5 _1 Y: O
- JMP Loop
l3 g# j; H% ~& z - 6 F! R1 w8 [. A& @' V. R4 u: X
- ;==============================" F9 ]) D8 `) Q, @, h8 F
- ;死循环, 等待NMI中断! `* S. s8 w6 b- ^
- Loop
% Z& m) o3 i3 X- _: H! C3 | - JMP Loop
5 Q- H' A5 h6 x+ c$ Q K* ^, f- f
7 j0 l, E2 \+ b- `" a5 K, d. {- ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.9673 k' a/ ^5 q0 f6 t/ w& @- q
- 1 v: b) @, I# C) M, f5 ]. A
- ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)( O3 X3 x2 D' |( s7 }/ z4 r- \1 \
- BEGIN_LINE_CYCLES_START = 32768 - (4103)
; C$ Y5 }1 q1 Z, G( V; k- {5 d - ;==================================================, L, [+ y* X. d9 W3 @ j; r. c
- ;NMI中断处理
# q/ h# \0 p q7 I/ b; Z - NmiProgram3 ]8 Y8 l0 X! j$ Y. p3 \$ y% p4 }
- PHA
6 O! O* K k7 @; D9 I) @: Y; g. { - TXA% A. H, i0 [9 q8 T$ {
- PHA
: A! B5 ?- |9 I8 }4 Y3 T - TYA" U( c) \4 p! @4 E; m
- PHA
3 ^' q$ g6 t/ W5 H9 } -
( `, _: |" I/ _9 C2 ` - BIT PPU_STATUS7 s2 @8 v( v( u: Y/ }9 X3 Q/ c% X8 z
-
' p# ]7 T! [- E% { - LDA #$00' s" F, l( N; _7 {% f
- STA IRQ_Index4 P+ Z2 U5 A% E( K' v
- 5 c7 D6 e+ U8 B" D' O1 V/ I
- ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动; ~3 g0 u% G7 \/ Y; s, ~
- LDA #LOW(BEGIN_LINE_CYCLES_START)
+ ?# J1 Q! v: k1 W5 }+ F+ i, ~" _6 [ - STA M19_IRQ_COUNT_L+ N/ Y7 @0 z# V, L- m8 `
- LDA #HIGH(BEGIN_LINE_CYCLES_START)
8 H1 d; u1 |+ `. T - ORA #$80
; {5 q' Z) J p/ a! q b; | - STA M19_IRQ_COUNT_H
/ C" \, v/ t2 R* } - CLI
; @8 o! c- [6 |& t' n! ^5 f - % _+ E7 E, t" {0 @- M
- ;关闭PPU控制
& N" T8 l6 [1 ]6 X/ ^6 D: J - LDA #$00
3 |1 D2 V* S" P - STA PPU_CTRL
2 a0 ^: q) S- [ - % W% P7 W! k5 n l2 G' R
- ;处理PPU/ O# C3 u. V. w
- JSR PPU_Process
- y$ I1 }$ R1 X: P, @ -
' V/ m' C2 [! `: _3 Q; ~- V3 y - ;开启PPU控制/ u- w- `, C# D: @3 H' U$ D! O7 A
- LDA PPU_Ctrl_Buf
' Y7 w9 R7 M: X - STA PPU_CTRL
) e* d/ [8 T) U/ }8 d - 7 S5 i. I; G- j3 M
- ;手柄处理
! q0 G, ]4 d+ ]3 d2 t% c - JSR GamepadProcess7 B! {) J! E: G* V' Q9 V4 ~8 v
-
/ O) }+ j+ U( U. j& n - LDA #$00
6 b( ?) \7 F& | - STA IRQ_Index
1 s- @2 M: {& b" x; f - + [' ^. `8 _- n M
- PLA' l2 S6 O- H: Z9 t0 }) Q8 i
- TAY
- H" y, s7 x8 L! c - PLA! x& s, r! W. {; @; G
- TAX
: D% d4 F1 `; V3 L) V7 f - PLA! H9 Y, N( Q( t8 U' O
- RTI' J( |# ?6 ?: J, g
- 6 L$ U1 ~0 u# V b: t
- ;每行扫描线113.676 R8 b+ ~2 x( \( T2 B
- ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)
K+ E2 _/ E# z0 @ L" M - BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7* o% \+ [; K6 X: P- l, @
- ;==================================================4 z, c2 \4 x% ~. E3 }& {
- ;IRQ中断处理
; n( j& i( b9 i- O+ y. @6 O9 L4 A - IrqProgram8 L9 S1 Z8 T. P$ B; g, n- _
- PHA, q C9 ~/ _0 |9 | t; l4 I
- TXA# O2 b. d2 ?) q- |0 g$ ~3 ?1 J8 i
- PHA
0 x# m3 Y5 a' k0 `! A5 f& y A! @$ y - TYA
, a% X K+ i- N" N - PHA0 l; C7 W' k+ x l6 q
- - f$ _/ ^- L$ h, w K4 \
- ;16条扫描线后触发IRQ0 c" Q6 T3 o0 i1 o$ Z2 {' [$ _
- LDA #LOW(BEGIN_LINE_CYCLES)6 ^% s8 y% b5 o! F
- STA M19_IRQ_COUNT_L
1 V1 ^# S8 K/ H: j3 ]. F" Y - LDA #HIGH(BEGIN_LINE_CYCLES)5 V4 x: z0 x) ^* N5 x- }
- ORA #$80& G7 B t( M; L" h3 I
- STA M19_IRQ_COUNT_H" t; o$ F6 A3 f* b+ M
- f3 m3 Q2 J' q' i
- LDA <IRQ_Index( V V2 L3 v( ?5 g0 `, x5 k
- BNE * + 4) S+ p. Z' D6 r" \+ q5 N
- INC <PPU_Scroll_H; V. Y5 K# K$ v! a2 t
- $ \9 K: F' P% |7 m( z
- ;设置屏幕滚动
$ J. j1 _/ G" ?, r - LDA <IRQ_Index
7 Y R( `: E1 B4 t2 O, T - AND #$01/ R" J% u O2 G5 {' y
- BEQ Irq_Scroll_Right1 w3 g% v! Q' V; q g+ a8 w
1 Y0 C* G1 }% N7 `' q- Irq_Scroll_Left4 s6 J6 V" \; l+ u5 H9 c
- BIT PPU_STATUS. U/ _) m6 v5 b3 m
- LDA <PPU_Scroll_H
9 D$ \8 e! G, D0 F+ q - STA PPU_SCROLL$ h- J4 r$ u( [7 {! V$ k
- STA PPU_SCROLL) u9 m; F( [- E2 j- h
- JMP Irq_Scroll_Over
; I/ E1 E3 L. O, T -
" x# l. \3 i+ s4 q6 n0 _ - Irq_Scroll_Right1 U$ v' B% n3 H; w- P5 }
- SEC9 D3 s6 e. G% l; h% T) E; n0 c
- SBC <PPU_Scroll_H
- Y! u4 Y( T/ o - STA PPU_SCROLL4 w: A: h5 h* a; k$ [0 R
- STA PPU_SCROLL
! L z- R/ h) F c, p: A5 u - Irq_Scroll_Over
% V; A' a0 I6 {, Z Q6 J2 K - ! s, E6 a+ k( H& P. c$ K! E
- INC <IRQ_Index
; S, l0 X/ d( d8 ^2 y - 9 c/ S' {/ @! r6 |4 b# A
- LDA <IRQ_Index; h* ]9 @6 l9 f% c3 i
- CMP #14 X3 h0 R% e# I6 |" I. i j
- BCC * + 10 ^+ ]* g3 }( e0 y) l6 u
- LDA #$00
) E% P' Q9 U; n. ?2 u/ U% u- i. _3 y4 P - STA M19_IRQ_COUNT_L. |" L/ |' X; [
- STA M19_IRQ_COUNT_H3 u& M. B! }9 _
- $ O* ? R! T1 x
- IrqProgramEnd
( ^# M/ D% Z" ] - PLA u* B4 z1 P; h8 V( |5 S) P, v
- TAY- s8 U* ~6 R# f) C
- PLA
% o( r1 v2 f, c2 \ - TAX6 Z% @5 @* V Q2 b
- PLA& {3 a0 q. j; p+ `0 x
- RTI
3 H' \- ~4 [, w& G1 ]0 a( d9 c, a -
: s+ T2 u5 T) N: ~! j, w - ;==================================================9 Y7 d9 m' y) _& H! d2 k, J: d4 R
- ;中断表, P) R1 `* I6 m2 W3 R7 s1 y$ O
- .ORG $FFFA K+ K# r. g; ?8 s! L
- .WORD NmiProgram
2 a- y% @8 g! i - .WORD ResetProgram2 Z, [) |+ Y* G9 y) ^+ P& N
- .WORD IrqProgram
复制代码
8 a9 {+ D1 c o |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|