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