|
|
- ;[FC][Mapper19 IRQ]7 q0 t+ {0 P' E- H& X. C) K: }4 I" d
- ;FlameCyclone 20230710! V+ I" j$ k) `6 w& i
7 O m* o' U) R5 H+ c! G6 D- ;文件头1 Y1 u3 O: a+ v' J# E O: N
- ;======================================================================
2 ~6 l# B" S* ? - .INESPRG 4 ;16KB PRG 数量. i3 d, ?* z. X4 {, k# O& n
- .INESCHR 1 ;8KB CHR 数量
) m! J ]( E5 F7 |1 Z) _ - .INESMAP 19 ;mapper 19
4 X; r$ |* ?- X- q3 L; N. X8 S9 c - .INESMIR 1 ;命名表镜像 0水平 1垂直. w! y+ C7 z7 q
- & U$ n6 I3 F3 e$ k
- ;必要条件9 C3 y# R+ n6 ?+ s- [
- ;1.持有CHR ROM
' q6 m" @7 g. E9 U: n% ?5 Q! k I) b1 z - ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$10001 d1 ~2 b7 L! d
- ;3.精灵内存(OAM)不为空
$ L" l d* P* u R" M4 Z - , B! ? h6 |) V T3 N
- ;==================================================. H# j" D, p$ {& j! U
- ;NES端口常量
- ^* E$ g; H8 h* |, i - PPU_CTRL = $2000 ;PPU控制寄存器, K% d, h$ e+ U
- PPU_MASK = $2001 ;PPU掩码寄存器
$ N! }# ~* F+ F" g* U/ H6 _/ _ - PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位& z; N# C+ ^+ _9 p. O6 @& {
- PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
0 m) H3 W5 ?4 W: w - PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1- m5 a7 N( V( I$ U7 ~
- PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
) q" N* c( C2 T9 |6 ` - PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加5 f, E; m& t+ U% c+ b
- PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 & a: h0 A3 r3 y1 v
- OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存$ _( C& ?8 x! ?1 B! t" ]7 I0 E- h
- APU_STATUS = $4015 ;声音通道切换
# y2 o/ l: W' v( Z$ ] - JOY1_FRAME = $4016 ;手柄1 + 选通# R1 V0 r% ?5 w
- JOY2_FRAME = $4017 ;手柄2 + 选通
% L0 @% e G* F0 Y - M/ j+ ^3 `: A% s
- ;==================================================- S7 f7 H5 ^2 ^: j" ?( W0 z4 [5 `
- ;MAPPER 19端口常量
% V; ]% j% i, [# i# W% _+ L - M19_CHR_0000 = $8000; I( l. w/ B2 ^" H6 N, _8 S
- M19_CHR_0400 = $8800
1 M) H" l5 P+ i0 P - M19_CHR_0800 = $9000
/ D+ l. Q6 M# J* B( z- W - M19_CHR_0C00 = $9800
0 S6 F1 |% A9 C# J5 e - M19_CHR_1000 = $A000
3 p2 ^4 v+ J! n" r1 Q2 y5 j& u/ @ - M19_CHR_1400 = $A8009 _0 ?9 [9 j. I" ^/ w A
- M19_CHR_1800 = $B000 A1 S3 \ Y7 ]" g# i: J9 I0 P
- M19_CHR_1C00 = $B8004 [. V; _/ ~, Q: q% ^
- M19_NT_2000 = $C000
# i5 T, T) s: p# V+ c7 ~6 }( L( N - M19_NT_2400 = $C800, u( ?: y1 t9 K: ^7 D
- M19_NT_2800 = $D000( a$ w" Y7 G1 C! d
- M19_NT_2C00 = $D800
$ {& E; J+ D1 [4 Z- B- c! \5 ? - M19_PRG_8000 = $E000& E3 o% l1 F* j2 m$ g( G
- M19_PRG_A000 = $E800 A4 o) ]! }) V* u, b, b+ W3 \
- M19_PRG_C000 = $F000/ A8 x4 x! H0 d4 z% } G
- M19_IRQ_COUNT_L = $5000
8 ~/ L/ {6 l5 x: u5 ` - M19_IRQ_COUNT_H = $5800
: Q0 W9 Z5 c b5 O
% g. v2 T3 Y1 m/ g6 ~- ;==================================================
5 @. s; r+ _8 @/ t* g% t7 ^ - ;程序块配置
& v! E" M% w5 |! V0 \; d - BANK_DATA_MASK = $07: \$ u9 a! |; F6 N
- ;--------------------------------------------------( s+ S3 k, e. O+ Q0 ~! d) f
- RESET_BANK = $07
) X$ y% c1 T8 g - RESET_ADDR = $FC00/ ~( k4 L" J4 i7 p
- 8 A9 M# |6 b0 h# O' P
- ;==================================================
8 f- }3 D8 o* c8 P3 ~* F: U - ;图像块配置
9 I# i& ]. s; r4 Y; J/ ? - CHR_DATA_BANK = $089 G9 F w4 j7 m- [
% H5 B! v/ Y# a( X- ;==================================================) O9 X4 T, q2 a/ Q) N
- ;零页内存地址配置
' j" k+ L! s; i9 K" \ - Use_Ram_Addr = $80
$ I z& i6 F9 g; s8 g0 c# S - PPU_Ctrl_Buf = Use_Ram_Addr
P# P5 Z; [. t3 f& V9 Z - PPU_Msak_Buf = PPU_Ctrl_Buf + $01
6 T1 K/ W3 ?. C; k0 _' W# h9 z8 Q - PPU_Scroll_H = PPU_Msak_Buf + $01- \: y% V: v9 M- i1 ^; q1 U/ k
- PPU_Scroll_V = PPU_Scroll_H + $01
& K& N" {, b" Z% t$ { - FC_Data_L = PPU_Scroll_V + $01+ M/ b+ \ k5 w
- FC_Data_H = FC_Data_L + $019 T7 g( a. e }$ G: I
- FC_Data_Buf = FC_Data_H + $01, _* C0 a5 p! a; v9 N% w
- ;==================================================" i( y4 K/ K" P! ^
- , n" S$ O5 |2 p9 O4 N
- GAMEPAD_MERGE_FLAG = $044 g: R0 \0 r! k% C; ]
- 7 h1 u! ^+ E! i
- Gamepad_Keep = FC_Data_Buf + 1 n3 o( W+ u6 r3 ]4 @
- Gamepad_Once = Gamepad_Keep + 2 j6 B: d/ ^" P# A6 `
- Gamepad_Temp = Gamepad_Once + 2
' e7 Q& \3 T: Q3 G - . m- h9 E4 C8 s+ H- s% Z9 |0 \
- Gamepad_0_State = Gamepad_Temp + 2
1 M4 c( w/ v* ?! q3 k1 }1 Z( a9 \) A - Gamepad_1_State = Gamepad_0_State + 16 }- x5 d# `1 r: B; x1 \/ q
- Gamepad_0_Value = Gamepad_1_State + 1
6 @* l& u) J2 y- x8 _7 A) S9 @ - Gamepad_1_Value = Gamepad_0_Value + 1
7 l5 l; L: s) d' i2 j - Gamepad_Port_Value = Gamepad_1_Value + 1
$ J' m r9 M+ P8 x% C" G - Gamepad_Merge = Gamepad_Port_Value + 1
! y% G( r0 s: O - 3 D- u9 w" o% P, l
- ;==================================================
/ Z9 j. d! P5 O3 x - IRQ_Index = Gamepad_Merge + $014 b6 r' ^& U* k7 B" H* u% a3 g& u
- ;==================================================3 e* {. J) p" V! Z2 ]
! [3 z. a# B% q2 C- ;CHR图形数据9 g9 q) f5 P4 j
- ;==================================================7 j2 [7 @+ s& X% }6 ]7 H
- .BANK CHR_DATA_BANK, `1 u0 A& I* ]) ]6 D
- .INCBIN "chr_bank/chr_data.chr"
# h7 p) ~& q6 V; j1 o0 p. j -
1 C4 f3 ?1 K% Z: W* u - .BANK RESET_BANK & BANK_DATA_MASK: E! ?" q) }* F) N1 V( |: \
- .ORG RESET_ADDR
6 |2 z3 Y, {" g- \( ]4 v# T -
+ x$ S' k0 K: R - ;--------------------------------------------------! `( a* D9 u& a, A4 `& t
- Attributes_Data* }6 x& J* D, [8 ] b0 L1 r, h
- ;命名表属性! V% w" S D7 X/ A; |* C# G
- .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00' K+ p. L2 D" Q* j
- .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
; x, E4 L' T4 L" n, ^. P - .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA4 O6 m5 _( g* C4 g2 [6 ^! A, ?
- .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
6 w2 L/ J5 ~4 Y1 [/ A - ;--------------------------------------------------
6 _/ m7 P2 w. t2 o$ s - ;调色板数据6 Q" h( X1 {6 z7 s; W) b |0 g
- Palette_Data/ S' x: |$ \; K# v2 j5 c8 O8 l
- .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F0 {0 t8 I# Q; X, s( S
- .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
- u; b5 ]4 c/ Q. w, S
6 z) i3 l; X: {8 _- ;==================================================0 O5 t% T8 C0 |/ r/ M
- ;命名表初始化
! k( s9 \/ W6 D `- o - Init_Name_Table
6 b$ C, R- G$ G& R' D - LDA #$207 P/ v$ U8 K1 r# q2 y: ]
- STA PPU_ADDRESS O: D y( D0 f% I, w+ J
- LDA #$00
/ H/ v& }7 I1 F0 n R1 a - STA PPU_ADDRESS7 K' Z( l9 K1 y/ e/ z5 K" n
- LDA #$00: x8 Z3 D) C5 m# |- k
- LDY #$00. d ~' f% ?5 E" j( U
- LDX #$10
1 C& @+ ?; i" p7 N - Init_Name_Table_Write, l: j+ S' ~2 @+ y' K: w) `
- STA PPU_DATA
: l# c" x+ [, v. p - INY
! ^9 [' }9 U% A% b" F k - BNE Init_Name_Table_Write
4 U6 \8 z5 r* r" q5 ? - DEX
# y) k! d* Q* [/ w - BNE Init_Name_Table_Write8 K: k- G3 J, ?$ G" [% ?
- RTS z9 g8 P: q7 ^9 c. T0 Z' s$ y
-
: b7 Q: q' E6 z: v - ;==================================================
; Z7 I+ K- G( h! G0 x4 x - ;调色板初始化
- K3 A9 d1 G2 ^' j U) }) J! y - Init_Palette
; u+ A7 B& T" C' C - BIT PPU_STATUS$ ?/ }$ k( O8 a
- LDA #$3F
$ _) n5 \& k1 [% ~6 D8 W4 b' m2 p& c - STA PPU_ADDRESS
! Y% \" m# R5 N0 r - LDA #$00
+ _9 b% P' |7 o- o% a3 S' e - STA PPU_ADDRESS! C3 q; l, p/ A! T# t0 T% U0 C
- LDX #$00
7 [( Y3 L" k( W# P& I3 J - Init_Palette_Write7 T4 I, P6 Z3 H
- LDA Palette_Data,X
# U5 P; @0 y* S2 J - STA PPU_DATA
# B) |* R9 G$ M6 R: \* R4 B" z - INX% H/ o9 ?+ S# a- r; ^# p* [; z& t1 O! i
- CPX #$20: b" q) g& H2 }
- BCC Init_Palette_Write
7 a3 c N$ i4 ?/ O: k1 Q! R5 P. x - RTS& D5 F: U2 b1 d3 _2 X
- 8 e y" s0 }9 K& C
- ;==================================================
0 n9 W/ m4 ~0 c - ;设置命名表属性
c; g- ^1 V+ |+ b0 h& R - Init_NameTable_Attributes' Z' S( H& o' }( W
- BIT PPU_STATUS
; G9 [. C7 N0 l" l& }4 q - LDA #$23
5 g( {2 [* h3 N3 j8 M - STA PPU_ADDRESS
@ B6 _( l; J8 z- C- ^ - LDA #$C0
/ b8 `/ j7 q- H1 z4 S5 A - STA PPU_ADDRESS
3 O9 C* Z8 ]# C0 k' ~. |- w - LDX #$00
+ [# v3 I# b+ \+ @* ^$ K4 O - Init_NameTable_Attributes_Write
' J+ ^, D, k5 u3 [% W - LDA Attributes_Data,X
8 W5 V& g8 O z% g; r& N - STA PPU_DATA
K- Y- U# v2 t# S- E - INX
3 ?4 f0 ^2 V% u1 {& v, O - CPX #$40
8 _9 s l- X* ~1 S/ d4 B9 [2 K - BCC Init_NameTable_Attributes_Write
, u4 N! J( J% _4 k' X - RTS0 O& b$ E$ T7 {2 _, ?. z9 o
/ {8 ^' c# t9 V9 j- ;==================================================# S- {- [9 N( [' F1 w. J# ~! Q1 l
- ;初始化命名表文本$ R) k' Y& D8 ^" @8 i3 ?+ K; @
- Init_Name_Table_Text& h6 }3 m3 _! w; j# ]
- BIT PPU_STATUS5 Z4 i' H' N2 t, Y; \9 [$ G
- LDA #$20/ R- Y9 v% J: Z$ R
- STA PPU_ADDRESS5 a4 K1 M2 t( j8 F1 p7 H
- LDA #$000 \' }) D1 O3 Y# s" x7 e& w' |" D
- STA PPU_ADDRESS) m5 }, [ h* l+ U9 j) G" G
- LDA #$002 t m! k. y, u. Y Z
- STA FC_Data_Buf2 [7 ]( }4 `* l+ E
- LDY #301 ~7 d% v4 ^( D! W9 [# x. @- i
- Init_Name_Table_Text_Write
! O! H6 C, M, E - LDX #32
1 N4 J( w$ {; v5 r7 i$ p/ q- Z" L - Init_Name_Table_Text_Write_Char
" Z' o' A% X3 } - LDA #'0'0 F) w$ B0 d/ n. k) A/ d
- CLC
2 G: M' f. G6 n - ADC FC_Data_Buf b8 h& @+ k& h5 R8 e( R+ `6 s/ E$ Z
- STA PPU_DATA
- f, z- R! U$ H9 s - DEX/ ?( {" T% ?: d, V+ i( _# V3 ~7 ?
- LDA #$14- [; ~9 O1 j' f' }% L
- STA PPU_DATA
' l' I3 Q% l( e/ s& U/ k) e - DEX0 F! ^ t( u( v/ V8 I( F) h6 y1 Z
- BNE Init_Name_Table_Text_Write_Char
' X4 Y6 k6 M' N& [) v8 E) r( d - INC FC_Data_Buf6 K: f$ V5 o" Y1 I1 V# v3 C: f
- DEY8 \* ~% \$ V- D: D
- BNE Init_Name_Table_Text_Write
; X& x7 J' v. F2 Z8 M9 m- V - RTS+ X8 j1 D7 T' U# c- K L9 ^5 p
- 9 g8 Y' a5 {$ |3 ~: {1 `5 D
- ;==============================/ g8 C% ]& h, U; r! ^6 E% d
- Init_OAM_Ram;初始化精灵内存
' _4 g" d- \% Z8 s3 m# Z - LDX #$00
: c; G( S3 t* ^8 x) S) c: c - LDA #$00
% ~& M; ?$ H, b - STA PPU_OAM_ADDR
0 x3 j% ~' n) n" [5 D - LDA #$F8- A5 _ h$ j/ z. d. t
- Init_OAM_Ram_Write3 q3 J3 H4 P+ X# U- D
- STA PPU_OAM_DATA! y- P5 @9 J6 f! t6 X
- INX6 K5 N' I% T3 G* o/ `+ l
- BNE Init_OAM_Ram_Write
0 b _3 R8 f' D1 V/ `" C - RTS
! j- k- n. d% S' l2 X1 D -
$ [, G) r- t( p8 J: s - GamepadProcess;手柄处理
% d" }4 L4 c% O& q h7 q - JSR GamepadDatacan, O# d) j$ x% t0 {. M7 w% q
- LDA <Gamepad_0_Value
: q8 c" ^5 U; K4 i& B - STA <Gamepad_0_State: a W' ~- C. t
- LDA <Gamepad_1_Value
$ Z: |# q2 } J Z$ _! a g8 W - STA <Gamepad_1_State$ Z, [+ S+ Y+ \. v/ @% u
- JSR GamepadDatacan
/ T8 R( Z; {' I( T) }% _& Y5 {$ W - LDX #$01
! q. F. P5 N$ w$ t$ q! g5 b% K - GamepadMergeCheck;合并手柄输入检查; H, e+ P+ P, M1 ?- G( `& K9 a
- LDA <Gamepad_0_Value,X7 g5 x9 u& V; D" g! l% m3 k$ d( |0 d6 z
- CMP <Gamepad_0_State,X
8 C: U1 \7 Z# C4 n - BEQ GamepadMergeInput
6 |; w! {$ ~$ V5 S) O - LDA <Gamepad_Temp,X; |2 u1 `+ D4 I4 K
- STA <Gamepad_0_Value,X5 A+ }5 L) [4 }1 Y; L' j3 Y
- GamepadMergeInput;合并手柄输入1 O; r y2 u) N1 `8 s
- DEX
/ O) _4 J+ A" Q& A. } - BPL GamepadMergeCheck# L2 i# B- e0 {6 I( v
- LDA <Gamepad_Merge
; q5 \ P* i9 p - AND #GAMEPAD_MERGE_FLAG9 k3 B r3 y3 I5 @/ \9 t$ n' L
- BNE GamepadStateProcess Q$ Z+ W3 ~" z8 P, l
- LDA <Gamepad_0_Value% h) y+ I- L) ]" D
- ORA <Gamepad_1_Value, d) [0 R5 k( R
- STA <Gamepad_0_Value [" [! O- B$ Q& }% f" l/ B, `% T+ {
- GamepadStateProcess;手柄状态处理9 d0 O9 k7 Q# u8 G
- LDX #$01- W# w. x5 i4 y! E2 j7 @
- GamepadStateSave;手柄状态保存
/ p$ o ^0 C) J7 f - LDA <Gamepad_0_Value,X# ~+ w" W g" j2 y7 Q d& x. f6 B
- TAY) {- G" R" p) B$ r
- EOR <Gamepad_Temp,X
1 {% I! S7 r, f* a& b - AND <Gamepad_0_Value,X
W& G2 }" c4 m$ c - STA <Gamepad_Once,X, N$ l/ L% a. N) _# z1 s6 z
- STY <Gamepad_Keep,X
( u! f/ v3 \& A9 g - STY <Gamepad_Temp,X
2 X8 j, D: i. u1 N0 B6 t6 \9 j - DEX* R# |. R$ U; K/ D# [! k
- BPL GamepadStateSave; w" n n8 _; E, f* s: ~4 N
- RTS2 K8 J! L1 p3 K! @$ \) `. X
& k( Z |, M9 {- GamepadDatacan;手柄数据扫描2 |) O$ J# e( V7 p4 m* i
- LDX #$01
. q0 u: p+ K6 |7 S7 P! h - STX $4016
- r7 u6 b. O& ^2 ]( d1 t; g - DEX
3 ^4 Q' h2 t: @6 d1 x, w" t7 | - STX $4016 w# O. K; R7 z9 f H- Z4 ~( x" ?
- LDY #$084 A6 E+ j3 I! e3 f) c- v
- GamepadPortScan;手柄端口扫描, n' E7 `- m8 u
- LDA $4016
; q( T' X3 j. I3 ?9 y1 y2 m7 d- r - STA <Gamepad_Port_Value: l$ r4 V0 k3 N* s& f
- LSR A
) S2 t" ]6 ?+ l) f; e9 t - ORA <Gamepad_Port_Value
$ _5 d4 n0 Q# B# t1 ? - LSR A4 t, [' k* C! ]. }+ {' Q6 P8 z
- ROL <Gamepad_0_Value
3 ?2 I+ f( s4 i; p - LDA $4017! D) ~2 ?1 \" R; [% a
- STA <Gamepad_Port_Value/ x! S/ t' q& d7 ~
- LSR A
) r6 ~2 t: u3 N/ D7 @. _( s+ P: S - ORA <Gamepad_Port_Value
4 ?& I; C @0 ]- J, B - LSR A
0 U2 l3 I( q: m J4 e1 Z - ROL <Gamepad_1_Value
& s$ B+ Y7 D- ?# D1 z5 x - DEY
; K, q( Q* H, Y; r - BNE GamepadPortScan" Y; B c% }: E" }2 T# F
- RTS3 r; B- n1 G7 }6 Z" P. h F x
-
: Z* A& H+ L1 R" [, m- ?7 q2 |1 Z - ;==================================================8 @$ Z- M: |" s# H
- ;PPU处理
( p$ q# n9 j0 p" u - PPU_Process
6 E, S; T3 ]/ a: Z - LDA #$00; s& v. u: r) {* {0 V
- STA PPU_MASK
5 m$ j |% Y& x2 M -
]. i. S# r1 N. V7 q - BIT PPU_STATUS
" z; B6 r3 v6 q+ h0 D% p' T - LDA #$20
% U8 _5 c( L) o: ~6 u# _: a. E! I - STA PPU_ADDRESS
8 E2 ^- W2 |0 `, I* _3 s - LDA #$00. X/ c) Y$ [# @
- STA PPU_ADDRESS2 z( J# K+ N5 j/ Y: O
-
1 D% F/ H) v) l' z - STA PPU_SCROLL, ]/ n8 B: z! C+ ~! z
- STA PPU_SCROLL" W3 V% y+ A% N* \
- / S p- U% Z; i, J! y. e/ U5 S& o% M
- LDA PPU_Msak_Buf8 J; u% q5 s* a" h3 p% U% W/ T
- STA PPU_MASK7 Y7 a3 D/ e3 k0 V2 M
- V3 n/ G7 ^$ v" J, a- RTS
3 n% Q. e; _0 i {- b; I. M - 9 ?; W$ w# K' Q% u! b" `. m
- ;==============================2 }+ B; k) ]1 ?7 r. ~/ n) v
- Time_For_Vblank;延时等待
: ]3 `' r, Y0 w& a5 C8 X - LDA PPU_STATUS
, x3 j% ~" P7 F - BPL Time_For_Vblank/ H8 p# D* j3 w. q4 l/ Q4 F
- RTS6 l! J& B2 [0 u* o D' R# C$ M* W7 ~+ J
- : w8 `# {5 t4 i
- ;==============================8 H Y" N; q5 w. f
- ;初始化MAPPER19
5 O7 F% L" ^, g: \* ~3 n: F& U - Init_Mapper19
- {) K% k D7 k* G q, D) u - LDA #$009 T( B6 @+ m; i3 u. E4 J. \
- STA M19_CHR_0000
, N: w4 z; C. ?) ^5 V# S& t$ z - LDA #$01
- |; p+ T( W) \$ J# U - STA M19_CHR_0400/ X2 I& w1 G& [0 H# n) H
- LDA #$02
( J3 _$ ]( S2 E% D, p9 n7 z8 J - STA M19_CHR_0800
+ ?8 }* V1 g. a% E( \2 b - LDA #$03
# y+ R. K3 {, O2 q y% B1 I8 b6 O - STA M19_CHR_0C00
* D) k3 s6 |6 Z! \ - LDA #$048 S9 U* M: Q2 L/ L4 o
- STA M19_CHR_1000
# k f+ O# q! r9 m - LDA #$05
5 Y3 `4 ]. u9 H0 E0 [# ]2 A - STA M19_CHR_1400
* K8 [- n# ^4 ~; m7 K4 j - LDA #$06+ [" G) z: T1 b$ A1 h0 d5 _7 q
- STA M19_CHR_1800
3 G7 |& T+ W G, T - LDA #$07
! G6 ~- B' d. ^6 }: u7 @ - STA M19_CHR_1C00' \' P" p; e& `6 R4 }
-
; y; V5 m4 d; v5 ~' y0 z - ;禁用IRQ6 U2 q4 R' m6 G. ?
- LDA M19_IRQ_COUNT_H" s$ `! G6 X! `8 L
- AND #$7F
9 f# n: D: B5 H* d7 z5 O+ C - STA M19_IRQ_COUNT_H
& Q* F+ m0 u5 i |5 \ - 4 C* S. Y8 b/ t# h3 O$ h9 A( W
- ;命名表
% X6 p5 \2 { \% A' O4 \9 d - LDA #$E0# N% B1 R3 [9 R4 J+ l" ?, \) a% f
- STA M19_NT_20001 D K; Q0 B3 P: i
- STA M19_NT_2400$ v! S. [3 z, x, g
-
& K# F; h$ ^6 O$ o& f) ^+ o5 A/ | - ;命名表
& [* u$ [8 b/ b. [5 o4 |' Y - LDA #$E1$ A! V3 B! A. M
- STA M19_NT_2800
+ W ^6 o% Z& X5 Y" W - STA M19_NT_2C00
$ G! [3 V1 b; k' T+ q+ N5 [1 X - 8 w' ]& B: Q, [+ Y- k
- RTS! }7 l: T6 y. I9 `% ~
- ' R( v0 j: C% u* N6 [$ v' }2 [- _
- ;==================================================& b( p! p2 X' O. a
- ;重置中断处理
. I; z8 g7 _) U - ResetProgram ?! ~5 ~" F W" x
- SEI7 U8 P r) U; H# X7 D. a
- CLD
9 m3 [# i8 K2 @3 G' K Q - LDA #$00
0 l: |& @# ~3 |6 d; G5 p! Z - STA PPU_CTRL! z. H: _$ u3 g X* v3 g
- STA PPU_MASK Z, t) s; j- u/ |
- STA PPU_STATUS: i. ~: ^7 l( l1 |
- STA JOY2_FRAME: C$ T9 B* P$ q7 X0 a
- STA APU_STATUS
' k, ^& C) I/ f. n - $ ^, F3 s* V% l# f0 L# s6 D C* o
- LDA #$C0
& F7 C- ~$ [4 _" F1 d - STA JOY2_FRAME) c2 y+ d4 V: f$ K5 h3 F4 R d1 g
- 3 W/ B. [ s, m( A% L5 O& L
- ;等待vblank
a. s! Y: o. b3 N) z; W+ r+ P - LDX #$020 W' \' g# D0 f4 M
- Vblank_Wait_1: j/ U. N5 f6 x. V5 w0 |
- BIT PPU_STATUS
$ J" X. t% N0 j, X% P- a+ M9 |5 Q: g( s - BPL Vblank_Wait_1
- A1 g8 N. @, ^, P - Vblank_Wait_2
* V! W' {$ B- q# r% G. ~& a - BIT PPU_STATUS0 j2 K; |/ N5 L- L- I$ L
- BMI Vblank_Wait_2
+ F4 c F1 D3 X8 N% F - DEX
1 }% b3 s" u6 x" ~) o4 U& A - BNE Vblank_Wait_1& a' d% X4 J: W. {% \
- ) e1 E, Q1 q2 h3 n7 f1 J
- LDX #$FF
: K, ^( P! C% p# @3 ] - TXS
- J$ g) a5 B4 D7 O - ! `( K2 g0 r) o8 C
- ;初始化MAPPER19/ h% d) c; `$ \ h% n/ M& g" ^
- JSR Init_Mapper19) J5 l: u$ I0 V0 N; h$ t7 r: S
- : K7 o% j8 w& B
- ;==============================
* [+ T3 i! U7 k b1 p/ X - ;RAM初始化
+ k, Z& }; v& U$ A - Nes_Ram_Init1 y( L$ _: X7 K3 J# s. ^/ N" k5 _
- LDY #$00
! P Z; U% n: k - LDX #$08' I- N. O( M7 a( N
- LDA #$00
- ]* E d" C+ G" q$ L4 r q - STA <$00 z8 l* X7 S' c) C/ l+ p) _: Z
- STA <$01
) u- o+ ^% b1 M& H; p9 p - Nes_Ram_Init_Write
5 n" ^6 \# s% x$ q - STA [$00],Y+ Y5 ?" S" t# a$ _6 ^
- INY) m/ z6 X$ O7 l( U
- BNE Nes_Ram_Init_Write9 F# x8 n7 V1 L. m, L
- INC <$010 Z( F8 ~2 \; Z" Y
- DEX: \. Q1 }1 G0 `# `
- BNE Nes_Ram_Init_Write
$ f' v9 T# |( g c! N; C - 8 r, a/ H) w. S3 y
- ;初始化命名表2 ?: s& p5 e7 @6 V1 u; `7 j
- JSR Init_Name_Table6 u2 C, p5 Y1 Y# V$ L7 _
- / V0 i5 T& z) y3 t; c
- ;初始化调色板
! T0 w. \. t2 X3 K - JSR Init_Palette
5 x; N) l. K, m - 0 N/ D3 P2 x! `) k7 B7 Z. F
- ;初始化命名表属性5 \& `3 ^3 }* k, y( a( q
- JSR Init_NameTable_Attributes/ E# O% _; \7 m) ^9 h
-
' D6 ~' T+ P2 E - ;初始化精灵内存2 ` X) G+ G, J2 H8 l
- JSR Init_OAM_Ram7 v% o y2 ?# e' J
-
" y# f0 U( i1 b8 Y; z0 _" g+ S2 w - ;在屏幕上写点东西' i# b" W$ B+ j& F9 a8 H2 d
- JSR Init_Name_Table_Text0 t$ }; w5 w- R% M/ m8 j; T' b- w
- - ]* g5 A i2 U. s+ F) n" a: b
- JSR Time_For_Vblank
( i% `2 ^# v. H; g, N8 }& ^. y2 v* I - ;开启PPU控制
& l$ z' V* j/ ? - LDA #$A8
: p y( _. C4 m3 F$ S - STA PPU_Ctrl_Buf8 X A l. N) ?& X+ b8 t. J
- STA PPU_CTRL
+ n: W" f. ^7 w2 {" q) N - ( n1 c' f: `6 [# L% m" C" i( Z
- ;开启PPU显示
8 n6 A# e B U6 S - LDA #$1E: _9 y/ r, o p" f6 l" s8 f
- STA PPU_Msak_Buf
5 O' p/ U+ h+ k3 G% W -
4 C: ^! z3 s' C% I' @ - CLI v! R' G. V- {, j3 o5 B# c: x
- JMP Loop; D+ O, K4 |: D/ h
-
7 i5 q" x: }4 |* m' n: [$ Z& ^ - ;==============================7 G8 i( Y0 b4 [ y
- ;死循环, 等待NMI中断
' T& [% o" s! Q; F* e4 m/ r& Q, |( h - Loop
7 p3 _8 r' N0 Z* ]$ g - JMP Loop
! Q; j$ B# b3 v: r1 y7 F - ( B* f q; j @" W
- ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967
" }7 h- T( S& b! c - * W; o8 ?5 E+ {
- ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)% A/ n9 T6 A" q- | r9 y5 x
- BEGIN_LINE_CYCLES_START = 32768 - (4103)" @4 l8 }: ]# q
- ;==================================================" X5 o2 b4 R7 r- \: G# Y e
- ;NMI中断处理$ f6 E' j9 \% o+ l4 i2 T9 k
- NmiProgram2 @. i$ A+ e7 _
- PHA& H ~, h( S G" r0 S/ q
- TXA+ Q3 |/ p9 ]/ G/ \
- PHA
, F) A; S( a7 y3 E- Q% W - TYA1 H. u- O2 }: ^4 W$ z) {2 j( l
- PHA
& h+ P: `% Y: M( g! |% V - 3 V+ p% U6 @& s# f% s
- BIT PPU_STATUS
4 k# e, | T4 p8 _ -
' P' q9 P# q7 U# J - LDA #$00- Z" @3 B8 a6 n4 C) S# m/ E7 C
- STA IRQ_Index
' C# d( g$ m7 w0 d - ' V" l5 n% _) g3 r+ F# c
- ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动! Y% @. `1 @# k s( B+ v1 D3 O
- LDA #LOW(BEGIN_LINE_CYCLES_START)
0 i1 q W' Z" W! f3 E% X. v# b - STA M19_IRQ_COUNT_L z: l) P+ X ^ Y* X
- LDA #HIGH(BEGIN_LINE_CYCLES_START)) i6 h1 r6 P: T+ P
- ORA #$80
7 _* {7 Y7 |1 V6 l- q - STA M19_IRQ_COUNT_H
% V5 z) ^: H+ V! R5 g - CLI
8 [+ {; z( v& Y8 V0 p4 b - : K1 V- T( F ?6 u: k
- ;关闭PPU控制
9 x5 V' x" n0 d/ _) L1 c* U$ S - LDA #$00, _7 d( b% A9 c* U& m7 c2 R; ]
- STA PPU_CTRL0 o6 b/ D i/ K- f2 A q
-
% g+ o) o- i1 a: w - ;处理PPU
) a) k% U, j% K: P4 O1 ]3 j - JSR PPU_Process$ }1 J0 T- u N1 d. M+ q+ n3 I
-
- S" J/ E4 ]: V" \, z; ] - ;开启PPU控制) E- z' ^) Y1 m: y
- LDA PPU_Ctrl_Buf |: a0 V" S% ]& O$ D" |
- STA PPU_CTRL9 \2 ^: `% Z! C, y* S3 V4 [
- / n- n2 b% e3 H+ q3 }' W' D |
- ;手柄处理! `! M0 W5 `# B2 K, g
- JSR GamepadProcess8 R6 [) ?$ u: `; k# R
- % ]! d; u3 R6 a ]( H& h
- LDA #$005 S; |- Z/ `* R, g& z) ?
- STA IRQ_Index
( B5 d1 J6 o! w& E, d - 3 `* c. N9 W, Y4 c8 {5 B& [
- PLA
7 {4 h! O6 W: J9 C9 K - TAY
) x# S5 v. I, T3 F z - PLA; f4 \' ?1 R( h0 |& ]5 U, C( l
- TAX ?( V. K/ H3 U' K8 [
- PLA
- Q0 X) _/ F5 j$ |) R - RTI
' D: Z y- c3 n4 j I2 H- y9 I- X - ( {: o4 J8 X1 O1 A
- ;每行扫描线113.67# d, s6 P: b( }0 [: g. h
- ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)' \/ L0 R5 R8 r0 [) {8 z" u$ O- K4 f
- BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
, o# _% k& E; B+ u8 i" \! [' g* `/ X( ? - ;==================================================4 m; \) l' W5 d# `" o! c2 |
- ;IRQ中断处理* n: J6 p/ O6 z* e. e
- IrqProgram8 W+ A% ? B* J/ H# O- ]% ~
- PHA) F& X' s& k! V1 f& a
- TXA% m* C# g3 ~" }' k, }: ~. x! }
- PHA1 ^ [ T2 X& K( g$ K
- TYA
; M0 D5 W+ b, [ - PHA" P" i6 J( }9 d* K- J/ r- \
-
% p& \; z# o# l& @. l; e$ v - ;16条扫描线后触发IRQ
T$ c$ O6 U1 G" Q, j - LDA #LOW(BEGIN_LINE_CYCLES)
1 d: o/ W- D u' E- w7 `$ x9 m% m - STA M19_IRQ_COUNT_L
4 Q& h& E5 f. k, N - LDA #HIGH(BEGIN_LINE_CYCLES)
! ~4 C# n( z F - ORA #$801 c) x9 g1 j/ f: W) w1 q& h, \& l
- STA M19_IRQ_COUNT_H. Q3 k" K) p/ v& N: S6 f2 i8 f
- * r S5 S2 b: [9 q! X6 X9 |2 C. ~( Z
- LDA <IRQ_Index
4 a/ A7 R l* L( @' }4 g M - BNE * + 46 t2 d2 @+ u& s3 D+ L
- INC <PPU_Scroll_H- P# v8 d0 W: u
- + f" R6 x9 l" \5 H. D
- ;设置屏幕滚动8 U4 i' S5 R1 H1 m
- LDA <IRQ_Index0 |- P3 W Z5 R0 C' t$ W
- AND #$01& O8 G: h% L" g6 x/ P0 l$ `
- BEQ Irq_Scroll_Right- \6 D9 _* g. K5 S
- " ]6 b0 }( s; g) d4 W
- Irq_Scroll_Left
" g- [ y% B, s4 o8 @+ N5 U - BIT PPU_STATUS/ ~1 a, ]' l, d8 C" j8 m
- LDA <PPU_Scroll_H
8 ]( H$ `, ]5 C4 Y, u - STA PPU_SCROLL
6 d! h( v1 T0 d - STA PPU_SCROLL+ D; I% i) S: e# M8 L' n
- JMP Irq_Scroll_Over' @9 F( x) h# \4 O
-
4 ~/ d$ ^0 M3 @, l# } - Irq_Scroll_Right) f* m3 Y( V& t; ], X6 X
- SEC
: T: M$ M1 `: ^ - SBC <PPU_Scroll_H- V; r5 v* w S0 k
- STA PPU_SCROLL; Q1 A, g( b6 Q" E& w
- STA PPU_SCROLL
. E" N* p2 p# K, L4 L+ ^ - Irq_Scroll_Over% L% H- p9 |* G, Y. e
- ; }2 }5 x& B2 \3 M% R7 H3 R+ z
- INC <IRQ_Index: u3 N& n& Q+ M' }% b4 D/ i
- 3 e! U8 k3 b7 p- `4 e0 o' h
- LDA <IRQ_Index
' \$ H! g4 N, i - CMP #14; E* L+ G% j/ T: I; w+ D
- BCC * + 10
6 D \/ R9 b8 ?9 F - LDA #$00
" ?! r1 h% V0 A! s, U8 ` - STA M19_IRQ_COUNT_L
9 w8 g3 U- C/ I% g/ ?6 k6 G( o - STA M19_IRQ_COUNT_H2 h: L8 S2 ]$ h7 u& Z9 s3 {. ]8 Z
-
2 z6 `8 ^& P. \ - IrqProgramEnd9 t0 O( @& p" @6 }, U* x, k
- PLA8 @2 N7 c# g: \7 d7 p* F
- TAY
. b; ]1 W+ X& T' V1 Z( `6 t+ a/ ` - PLA
; }( x+ o- w0 k( d2 |2 @ - TAX
: Y* g. f" B! |6 T8 Y5 @ - PLA+ r/ R& o: K7 j; J7 b2 b& h
- RTI! Y3 a. l# p5 K9 T' |' y) R" }2 P
-
/ `$ r+ k; [+ a2 D) R- I - ;==================================================/ ~+ j2 I7 k4 S
- ;中断表
. O5 x6 M8 D6 f$ p7 q8 Y - .ORG $FFFA+ O+ V3 B0 ~/ m1 _4 {# K
- .WORD NmiProgram
1 N) ?7 R' d. \( h# J0 S) p) v* [ - .WORD ResetProgram9 j$ T T7 L) B
- .WORD IrqProgram
复制代码 1 B& s2 R1 O+ y6 v$ H2 q" \
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|