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