|
|
- ;[FC][Mapper19 IRQ]6 h6 o/ r$ D' r: e) Q1 G
- ;FlameCyclone 20230710
8 E& R" P/ k5 {" T) X3 L7 T7 {5 H: P - 8 ^: Q% g, D, @
- ;文件头
; I$ A5 `" T$ k, G - ;======================================================================
n: W- U( J6 p; [ - .INESPRG 4 ;16KB PRG 数量7 q" I. N# M. T
- .INESCHR 1 ;8KB CHR 数量- u" ^9 T+ _, S' e5 ?/ u
- .INESMAP 19 ;mapper 190 u$ D# Q! w; E. n
- .INESMIR 1 ;命名表镜像 0水平 1垂直* o! w! ?9 T* @' |3 i
: g9 b* O4 H+ G" {2 d- ;必要条件
6 m9 {8 ?% W! u* X/ k - ;1.持有CHR ROM
9 ~( \* `8 T8 V - ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
' c j( V7 Y9 M% h - ;3.精灵内存(OAM)不为空
$ a8 U+ U. k3 Z8 g; ]6 |) K; Q' a
) `* u2 o- {# f" A- ;==================================================
3 J; Q# B* D" q' M( I- @! ]1 M7 D - ;NES端口常量
; R& p! u7 p! D" D1 z - PPU_CTRL = $2000 ;PPU控制寄存器3 F! B4 [1 i J! G+ p2 P: Z- X
- PPU_MASK = $2001 ;PPU掩码寄存器
& v8 @9 i6 u- V; R - PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位/ e6 K4 O! d7 n/ D! `, a2 d
- PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1& i, @* F6 g- ^! ^+ V% r6 T
- PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
V# {0 r* x8 ]+ ?8 g - PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 / h& S- o2 ^* q6 N* u1 u
- PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加6 H9 S% ^- o$ Q, K- n$ Q
- PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 D c! O( O1 [* m: O2 k) i6 ~2 \: k
- OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存8 y! k* e: K; j9 w4 W/ C7 a
- APU_STATUS = $4015 ;声音通道切换
* m% T6 O0 A$ C1 Y0 g - JOY1_FRAME = $4016 ;手柄1 + 选通5 l& @$ j3 p7 B; t2 T$ `; X) q. l
- JOY2_FRAME = $4017 ;手柄2 + 选通
# t. ]+ E0 _3 n
$ ?0 I/ i3 y( i% O. w/ g- ;==================================================
~9 @' G" d1 E! }) i: T" _& i - ;MAPPER 19端口常量
% k& }, ^+ b) M# T - M19_CHR_0000 = $8000
W- k, s, ~0 h, D3 _* g; ~/ E: U - M19_CHR_0400 = $8800
A3 W' b/ _# c% _( t - M19_CHR_0800 = $9000
1 f" X. _* ]" g% r# {7 a: s: b - M19_CHR_0C00 = $9800& L) s0 z1 V, ?
- M19_CHR_1000 = $A0009 w2 q1 }! l, a5 R
- M19_CHR_1400 = $A800
! ~& a* O5 r/ V3 C# [ - M19_CHR_1800 = $B000
. g1 X) ]+ {0 Z* D$ v+ o6 E - M19_CHR_1C00 = $B800
q4 c9 o3 s2 N$ k4 {/ i" s2 c n& H - M19_NT_2000 = $C000
% `, S9 d0 |# P- v4 J - M19_NT_2400 = $C800
; C; K5 T! d, l) R1 j - M19_NT_2800 = $D0000 E: H7 g- K& a2 Z2 E& l$ T
- M19_NT_2C00 = $D8005 \- x5 t5 y- ]% W! i" C* {0 @
- M19_PRG_8000 = $E000
O" u B1 n8 N' n3 R+ i0 { - M19_PRG_A000 = $E800- l9 Z7 e% x; ], ]" n
- M19_PRG_C000 = $F0006 V! w& d8 C7 h0 f7 _0 X
- M19_IRQ_COUNT_L = $5000
! M' j$ ]0 Z9 M6 n' M( d1 g4 G - M19_IRQ_COUNT_H = $58003 H0 F3 W/ r# q' Y! G6 |! t4 S
, V# w# ~% a) d: v9 L% [- ;==================================================6 N5 M+ f3 y! ]
- ;程序块配置+ w: n2 d ?% I. p) i) C
- BANK_DATA_MASK = $07, ^9 Y& F6 Y/ D5 N! H
- ;--------------------------------------------------3 a" N! V' V+ l8 y6 t
- RESET_BANK = $07; \" B' t7 _9 J3 e0 M9 e% Z
- RESET_ADDR = $FC00% P0 n, j* w- ^
1 e3 X- n3 U/ o- K( Q2 \ T( Q+ ~- ;==================================================0 s* F& u" i/ s
- ;图像块配置7 `4 X. F5 _# ]- Y4 M9 x& V1 q
- CHR_DATA_BANK = $08
4 a. ]2 Q B6 C( M( Z
/ i5 m |( r! k7 A1 ~( F/ L9 j- ;==================================================6 W5 b0 F* I7 Q/ h& m: z
- ;零页内存地址配置
8 ?$ p# j/ Q' E% H. q* T7 J$ a - Use_Ram_Addr = $802 f' H5 w( M# p1 E$ N# D& f/ s
- PPU_Ctrl_Buf = Use_Ram_Addr/ E: m1 e8 S0 @" V" ~* ~0 ~( a
- PPU_Msak_Buf = PPU_Ctrl_Buf + $015 b' z( [& Y8 q3 x; m# }& I3 u
- PPU_Scroll_H = PPU_Msak_Buf + $01/ p) R# b2 T2 k8 A: `7 G! G9 s e
- PPU_Scroll_V = PPU_Scroll_H + $01
; j+ u" c) O b' X3 K1 K! s - FC_Data_L = PPU_Scroll_V + $01( r0 Q. H. t1 ^" Q+ v
- FC_Data_H = FC_Data_L + $01
[! t5 i! `; U4 D- J - FC_Data_Buf = FC_Data_H + $01
1 | m" n, d% m5 Y( r - ;==================================================
1 ~; ?; M& @" j$ b$ q! U$ J - 7 Y/ q: T0 y) i; i. x" `8 U) g& s
- GAMEPAD_MERGE_FLAG = $04
8 {% t+ o% l2 d3 x/ n9 t& E% v
! ?! x: B" C/ i( s0 A- Gamepad_Keep = FC_Data_Buf + 12 [& q, x, H" o7 O+ R$ x- O
- Gamepad_Once = Gamepad_Keep + 2
C' A, g/ \5 w! T5 x! Z - Gamepad_Temp = Gamepad_Once + 2
: O- k" W# @& o8 ~6 K8 i9 H -
2 v5 A2 p5 b2 I: S/ C4 T( X# Q - Gamepad_0_State = Gamepad_Temp + 26 Y0 D2 Z+ s: k5 S
- Gamepad_1_State = Gamepad_0_State + 18 \& n. o+ r0 t" L
- Gamepad_0_Value = Gamepad_1_State + 13 ], d5 w. t8 z2 \: a7 R
- Gamepad_1_Value = Gamepad_0_Value + 1
7 e3 X. F* }6 c# C% G# l7 }5 u k - Gamepad_Port_Value = Gamepad_1_Value + 1+ u% b' V# s) \
- Gamepad_Merge = Gamepad_Port_Value + 1: G. L% \, l- J u' |
- 9 x# r! ?' ?# F6 E0 P% s
- ;==================================================
1 n6 [0 L* V. O1 s: g6 {2 L - IRQ_Index = Gamepad_Merge + $01" ]5 w: D, S4 k- ^
- ;==================================================+ T# i. V7 U N5 q# `) n
- ! Y9 P9 E9 L2 Z( l L
- ;CHR图形数据
0 W9 x( |9 A- N2 h- T - ;==================================================
5 i+ a- {( D+ t# X! v: V - .BANK CHR_DATA_BANK$ J$ V& w' u( v3 U, G
- .INCBIN "chr_bank/chr_data.chr") }2 X; W0 k! `, x" M! G/ k
- l% G8 i* x0 G9 c0 e# l8 U, c
- .BANK RESET_BANK & BANK_DATA_MASK
6 `) P4 f! M6 O# u4 v( }6 @ - .ORG RESET_ADDR
/ Z; \3 z. O+ e" M o) \. N; t% U - 2 c$ u5 F! a# u. O
- ;--------------------------------------------------: P( z" o& {6 Z) y+ s; L
- Attributes_Data
2 F0 e. l+ C* k# `/ w& j; p& E/ G6 P - ;命名表属性+ f5 S4 t6 n4 h0 ^( g- ~
- .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00# G ~6 o7 n1 Q5 r8 K% X
- .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
- K& g, U: W+ o+ o* ? - .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
' s7 D5 {1 g4 t - .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55# Y& i5 |8 P" ^3 N
- ;--------------------------------------------------: F$ r3 X' g1 I5 f2 p: |! Z+ `& J
- ;调色板数据
! _$ }' D3 |% |& p- `1 _& O n - Palette_Data" C8 @) M$ j0 X4 H- H
- .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
% j/ p7 j" ]1 G4 R - .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F7 A( L3 ^8 F0 _4 _7 T- A
- 0 L$ ~3 ]3 j0 b# T
- ;==================================================
8 B0 ^+ R3 j) V) [, { - ;命名表初始化
7 z0 k, R% \. e# q' b - Init_Name_Table( c. _+ T' Q a: B" `/ [0 z: S
- LDA #$20
7 a& J3 f" c$ D4 |' b: T: m# I - STA PPU_ADDRESS
1 h& X& a4 j: ]+ }4 Z! @ - LDA #$00
8 c! P0 P0 H3 y - STA PPU_ADDRESS% B+ O8 D# T& H' X6 x! ?
- LDA #$002 _- N/ X5 p& p% b: E$ ], g
- LDY #$00
) |2 [/ T7 E. y) x6 p. r - LDX #$10
- F0 e' W+ U6 x8 U) ~ - Init_Name_Table_Write" M0 \ Q: Z7 Q) I4 _
- STA PPU_DATA
{1 e. K. }- k* p0 S" F3 O - INY. L7 w o: j/ z" V
- BNE Init_Name_Table_Write' u Z1 g4 r( D; ^- `8 |" @
- DEX4 C* M( a! c J1 Q y$ ^# t( k
- BNE Init_Name_Table_Write9 \9 b3 b3 f3 P+ }( M6 |9 ]7 C
- RTS3 `: h8 T4 u- q4 Z2 N, K
- " a( |. T+ Y% z/ N0 R
- ;==================================================
0 y$ V0 x/ i. D, ^5 O; p - ;调色板初始化
* t, X4 U2 L- _! ^: M - Init_Palette& S$ m$ t" U# L3 t$ t3 n
- BIT PPU_STATUS
8 c6 O7 l! k& {, f& z - LDA #$3F7 ?" h( J9 T1 S- v c; I
- STA PPU_ADDRESS
4 q* `9 ^ t& [0 B2 h5 ~ - LDA #$00, c5 x) j+ B: L: W& U2 ~! ~
- STA PPU_ADDRESS
6 R! p0 g0 [+ }# D. e3 Y( T- K" v4 t - LDX #$00. J# Y- @0 j! ~( c4 o% ?/ I Z3 Z- F$ |
- Init_Palette_Write
( U0 Y3 I' X# W) W5 V, t V' L - LDA Palette_Data,X
0 ]0 L* u, ?, Z - STA PPU_DATA+ }: r% V* W5 v$ p
- INX V& w3 H7 ?. e7 C( S0 S' n+ o; ^
- CPX #$20 [2 x6 u7 @9 u* a3 _+ E
- BCC Init_Palette_Write
% O3 _$ E" V0 m% U* `: c - RTS3 a: y8 u6 L F0 F7 R6 n+ G
- $ U5 L$ v0 Q1 N9 U: i1 X/ h) `
- ;==================================================4 O" x( K$ ^" _5 z, p
- ;设置命名表属性4 Z' }: ^" [' @" ]# g" N% @
- Init_NameTable_Attributes; ?1 w% F0 B, {3 @3 ?: J
- BIT PPU_STATUS
' k6 ]# P/ G! K+ U7 @, o - LDA #$23
& b8 I- ~1 q, I: y - STA PPU_ADDRESS
' `- T( @$ g3 P& Q - LDA #$C0
( L8 W0 |! x/ d& Y: N3 m! Q - STA PPU_ADDRESS
% [9 _7 N& d o0 h2 s: \ - LDX #$00
; _. [$ F5 a8 F5 o+ c. L5 z - Init_NameTable_Attributes_Write
. _/ r% i4 z% j$ U; d, y - LDA Attributes_Data,X
' |3 U: z) A4 a - STA PPU_DATA
" D/ A# I7 T/ W [ - INX
3 R0 t1 G; P/ p; V$ r - CPX #$40* E( O& V, P; ~+ s C) Q3 g
- BCC Init_NameTable_Attributes_Write
7 K# S1 O5 _& g+ f) x# A& M - RTS
+ T; {0 U5 _! o$ S
& h5 V S: J! X% _5 l! b5 m: ]. N- ;==================================================
; G" o3 _, i! D - ;初始化命名表文本% g: Y% \% T7 S
- Init_Name_Table_Text
+ i6 I7 Z, Y& } - BIT PPU_STATUS0 ]7 d; E5 M0 V: U4 q6 |) r
- LDA #$201 p& \0 P/ W* V" a+ s
- STA PPU_ADDRESS' N" ?( F: N% c
- LDA #$00: m" x, a6 {8 z& m+ D
- STA PPU_ADDRESS
1 [# J* A. I0 u+ m1 @9 b6 I; Q - LDA #$006 }: q4 q$ w1 y6 s7 i" C% o
- STA FC_Data_Buf8 c3 u/ _3 y9 Y* o
- LDY #30
* h/ e% v9 r3 ^( K - Init_Name_Table_Text_Write
8 O5 G& L; P. o9 H9 m* M. T+ l( v - LDX #32: X% i8 s* t7 d# z# o9 d
- Init_Name_Table_Text_Write_Char
, O- t& K5 m9 |( I - LDA #'0'
( g5 n _ Y5 Z" W$ U% e - CLC
! C7 I$ d U6 l; l% [, } - ADC FC_Data_Buf4 U" y! S, o# H4 L4 N- o# ]
- STA PPU_DATA
: S; {6 P/ x0 Q3 V. _2 S1 [ - DEX
. n: ]- K, o8 h8 W2 u4 y* k - LDA #$14
' I" M4 L% ?1 B! \( t) V% C - STA PPU_DATA
7 p( j# f; b) e. N7 |- B - DEX
( F3 n, ?8 U9 O( r. |3 L - BNE Init_Name_Table_Text_Write_Char) j, J6 }- Q- F/ |
- INC FC_Data_Buf
6 n7 v& }3 C/ u0 @! n) a( h, t - DEY
: T) u) i. ]) n9 J! y' G. w" ? - BNE Init_Name_Table_Text_Write
' O/ w$ i1 u7 `1 ] - RTS
( J8 O1 D# K0 @ - 4 ]' j" L+ ]. I6 ^+ x
- ;==============================
$ {3 G- h, S/ f, P - Init_OAM_Ram;初始化精灵内存
' U/ X& G( D1 G* n$ ?8 r - LDX #$000 I) ^7 Z2 o* i( z3 M, u' H# m
- LDA #$004 L0 l( t' H- v# {
- STA PPU_OAM_ADDR
; o' E3 B, F# y. l1 ^- |/ x - LDA #$F8
) p1 V2 {5 L6 M6 P$ l - Init_OAM_Ram_Write4 e, ~+ q& [: @5 ]4 D1 L
- STA PPU_OAM_DATA$ N$ u' L3 t+ |; r; N
- INX$ f/ l% l4 P/ f2 M* X3 E9 O" ~
- BNE Init_OAM_Ram_Write
; }, L# p5 t" C; Q# w. x - RTS/ ]/ {4 j$ b% [2 p
- ; O2 P/ ^: H! y5 e
- GamepadProcess;手柄处理: O6 a3 p. ^( A$ A( T/ J
- JSR GamepadDatacan
+ |* ? D$ m `/ \0 a ` - LDA <Gamepad_0_Value
5 r! Y+ w1 P( B* F2 m - STA <Gamepad_0_State5 U" q% A0 l" q3 j: v) G
- LDA <Gamepad_1_Value
; c! [( A0 z8 q+ n) S! K0 E - STA <Gamepad_1_State+ L4 }) Y# G& S' e
- JSR GamepadDatacan
. \3 U0 F/ U5 p - LDX #$01
2 B! ` h1 q& m8 M1 U - GamepadMergeCheck;合并手柄输入检查- Y! a! X9 U6 X6 b6 ~
- LDA <Gamepad_0_Value,X- S5 P4 \7 m' C/ H6 S" d
- CMP <Gamepad_0_State,X
, L1 c) d( p S( J& s) B - BEQ GamepadMergeInput
" ^- s4 `5 V2 L9 ^- |/ F( P- ? - LDA <Gamepad_Temp,X, g2 @. i- A' u, d- P1 b2 d; Z
- STA <Gamepad_0_Value,X# {+ I% e* M* C! h' t. n
- GamepadMergeInput;合并手柄输入
6 n; z6 Z9 l/ O# q z) A - DEX
8 w6 M; D' C! L- Q/ \1 a - BPL GamepadMergeCheck( f, H B* Q' B U
- LDA <Gamepad_Merge0 ~0 f: R) X) V; Q4 m: I! Y4 n( J
- AND #GAMEPAD_MERGE_FLAG
+ ]/ ~" F# t; p. b8 J - BNE GamepadStateProcess+ t: W% h8 a2 [, K
- LDA <Gamepad_0_Value1 H3 B1 Y$ K/ U9 l+ b2 m% }9 s7 M
- ORA <Gamepad_1_Value6 P3 ^$ K$ }9 y7 }1 f; K& u
- STA <Gamepad_0_Value
u" _; w9 u& M2 D# ~, @ - GamepadStateProcess;手柄状态处理" I7 `- Z& h( n- Z
- LDX #$012 O3 B s: p, Q4 _' r
- GamepadStateSave;手柄状态保存
; t9 t8 p% v8 ]2 _ - LDA <Gamepad_0_Value,X) d( l, t4 j1 B) {$ v$ l" }
- TAY
" Z9 K- y4 `. r1 Z8 D - EOR <Gamepad_Temp,X3 N8 g+ v% a( U( V5 J
- AND <Gamepad_0_Value,X
+ _' h0 t. H6 B# ^: P) T - STA <Gamepad_Once,X
9 x( P |1 E2 ^4 y0 P! R - STY <Gamepad_Keep,X, ~# G0 g# S# C, `- l
- STY <Gamepad_Temp,X
6 y$ Y7 a9 @* e8 V- V6 A4 y4 m N - DEX( S9 j% s" C+ g0 x0 T9 `
- BPL GamepadStateSave! J+ P V1 U0 M2 F( l! }
- RTS! }0 _8 ^6 x% z8 ?
- . h' S: w0 }8 I: Y* c% ^! q
- GamepadDatacan;手柄数据扫描
* ]0 J( c7 _* G - LDX #$01
6 n1 A+ {* |) P. Y" | - STX $4016
8 {, f: e' L0 ]5 L& @+ Q% P - DEX3 G w0 L" v+ c% t6 C
- STX $4016/ y6 ~6 {9 q8 s: q
- LDY #$08% [; g4 |3 U2 w
- GamepadPortScan;手柄端口扫描! W% A9 C( k6 q3 }- C
- LDA $40165 P9 n3 | F. f4 D6 L; H
- STA <Gamepad_Port_Value
' H0 D0 Z f. o - LSR A
. g, ^1 I- R8 ?: r - ORA <Gamepad_Port_Value
# d8 q7 O! ]3 m2 s7 s& z - LSR A
0 j u: C3 ?# _+ ?7 p/ s# D: Q - ROL <Gamepad_0_Value# v" T- Y) _6 w, }" ]* r1 H$ G- [
- LDA $4017! t0 D4 s1 W+ W5 K j% b
- STA <Gamepad_Port_Value4 \$ S- O! j( k0 d7 }1 s3 q
- LSR A2 |2 C, S* g5 U; z
- ORA <Gamepad_Port_Value
w4 T1 y5 }3 ~6 b9 y0 D4 V% \% v - LSR A
' T" l. a+ l. B- i' c - ROL <Gamepad_1_Value x' f6 B/ j4 Z+ o: j7 j8 {+ W, {
- DEY d+ t9 e/ r$ D4 B+ |
- BNE GamepadPortScan
0 e6 H$ z& y& \- ]5 W0 z7 m8 N/ z# ? - RTS2 p- d0 K3 p2 V) [4 a" j% `; f
- 6 i* X: q) @7 b; r$ n
- ;==================================================: r/ }$ h8 v: O2 a0 s2 S- ?
- ;PPU处理7 V6 C# I7 X0 K+ l+ s: L& y! i7 V' F
- PPU_Process9 S# D8 ^2 K& [5 D9 c
- LDA #$000 `$ a* _9 O! ^( n$ J
- STA PPU_MASK
1 g) i: W% g9 K -
6 `8 e% d0 q4 \) B - BIT PPU_STATUS
" o9 K- w$ x' D i - LDA #$20* i( _( v8 Q6 F) {& L% S* Y0 j
- STA PPU_ADDRESS. Z# J" A+ }' A' _$ |) L+ z
- LDA #$00$ S9 L) D0 T Y0 B+ F# f n
- STA PPU_ADDRESS$ R% q2 v9 G9 R( E/ r
- , ?1 p1 {! |/ w/ U; ]
- STA PPU_SCROLL* F7 q8 N7 g9 Y
- STA PPU_SCROLL: y1 S0 W& o$ @5 \' l% ~5 e1 F
- : r" E/ q" j1 s# m0 m ~2 P
- LDA PPU_Msak_Buf
8 s) R; i4 ^- J5 M. i - STA PPU_MASK, X" B4 r- S& i5 N8 |" }$ f
- / T1 n' U0 O( P2 A: r
- RTS& N) ]$ j; p. a5 K* w
-
$ ?5 x8 h( a$ ?; i% @" N - ;==============================
* m$ O) j1 p$ z' G6 I$ F& j; Y - Time_For_Vblank;延时等待
+ \9 A' C2 }5 e) b - LDA PPU_STATUS) V+ Q; H% \& |0 c; n4 J. \5 }
- BPL Time_For_Vblank [/ {% U1 ^1 C1 N- [* P
- RTS6 t3 F2 U2 f! q; X8 P
- : Z3 {$ b7 D" X% ~
- ;==============================: L9 h% j* r% h9 s1 m
- ;初始化MAPPER19
1 Y! w+ ?1 p2 Z- o- z! f) I' x - Init_Mapper19
1 ^* p8 b+ W- k$ Z' f& ?0 s/ Z - LDA #$002 P* M: n7 R) [! z* H* y) D
- STA M19_CHR_0000
+ ~; s; s# |) w8 `, A; [ y x - LDA #$01
1 `3 [' J7 B1 X' g" Y5 z - STA M19_CHR_0400* Z8 Y1 w8 V7 U* T
- LDA #$02& C$ X% M. n) [5 F' g2 \3 d3 a
- STA M19_CHR_08009 E {3 A/ l, B( U. U& j& E
- LDA #$03. c% G9 o# h6 ?9 R, w7 n2 @+ k4 ?
- STA M19_CHR_0C00
3 i0 m2 E% n& h% D5 ~ - LDA #$049 n) b, P. o c7 q. q$ H+ c, W' _! f
- STA M19_CHR_1000, o6 |5 x8 O+ i7 m1 ^. q5 S
- LDA #$058 {# u/ R+ a. G3 A! a1 S+ D
- STA M19_CHR_1400! x0 Q4 U2 z. r2 l3 [1 [, B
- LDA #$062 V4 Q# B- }" Q+ a* F
- STA M19_CHR_18006 M0 j" B. H+ K8 I
- LDA #$07
& _0 U ~ s9 P9 S0 Z - STA M19_CHR_1C00. f0 O$ g' D0 f$ m) v$ L# I
- . ~# ?: k+ r( D6 S5 g7 H
- ;禁用IRQ8 `. D& R' p0 X' c* t j
- LDA M19_IRQ_COUNT_H1 i& i5 ^; ]3 k, l. Z7 H
- AND #$7F$ I) w$ y* t9 W3 q, e- _ d
- STA M19_IRQ_COUNT_H7 |5 c& g+ n2 I y* G
-
( G' V. b: K9 @4 j. X, r n. D6 l - ;命名表! N$ r D4 F* n; {
- LDA #$E05 x" N' F% }2 K; {8 ~, g! \' \
- STA M19_NT_2000
$ ?0 ]. S3 s6 C6 C/ L j0 `# B/ p - STA M19_NT_2400
, j3 e% P% c2 U0 l1 z# f6 H# E -
2 i$ R! C1 `# z9 h - ;命名表
8 H+ ]) m8 Q, e" q2 c" J0 _ - LDA #$E1
3 N. b. D" p8 M0 \& Q( U6 C - STA M19_NT_2800; d5 m2 S8 p4 }( Y7 |! w" J; P1 s& ^
- STA M19_NT_2C00" U. `$ ^4 C, }1 _2 B
- X) q3 X; @) {9 {# O; m8 v
- RTS
! g2 [ z0 t- D6 y! U* I - ; i2 C8 W, i% l" f0 ^& V0 m
- ;==================================================# e) e0 }+ P0 S# {0 p
- ;重置中断处理
% A9 s$ B2 k1 K0 U/ t# Z - ResetProgram
2 }0 G8 z, w# ^" j - SEI9 M% E) b0 \! e; J" Q+ O/ r7 D
- CLD
' G; g6 [2 I/ L$ Y2 |. Y! J, Y M - LDA #$00$ I" Y2 U& H! x
- STA PPU_CTRL
) t) i, C$ r- J4 f, N* n/ d$ o+ l' | - STA PPU_MASK
2 n! K( Y7 `$ y# ]( `6 t$ a4 [+ x - STA PPU_STATUS
4 f8 N# t& E5 W% L+ G% e0 R - STA JOY2_FRAME
8 m3 h& J! A" D6 W# @7 B - STA APU_STATUS
8 J+ j8 u8 o0 \; o' D4 i3 ]* y - 9 b# p: G6 v* `# W
- LDA #$C00 e4 W3 |: n$ Z
- STA JOY2_FRAME
0 ^' J* e& e6 x" c0 R -
+ E4 C& L& y0 C, d - ;等待vblank4 y2 C( \5 M) J w
- LDX #$023 q T9 ]$ N9 T! @+ L( |
- Vblank_Wait_1( Q \& ^6 O0 y# s9 C! \: F( a! k4 ?4 \
- BIT PPU_STATUS
1 L+ x0 J9 s4 Z8 T* I! r - BPL Vblank_Wait_1) Z, a. B2 e5 B* H/ H' X
- Vblank_Wait_2
& {: S" [8 s8 _: d2 m - BIT PPU_STATUS
, v) E" l( P( z7 ^ - BMI Vblank_Wait_2
0 W& `5 f4 ~9 I; R - DEX
" A8 V, k3 C7 D3 T& `! ]& M# F - BNE Vblank_Wait_1$ |1 e$ ?! L' t) T/ s5 _& q
- 5 A' _! T! g, F4 Y. R t- d9 N
- LDX #$FF0 J8 C0 v$ ]0 h
- TXS
) [) M+ ? _2 e' v -
$ b7 _4 ~- E) W3 o, l* } - ;初始化MAPPER193 s7 F& v5 I3 ^9 F, W+ K* ?' O4 l
- JSR Init_Mapper19
+ l5 a2 ~( i Z -
- P4 e3 v) B& R) w3 a4 _# `- O - ;==============================' P8 x7 m, B1 C6 M8 W, e
- ;RAM初始化
: h3 V7 z- h N! N - Nes_Ram_Init5 q# X3 x- _# Y" h/ y& I2 k
- LDY #$00. |7 l, J$ d' w2 ]* b3 R
- LDX #$08
( A: C' B' d/ c2 A) K* B) s - LDA #$00
. u2 p! Z5 t c! b - STA <$00( l- N6 v+ l f _( |! B1 x& j
- STA <$018 o- P6 b w& k" g c% M0 `# r
- Nes_Ram_Init_Write
6 M6 A7 W& P7 x# a2 x* f - STA [$00],Y. P3 p4 Z% G ]; Q6 s# w: `' J
- INY
0 s; R: T' T9 B/ p* B6 `, A% X - BNE Nes_Ram_Init_Write: {& B7 D/ T( U# @! a. ^3 @6 q
- INC <$01
+ ~; V4 k( E" c: n - DEX
+ \) Q+ v' z6 R - BNE Nes_Ram_Init_Write! h( Y! J7 q4 {; x
-
- T) M2 }: C4 [) W - ;初始化命名表
/ W: A/ N4 ?9 }5 g9 a! m% o - JSR Init_Name_Table$ k! N3 |5 j* y3 r/ r( ~. h
- . l' D0 t" I+ z, ~" a6 o5 Z
- ;初始化调色板
, M8 q, P7 J; _2 K6 i3 X0 v7 H - JSR Init_Palette
' ^4 B; n: k$ t' u( ?$ p7 M, y% o! D - . P2 \+ v& Y) n) I0 n- H' B, q9 s9 P/ B
- ;初始化命名表属性' `$ n4 D$ \ v/ D2 o/ y" Q
- JSR Init_NameTable_Attributes
4 O* }, F; \& r, M( } -
4 s8 q% c6 F2 ^, k5 Z: I - ;初始化精灵内存
( H3 p" S6 H0 U$ O2 H D - JSR Init_OAM_Ram$ K2 t6 [1 h1 n( b# v
-
) p3 [$ W/ c+ R0 e5 O* ^8 \) ?, J% U- T - ;在屏幕上写点东西) _5 S) m f0 c. r. }0 K8 t" w2 K
- JSR Init_Name_Table_Text/ g$ Z0 `: k; q) D
- $ l& G0 j( O! i: X ]9 a, `( ]
- JSR Time_For_Vblank
' o3 i1 t5 ?4 O2 A9 r3 y - ;开启PPU控制
2 P$ V4 S. g( z( z4 r1 i9 h# T: T - LDA #$A8
7 O6 ^4 }1 v& N' G/ x+ j - STA PPU_Ctrl_Buf
6 e0 u% o/ A9 u% ~& k - STA PPU_CTRL% j8 g* G% [0 z: K( G
- # ]4 \% v9 t- j& W
- ;开启PPU显示( M2 ], Y8 D8 i2 U
- LDA #$1E
( S9 b1 \1 U4 ^' I( U - STA PPU_Msak_Buf3 [' q' k2 R4 u. }( \1 }
-
' c. O" {% M a+ y3 l/ [5 W - CLI* x( ^% h" \0 p0 d7 C0 F: x9 k
- JMP Loop
% w& E6 H# G! E4 ^ -
" t# F' t4 ?, ^$ { - ;==============================; ]+ N) t. z' G, w
- ;死循环, 等待NMI中断4 r" j- m: ?. V- _. n6 J
- Loop' ?) h# e4 u7 m3 `$ u i
- JMP Loop+ G v( r: f( u; L2 R
/ F" U5 E# K; l! X+ Y8 ^4 y- ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967
; { D( i9 \+ }9 k/ Z' z) |6 f
3 z; l3 B% c& d' o4 X- ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)% i7 q, ^0 g* Q7 X' c4 e# u9 e0 o, `
- BEGIN_LINE_CYCLES_START = 32768 - (4103), f0 H+ w' a, V' ]! n2 L2 J. \
- ;==================================================* X( u& T* g( |" Q( D% D+ B
- ;NMI中断处理1 M& Z# i6 G1 B. W& S; L. ]& ?
- NmiProgram
! U! U o% Q4 j6 b* j9 l - PHA
- z+ J7 ?, W7 z- Z+ J3 m - TXA+ L0 Z8 ^1 X$ {* {$ D% t
- PHA: D# B5 f5 M+ [- K8 r
- TYA
, D$ l; E/ F/ C- L' w: z' }4 n - PHA" v5 B. ]! \) d7 a2 d
-
, b6 W3 w* _) d - BIT PPU_STATUS
6 p: F2 D4 @ V2 [ - ) t6 E ~ u8 o8 m. U; p
- LDA #$00
. E, p- [$ ^6 q9 v; @7 B - STA IRQ_Index% V$ n \( m! B% [& z7 y; ~0 h5 |
-
0 c; C: z0 C7 }. D! K8 `% U - ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
+ b. l3 m/ m0 L0 Z% q- _ - LDA #LOW(BEGIN_LINE_CYCLES_START)% Y8 C; n1 R$ f* R8 _2 a
- STA M19_IRQ_COUNT_L
# A0 r8 ]9 @0 ^! o) H; j - LDA #HIGH(BEGIN_LINE_CYCLES_START)
& z5 H: v( L7 f R - ORA #$80! m' J! v0 T& |3 D8 `; M
- STA M19_IRQ_COUNT_H
" o9 o) a5 O6 B' R" R+ a" e" L/ } - CLI
, q; \1 m! t; D6 s. Z$ p -
6 D/ n; e6 ^, u% x1 Y' ]8 i - ;关闭PPU控制, a8 e1 ?2 O2 z) ?6 A; O X
- LDA #$009 X: G7 i2 E2 e3 L, K
- STA PPU_CTRL
# V9 K- g1 L k: E/ t - 9 }+ t+ g [4 E( p
- ;处理PPU( X4 x: d# T5 s p& S4 _
- JSR PPU_Process' a& ^0 @$ ^1 \
-
& z$ d* X. x/ [8 a - ;开启PPU控制! J% M; S; ~* b
- LDA PPU_Ctrl_Buf
3 L4 G7 T. e0 q - STA PPU_CTRL
T# ?* z& S. f$ a4 A! U- x5 ^ -
) u' l, c) J5 j - ;手柄处理
4 U: {; |$ t6 t- | - JSR GamepadProcess
5 c9 x E& j5 x1 R, [+ A - . H8 F6 ^0 ^# `2 ?6 }/ l2 n n( }0 x
- LDA #$00. p: ^5 t' V0 G; y+ V1 a% s
- STA IRQ_Index
7 S( ^, H7 n$ r6 x% Y' Q( X% n6 \ -
' L/ x# t: L$ H4 Z - PLA U& y+ n& u' @( a1 k! g1 s: i) G1 y
- TAY1 T( u! }0 |: P1 _
- PLA
& f g7 |; @! @ - TAX
, i5 \2 S3 M, r - PLA
2 u! p6 T) C2 R L# } ]' ^ - RTI
$ Q5 j C; t8 f& l
8 I% v7 K/ z+ ]5 w- Y- ;每行扫描线113.67! P8 b O5 e- d" s5 p
- ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)1 y1 s ], v1 @+ ]1 V- P
- BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
& S1 q2 @1 Q: F; B) K$ g - ;==================================================/ ^3 q# x" e7 x i
- ;IRQ中断处理
; Y4 U2 Y: B0 }2 P - IrqProgram
% a% ~4 F* K9 ?6 [& v7 {/ ^( x! @ - PHA1 W: O& j* l" z. Q. I
- TXA
( p5 I) ~2 b6 W) ?" D - PHA
- s- Y+ K1 Q* X. d4 E, n, d - TYA
: l# S: Z: w) B - PHA
2 a+ O/ Y( J. y$ B - ' |1 ^+ a; n4 D6 A) a2 B
- ;16条扫描线后触发IRQ+ u" K, X/ y P6 U* u( ]0 \
- LDA #LOW(BEGIN_LINE_CYCLES)3 x( A h- \" b! D: H3 n2 e
- STA M19_IRQ_COUNT_L
. T. f, @8 t% [* E1 @7 ~. k( b - LDA #HIGH(BEGIN_LINE_CYCLES)4 o9 ^9 f! v7 ^& m
- ORA #$80* }. |& W/ t9 l+ J1 B5 @5 m
- STA M19_IRQ_COUNT_H
9 Y; ?/ n) }0 E2 {+ b* B0 z' a - ) Y7 u, t: ?& d# @* W0 q! q
- LDA <IRQ_Index
0 t" x! O7 \1 x: d% Y - BNE * + 4
& N- Z( Z$ k1 F o - INC <PPU_Scroll_H' d0 g: w D$ R9 d8 i# B
- 3 t: u) d' e; j( T
- ;设置屏幕滚动: e- Q* \4 w( A' G7 V
- LDA <IRQ_Index0 I: X5 L$ I" _+ S2 q5 V5 L- \
- AND #$01
+ z$ u: g N7 [# ^3 K% m3 l1 c7 O - BEQ Irq_Scroll_Right* M! j5 _2 Y* q9 f. D3 U
- ) I' w1 E: C4 d( e- ?* q
- Irq_Scroll_Left, }* y. X6 ~: `8 x
- BIT PPU_STATUS. K/ P3 \# Z: a9 O q
- LDA <PPU_Scroll_H
! P9 R9 p* f! R3 E8 w' h - STA PPU_SCROLL
; H9 G+ A: p4 R9 W/ s& y# o - STA PPU_SCROLL
" i4 t+ E* F4 ~* G) G o) _) {! G - JMP Irq_Scroll_Over
# ^& {+ x0 N. Z( a* L -
9 {* g y6 x. Y, _, G; c( p - Irq_Scroll_Right
2 F5 {# y" }4 ]6 L( c& F6 m - SEC7 n6 i; U" ]5 `! X7 }5 W
- SBC <PPU_Scroll_H
) k. k( Q; I* v* C, F - STA PPU_SCROLL( @% r: ^. [* R: }/ @) q( l
- STA PPU_SCROLL" A+ r/ D5 v* v
- Irq_Scroll_Over
; b- p% y' u0 e' a4 @ -
* Z% M. V1 N4 b7 ? m - INC <IRQ_Index
9 @0 }5 c3 w& @- a$ U2 B& P - , }3 w6 R* R# b9 n3 A
- LDA <IRQ_Index1 G. G. m* N2 C( K
- CMP #14
5 G+ z! v, M9 K8 _% D+ D - BCC * + 10
F* T% t- n9 c9 o9 O4 G! n. | - LDA #$008 y# d- B- d$ K. }/ ^! l0 z9 s1 o
- STA M19_IRQ_COUNT_L
. l7 E" I& m! l, Z* {* [ - STA M19_IRQ_COUNT_H
* i/ h1 D" P# s% h5 M3 z. y( b3 V; `% k6 C - 6 v# f3 Y2 f9 U
- IrqProgramEnd
( H' s2 t# _- l - PLA! X% U0 R+ j- ~
- TAY
) X9 L9 [# w! r) t" F6 x - PLA0 g/ D/ S. H9 P: ?6 g+ I
- TAX
: Y6 m! R5 M$ F3 s* m) ]8 c% k - PLA" W+ b- b/ I% {* y. A5 [, c
- RTI
, l P# h9 _; i; x' b2 q+ K - % d4 M4 n; V* S+ P
- ;==================================================% l3 l) S. c8 j
- ;中断表
) Q- p. H' H" m) ~1 i1 }5 h - .ORG $FFFA
( Y5 }/ e Z% p* D& p6 I - .WORD NmiProgram
" U+ H. P f3 u+ {4 k. Z$ D - .WORD ResetProgram
7 U# R/ r' M+ m/ F9 L - .WORD IrqProgram
复制代码
4 ^" E3 @& u/ c+ x2 w- ] |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|