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