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