|
|
- ;[FC][Mapper19 IRQ]5 @) h4 o, x. y
- ;FlameCyclone 20230710) L# E9 X/ e3 ]9 p- o/ f
# j' L0 D, ]5 L+ c1 g& H& E4 _& C$ r- ;文件头
0 _, O9 W% u4 u9 ~& ]3 j5 Q - ;======================================================================
( o# \% R) t' A6 r5 u5 N - .INESPRG 4 ;16KB PRG 数量6 u$ ]' _% E# W; y' V1 M
- .INESCHR 1 ;8KB CHR 数量
/ O% A: M6 e3 o! j. F - .INESMAP 19 ;mapper 19
. ^) A. F1 h; ~; `3 O. {. s( l; s - .INESMIR 1 ;命名表镜像 0水平 1垂直( X2 K3 |( y! p4 C9 L% U6 g, p4 A X
- & U v- l e' b. R3 W A1 i- O
- ;必要条件
) W3 g/ q- p+ ^0 N4 H7 @: p% K - ;1.持有CHR ROM
' `# e( Z( |0 X5 {+ G5 g8 J' z - ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
1 n, k5 H8 B6 d) C' {9 W* y - ;3.精灵内存(OAM)不为空
$ R6 P6 N% k! V$ X9 \& |# Q
U. n2 E7 v" U0 j0 V- ;==================================================9 Y9 X" h) p+ k I+ t; h
- ;NES端口常量
( a. y! s! W# f0 N - PPU_CTRL = $2000 ;PPU控制寄存器
# ^ S7 F- l0 H0 ] - PPU_MASK = $2001 ;PPU掩码寄存器
5 m- P* y+ x& n+ q2 @ - PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位4 z/ n d& M1 |. l% M8 c
- PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1, r* x1 L, V% {) x% A# p6 @/ @, C
- PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加18 P; z% \! I" n2 L& N* U) d# b
- PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
9 f: R, T# P7 c" v$ E9 ]* B - PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加$ B+ X' n/ @- k
- PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
' H h6 O8 U/ E3 V) o5 Z - OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存/ p5 z# c9 y2 Y. c
- APU_STATUS = $4015 ;声音通道切换
" P: a1 V' @2 [+ J4 m9 U2 E - JOY1_FRAME = $4016 ;手柄1 + 选通
, o/ z- _, F+ o" k& m0 j - JOY2_FRAME = $4017 ;手柄2 + 选通
2 k6 t& Z/ {& l. l4 H% W. v" G
: t w; U: U- r8 y$ m- ;==================================================% Q' i( m- I0 O
- ;MAPPER 19端口常量; X% f3 n+ i- y o0 Z
- M19_CHR_0000 = $8000
: F7 w3 Z+ g* Q) j: H - M19_CHR_0400 = $88000 X$ `, w6 D) R- r% t3 m! v
- M19_CHR_0800 = $9000
8 m% y, f( r: ]+ v6 u - M19_CHR_0C00 = $9800
4 W# F: }( S" L$ y2 f+ { - M19_CHR_1000 = $A000& A9 t m9 M2 Z' W# |9 a5 n# d
- M19_CHR_1400 = $A800
( y/ D( G4 t1 G) p# a- O5 g - M19_CHR_1800 = $B000
$ w! D) |* L* g$ m: D& h% L; P$ O - M19_CHR_1C00 = $B8000 {+ w5 z) u2 v8 ^5 `! ~- W) o9 q
- M19_NT_2000 = $C000+ C6 p, [" G2 \0 J7 Y
- M19_NT_2400 = $C800
) ?' n: W6 N7 e9 E - M19_NT_2800 = $D0003 N( u- k9 z. G* a: n+ z. V
- M19_NT_2C00 = $D800
/ Z0 h4 I' q) m - M19_PRG_8000 = $E0003 u" a) s. b1 m
- M19_PRG_A000 = $E800: T# ]% F7 v- [* b- M9 r
- M19_PRG_C000 = $F0004 y9 k9 Q2 |+ y; a
- M19_IRQ_COUNT_L = $50003 o9 l: r0 L6 {, @# t- N% T9 e! t* C0 w/ y
- M19_IRQ_COUNT_H = $5800
, f- a) Z; D; z! M - 5 X# S. _0 A+ _2 u3 D. b' p' k
- ;==================================================
1 G/ ?/ ]2 {9 O - ;程序块配置) d$ o) j) }0 F! d/ n0 n
- BANK_DATA_MASK = $07
" q/ E5 }) m$ P2 Z; G; Z - ;--------------------------------------------------7 R f+ y4 B6 ^
- RESET_BANK = $076 f- o* K, y) I6 g- u9 x: Z; v
- RESET_ADDR = $FC00
( Y2 b" Y# W, n1 b& b$ w1 R
5 C/ q$ P4 ~( v" D g- ;==================================================, I7 C/ l! B) r- |7 ?4 w
- ;图像块配置' t- j+ e: c6 q3 f( p* ?
- CHR_DATA_BANK = $087 d! X8 S9 m0 w# q& d
- ! ^/ F3 E! J `* e/ V% s+ a( T
- ;==================================================
3 \3 e% Z' O/ a+ r - ;零页内存地址配置
, b. ?& ]7 w y! j# C3 T - Use_Ram_Addr = $80
, H8 P. q& @" M0 g7 h - PPU_Ctrl_Buf = Use_Ram_Addr/ K& _3 T1 Q& k4 ~/ y/ R
- PPU_Msak_Buf = PPU_Ctrl_Buf + $01: V. Z$ T9 Y& s! Y, t% i
- PPU_Scroll_H = PPU_Msak_Buf + $019 H( b- a1 R/ E5 @) D
- PPU_Scroll_V = PPU_Scroll_H + $01
8 ^. I: N) W# K7 u, f1 J% a - FC_Data_L = PPU_Scroll_V + $01
5 \1 C' r4 c- A {* J - FC_Data_H = FC_Data_L + $01! a" ] a! R9 @' Y
- FC_Data_Buf = FC_Data_H + $01, S5 S* k; `: h1 s
- ;==================================================
# {; A; R1 i3 ?2 u0 F
+ g: l; f) D5 L7 P9 x) m1 h- GAMEPAD_MERGE_FLAG = $043 M* X2 v; [/ [, f/ I
- 2 T' N) ^( n- I3 l/ @
- Gamepad_Keep = FC_Data_Buf + 1
, a7 S/ B9 g4 R3 D/ M0 x - Gamepad_Once = Gamepad_Keep + 2
' a( S7 [0 I5 Z( F - Gamepad_Temp = Gamepad_Once + 2
7 O, x9 ~5 {2 ~ - 7 ~4 `' J! B; g; U: b. k5 p
- Gamepad_0_State = Gamepad_Temp + 2
a- d5 B" r3 x. v( Z' i0 W - Gamepad_1_State = Gamepad_0_State + 1
. T7 ?; D. g/ s' w r - Gamepad_0_Value = Gamepad_1_State + 1 D1 i9 \# P0 ~ ~& M
- Gamepad_1_Value = Gamepad_0_Value + 1" L- [3 q6 F. T5 Z( ^
- Gamepad_Port_Value = Gamepad_1_Value + 1
$ h5 Z. |! Z: [9 ?2 z B3 z- Q1 f - Gamepad_Merge = Gamepad_Port_Value + 1* |8 e: P$ J8 `# a6 B; @
" f/ N. E7 M4 Q% P- ;==================================================. V6 u7 P9 J" G6 L& U
- IRQ_Index = Gamepad_Merge + $01
4 n0 z7 S2 D. @ - ;==================================================
s% J. ^/ y. q2 b& c' _( |, ?
+ y0 |& w6 g: I' |2 l- ;CHR图形数据 N/ U c3 D# t! \2 q. `
- ;==================================================
; @ ]$ l& `6 }) w2 M: W0 y5 z - .BANK CHR_DATA_BANK5 e8 }1 G6 [4 g4 O/ [9 X
- .INCBIN "chr_bank/chr_data.chr"
) j P! O, V/ U" e - 2 K5 @& ~& ?2 {$ x/ S8 ?
- .BANK RESET_BANK & BANK_DATA_MASK5 |. u+ u. e" ~2 ^! d( S
- .ORG RESET_ADDR
$ F/ ]& D) U( r$ E -
! Q R8 t8 i1 k) I! k! b7 \+ r0 J, q - ;--------------------------------------------------
+ s8 G3 O' R' O7 S# u - Attributes_Data' y8 J+ a0 B1 h
- ;命名表属性# V, i) y$ e; ]) {$ Q' G
- .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
. ~. [0 {/ q) S# Q8 O4 d- L9 i - .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
2 r- z0 d7 Z" z b& ` |% J9 \ - .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA5 H2 h* h% Z( V, Y1 J* P
- .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
k' j$ U M( L% m1 B5 { - ;--------------------------------------------------" P$ I y; ]- h% B* E
- ;调色板数据
9 U+ H; H' |& x; E3 S9 {8 W4 G - Palette_Data
) V( D, w! G) v3 ?: L" | - .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
1 k) K8 `5 C9 B7 ~ - .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F8 p. ~1 o5 r1 d) @; Y5 H# r: Z L+ V& K
' q* W# b2 p6 m+ ]9 e, X: o- ;==================================================! u& B' W' A0 h$ J$ A
- ;命名表初始化# u) I1 l2 g) k
- Init_Name_Table7 l, O7 J) g) \, z
- LDA #$209 m8 ~8 r4 @, o! N0 M# `
- STA PPU_ADDRESS
# _# u5 l a9 U0 _" e" m - LDA #$00
+ a: s" A7 Q2 I: `7 i8 H - STA PPU_ADDRESS
7 _) _/ z. `) I; }- f3 O" ` - LDA #$002 @8 ~- F" R# r4 _( S6 |
- LDY #$00
* |( Y* M$ j3 H. P# _ - LDX #$10
% i0 M, W$ \- Q! ~- n0 \ - Init_Name_Table_Write" Z: F1 s- n) I( `
- STA PPU_DATA r* A9 Q8 K- }& Q7 C
- INY, b: k! P- M( X
- BNE Init_Name_Table_Write
2 p$ n' j) ?. a4 I1 ]; B - DEX& w# n3 h( y' C
- BNE Init_Name_Table_Write
0 y l! M, W1 u! N* R - RTS
M7 f# M, p& H4 F- \ -
1 A- J3 P0 S$ ?0 z0 G, ?& w5 E - ;==================================================9 n# A7 C; V o' Y! H
- ;调色板初始化8 g: Q! I. z& l& L
- Init_Palette' Q: Q2 O% G8 d. S2 T( w6 T
- BIT PPU_STATUS; u) O# l. C6 P# |
- LDA #$3F$ m! s0 T/ ]3 J" O
- STA PPU_ADDRESS
4 Q# [" ^1 H" e+ z1 f/ v. P# }% A9 F - LDA #$00
+ i5 [( ]( G3 T! L - STA PPU_ADDRESS
. d1 u' d" w; `& n+ O - LDX #$002 M3 w+ q# n2 ]
- Init_Palette_Write
* v8 R$ R5 v- N' | - LDA Palette_Data,X4 k: p+ u& A# g( m4 k$ [( f5 k
- STA PPU_DATA/ j1 z0 u1 T9 X) i& P9 d+ |
- INX2 b# j ]. Y) ]
- CPX #$20
* S, U2 }# n2 S {' U5 a - BCC Init_Palette_Write6 h6 e C1 K3 x. M2 |, s
- RTS
k7 c" y0 a8 `5 l6 d; X, v' W8 Q - : W$ l( l5 ?9 ~
- ;==================================================
A4 @" G& h$ O5 w$ b& S6 W3 L - ;设置命名表属性/ h$ h& n! a7 C5 ?0 t
- Init_NameTable_Attributes. N H( O( V& x$ E
- BIT PPU_STATUS
% x9 p* A W; T# M& q - LDA #$23& K2 U$ ?" P( T# V. c1 q5 g
- STA PPU_ADDRESS6 r5 g' W! O9 m D$ K3 p
- LDA #$C0- F' ?/ k& x9 D$ o/ {
- STA PPU_ADDRESS
- [9 ]& {+ c* U P - LDX #$00
) [' s7 }6 Z2 X3 e - Init_NameTable_Attributes_Write
5 \$ C2 s- ~% e- c - LDA Attributes_Data,X$ j7 L$ d2 x, a9 L! z5 L. y6 |5 e3 t
- STA PPU_DATA
' N% ]4 D( x5 v( Y5 Z! d - INX, c+ D, E* p, `9 q
- CPX #$408 U; K+ y: n9 u, r; J5 G' L
- BCC Init_NameTable_Attributes_Write1 [ [2 R! e) J: [2 i5 G4 H
- RTS. ^" W5 B6 R* _$ o
- + ^( F# A9 _5 J' a
- ;==================================================: Y) W% ]& T) I ^* V4 A/ |% ~
- ;初始化命名表文本# [$ C1 a& H5 N+ `2 Q
- Init_Name_Table_Text
3 r4 s; ]9 [" F6 n \7 X$ x* f4 j# H - BIT PPU_STATUS
# w4 G0 m8 U6 B4 f - LDA #$20# e5 M/ r: d, d" Y# Y: d! u: i
- STA PPU_ADDRESS; [, y' [ C v' H
- LDA #$00) D% j6 p" W6 ^! k$ B
- STA PPU_ADDRESS4 ]. W# ?/ A4 T, q6 D/ w" q
- LDA #$00/ w# `( M* B I
- STA FC_Data_Buf
0 p8 f0 n) e# N1 v - LDY #30
2 [+ i, w% g0 Q2 h( i- k3 I1 T - Init_Name_Table_Text_Write
' V' b) N5 }$ \7 o* |# X' T - LDX #32
! n1 M& j8 c1 h: R4 ^7 [( m/ [ - Init_Name_Table_Text_Write_Char
& J8 s6 G$ C, R! G I% y - LDA #'0': U) m* l/ m" i* p; ?9 @- S2 l
- CLC
1 Q9 ^9 F) P- D" d7 a; m4 P1 G0 b6 y - ADC FC_Data_Buf
* Z3 Z- k. t+ y9 i - STA PPU_DATA
0 b- H/ M ^. V' O( v: u3 y9 Z - DEX
: ]; O Z% N; a) Q4 W - LDA #$14 G2 z9 F* Q U: }
- STA PPU_DATA
1 Y2 p6 M- o% [( y - DEX
$ v" D! }& E+ m - BNE Init_Name_Table_Text_Write_Char( T8 g) D! z" @) l# x, Q
- INC FC_Data_Buf2 o5 H) N& z7 {1 t" ` l: U: Z* f* e
- DEY
0 Q- s: I/ ]$ Q9 @ u( ? - BNE Init_Name_Table_Text_Write
9 L; b* X0 q& r' Z - RTS
- v9 D0 i' T& t y! N - + o+ g, J3 r* A2 E
- ;==============================
) L# l8 l* j% T - Init_OAM_Ram;初始化精灵内存
% ]1 E+ @ `( C2 w9 T - LDX #$00% V0 z& i6 E7 F, ~
- LDA #$00) a- R1 g! H! V$ ~5 W$ I
- STA PPU_OAM_ADDR
0 @; H1 v! w. O# q: ]2 ^ - LDA #$F8
5 h1 v- |& r0 t2 x u8 j7 Z - Init_OAM_Ram_Write: M0 y7 P2 j* `4 b
- STA PPU_OAM_DATA3 ^& d- _* k k9 c
- INX
2 k! p5 ^( l! Y+ W w9 e - BNE Init_OAM_Ram_Write9 e# f9 r$ g8 O- H$ n5 Y
- RTS
1 ?8 G5 B/ W; k. M - $ {% z9 r+ ~& Q& H" j6 V
- GamepadProcess;手柄处理$ L" r# X: M3 Y# R
- JSR GamepadDatacan2 L+ D/ W% J9 h, S8 X: g% {
- LDA <Gamepad_0_Value$ f+ v/ `5 a5 m. ^* p
- STA <Gamepad_0_State7 N8 y$ ]' |1 s7 z# r Q _3 \. k; o1 e9 [
- LDA <Gamepad_1_Value, C; Q- e. l6 u, |! j8 b3 n9 b
- STA <Gamepad_1_State2 q, O# h9 d6 X8 ^. u
- JSR GamepadDatacan
8 I; l( `" b; L7 W/ L" }7 w - LDX #$01
' E9 X6 e& E2 p# G$ C0 N' I: } - GamepadMergeCheck;合并手柄输入检查# B4 h- O# N3 E& C& z# U
- LDA <Gamepad_0_Value,X
1 ~1 J! k5 g" t* ^7 `$ S - CMP <Gamepad_0_State,X1 `1 I% j1 e t' O" F9 l7 S- A
- BEQ GamepadMergeInput9 \/ v* X" T R8 Z0 p
- LDA <Gamepad_Temp,X
( u" s/ z: e9 e1 u! Y+ P; O$ T - STA <Gamepad_0_Value,X
4 Z+ d; H2 j( R3 {( `# X- ^ - GamepadMergeInput;合并手柄输入8 f: b0 t2 @0 x: ?$ }
- DEX; }# r" q0 [/ c
- BPL GamepadMergeCheck
- h3 w8 t4 S) z+ a4 K3 v* \4 w - LDA <Gamepad_Merge
8 t v! G( _5 ]" g - AND #GAMEPAD_MERGE_FLAG0 i6 |5 `. h1 f- T& n
- BNE GamepadStateProcess" @0 G/ m: P% U$ S M) v
- LDA <Gamepad_0_Value
0 n! d( X* G# D1 B3 |) e/ _ - ORA <Gamepad_1_Value
n' e0 D% N6 F* @6 d( c+ E4 a - STA <Gamepad_0_Value
5 m7 L5 x8 X. S! K' W - GamepadStateProcess;手柄状态处理- P) j% C1 [8 a+ {0 n
- LDX #$014 V% X1 U4 Q6 Y" K0 w$ J
- GamepadStateSave;手柄状态保存9 G/ V0 R$ v! o- G, N, J- P
- LDA <Gamepad_0_Value,X( \4 u7 q$ C; W( c
- TAY, A: S% \) N, e E( Y$ y( G
- EOR <Gamepad_Temp,X, q$ S: |1 A2 y6 k7 m. R2 A
- AND <Gamepad_0_Value,X4 W, G# ~3 J8 O% r
- STA <Gamepad_Once,X
7 I# A9 j3 ]7 J3 { - STY <Gamepad_Keep,X7 K' S& R' p6 o2 E3 C
- STY <Gamepad_Temp,X
% z t/ ]8 h1 b- B" ^" W9 G - DEX3 G8 E3 V7 I- `, C" R) {' u$ j
- BPL GamepadStateSave2 m6 t$ ]% E. u m. T
- RTS; x9 w0 A' [8 n) G2 c
- 3 O0 o c8 l. [! t- N
- GamepadDatacan;手柄数据扫描# D4 L! v+ M# P- @1 p6 Z! T/ ~
- LDX #$01
3 R, {2 e: P. j/ j - STX $4016
7 g. q. Y2 |/ f; l, u0 j1 y+ T - DEX
# V `; \( k; P - STX $4016; I' `' f7 B$ B3 D
- LDY #$08, f9 q* R4 I" D: F9 V* E( e" g
- GamepadPortScan;手柄端口扫描
2 u6 w# \3 _2 M# }7 W$ |& w - LDA $4016, }. R* ~4 u; G& i, A1 T; r
- STA <Gamepad_Port_Value- T9 ^* A: M: h+ Z& `
- LSR A
. `, R7 S% h7 j% A1 |; f - ORA <Gamepad_Port_Value
' v3 V& H7 Q ^& L1 }: S - LSR A
. U w% X$ ?" z0 f6 v - ROL <Gamepad_0_Value* t$ e( t# \' O8 I
- LDA $40179 L6 C1 c% e0 [4 w
- STA <Gamepad_Port_Value
0 o" E" [3 k+ E, r - LSR A
+ E* f6 Q4 z8 C+ I. {! B% V) m - ORA <Gamepad_Port_Value m' F( s8 ~2 E
- LSR A+ h$ P D3 c! r1 ^% Z6 v* M( T1 [2 c
- ROL <Gamepad_1_Value h3 ?& C7 `. z( i9 Y0 l" p
- DEY
O& f8 ^, r( p: B3 r - BNE GamepadPortScan
' ]) \9 D# T" V& c" \ - RTS
1 W! q9 }! ?6 A" l) X- I -
6 Z9 l- r' P( h - ;==================================================
$ O* G0 T- t* ~" K8 e0 o9 x/ W% G9 h) o - ;PPU处理
# C6 L7 | u+ o - PPU_Process
- o3 o# y1 D, U* s3 h3 [ - LDA #$00
- w% g* ~8 D/ O( Y - STA PPU_MASK2 L* m6 z/ h6 F- W9 b% w
-
% o8 K: Z. E+ \0 T, t - BIT PPU_STATUS
+ [, Z1 X y& ?7 s0 O0 t - LDA #$201 J( F% s( i% l4 R; c
- STA PPU_ADDRESS; V1 |) n, `! R" z, S; ]) |
- LDA #$00( ^3 l8 o4 j" P6 q, F- a
- STA PPU_ADDRESS
, ^+ C/ N2 N' j: g - 3 ~8 p% f& }- S) c' A
- STA PPU_SCROLL
$ J0 m$ _9 ~% ]8 d9 B8 j - STA PPU_SCROLL2 ~) X* |. ^: D, m
- 0 c* ?' U$ h* b7 A
- LDA PPU_Msak_Buf
* _ O5 A/ R g( g! R - STA PPU_MASK9 d2 ]" w/ p6 p' s/ M
- 3 D8 [/ w# v% k3 W! _
- RTS& h4 @5 j- d# m7 y# D/ T& {
-
3 |' @2 |! b/ L - ;==============================+ R' B" c! {3 n8 h6 H
- Time_For_Vblank;延时等待
/ C3 o! \# u2 t( J g - LDA PPU_STATUS
; F& Q' I/ K5 b8 `) K6 G; A: F - BPL Time_For_Vblank5 u3 z u/ H8 d5 u! r& B: Y
- RTS. R6 ?) V8 n9 T, m. w
-
6 {4 v; [$ L4 v6 ` - ;==============================: k" F( C4 o. `' k6 f
- ;初始化MAPPER19
1 E% t5 n# o- Z* y. S" E - Init_Mapper19
6 X$ W ?- y- r* V - LDA #$00
6 }4 L: I$ u' _, M - STA M19_CHR_0000
% z7 H* g" Q, { w - LDA #$01
5 v7 a6 N) t, `9 K- H - STA M19_CHR_0400( S ^( f: n: r
- LDA #$022 w: z/ B/ L* u C1 `/ ]5 s @
- STA M19_CHR_0800
( E& a/ R0 ^+ K; A) r8 D n - LDA #$03
% u8 V9 i- C9 k( ] - STA M19_CHR_0C00
, F% t- w3 _, s - LDA #$04* Y7 B1 a6 K- O1 b8 f; U. s
- STA M19_CHR_10000 h+ o7 r1 [+ `8 N
- LDA #$05
0 z* h7 e6 W5 S2 k - STA M19_CHR_1400
0 k! G2 B; g4 h( A6 f, v - LDA #$066 a( G8 [# [6 d# [
- STA M19_CHR_1800
5 Q7 \" l+ e. P' u' y( \7 q9 i3 x9 y - LDA #$07
: ` e3 K5 n/ {8 w4 R: k - STA M19_CHR_1C00# {0 L- C. \3 |
-
: l- M" t* D6 Y2 \0 D3 d5 D) L; }1 H - ;禁用IRQ
1 s$ F- `: T1 _ - LDA M19_IRQ_COUNT_H& f1 C# }& Y6 P
- AND #$7F
i0 x: }% m% n; Q4 ?0 ] - STA M19_IRQ_COUNT_H x0 }. Z) A9 x( ]3 m
- & S+ v' Q1 i" ^+ T0 Q" f: x ^
- ;命名表 G; m v6 r" H' @* v4 g
- LDA #$E0! U% {2 n4 I! J9 ?
- STA M19_NT_2000- q q. a- e+ {
- STA M19_NT_2400) u9 o) A! L6 h
- 6 ?# Z5 W- b0 }$ N* E
- ;命名表1 X2 }( U' F% U& ^3 E
- LDA #$E1
! v9 ?, }5 s2 |) E: a) H - STA M19_NT_2800
# j# g8 B6 H* _: M% d5 ] - STA M19_NT_2C00
, E: x" A6 E T; Y$ f+ i -
! [5 o1 x" e4 U: i5 W$ z - RTS/ q% T# c$ w! N; }3 B! g
- - v7 W2 a9 V, E( l- @
- ;==================================================
# V' Z! Z r6 k* d H9 T* G8 O - ;重置中断处理
6 {% U8 n- i! j8 I g - ResetProgram2 a/ S+ M* { E, [8 R, G8 c1 i
- SEI
9 C& S- V% Q6 @% D) o - CLD
5 I+ H# v1 r+ V2 \2 T1 | - LDA #$00
% c R9 q) y$ n0 g0 V+ s8 n% P( a - STA PPU_CTRL* l6 v9 N# W7 z* w
- STA PPU_MASK
. h$ Q. H1 }1 {5 C8 M! z' w7 u - STA PPU_STATUS' c. D6 m1 }. y: ~, i7 `7 f6 N
- STA JOY2_FRAME& @6 y) h# ?9 f$ @
- STA APU_STATUS
4 @/ k- k. N' k) k9 u- m4 v; W -
0 b8 ^0 A& \6 \1 X7 H ~ - LDA #$C0
8 E* R# _6 M* U Q. F8 } - STA JOY2_FRAME
( D$ Z% z/ k1 s1 t- a$ m - / E" Z9 o1 ~0 Z. L
- ;等待vblank
6 p5 s0 f5 q2 P; [0 l - LDX #$02
# C5 _" E3 `# C( _+ Q$ N0 H - Vblank_Wait_1
" F" |/ c( u9 S4 E* o' @ - BIT PPU_STATUS
! E9 D7 q O. ~* M+ P - BPL Vblank_Wait_1/ P4 a" X/ ~' A1 `# t# @
- Vblank_Wait_2/ O. ^$ R% o4 x/ o$ P, r
- BIT PPU_STATUS
2 C7 \2 d. a9 v* x$ N! { - BMI Vblank_Wait_2
* c3 f+ u7 d7 t) _; u& \+ [8 n - DEX
. `& w! D$ o1 ~$ w0 S - BNE Vblank_Wait_1+ f- S, t; ?; }) F( `
- 2 I% f- ^' @% L6 @, {4 A) }
- LDX #$FF
" ^8 I! I7 x# ]8 f. _. c, X - TXS4 b6 b7 c0 T* a q/ j# P, G
-
& l- ~8 {1 e- u - ;初始化MAPPER197 B, B4 v; l0 p0 u
- JSR Init_Mapper191 C/ n6 P3 c+ _" t& g+ S
- - ? v# Q; r+ V5 g( w. [
- ;==============================
& ^6 _$ K6 W, n% Z - ;RAM初始化
4 [. _0 @0 L% E8 R, j6 z - Nes_Ram_Init/ ^4 c$ J; B) j2 {
- LDY #$002 N. Y0 e/ }" G# J1 M) H' H
- LDX #$08
* x7 R) ~" H s+ J& S - LDA #$001 J% W. \. X3 B; |9 K8 ?
- STA <$00
7 q2 E9 g& y2 R) M - STA <$01# A$ R6 f8 m% ]
- Nes_Ram_Init_Write
+ n( m0 z) V$ l! W1 n+ P - STA [$00],Y
1 ~; j& J/ ~& g; f" t4 E" h - INY
4 e7 x0 o4 m' |# R) ` - BNE Nes_Ram_Init_Write J1 t, R/ |7 ]
- INC <$01: v) d% W! X, y& F. j0 i* o
- DEX
1 g% R2 e9 X. _9 o& ^ - BNE Nes_Ram_Init_Write
+ a: D6 i! I9 b -
8 V) d! O$ y( E% u0 G* W N - ;初始化命名表
; f2 e- M6 I3 ?$ a/ J. u$ w* t* N - JSR Init_Name_Table
/ K. q" a2 L2 M1 _8 _ - % @( c$ q) w% T, b; |; m
- ;初始化调色板
& G+ k/ v- D& \ R - JSR Init_Palette# d& X* i O& {0 N8 k4 T7 V
-
4 j" D- T3 f' Q5 v6 O5 j - ;初始化命名表属性
; a) a% h( A" Z6 `+ A - JSR Init_NameTable_Attributes
! O0 {# s+ w! x- F -
[" k! K: q% }' G8 v* R; p - ;初始化精灵内存
( D4 ^, e) j/ q - JSR Init_OAM_Ram% @; J; w3 E K' n/ l' O
- 7 i1 g& t. Q# l
- ;在屏幕上写点东西
2 ? ~: n( l* b4 s( ` - JSR Init_Name_Table_Text
! w0 F2 |$ V1 x: b( a3 s0 s( `3 _ - $ m. [ Z' l+ n1 h! t( e
- JSR Time_For_Vblank
3 u" X/ y9 F2 V) ~2 l8 M - ;开启PPU控制
6 E1 y" i0 r. C - LDA #$A8) _& V6 z! V8 ^+ |
- STA PPU_Ctrl_Buf- i, A# ^) Z: U6 p+ G5 T
- STA PPU_CTRL
, N! h7 y$ i8 Z; C# Z/ C, p- k - . D/ [# l$ G$ |( }2 B- ]3 n
- ;开启PPU显示
( G2 {, w! p8 T$ o: Q7 X1 U - LDA #$1E/ b- L! k( W' u b _, M
- STA PPU_Msak_Buf" t% G7 R& _ `7 a& m. `
-
+ g+ z: V' T" H0 Q: m) i& ? - CLI
- s* x* }7 B9 I/ O! m2 _ J8 y - JMP Loop6 @+ Y4 ^( N% J0 o* v
-
1 X9 _0 M4 ^2 K! r - ;==============================2 z" r0 i/ { P; b$ ^
- ;死循环, 等待NMI中断
8 i( \" n4 b F0 g) y7 ` - Loop6 _& M, w% F% _9 v0 t. @
- JMP Loop8 W0 @. @- J3 ~" T2 h [' ]7 w
+ x7 h2 C6 a/ p) Z: U' D4 }- ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967. [/ D; Z# h# N1 R# v
. m; |' y1 {. }- ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)
( |* `+ k: [* e% L" T# a - BEGIN_LINE_CYCLES_START = 32768 - (4103)/ d0 ?$ y% j6 E
- ;==================================================& H3 b& T& {, r2 e2 C
- ;NMI中断处理" d# X# f3 c' h+ B
- NmiProgram/ [! }, d& I, r9 [
- PHA, d5 `( E! Y, G' E% X
- TXA2 Z5 [: S8 {3 {$ x
- PHA
1 r$ H4 d# j1 u4 v/ w" A - TYA+ j. ?) y4 @$ a& U% l6 \1 @
- PHA
8 J. [% a1 h: y' M -
! M, S8 `& |; z* K# ] - BIT PPU_STATUS
: |7 b6 q m. O% A - - ]+ Q0 h6 L3 M' T7 v3 _4 c
- LDA #$00
- _6 d R6 b* r6 Q# e# J. t - STA IRQ_Index
& ~- @* r. {5 @: v9 j5 d) R - 7 t7 d. u- k- G( r/ [3 v3 I( Q: L
- ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
2 D8 c8 g! M' t; i4 P5 p- u - LDA #LOW(BEGIN_LINE_CYCLES_START)5 Q. o) q+ a2 I
- STA M19_IRQ_COUNT_L
; u7 W( Q5 E( J; h/ S! h! v5 b - LDA #HIGH(BEGIN_LINE_CYCLES_START)
' F5 v: c8 O) X6 @' s- z - ORA #$80! |8 v5 e% z$ D l8 `# w. ~$ H
- STA M19_IRQ_COUNT_H D0 p: ?' J/ E5 j& A
- CLI" {2 V5 U" V( r: \/ O2 S9 e/ x( v
- ; W( e# d4 R+ _9 p
- ;关闭PPU控制
1 t% R9 ?7 k7 K7 w+ b - LDA #$00
( j( l }9 d" P3 z* N( A - STA PPU_CTRL) {- `, y% |6 S* |( F
-
, b0 _$ a: V& w6 `1 Y - ;处理PPU
3 o8 ~+ l" d% J$ h( `- b Y2 z- V) G4 [ - JSR PPU_Process$ A4 z1 C, ^0 X, R
- + |+ f1 c, l. ~' k. a
- ;开启PPU控制3 j# j) {7 B+ f2 e3 ?/ n6 |
- LDA PPU_Ctrl_Buf
^/ G3 M$ B& l* V/ E1 |# y - STA PPU_CTRL2 P3 k4 J v6 t
- & y4 {5 w% M2 [2 U) F0 S% h6 f
- ;手柄处理
j" T3 H: x" R |3 i. T5 W1 m4 E - JSR GamepadProcess
2 l# G8 r+ S& r: |' c- J% f - 0 i0 `- Z/ h" G6 V* m4 [4 s
- LDA #$00
& q; Y( ~9 f1 p - STA IRQ_Index9 g7 B( I& K* p9 m% L1 B
- 8 ?2 `, ~9 {, X9 K5 e$ W; b
- PLA: x- e. c* e( U% u. j0 j. X
- TAY
0 Z% Y' L% i. P6 } - PLA
+ y& O) y6 r$ Z: i! B4 \# C - TAX
- b' l: N; S0 s% X4 Z$ t3 @; C - PLA
! c* W* I2 S( h& ]2 b3 } - RTI' v. |* }7 g! d) @5 Q
3 w L& R4 P" x" K/ ?7 G- ;每行扫描线113.67
% s1 u: ~9 X- D2 K5 v - ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)
* @ t% u+ [, W8 C* u" o- v$ r! Z - BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
+ r. X `5 }' f" v. x - ;==================================================
0 I9 ~% q) H& O4 z8 |& @2 ]; r y - ;IRQ中断处理
`% [5 V6 k- p9 u8 m' Y - IrqProgram
2 E7 j# I" b" t0 \5 B - PHA3 W0 \* Y1 H! h |$ Y- Z: I! m& u
- TXA7 r2 Y0 O, h9 k1 Q# S! b
- PHA
1 y5 T( C- Z3 B$ a8 _: {; ? - TYA6 l3 T+ c0 n" f$ X3 \; }: F
- PHA$ e- i/ G$ T: w- ?+ }4 ]
- ' }* Y8 | Z9 J/ {& ~5 s
- ;16条扫描线后触发IRQ
7 }- {8 M( T+ J - LDA #LOW(BEGIN_LINE_CYCLES)
/ ^( m6 N5 t8 n. V6 |# }0 f3 y - STA M19_IRQ_COUNT_L
* v0 S& `4 h" ]; D) E" g - LDA #HIGH(BEGIN_LINE_CYCLES)
9 X V, i2 [# H- W - ORA #$80
$ `, T2 O( N- v! @( E - STA M19_IRQ_COUNT_H
2 T9 m2 v, A: r, S S1 \6 ^: R1 K -
1 T6 O T! u6 e6 j s - LDA <IRQ_Index
- b4 I9 Y- m( s, }: R - BNE * + 46 U( v; t6 _+ E( E! D9 X! N
- INC <PPU_Scroll_H
e l) s7 i+ f4 \+ I- b# ~* { - 2 I. I2 n, `* q( W. B
- ;设置屏幕滚动 y. z7 @4 e# N- ?
- LDA <IRQ_Index$ J5 |) s6 s y- W& K
- AND #$015 T- B( V9 q( @" K- l: L* x! X& e3 A
- BEQ Irq_Scroll_Right+ S; H; ^2 e; N0 F- Q" y' A
" l9 z$ I8 b- o- Irq_Scroll_Left- f! e& [: z! t' [$ Y( J
- BIT PPU_STATUS
; N8 c" j! `% H1 i - LDA <PPU_Scroll_H9 U2 n8 k% h s% c
- STA PPU_SCROLL
& m* \% \0 J) F: J - STA PPU_SCROLL
7 D. \8 h+ |$ x& G - JMP Irq_Scroll_Over
# o. ^# M. O) y, s -
; |4 Z+ ]/ ` p1 F% S% z3 Q - Irq_Scroll_Right
2 P# P% q- D% o; h- m - SEC! ?/ Z$ o% d7 x9 V' M2 F; J. Y
- SBC <PPU_Scroll_H3 K" h% A5 B9 L+ K" N) \
- STA PPU_SCROLL+ b8 I/ I# k/ [! |* ]# w8 E
- STA PPU_SCROLL. r" [; @; ?' y: v: i8 G9 x
- Irq_Scroll_Over
( v8 @ E9 D" ]( _3 l& i8 V -
0 N0 l3 z& |# ] - INC <IRQ_Index
7 ?& l2 L0 V7 I: X) y) ] -
/ Y! F# f; Q# a* U: h0 M/ v3 X& @3 } - LDA <IRQ_Index
n% U( Q! G) E4 {( |, c V - CMP #14& g6 L0 G9 b, @8 ?' v
- BCC * + 10
6 w3 ]( e7 Y' H B( V - LDA #$00
% z0 A6 a. o( G5 w9 X - STA M19_IRQ_COUNT_L
7 r4 f* ]5 ^9 g5 i r - STA M19_IRQ_COUNT_H1 I$ u; K. O0 ~: n2 _" E4 k8 q6 {
- 3 I6 y8 l' `' z4 k: P
- IrqProgramEnd
- q8 d0 q' V' m w7 z; U - PLA
5 Q Z% n- G# q- ? - TAY7 T% W2 p Z2 @
- PLA# R# I1 V: H8 c6 N; G
- TAX
! S' F7 @: [7 m: v - PLA" ?: a Z2 ` m u/ R
- RTI
8 h/ d8 D" v! n2 G. \ - f! R. Q- U( @# [0 {& P8 `
- ;==================================================
- l- d4 W' f. Q9 p9 K* f - ;中断表
4 Q" M3 B/ i% ~/ x- @ - .ORG $FFFA
& h1 U6 |3 q# F1 ~( H8 g - .WORD NmiProgram/ P# Q6 S) f: l* F2 q: q6 j$ c& A
- .WORD ResetProgram
+ D* i- P* l5 u/ c0 H h, E7 _! | - .WORD IrqProgram
复制代码 - O% I$ e, E8 Z9 s& k- [) U* x* o
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|