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