|
- ;[FC][Mapper19 IRQ]
. N0 V4 d4 q/ A/ @ - ;FlameCyclone 20230710
3 C" o/ S+ c( M/ J
5 [) o" ]7 c' s% I' h- ;文件头: ^" r+ w- r% M' n
- ;======================================================================" e" \$ l: L& P' n& S' S. E
- .INESPRG 4 ;16KB PRG 数量' M" Q0 Z0 R% H! V: a+ Z6 H
- .INESCHR 1 ;8KB CHR 数量
- }$ s3 @! P1 Y" j - .INESMAP 19 ;mapper 19
: X5 E! i$ \1 {9 T% z/ X( x- P7 U - .INESMIR 1 ;命名表镜像 0水平 1垂直
* R2 x# L: k7 J! B - 8 c/ h6 e( d4 i7 \
- ;必要条件
' T) @, ~2 P/ w' a2 {( G - ;1.持有CHR ROM
* s$ @2 P6 k) S2 e' Z - ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
# e. @' F$ a4 B1 Z& {; f. D - ;3.精灵内存(OAM)不为空8 d) S" q$ E+ d1 d* v: G$ F4 E& G
& f2 p2 ^. x [5 O7 Q- ;==================================================
( G v+ i, f/ R, O - ;NES端口常量
3 p6 Q1 _7 E# P - PPU_CTRL = $2000 ;PPU控制寄存器
1 _* n. O* a" ^$ [; H4 k - PPU_MASK = $2001 ;PPU掩码寄存器
) K) Y# Q: ]' x0 L9 s `' c1 C1 r - PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位" U( e% K7 K6 ^8 k2 Q
- PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
! l, o$ ~6 i" { - PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
4 X+ T9 K, H, k9 R - PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
" L2 f/ b' b( w7 {3 ~7 [/ ? - PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
+ ^/ r: C0 |) i$ ?6 \3 N% r - PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
* h) K, H X4 [: b+ z9 G: Q& b( j - OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
" k B5 n! s7 X, r% G8 u - APU_STATUS = $4015 ;声音通道切换# [4 R9 e- ?3 y
- JOY1_FRAME = $4016 ;手柄1 + 选通3 w4 C; ]; |: @4 O7 ~7 a3 `: e
- JOY2_FRAME = $4017 ;手柄2 + 选通- v) S% s! \- o) ]/ E
- - R6 y7 k y+ O/ `7 K# w; a2 m( g
- ;==================================================& j* l& O* T6 j* \
- ;MAPPER 19端口常量, ^) f3 {0 `0 K. m
- M19_CHR_0000 = $8000$ q. f" L) b. A, A; Y! p
- M19_CHR_0400 = $8800; @) }+ q: D: `" g3 J. Z. M
- M19_CHR_0800 = $9000
6 z0 G3 n) z, ?2 R+ U" f$ c - M19_CHR_0C00 = $9800
, T F5 C$ S' d: o - M19_CHR_1000 = $A0009 M1 Z5 u m3 b/ z: q
- M19_CHR_1400 = $A800; p. W f$ L2 _
- M19_CHR_1800 = $B000
2 N6 F' G+ k3 i t9 Q - M19_CHR_1C00 = $B800
1 C- y6 w1 O H1 s$ ^6 M - M19_NT_2000 = $C000* F+ z$ \1 e7 F9 u9 s$ Z; N
- M19_NT_2400 = $C8003 G+ Q% Z1 g/ [' F* X+ p
- M19_NT_2800 = $D000 }% k# i2 `1 h k% J4 @9 H6 H
- M19_NT_2C00 = $D800
3 c9 U; j7 \7 n, N, a6 Y% S) r - M19_PRG_8000 = $E000
; z* s4 b8 v# [& [ - M19_PRG_A000 = $E800$ f; x' \/ {9 ~/ {3 g8 U! z5 ]% ]7 C1 Z
- M19_PRG_C000 = $F000
2 K# F, y' W2 n) t7 Q Y: l - M19_IRQ_COUNT_L = $5000
+ x1 v' ]- W$ j% k& D - M19_IRQ_COUNT_H = $5800' f+ f* v0 H/ H3 ]3 |
1 @7 T: ~; [* c0 m( b6 i+ l' t- ;==================================================
6 Y% I% w4 R4 k, W3 ?, p B - ;程序块配置5 v+ m) N8 F/ d4 E, T, t A
- BANK_DATA_MASK = $074 R9 O- l* h; \8 E: Z" y) J8 b
- ;--------------------------------------------------
% S5 t0 ?. K3 T7 O- r - RESET_BANK = $07
0 ?: U! g, A8 P - RESET_ADDR = $FC00
; v7 g: y+ ], f( c- r6 x - ) l+ j. [& l; }# G' P
- ;==================================================% S) X6 N: }7 p2 c$ I! [* ^
- ;图像块配置
% n! ~; f) {1 S* u# [ - CHR_DATA_BANK = $08
W2 U! D* g T; k, H; x- i: _
/ ]8 b: }1 p/ b1 }- l! c- ;================================================== ]! l V" [ Y
- ;零页内存地址配置
7 q l/ E# g( Y8 y2 X - Use_Ram_Addr = $806 a( S+ n6 S( f9 ?
- PPU_Ctrl_Buf = Use_Ram_Addr$ S, g2 ]# f3 J) Z6 J) {
- PPU_Msak_Buf = PPU_Ctrl_Buf + $01' J1 l3 v, G, k2 D) J
- PPU_Scroll_H = PPU_Msak_Buf + $01
* Q& W3 ]3 I* h3 A - PPU_Scroll_V = PPU_Scroll_H + $01
$ D% ?0 a# }3 @+ t s& N! M - FC_Data_L = PPU_Scroll_V + $01
' C/ X. J, W0 r - FC_Data_H = FC_Data_L + $01% E- H9 _1 n% U. ?0 ?0 `
- FC_Data_Buf = FC_Data_H + $015 `- i( s5 V x. _3 `7 g% G
- ;==================================================
/ d$ G" V7 r! ]4 s3 b) Y
2 Q) y# `+ p2 n1 D; Q5 O- GAMEPAD_MERGE_FLAG = $04
: T. Y3 ` w1 o$ _ - ( Y$ k5 @0 w4 p; X* A) z3 U* I
- Gamepad_Keep = FC_Data_Buf + 1
( f& D3 c5 r/ P% g - Gamepad_Once = Gamepad_Keep + 2
% W( }, F- U7 u: s) y: w# T - Gamepad_Temp = Gamepad_Once + 2
( t$ e0 C2 W5 x/ u4 T - : q4 E; u& M4 G; A# k- W1 m
- Gamepad_0_State = Gamepad_Temp + 2- }) C3 O3 J9 @, S: N
- Gamepad_1_State = Gamepad_0_State + 1
+ X7 x9 u% l- ~# L - Gamepad_0_Value = Gamepad_1_State + 1, r Q0 v6 h2 x- g$ S q% o
- Gamepad_1_Value = Gamepad_0_Value + 12 M M) G* C- W/ A( `
- Gamepad_Port_Value = Gamepad_1_Value + 1- A( G: B6 a# u* _& ^8 G
- Gamepad_Merge = Gamepad_Port_Value + 1
* R+ K5 a+ Z8 t3 K# r+ {2 y - , v; Q' M$ {. S6 \5 \2 r; y
- ;==================================================
; U# Q( S9 m) |9 o: i; K0 [; ] - IRQ_Index = Gamepad_Merge + $01; m4 X) B/ i! a; O# s {
- ;==================================================& Y5 l; R8 U! P$ h! l. r, q
5 l0 Q; J( f1 F0 ]$ K9 v- ;CHR图形数据
/ U0 I; H& J _9 F" c! N6 P/ C! e- O - ;==================================================" p3 p v1 F* a. e5 ~& Q* ?* R( x
- .BANK CHR_DATA_BANK
1 g# K# k. Q( b4 f8 x" z - .INCBIN "chr_bank/chr_data.chr"
& R) F% W' l$ m2 P1 a( @' t8 c# i - 1 f7 d/ H0 Z6 n9 i
- .BANK RESET_BANK & BANK_DATA_MASK
% ~* n, h' l9 {. _4 Y - .ORG RESET_ADDR
( s% b4 ^: a& k+ E6 B( q2 n/ d- x - 0 ~' T7 r3 X( \2 p& B$ p. I
- ;--------------------------------------------------
8 W4 O) R7 z1 Y+ x+ b1 }! c1 b- [ - Attributes_Data
, w3 r# D- i! R" }$ ^ - ;命名表属性+ l+ s9 B9 R) n2 _6 B$ o9 ]# J1 b
- .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$003 d4 A$ u* E" `. A+ u0 u6 T6 |
- .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA8 v; _' Q3 `5 S! B
- .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
% n. b6 K+ l" O/ G; G2 ?* O - .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
/ K8 P9 a# P) z+ a5 y - ;--------------------------------------------------$ f" r1 M6 I( N! \6 v
- ;调色板数据9 P: R# ?, c: D- B
- Palette_Data! R; M: e4 P. e' a
- .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
1 c# K# L9 q2 [5 _ i7 n - .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F6 [' o* Q/ y; ^0 T& z* m
- 9 S# d6 p3 l+ |1 C
- ;==================================================
8 `+ Z) B; z0 ~ w! F5 u( m% Y - ;命名表初始化
9 j% j6 `4 f3 _3 {3 P0 ` - Init_Name_Table. \9 h& g ~2 E
- LDA #$20
* ^; T9 n0 a$ q1 J - STA PPU_ADDRESS
% }3 b1 c- E3 C1 Q - LDA #$00* e1 b4 W2 {, W
- STA PPU_ADDRESS% D* m3 `* i$ D8 U; W, L. f
- LDA #$00. l' z! o. ~/ ~6 ]4 Z+ b
- LDY #$00- W: T- b: F. Y q
- LDX #$10
* K% H+ X5 A7 ~) l - Init_Name_Table_Write
0 ^- k+ ?- }" ] - STA PPU_DATA9 }1 n! ~8 M# n1 ]- U
- INY6 p6 z i: w$ X4 f
- BNE Init_Name_Table_Write
# ~$ _. O' }8 \' r% n7 p - DEX3 @( @% ~* Q& M3 f3 \0 N
- BNE Init_Name_Table_Write
! z$ i- `) `, E6 h6 h- m - RTS" e% U A. r8 T/ }+ t; f
- + B2 G( x! w! o
- ;==================================================
1 U# U. p% l( {5 L ~! m; r - ;调色板初始化# a+ ]: x! y q: T0 v% O0 J
- Init_Palette
" I) I( q8 \: |4 | - BIT PPU_STATUS9 }2 A: ?- c2 y3 o3 i
- LDA #$3F
0 |# V/ ~6 O+ K& o0 B - STA PPU_ADDRESS
, r! M- U, I. y0 ]/ U - LDA #$00 z9 R( d1 V5 m6 [/ p3 d0 |
- STA PPU_ADDRESS# \" l4 ~0 d& n6 l+ p# E! r* a) \
- LDX #$00* A! a) Z6 w8 u' D6 O) _5 ~% V3 F( B
- Init_Palette_Write
% O5 X) K( D' n - LDA Palette_Data,X9 S6 Z# p* _2 b, P, ~% D% }. y' u& `8 l
- STA PPU_DATA! ~1 A/ _0 ]$ k9 Y+ r6 W* J
- INX, J* E. ]$ [; R( q0 ~. m t
- CPX #$20
7 [* I- B( r0 t4 X6 c9 o& N8 f1 P2 C - BCC Init_Palette_Write
, S. [+ R& E/ s$ M! q - RTS
2 K0 {6 J v. i2 `, B - ; O) j8 s, W8 m* M
- ;==================================================! [% X8 O* z3 W& G# U
- ;设置命名表属性1 l& [% T8 w7 [1 S
- Init_NameTable_Attributes* |* k- A- C7 W1 b) D6 W
- BIT PPU_STATUS3 B; ~' q) `- a/ {
- LDA #$239 h4 V3 f8 l: ?3 ~& l$ W3 n
- STA PPU_ADDRESS
4 i- B5 b1 _% L3 ^ - LDA #$C0
. S' j- p0 m* p U+ B2 O - STA PPU_ADDRESS8 r2 ?; w2 n3 K8 t: r2 Z$ O2 m* C q' E
- LDX #$00" l$ U; d0 r( a# K" ?3 |1 _
- Init_NameTable_Attributes_Write
V# v" P- {# H/ q9 `/ L' @ w - LDA Attributes_Data,X1 {. A3 V5 f( q) A3 a) w
- STA PPU_DATA
6 `; i- @; x2 N" N - INX
4 j( n* C$ ~& V7 L+ u - CPX #$40
6 y O# J6 }% }1 l4 } - BCC Init_NameTable_Attributes_Write. t! i! x% W' k2 J. x& N" y
- RTS
' q) o: b( {& _" f( z
# E2 H" G" A; @; b- ;==================================================
) Q3 e( U, N) L6 `/ f2 i. n5 @- c - ;初始化命名表文本
: V3 [6 c1 C5 {& c9 B Q - Init_Name_Table_Text
; g- L- V% h- s1 `0 t1 j - BIT PPU_STATUS4 q. V; n" Q r1 }6 J# |* C
- LDA #$20
. q- ?8 l' K4 K# C - STA PPU_ADDRESS2 l9 ^0 W( w0 h* T4 s
- LDA #$00* n/ q, ]" [1 b/ Y$ X K" n
- STA PPU_ADDRESS
' v+ q3 n: k, X - LDA #$00
! [2 v. ~6 D; E; Y2 r5 ` - STA FC_Data_Buf
. j Q1 E% j5 H* }1 L" i/ G - LDY #30* t2 K( d: C3 b: r W4 \, H
- Init_Name_Table_Text_Write
: N# N0 L3 r5 }5 C0 \$ S - LDX #32) }; q d2 J; h* M
- Init_Name_Table_Text_Write_Char
0 U" O$ _2 a% E& J6 @ - LDA #'0'
9 n, F4 N3 j+ { U - CLC2 o% Y( X* _! S4 R8 G# r
- ADC FC_Data_Buf2 E" Z) ^9 C Y0 @$ U4 k8 [4 n% i( F
- STA PPU_DATA
# F _2 M& P9 @6 z - DEX
* t! X: n+ u9 v3 `5 g: z! C - LDA #$14
+ M. q, Z8 u4 U# r4 ]9 C - STA PPU_DATA
! R5 L( x. h. y$ y/ k - DEX t- f* I& a$ H' F( @! M; Q/ ?
- BNE Init_Name_Table_Text_Write_Char
4 K. ~* O- |0 A& W - INC FC_Data_Buf$ t( u+ n+ m5 Z$ Z: G$ x
- DEY% k: t! D" ^% @% O* i ?
- BNE Init_Name_Table_Text_Write
2 }$ d" L) h; m$ N- |# \$ U' W - RTS* D0 t2 S: p3 A$ I9 y
- x2 B6 B* r" ?) j; n
- ;==============================
. ^4 x: e4 V; o; y - Init_OAM_Ram;初始化精灵内存
3 s* `6 u, r2 p6 w - LDX #$004 V% R ] A( g
- LDA #$00# x% `& h& `: B
- STA PPU_OAM_ADDR
* u( v1 _- o* P8 a7 A9 g8 U' @: c- n - LDA #$F8
) R3 e& a& E' f) V9 O4 C4 |* l - Init_OAM_Ram_Write
7 I$ B/ `) K# m4 z - STA PPU_OAM_DATA
# y* B2 \* h( w: ^, P- E. I; b - INX
% i4 y" G* ~/ G n; D - BNE Init_OAM_Ram_Write
9 m7 N9 q5 S5 v0 g- {6 j! C - RTS# y& Q- {: p+ J2 ?( p$ T- E
- " h( H. F7 L: E
- GamepadProcess;手柄处理
* V" I' m1 ~7 {+ J' B7 P9 M( W) P - JSR GamepadDatacan
7 M. h8 W4 {" P$ c2 h# i+ E' e - LDA <Gamepad_0_Value
' I- }. l8 [( E& s - STA <Gamepad_0_State* |$ O6 {+ ~! K8 f
- LDA <Gamepad_1_Value R( ` [( r3 y: r
- STA <Gamepad_1_State" H) Z" f8 s- L) N' A+ p1 r
- JSR GamepadDatacan
7 s( j5 y1 m# F/ r2 L& j ]# _: n - LDX #$01 J3 C# o6 Q; c& D; n
- GamepadMergeCheck;合并手柄输入检查
$ Z- ]0 h& y3 W, P - LDA <Gamepad_0_Value,X
2 G) z4 T2 P4 O2 E+ i3 j1 c - CMP <Gamepad_0_State,X
- G& k$ l) c5 a" e& n/ | - BEQ GamepadMergeInput8 x" s# _1 J O; p0 }8 z* n' V% |
- LDA <Gamepad_Temp,X8 F, @. ~+ V- q! r: G/ z: p) l: g* E
- STA <Gamepad_0_Value,X; U% t0 L. `, z. e; b5 j C
- GamepadMergeInput;合并手柄输入
( C; X8 v! |9 [6 {9 o4 W - DEX; y( R% o2 @* N: S" L
- BPL GamepadMergeCheck7 g2 Z' w* p. ~) n" b
- LDA <Gamepad_Merge
0 _: w& }5 {: z/ @! E6 T1 `% E - AND #GAMEPAD_MERGE_FLAG
6 e2 h f/ {, F- I/ l, |: j- Z* Y6 d - BNE GamepadStateProcess
8 X3 q$ I& ]/ n+ r0 c: g - LDA <Gamepad_0_Value
2 ] N* q9 e2 r - ORA <Gamepad_1_Value7 k3 W* d `, s
- STA <Gamepad_0_Value
3 W, F' k0 }3 o% F* O - GamepadStateProcess;手柄状态处理
( G: E x1 ~% a - LDX #$01% n" N# }$ H& M0 g
- GamepadStateSave;手柄状态保存$ }( T+ Q5 _! e3 x9 M
- LDA <Gamepad_0_Value,X( U8 Z( I8 u9 A0 L
- TAY8 m' f1 G; b9 @! w
- EOR <Gamepad_Temp,X
! i3 u. L1 S. v+ P' f% m( q - AND <Gamepad_0_Value,X
7 w O9 P l1 K- q* K - STA <Gamepad_Once,X2 k$ D- o' S% q! N
- STY <Gamepad_Keep,X
! H- w, ?5 I: s - STY <Gamepad_Temp,X& i) x9 F+ c C9 I
- DEX; P: V: @9 f7 h% O1 l: Q
- BPL GamepadStateSave+ d& e' `, y% f0 b
- RTS
, d- g. `# F1 ]+ f z - . z. a1 _+ j. v8 I4 d
- GamepadDatacan;手柄数据扫描3 `4 r6 I, h: _& I
- LDX #$01
8 h9 E# `' Y' Q: V, b; j n - STX $4016
! _; t) M! t2 A! F) C- O - DEX
! B3 [+ i* q# E7 L, a' p) k& u - STX $40169 u* G7 J( ]6 e6 w# I
- LDY #$08- y$ r2 r8 ?! ?( ~
- GamepadPortScan;手柄端口扫描* @8 V! W L% \ v
- LDA $40162 z2 w$ g% k s/ \
- STA <Gamepad_Port_Value
: A: f+ l1 C0 A1 ^' F1 S - LSR A% O% B& z% f& K* g' ?! ?
- ORA <Gamepad_Port_Value, r0 ` K+ G5 e9 }6 B, Q/ p
- LSR A
; ~/ Q/ K! @5 ?2 u; b) n - ROL <Gamepad_0_Value: s$ E1 Q/ _( R6 D
- LDA $40177 m1 E) z) Z2 U' z/ j0 B2 D
- STA <Gamepad_Port_Value
! m, Y1 N$ L* p2 L; }7 G - LSR A2 G6 D5 M# p- K0 i7 M2 a
- ORA <Gamepad_Port_Value) @; u# k) t% G4 G+ f
- LSR A
- h$ h8 o" ~' a$ J, r - ROL <Gamepad_1_Value
, b" r* N, ~5 |# t8 x& e+ { - DEY, I- ^7 u+ Z- \/ c! e1 e: h8 d/ X
- BNE GamepadPortScan
/ U' D( w4 j0 y1 P+ M: t' x5 p - RTS% v' S/ f! v8 \8 n9 y# ^
-
3 M% X N! s; D. v h m$ z - ;==================================================
. l9 [1 O V# b; U. R - ;PPU处理
" t& z8 \# N$ b - PPU_Process
( x. H9 z$ g2 k U3 R - LDA #$00
0 Q- f- `% {/ }; k. _ - STA PPU_MASK. ^5 W! W+ r/ H4 Z# q
- " G+ \6 D3 G: k' v( s
- BIT PPU_STATUS
/ \! {7 T' w* [6 L+ D$ I& P - LDA #$20
1 [, \0 z; I B& w0 Z5 ]) s9 H - STA PPU_ADDRESS
# F* F4 h$ @: o; o6 B4 ~, } - LDA #$00
: P8 p% B' \+ I; s - STA PPU_ADDRESS
' Y; }- @) \1 G q* y4 S2 ~ - * P6 A- ?5 L4 s5 h
- STA PPU_SCROLL
8 p& x1 W3 J4 F2 u+ }1 Y - STA PPU_SCROLL0 B+ V s7 T5 |" a/ C2 k
-
S# {) u7 v# L& z" @ - LDA PPU_Msak_Buf1 c5 g! d: u- i" s7 Y+ l" h5 Y
- STA PPU_MASK' K9 N6 ?$ X! q* n
- 1 \% f# Y0 H# `3 ^; m
- RTS% N& f; |0 |. n1 l7 Z! B ]* T
- 8 N% N- ]. L7 \9 ]
- ;============================== d" m ]5 Z1 O3 C
- Time_For_Vblank;延时等待- H. j* J9 B0 t `. \
- LDA PPU_STATUS3 C& H6 D: {) h6 _2 F: T, M
- BPL Time_For_Vblank1 n* _. S4 O& {, L
- RTS7 G9 s1 a& Z- H0 l6 X* ^
-
0 H% S3 _4 P* z5 r* ] y2 M - ;==============================
* ^1 k. N" ?% N N" i* o1 x - ;初始化MAPPER19
9 P* b9 I) A& [! F8 f - Init_Mapper19% K, [; [3 Y! {0 H5 ?0 ]6 V1 y
- LDA #$004 O% u+ x( B1 w1 K) ]# c# W8 l$ [
- STA M19_CHR_0000
, l9 _ O4 @; r5 L - LDA #$01% q' d" P2 z0 e; V8 H6 a) N# _
- STA M19_CHR_0400( F9 k! K4 n/ r: z; q+ P8 P; x# h( D
- LDA #$02
$ k, i) w' k' d0 w+ |* R - STA M19_CHR_0800, h& R) l" c0 | q
- LDA #$03+ O7 z# R$ s6 `' f
- STA M19_CHR_0C002 k! B: ]$ I: [ [& Q
- LDA #$04: x) G5 |& V' l
- STA M19_CHR_1000
3 I4 [2 e! a8 x0 c# i1 ?0 P - LDA #$052 w# ~! h5 `' r/ E: W
- STA M19_CHR_1400( H d6 \( s3 j& }
- LDA #$06* n& [3 w- p; J! w* l
- STA M19_CHR_1800
0 s' ? L9 F4 p/ [! I - LDA #$07
/ D3 t' [! r* t4 ]" c - STA M19_CHR_1C00
6 `$ Y) B3 Z- ~! O - ' M! G$ ]- w" G e% O
- ;禁用IRQ
, l) C# k1 G# Q+ L! W1 a& i9 q/ ~ - LDA M19_IRQ_COUNT_H
3 M! c, r ~ i: U - AND #$7F
2 w) Z. W# q1 |. P- P - STA M19_IRQ_COUNT_H9 T& d/ H" b P0 ^
- . Z- [/ x! t! g* I1 f
- ;命名表* W4 k0 i0 X' ]& B7 |
- LDA #$E0
0 U$ I% t P0 P - STA M19_NT_2000
}3 S, n3 f5 y2 i - STA M19_NT_2400
3 {* \: a! a; M1 n) ^! ` -
8 Z) u7 J- }8 ~( G+ Y: j6 T - ;命名表
' U; p1 ^. }; `: }+ I - LDA #$E1
) E0 b% [5 H# T+ @! p/ x8 E7 k - STA M19_NT_2800
, R: @9 e0 v6 K! P8 v6 W - STA M19_NT_2C00% ?# I1 Y* @* K3 a/ Z1 s6 F
-
- B5 v |2 d8 Q6 C1 I - RTS2 y# \1 j1 o7 r4 ]% D. w# @
-
6 h. I, Q9 }# }- V3 ?3 ~1 _ - ;==================================================! Y2 y1 N# w5 y: f& s) T
- ;重置中断处理
7 e( {5 x x( j3 e1 Y - ResetProgram
, g3 l9 `& T+ w& O) E7 A, f - SEI( h- P) j3 F4 S9 W% I
- CLD9 R6 M* I2 s# x/ o5 {$ t6 D
- LDA #$00
( {' n- a4 r: T - STA PPU_CTRL5 j) Y. p% q2 ~# N* l4 `
- STA PPU_MASK' d9 J) b4 v- `, n+ w% i9 C: B b
- STA PPU_STATUS
* V) l: |1 z' r" y8 k - STA JOY2_FRAME
9 l: H3 G. ]( y* W( F8 a: z: I) q4 j - STA APU_STATUS( y$ Q' c- d y
-
3 l/ s8 E6 n4 Q- ? ?3 l$ J* S, G" y9 S - LDA #$C0. K" U$ q: D( h
- STA JOY2_FRAME; [0 ?% _; m% a
-
9 x7 F' ?/ k |; [1 d' L [ - ;等待vblank
' b5 }% K( ^( H1 F: q, c- X - LDX #$02; c. O" [5 y8 C! Q' t0 K8 i3 M
- Vblank_Wait_1
( F# z/ Z& _$ b8 `8 m9 \9 w - BIT PPU_STATUS/ _, r5 k# R+ h5 K% |5 g& Q
- BPL Vblank_Wait_1$ @& J4 |) E7 Q
- Vblank_Wait_2
. W4 Z2 s0 h0 Y - BIT PPU_STATUS8 Y6 [! d' q8 z% b( _
- BMI Vblank_Wait_2
1 d& x# z8 [) U/ U2 a$ r+ D - DEX
8 o0 n6 {: J# [$ e! b" M& T. @4 R - BNE Vblank_Wait_13 ^0 `9 ]4 L2 m! O2 Z
- 9 B0 }; a. P* p* ^; ^) ]! T
- LDX #$FF" l0 @8 }; c- l. f
- TXS
( |% Y( x7 _; M4 O! Y- m - % Q4 L1 h, }. v% ?6 _
- ;初始化MAPPER198 j/ \$ C$ ]! O8 `2 d) j- C
- JSR Init_Mapper19- N$ ~5 p9 a6 @5 t
- . n7 ]( M; [0 Y/ o
- ;==============================
8 C9 @# F# B$ ^( Y - ;RAM初始化
1 y4 H, H, E0 x8 p4 m9 a/ O# Y# r& u - Nes_Ram_Init
4 A1 t% A" z" { - LDY #$00
7 X4 _7 y& r) \3 ]% b - LDX #$087 Q2 r2 m1 W% `
- LDA #$00
) \. l+ r3 j; z) q U% r% x% [ - STA <$00 a( `& n: x6 N
- STA <$01
& p" c' n6 U: n' C! X6 r - Nes_Ram_Init_Write
( \4 F. ~. h# m9 |6 W - STA [$00],Y: `) F( g \$ f
- INY
: y/ W" }- {! f; i: I - BNE Nes_Ram_Init_Write
4 V( ^9 d9 v0 A - INC <$011 ]$ G: \8 j( {" k" ]/ C2 t6 \
- DEX* R, n' z C4 ]: }
- BNE Nes_Ram_Init_Write
1 e, t( G, f1 y3 x. ]( Z - . y# i7 r: v4 D3 u; l* E! I1 ?
- ;初始化命名表+ v3 ^8 B1 t4 Q% m) h
- JSR Init_Name_Table+ X9 K* f; o( g8 M
- 0 n) J6 b2 u5 a( h5 H" v* q
- ;初始化调色板6 t! o1 ]/ z, M, c1 [' a5 w" p
- JSR Init_Palette6 j i6 u* c; B4 M/ n `
-
8 y6 s5 p9 o0 e - ;初始化命名表属性. B3 Y+ K( y$ r% A. q
- JSR Init_NameTable_Attributes- F! l5 H" ]; Y, e
-
8 C3 X8 }3 U8 k3 e, I& R - ;初始化精灵内存8 S( Y$ M' g4 G. C1 X1 ^
- JSR Init_OAM_Ram% R/ X8 c( K) d) {8 q1 P: A$ }6 A
-
8 p$ e) T3 c3 o - ;在屏幕上写点东西7 ]2 F; R) \( A! r2 v. e6 @
- JSR Init_Name_Table_Text) l/ R; r& \/ t4 g0 o$ q
- 3 o4 u: b1 F( t3 B: Y; v( j
- JSR Time_For_Vblank
`3 w7 t, n! E# ^ - ;开启PPU控制
" S Q7 _1 _! } - LDA #$A8
3 ?4 H1 C' R) m0 r - STA PPU_Ctrl_Buf1 O+ t" P' g8 z, \( k# `' y( S( G8 B
- STA PPU_CTRL
z' E3 b. d; f - 5 z+ B& K% x$ m8 F# ^
- ;开启PPU显示
1 K$ M3 T W, P7 T' D; s - LDA #$1E7 y/ e* a/ n% r) b' l [$ T: o3 v
- STA PPU_Msak_Buf
" h# C& }2 n+ W4 m6 B9 ] -
6 \- ?% m: H9 ]* V( a0 N0 z - CLI
& E. v! t' E8 [; X8 p5 E - JMP Loop1 z3 E/ D% P; n8 M* _
- ; s. F% y/ ]( x2 t* t0 k$ Z
- ;==============================
$ s- v! q4 X# A1 V - ;死循环, 等待NMI中断4 J! X8 l% v4 R
- Loop
`' x- r, o. ^" N. P/ L - JMP Loop/ e) \3 q- r3 \& T- y/ L7 _* Q
- ; r& _+ e6 w- w' e
- ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967
5 B) n8 o2 n7 x, Q) W* m3 e
$ s4 w) f( p4 S. {0 Q$ @/ \: f! z6 o( i- ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967). O+ A" k% [1 }) l9 g+ ?( o
- BEGIN_LINE_CYCLES_START = 32768 - (4103)
: g4 ~. {9 I# Z6 a$ H& E. ] - ;==================================================; S( H4 P0 Z/ ~1 N. V
- ;NMI中断处理
8 ^7 W p% y7 W9 v - NmiProgram
$ Y6 t/ o" b+ g- C3 f2 L - PHA) v/ ]2 r5 B+ k- C# V$ Q+ {+ T- T7 K
- TXA6 Y; K) ?- Q) [/ z9 Q
- PHA
7 N: P" \) y2 A3 y: V - TYA5 q# o& L6 I7 Z% x$ Y2 z3 A
- PHA9 S- P- L2 N7 t5 }- u4 |$ L, B% m
-
* n3 q ^2 r% ~/ ?1 h$ _0 A4 q - BIT PPU_STATUS
1 ~! [3 N4 e) }2 K7 V' @+ { - 1 N( S6 I& }7 O0 ?
- LDA #$00
6 O: |7 Z, r: O3 E - STA IRQ_Index
" P7 t+ Q; U' h5 V: E -
3 d$ z0 s5 C, p, x. M4 d - ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动" N: Z, G F, `7 u& t( l
- LDA #LOW(BEGIN_LINE_CYCLES_START)
- v) E6 Z5 M/ E/ n4 W( [ - STA M19_IRQ_COUNT_L/ l& J& m% j# o T" S2 M" R" D
- LDA #HIGH(BEGIN_LINE_CYCLES_START)
! s9 y1 V# C& V- {* t. L& l& l - ORA #$80
0 Z% ?( {1 |! Y& d# ?0 \2 ]1 g - STA M19_IRQ_COUNT_H
" F! N: j& ^ t) t6 J - CLI% B v% _( @, g6 L9 ?1 ^$ n/ _& o$ |
-
- y) e# S. W5 \$ M! {5 { - ;关闭PPU控制. t) x- S. }" W2 K: A; h% f [8 H
- LDA #$001 ~/ K# v* C5 f% Z x
- STA PPU_CTRL
. W, o5 W% u! S - ' j0 {: a' g' L7 h/ }
- ;处理PPU( R$ \7 N% ?" m6 s
- JSR PPU_Process+ n/ i, \6 k. U: w2 A
-
: W; p- ]) ?; h: R3 b - ;开启PPU控制
( I. |" a5 l; L/ A. U/ }+ e - LDA PPU_Ctrl_Buf p0 r: }% ^+ g+ W0 D
- STA PPU_CTRL
) ^5 J1 i% M+ g7 l -
% U# j" }+ o, y+ F* w4 W7 Y - ;手柄处理
% C2 n7 M3 f8 _( \ - JSR GamepadProcess! @9 H, u+ Y: E) N/ j9 Q
- * T, g" Y% \ E
- LDA #$00
( N( |* D2 |' ~9 P9 n0 r - STA IRQ_Index
$ Z% B+ f* T( z8 j/ x - ; I. k4 b; A( e' N
- PLA
2 z: s8 ^% w4 ~# g - TAY9 A# x5 B$ D" Y5 |8 i3 [
- PLA8 k9 t' Y& ]& U3 K7 Y$ {9 e6 `* ~
- TAX/ C6 e; m2 w; |* P
- PLA4 S. s2 I5 ?2 _2 V. v
- RTI
0 {6 V9 I8 w' z - - [/ @$ ]7 C, I6 r
- ;每行扫描线113.67- w ^; ~& o4 o
- ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)
2 A# h; t& b6 c. B - BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7 T8 W: p( g) i0 ~6 n. h5 w! V) {
- ;==================================================
+ B4 v/ j6 C' |8 b7 } - ;IRQ中断处理3 e8 d. w% S0 e" j5 s
- IrqProgram" q1 n% G+ X" C7 e" r" g$ d9 d! T
- PHA
! J. N) Q5 s5 K2 s* U - TXA
* T8 d4 U; o5 |. u* G- K - PHA
$ |6 e. x! O0 A - TYA/ \6 u+ i( A } r/ w
- PHA
4 r: j4 V: `1 h5 A) F1 ^. H - 5 N# J/ w8 u% a$ [
- ;16条扫描线后触发IRQ
! C2 y6 ?7 K/ F6 w- H- @ - LDA #LOW(BEGIN_LINE_CYCLES)( I) V4 e7 q5 h% w4 m
- STA M19_IRQ_COUNT_L
; T9 a# z5 `* H; p - LDA #HIGH(BEGIN_LINE_CYCLES)- P* Y: Z. Q& H) \/ d
- ORA #$80
; i$ h( k$ |2 o. U5 k' [* T- a - STA M19_IRQ_COUNT_H( f3 g3 u4 f: Q" |$ u6 @: N: L
-
- l* P$ x! B/ N9 [ - LDA <IRQ_Index2 x% [( W- ?$ `2 V; D
- BNE * + 4
1 W' B6 v9 ^$ L6 j* s4 C: e - INC <PPU_Scroll_H: E# a' x: R/ g3 Z5 W! S
- , r+ T1 n: Z2 j* [: T. k
- ;设置屏幕滚动
7 J2 c7 A3 \) Q( [2 } - LDA <IRQ_Index' U; v$ ~* Y1 z& {7 }
- AND #$01/ J' H6 T4 s, O. X2 q% S, v. _* e- [
- BEQ Irq_Scroll_Right
2 q0 p0 v( }3 b; u - ) B# N7 J% f) S3 Y3 B: w5 ~. f
- Irq_Scroll_Left
) z* C: i4 b) y4 @5 v @ - BIT PPU_STATUS
f1 F/ P( ~- \# k - LDA <PPU_Scroll_H7 m* S# F" y- q$ o9 j0 u
- STA PPU_SCROLL* ~4 R( r; O" T
- STA PPU_SCROLL
, K( Q) c4 K* X' Z6 V - JMP Irq_Scroll_Over1 R$ J# N7 P8 z7 K. p( p
- 7 p. x% ~8 r7 x: Q3 h2 Y" F
- Irq_Scroll_Right
$ P/ [- t, ?' V: |* q - SEC
0 ~) s' `6 A3 `6 a - SBC <PPU_Scroll_H
# K n+ h* T3 s: y0 u5 E7 X - STA PPU_SCROLL5 M5 y1 {/ F4 d: d/ B$ v( f
- STA PPU_SCROLL
+ ^" l- r$ q. E( E7 S* n u - Irq_Scroll_Over9 f* ^: |) _# W" S2 n
- 3 }# a% n6 I) b- Z9 A
- INC <IRQ_Index e' [9 X7 M6 q0 P9 R
- 0 t) T2 o" [6 q8 S2 S' f" h$ q
- LDA <IRQ_Index
5 D8 d% _9 s# z - CMP #143 d+ |' f t% Z7 S' k: d
- BCC * + 10
; b+ \& J& t: M' l - LDA #$00# m% O x1 j( ] f
- STA M19_IRQ_COUNT_L
@) w6 K8 G4 n1 }5 t - STA M19_IRQ_COUNT_H
1 w$ D) I3 }1 C+ ]7 o - 9 U0 P1 A- C* z. b' m% m
- IrqProgramEnd8 I" n, I' R9 M* [' |( z7 r9 H# ?! Z
- PLA# x! a* f# w' }" P, E: p y
- TAY- a U5 K0 |4 _6 Q: }/ ^" g
- PLA2 `. C" Y+ _/ y/ S
- TAX( }8 D6 O& U! P! j
- PLA* J0 D) Q/ Y9 W! ^" ]9 e
- RTI1 a B4 b4 N. E$ p. x6 r d. b4 K
-
' _* C7 N/ z5 U2 A+ ]! Q9 E - ;==================================================2 V/ u7 P/ U/ ^. L, J
- ;中断表; i; p6 B4 x- A8 y% O
- .ORG $FFFA4 c |. Y' D2 r" d+ t+ }" N, H" ]
- .WORD NmiProgram+ Z% B6 s i9 Y# O7 Z& t5 i
- .WORD ResetProgram
6 q& E( [2 ^6 u6 E+ }/ h - .WORD IrqProgram
复制代码 6 I# `0 r7 z4 N6 D8 t
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|