|
|
- ;[FC][Mapper19 IRQ]1 T% v2 E- {7 x& r* a
- ;FlameCyclone 202307102 k# Q% k! L" p r; e" A
- & R# m! j" I3 G% I
- ;文件头
0 y! v' u) O* `+ s ` - ;======================================================================% W* \" n$ P3 w7 D$ y( q
- .INESPRG 4 ;16KB PRG 数量
: D, p4 r/ x$ s/ x - .INESCHR 1 ;8KB CHR 数量
! y" O k. k2 E* ]( D - .INESMAP 19 ;mapper 19
, ^# N9 J7 U9 N" b1 k' ]+ W - .INESMIR 1 ;命名表镜像 0水平 1垂直
4 ^+ l4 T) B! }6 n- P, s6 M - a. S+ W6 _# m3 Y, a0 }# g' R
- ;必要条件- R( b' ~, L+ E; r; z0 d6 p7 R& J
- ;1.持有CHR ROM0 |% q @9 t* K+ e1 y2 I9 Q
- ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
& T1 X6 F7 x+ P$ }/ o% z! S - ;3.精灵内存(OAM)不为空
+ D& K3 `& a; [0 ~" l: d - 4 T) _( O% S4 n( e. X+ Z+ y. x. d
- ;==================================================! y! }# T1 V2 {) R6 ^
- ;NES端口常量( z" a9 E+ O5 j% W8 v
- PPU_CTRL = $2000 ;PPU控制寄存器8 v; k% E) O. E- n9 Q6 d* Y
- PPU_MASK = $2001 ;PPU掩码寄存器
8 [5 [8 M0 k+ y5 a. [ - PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位% J$ v0 o# u: \# I8 R! j/ Q
- PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加15 D q* U% j* z. v
- PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1
. E1 v' ^% a/ a4 w - PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 6 q# p+ J5 u. j" y3 [
- PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加' U) K; s/ @+ [9 A+ F" U+ x
- PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 . L: L/ B8 C1 \+ i* P+ R
- OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
" }. v( v8 c7 M [ - APU_STATUS = $4015 ;声音通道切换* ? `9 |0 v8 d; X8 B
- JOY1_FRAME = $4016 ;手柄1 + 选通5 T" c1 L1 `( G7 t
- JOY2_FRAME = $4017 ;手柄2 + 选通
3 {3 {5 X% U2 F' F4 ^
0 m" F% x/ D1 g; k A% ~/ I p- ;================================================== [2 @" R& T; |0 B$ U
- ;MAPPER 19端口常量
: y; D) a8 {# U4 Z - M19_CHR_0000 = $8000/ p* R1 i+ u: W7 y# J5 a
- M19_CHR_0400 = $8800
* ]5 L) h: e# c/ N2 | - M19_CHR_0800 = $9000
; H" _* H$ e& ^) l. V C( s - M19_CHR_0C00 = $9800( o) Q' B2 n. ^9 ?% b! c
- M19_CHR_1000 = $A000
: r/ X% `* k2 x, J3 ^0 O - M19_CHR_1400 = $A800
9 j" y' B: p7 c3 z/ f! b - M19_CHR_1800 = $B000
6 _$ p6 e% `9 E - M19_CHR_1C00 = $B800
* s$ g. M! w( ~ O% T& r, r - M19_NT_2000 = $C000! w- m5 _( ]! c1 E
- M19_NT_2400 = $C800
# k5 o; A) }/ X" g8 C - M19_NT_2800 = $D000$ Y% _* ]. K. c; H& O
- M19_NT_2C00 = $D800" `' r$ W6 ]- H. @7 `; ~) i: _
- M19_PRG_8000 = $E0008 R& y, K8 {7 Z
- M19_PRG_A000 = $E800
. o1 F" ]8 t3 @& o5 k. z" [. ^' U! P - M19_PRG_C000 = $F000
2 h/ h8 l" G' u: `8 K5 K - M19_IRQ_COUNT_L = $50006 H+ q& C4 k+ X
- M19_IRQ_COUNT_H = $58002 |- r' y6 \5 ]% C
( ]: t$ n% ]* \2 D) N- ;==================================================
2 r" Y2 p& I% I; ?/ [2 |# z0 V - ;程序块配置
; s; }5 O2 E0 k - BANK_DATA_MASK = $073 U* E6 `+ w2 i1 r' ?1 K) ]- x
- ;--------------------------------------------------
& R9 l) |! a0 R! Y* r. k7 j - RESET_BANK = $07& `) q4 @9 i' Z* t0 C$ |
- RESET_ADDR = $FC00
- E0 ?& F! c9 Z% `- T7 H+ h4 k4 ^% m' t - & M- W# W! a+ g- n
- ;==================================================; S- f8 l3 F& [5 B+ B) U8 E
- ;图像块配置
5 |5 f3 ? q; L7 m - CHR_DATA_BANK = $08
% Z7 @8 @" e1 b# [' f
* ]4 ~/ ^3 ~ W* Z' S% ^5 t( I- ;==================================================
. @+ N/ \( i p" E - ;零页内存地址配置; F9 ~: f( h0 S3 g7 E
- Use_Ram_Addr = $806 a9 z: g5 m* @( N3 C
- PPU_Ctrl_Buf = Use_Ram_Addr; q4 F- `3 I% p3 ?6 W2 M" w
- PPU_Msak_Buf = PPU_Ctrl_Buf + $012 }, f6 p( {" R" b
- PPU_Scroll_H = PPU_Msak_Buf + $01
% @ n! v* I5 |4 q: l - PPU_Scroll_V = PPU_Scroll_H + $01
8 s, }% g* f1 w' i7 U - FC_Data_L = PPU_Scroll_V + $01
2 s/ M- V! Q/ N5 f - FC_Data_H = FC_Data_L + $01( i9 T" p$ G5 c y8 p, k8 s( E8 O
- FC_Data_Buf = FC_Data_H + $01
) [) z# S5 H2 _- c0 W; v: _ - ;==================================================/ N/ D e+ `! E2 _6 q
6 ~- M8 X4 n0 z I5 u5 k, j- GAMEPAD_MERGE_FLAG = $048 M5 d* b% I/ | V k! y
- 3 Q2 p6 s# O T w2 Z% ?' b, R
- Gamepad_Keep = FC_Data_Buf + 1, I3 P4 P& N( E- Y! j
- Gamepad_Once = Gamepad_Keep + 22 t( ~8 d7 W, S5 [9 X$ {# w
- Gamepad_Temp = Gamepad_Once + 2$ z, v" B* e; b7 n5 Y& l( v6 X
- / \* V2 ~7 }4 u3 n% e
- Gamepad_0_State = Gamepad_Temp + 2
5 V/ |6 k2 R: c6 K" D8 V8 U - Gamepad_1_State = Gamepad_0_State + 1
6 \2 H8 G& k. @" X5 C - Gamepad_0_Value = Gamepad_1_State + 1
8 _4 `" c) h7 h( ?$ t - Gamepad_1_Value = Gamepad_0_Value + 1
: s; j+ Z7 ^1 M9 B$ S, H - Gamepad_Port_Value = Gamepad_1_Value + 1
3 T( [: b0 {7 n& }$ W: Z" W - Gamepad_Merge = Gamepad_Port_Value + 1
4 J/ ?2 F- [4 b {( P X9 ?0 H$ ?- G
) Q" Y3 H8 }* j P) B- ;==================================================
& r h: Z0 ^3 J5 j - IRQ_Index = Gamepad_Merge + $013 Y [3 n# V d' e0 P; r# A
- ;==================================================# s: A9 Z X5 M1 ~
4 o% C. n: z) `4 t2 |- ;CHR图形数据
1 [+ e! b* j: n7 e6 Y5 f - ;==================================================
4 O" E1 ^: @7 b- L+ A) B: k - .BANK CHR_DATA_BANK
. w) b( ~" h: B) x* M1 x' A/ f- R - .INCBIN "chr_bank/chr_data.chr"
0 o8 ^" B6 v4 \; x8 V0 H+ v - o# ?7 r/ a4 S6 A/ \1 m
- .BANK RESET_BANK & BANK_DATA_MASK# |8 v$ W/ @, r9 m) f
- .ORG RESET_ADDR
, G1 i3 ~* c4 @0 ?- }' { - ) X5 c# H. S3 S) R( c
- ;--------------------------------------------------
1 c- U. ^8 {, x6 H" ^- r. l. w - Attributes_Data
# y7 i9 N+ Z% v& B, L - ;命名表属性+ V9 J' N( N5 l: n- [
- .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$001 P4 R6 V' w; K& L; X
- .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
* |! F& Z* }( ]8 c x4 E - .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
" a) H. U. _" W - .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$554 k0 @: A# e0 L/ G" |
- ;--------------------------------------------------
7 b9 `2 {7 O5 c! a - ;调色板数据
* F1 T& }7 X# p - Palette_Data- e7 {, z, J. m+ K, `
- .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
2 _/ L* l# e. T* |& S9 n+ d - .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
0 N0 \+ f( s: L0 S" I) r; F - * Z1 E% a0 w6 F+ }0 i9 R
- ;==================================================1 I% W+ ? U8 }* U' c! E7 R1 ~
- ;命名表初始化2 c* r5 d( e( v( u+ f _
- Init_Name_Table
3 Z" d, U4 r* g _3 j - LDA #$20& j1 }" O/ D) y# L
- STA PPU_ADDRESS( G4 g4 }/ r& D: t7 K+ z
- LDA #$00
* p3 {3 F; a! a- Y+ v - STA PPU_ADDRESS j O2 Q$ Q5 Y5 a J! \- |6 t
- LDA #$005 v; \! y, J9 d x3 q8 i
- LDY #$008 ~+ Z7 f' m0 t8 Z$ d
- LDX #$10
0 I' m q; j7 Z! b) X1 k5 q - Init_Name_Table_Write
" i# d F8 X' }! x4 I - STA PPU_DATA e! t, u; E0 i$ M& S; n; J8 N
- INY
( m( \* N( y+ z8 L. [ - BNE Init_Name_Table_Write' r5 L6 ^+ a" x' C
- DEX" t3 [5 Z& r- a4 _) C1 _: t
- BNE Init_Name_Table_Write
9 c' w# e7 \9 h( f2 C1 ~! O; ~ - RTS. i6 m" ^+ ^+ @7 r" r
-
* |% ?- q6 t9 g9 d! W+ V - ;==================================================! b! C3 O+ G8 `3 C3 [
- ;调色板初始化. P5 L! V+ U0 P! @$ n8 k- L
- Init_Palette
3 c3 U9 P+ R( Y - BIT PPU_STATUS+ v. m C: I0 y$ i$ ]
- LDA #$3F% `; V% C6 |8 p9 a. {7 z ?
- STA PPU_ADDRESS
' I( b( E7 y ^& h1 F - LDA #$00
% I; t8 _8 n" M+ S" b+ [ - STA PPU_ADDRESS; L% W" K% z \8 N$ i
- LDX #$008 U# h: S& N8 V
- Init_Palette_Write
7 m. K$ n) k- S+ U2 K, @- m - LDA Palette_Data,X
* a/ m+ ] b; b/ ]& ` - STA PPU_DATA
h; P8 E7 r8 J' g# D3 P, t - INX- w' z" j2 o) ^6 t, O1 c: _5 w F
- CPX #$20' @4 J7 d& s8 F7 G
- BCC Init_Palette_Write
8 s+ w/ I, }6 p! } - RTS+ F8 J' \0 {( a4 c8 h+ [1 k
- 5 \+ z, D. D M5 D# b* f0 a
- ;==================================================$ s8 \' Y9 I9 l$ w; i) V, d
- ;设置命名表属性
) l+ u( K1 Y% j( e1 I( u - Init_NameTable_Attributes8 M9 A9 U5 f7 p2 e4 w% R
- BIT PPU_STATUS
- w; a! L+ c7 D' X0 W/ r2 k - LDA #$23
x+ i6 v6 h7 @0 p/ w+ F - STA PPU_ADDRESS
. H3 l/ k& }( L7 c: @% | - LDA #$C0+ L5 {2 |: Y( K$ x: @
- STA PPU_ADDRESS
! f' _! x" U4 g3 ? - LDX #$00: n. \. D# |, v- H: z7 D6 ?8 V
- Init_NameTable_Attributes_Write5 q5 ~* m$ I7 P( Y
- LDA Attributes_Data,X; w. u: N+ c F; p) \- |0 y5 }
- STA PPU_DATA
5 `) |8 ^( \9 L8 G- Z - INX2 D% h1 {% w z0 o) v- h
- CPX #$407 { s8 R# @1 A1 _* M
- BCC Init_NameTable_Attributes_Write/ V. K' D4 T7 O6 x* T: J
- RTS
* O* B; `+ ^6 D
" b8 @0 A3 y6 y- ;==================================================
1 {7 x) `$ m8 O, O# k4 k( n - ;初始化命名表文本
3 G6 L$ {$ v [& H) ]) W/ n - Init_Name_Table_Text" z4 }1 H: m5 [5 W& v. m
- BIT PPU_STATUS# W: x1 g- @; w
- LDA #$208 D/ T8 b" b% \
- STA PPU_ADDRESS
$ [: U' Z4 u0 [% s - LDA #$00
`7 ^3 J; w8 i4 R/ D - STA PPU_ADDRESS- [: a) t% b6 s5 f, A L$ F
- LDA #$00
3 X8 ]3 L% ?$ V5 I9 v. r+ ]# T - STA FC_Data_Buf
1 F, ?, h- L) e+ K+ [ - LDY #30+ P# ^" T! f' s! ]# _2 A
- Init_Name_Table_Text_Write5 ]; U( k+ u A( ^2 ~9 V% j
- LDX #32
" S3 N7 Y0 o5 }" `9 q% Q - Init_Name_Table_Text_Write_Char, S0 M$ D# l' k+ q# ~7 I# T
- LDA #'0'! Z; _1 `0 B- P- B# g
- CLC
9 I0 j; O v8 R" |7 P - ADC FC_Data_Buf
( O6 Q" a- z, p/ q - STA PPU_DATA
9 A/ O# X9 P+ j6 w$ B$ _" N1 U4 X - DEX
; Z1 l% `% Y: ?$ N- A: l( Q - LDA #$14
. P o. J4 ~7 M, s1 ]3 s# ~ - STA PPU_DATA3 K! r5 f5 X& n0 @! @- B& V
- DEX
" V) B8 N4 d. V% q3 e - BNE Init_Name_Table_Text_Write_Char
' f) c) U; W- [ o9 C/ G - INC FC_Data_Buf
0 ? z5 w9 w9 i. ?1 J3 ^ | - DEY! e$ ?( n0 V O$ r
- BNE Init_Name_Table_Text_Write
- ?% e( t, g2 }" r+ Q1 t - RTS
* j$ O; ?5 x* Q4 h; ~8 R; d - $ M) C( T( C( K$ c, G
- ;==============================
7 J2 x, K7 D- y - Init_OAM_Ram;初始化精灵内存
! \7 o: e: g3 C( F - LDX #$00% C" c8 c; u+ w% ~4 L% B* h' D/ k- U
- LDA #$00
2 E' e+ u! [# Y9 [ - STA PPU_OAM_ADDR9 R. C- R& w* i2 X) \
- LDA #$F8* B5 N& S: l" K2 C5 N' `! Q
- Init_OAM_Ram_Write
" a+ D. L! O: I5 K- @& M8 }! f' J - STA PPU_OAM_DATA
7 R' t- a2 L' E; c9 U; s4 n - INX& u$ m; p5 S" u3 l
- BNE Init_OAM_Ram_Write
6 ?- a1 M- }( ] - RTS/ H) i U6 G5 W& l u6 O
-
; G \/ @! _2 m8 r - GamepadProcess;手柄处理
& Q# f2 C% x/ r2 O- R - JSR GamepadDatacan
|$ Y, p+ H- n& a0 M1 s9 r! C - LDA <Gamepad_0_Value
4 u! ]2 ~+ h8 k+ R) z7 n5 f9 L2 C - STA <Gamepad_0_State
. H: H. w) f: Q' t- J - LDA <Gamepad_1_Value a; F7 U2 s* V7 |2 N4 Y8 Z
- STA <Gamepad_1_State/ W/ w) [+ F/ X5 ^' M
- JSR GamepadDatacan
$ w% p' x! @! U! T5 t - LDX #$01
/ p, M1 P" b1 h7 Z5 u+ W+ k6 I - GamepadMergeCheck;合并手柄输入检查
6 ? _: `' P# f1 D8 s" `8 x - LDA <Gamepad_0_Value,X% Z* O9 J$ c% V
- CMP <Gamepad_0_State,X
9 h- Y9 o- q4 C. q2 W r0 Z - BEQ GamepadMergeInput
5 X r- l0 K: R/ } - LDA <Gamepad_Temp,X
4 x# m3 p6 B* y8 W% Z: G - STA <Gamepad_0_Value,X
' O2 d+ b5 c. @ e+ y- N - GamepadMergeInput;合并手柄输入: W% ?" B: S/ E: \8 G+ z
- DEX- z% {6 }% P) ^2 |& d8 e
- BPL GamepadMergeCheck& ~# E/ m" w7 ?' N5 f$ D
- LDA <Gamepad_Merge
5 O' t' j8 B+ G8 e2 Y9 [6 \7 w - AND #GAMEPAD_MERGE_FLAG; k/ {8 s9 o. t0 S& L# k
- BNE GamepadStateProcess- j9 B: @6 \% D5 |: [, J+ [
- LDA <Gamepad_0_Value. F, ^8 }; W+ s! V
- ORA <Gamepad_1_Value( X! r; S2 D' f9 R0 P2 I2 f( `/ h
- STA <Gamepad_0_Value
9 C7 a# n) [4 U. S9 T - GamepadStateProcess;手柄状态处理
& b t y" o: Y/ b/ `5 H3 h2 R - LDX #$01+ o8 u9 J, L9 ^) \
- GamepadStateSave;手柄状态保存
' x3 h3 y' ~9 | - LDA <Gamepad_0_Value,X
8 E# A4 U4 M$ u9 C$ |" v - TAY
3 g6 A0 G( L9 W+ h% f8 U) D- D - EOR <Gamepad_Temp,X
1 L# M, l# C# J) `6 f7 a- e - AND <Gamepad_0_Value,X
- c N0 Q+ S; X+ f. u - STA <Gamepad_Once,X% E% u' b9 W9 Y$ `! {0 w
- STY <Gamepad_Keep,X
4 `3 Q' r$ c7 H, w8 j+ A - STY <Gamepad_Temp,X/ I7 e3 A5 I5 S3 Y
- DEX2 K: O. B+ {/ ^# B4 d; G& [, o1 _: a
- BPL GamepadStateSave
2 s$ u! I7 a8 p4 b6 P, e: S/ m - RTS2 C$ f4 M3 y( X/ o, t8 S
( b' e6 D I8 X, A' f2 J1 d- GamepadDatacan;手柄数据扫描2 A& S$ C$ {' p5 j2 _
- LDX #$01
4 g/ P' P/ p0 V5 u$ } - STX $4016
. g, _. z# h2 @ - DEX
3 z% ^7 b1 k, j, ~( o- B - STX $4016
: O5 }8 \- ]; }- [: o. G5 ~. O) q - LDY #$080 `1 \- x/ f) B" \8 A
- GamepadPortScan;手柄端口扫描3 d& ^9 A* t4 `
- LDA $4016
0 ^! @, r: F$ Q; K8 k9 e - STA <Gamepad_Port_Value+ w* [ m0 J4 a) ~, Q) f8 m5 Y$ \* W
- LSR A2 |% R# J& H; S! C. K$ a
- ORA <Gamepad_Port_Value; H/ Q( ?2 @; m8 o# X% R
- LSR A F, k9 S5 ~, G( [' M( O
- ROL <Gamepad_0_Value' K0 P4 v# n8 D6 z# A! i. w W
- LDA $4017! A' x2 {# s( o
- STA <Gamepad_Port_Value! `2 u3 k( l: E
- LSR A
; L7 y! j8 C$ K- S9 ~1 E3 l# F - ORA <Gamepad_Port_Value
% V# R9 @5 O9 t6 d - LSR A$ H3 B, P+ s z" \: i' m' _3 [
- ROL <Gamepad_1_Value
5 m) ^$ b2 j0 e" r; H$ L( v - DEY
H% X, V1 z- @8 E0 ~1 ?. I! c! h$ L - BNE GamepadPortScan u, F5 D$ H8 t1 k7 h1 ]5 b
- RTS
7 Y( i6 u& x( ~% L -
* s4 e; e8 F8 q: O Q - ;==================================================; P" e: k6 ~; X" l+ {
- ;PPU处理
" J0 F$ ]6 j O - PPU_Process: z! v$ `; a$ \( P) Y
- LDA #$00
B9 o2 l: y. a" q9 l: E% l - STA PPU_MASK3 y5 J& V, m+ l
- $ U2 |- E0 l+ l" p0 g. i; W
- BIT PPU_STATUS
8 h9 t7 w' f# X - LDA #$20- M3 p* H0 {' Q7 [9 ]. y( D
- STA PPU_ADDRESS2 b! I: G8 K5 |1 ~' p# M3 A
- LDA #$00
! K3 W5 c$ |: V) y - STA PPU_ADDRESS9 T' o/ m# I' j; G
- ! `' }. S5 p9 G0 b' V G
- STA PPU_SCROLL/ Q5 d! G6 U% x
- STA PPU_SCROLL: I X3 L% O" I* r4 w( B
- n k+ L/ p; Q/ A0 ]
- LDA PPU_Msak_Buf
& v/ n5 a2 \! V, I1 l - STA PPU_MASK
0 A' u9 a, U0 Y1 x8 m8 ~9 r4 _- S* u9 R
: @. L6 U$ M& X- RTS
: t5 w: a4 f. [8 X6 e9 @ -
# J3 N* r' M4 ?) l. ]9 C) \ - ;==============================
; Q3 X" W) c. ]3 b7 j7 L s# j3 R - Time_For_Vblank;延时等待
& x9 _, g4 D2 \% e9 m. D7 C2 U - LDA PPU_STATUS7 v/ e0 y' }2 D2 O; S, }* K
- BPL Time_For_Vblank
5 a6 E; b+ D% v. H - RTS2 k5 y% {; Y% {1 K8 M* g) e5 R2 B) L/ B
-
9 l$ u: u* }7 ]8 Q W+ W - ;==============================
( [3 \6 D! ~% P9 `. O9 G% W; K) g - ;初始化MAPPER198 H! @+ y' j2 {. L8 A9 L; G
- Init_Mapper195 Q& ~: k% r" O
- LDA #$00+ V4 Z+ H$ T; B% S3 W: K- ^
- STA M19_CHR_0000+ B0 A" T5 q8 k9 E* `0 k/ d
- LDA #$01
6 e) L5 s- J/ \7 Z - STA M19_CHR_0400" G0 `6 d m; i
- LDA #$02" t: W$ W& O# l V: x! B. I
- STA M19_CHR_0800
1 L0 `* T) T$ @ - LDA #$03$ k+ b" u: v( X# j1 E8 v( p* R9 Y
- STA M19_CHR_0C00$ |) S* w. O- q
- LDA #$041 l5 j. K/ q* R% e
- STA M19_CHR_1000. U- N5 }& ]& @4 A) P
- LDA #$054 R( D2 M n: }3 K- n: }% h2 R$ ~
- STA M19_CHR_1400
" I" ^% W4 M0 \0 x, D - LDA #$06! x" ^8 y- R F, w
- STA M19_CHR_1800. _: x; {. c* z9 L8 G8 x% v* I
- LDA #$07
# Y# ^. L+ \0 G4 T- k; O) t) n7 @ - STA M19_CHR_1C00- P- ^3 Y8 j9 K
-
) M) \. ?. [; z8 O - ;禁用IRQ' L u& u' }# d9 `
- LDA M19_IRQ_COUNT_H
9 D7 T5 H [: @8 b$ R - AND #$7F7 A7 W9 b9 b$ I# g! s7 x6 h0 x
- STA M19_IRQ_COUNT_H
) }+ @% r/ h5 V. E% M, z -
1 I& ?) H9 K' K0 w& M. v - ;命名表- x+ a9 J7 d* e& K3 B% {
- LDA #$E0
8 b, Q. ~) U7 D: x O( X- b - STA M19_NT_2000! @! L) y. A7 I
- STA M19_NT_2400& _3 w: h. Z( x6 a4 C) ^) o, O0 q
- 7 T7 U2 q3 W+ u5 C9 x
- ;命名表8 V V$ _+ G1 T4 [
- LDA #$E1+ d, j7 [0 P9 @5 l1 m1 [
- STA M19_NT_28007 Z, v R; O0 A" `
- STA M19_NT_2C00' K9 l) ^2 W9 T! I0 e) J* [
- 0 h6 ?0 g E7 E& k9 Y
- RTS
+ ?1 N' P' B; D& \0 u$ `' e - 5 H$ o' V( w* f/ A7 V4 B0 D2 J
- ;==================================================
; h( h2 @* q. |8 U - ;重置中断处理
9 F9 I! K+ F" i9 @( t - ResetProgram
3 [; k1 a& W, K0 M9 ? - SEI
' H( [1 Z( j5 D - CLD
: E$ s+ Z8 I# y" q$ Y - LDA #$00- {5 }! G+ g2 k0 ^7 O
- STA PPU_CTRL7 b2 P R5 V' W* Y! |5 U0 q
- STA PPU_MASK4 N, u J" j' H9 a. V
- STA PPU_STATUS+ V) |$ P4 ~# f& F i& P
- STA JOY2_FRAME
5 J# A0 v/ i$ B+ I - STA APU_STATUS
) V, \! K0 [" e4 U8 f# h) ^0 |' V3 H -
1 y# D, Q3 r4 b# S" r - LDA #$C0
& u8 R, m# L$ r% b- f6 O - STA JOY2_FRAME8 e4 k& B7 A) R/ [$ P2 l6 o5 d
- . {1 r5 n! s* m$ {8 P
- ;等待vblank
# N' f( Y+ z# B1 r - LDX #$025 Q/ Z7 r j7 w) d' C! ~
- Vblank_Wait_1; G( ~# A1 T6 }. ^3 J* y
- BIT PPU_STATUS
' p$ S4 O* j4 T* D$ D! u$ R - BPL Vblank_Wait_1
7 `+ k3 L- D9 h$ [% n5 a - Vblank_Wait_2
, `' a/ q6 y& H8 E k0 J# |4 z - BIT PPU_STATUS
6 |+ p: x; f# n4 C3 r, q: f - BMI Vblank_Wait_2 `1 ?* p: U& z# L
- DEX
/ d' K9 w. R( s& T$ Q - BNE Vblank_Wait_1% k8 _$ A1 \" T2 d, |" K
-
: q' c9 w; M1 t ~! ?7 F - LDX #$FF& t0 _8 R# N: n0 V
- TXS
f7 W5 I4 ]; y, u. Z& }, ?) d+ ? -
$ f, r3 s$ ^( N8 Z - ;初始化MAPPER198 {4 ]! e; V ^ b4 M8 Q
- JSR Init_Mapper19
8 t* Z1 W2 l; ?1 n3 g - 9 [# M A1 ?2 H+ N1 S2 N9 ^+ `
- ;==============================
8 r0 D8 _& s- w% K8 U( G( t - ;RAM初始化+ i2 k4 m: S% h. @; S
- Nes_Ram_Init+ _" @- R6 z" o9 _' Q
- LDY #$00
* }4 Y# l @/ W4 @) s - LDX #$082 I: Q |: e" a8 I' a: K
- LDA #$003 h/ e7 `; L R0 Y0 N
- STA <$00
* ]! J3 `) J2 b2 w) g3 [3 b. H5 n - STA <$01# k/ m! W% f# L* [- b2 q
- Nes_Ram_Init_Write
/ W% T# `/ r! k1 D2 v8 B- A - STA [$00],Y. D$ V8 f$ H% D5 p. Q6 F2 G
- INY3 G2 ?* p* v, M$ ~( w/ |5 B
- BNE Nes_Ram_Init_Write
0 Q! h D4 z0 x7 t8 C+ ^ - INC <$01
6 t( e3 \* Z4 y' W - DEX
' z5 Q- K. ?5 d) ^ - BNE Nes_Ram_Init_Write$ J6 u! j% `& C7 A# f5 u7 g9 J$ O
-
6 i, V8 T/ _" m1 j# B - ;初始化命名表
4 ]) e* W; q2 t. U+ j5 O: W - JSR Init_Name_Table
( ?3 }. c' T, D- b2 z: C v% @7 i - ( x! I4 u- ~: h
- ;初始化调色板
- m. D" Z' A( D1 I& t - JSR Init_Palette
! x1 k, |- ~# T2 T8 f* X -
k) ?+ v7 O g8 Y9 z- L+ R1 { - ;初始化命名表属性/ O8 I" c) D" @% J D
- JSR Init_NameTable_Attributes( {2 ]" ^5 q/ P% H2 E" E
- - O3 x, M5 }' U* K, N p, c; t0 W
- ;初始化精灵内存
1 C( y1 _2 n( D( ~! v - JSR Init_OAM_Ram5 V: g) a+ S8 t4 M$ d2 N; O9 n$ ]/ K
- / r7 \ b( x# d& N4 G) Z
- ;在屏幕上写点东西* e" D0 Q5 Y3 H2 a! @+ U: A
- JSR Init_Name_Table_Text5 x% w" s# j" q! {1 ]! _
-
0 k3 E* N$ a1 M - JSR Time_For_Vblank0 `* s7 A! T1 @' e
- ;开启PPU控制
6 c% {; S0 L" b2 f; F - LDA #$A8
5 [! [1 v6 E3 s1 ~- T7 ~* l - STA PPU_Ctrl_Buf" {( P0 ^1 f; K& V% t- ~
- STA PPU_CTRL" b0 S! ]3 W+ @, g& J" l
-
- E8 f0 U8 N& h6 o3 G% l - ;开启PPU显示0 X" ^) F5 j2 M% _5 e* G
- LDA #$1E" d- |3 W" ~ {$ t( M" L: ^
- STA PPU_Msak_Buf
/ B5 g7 H% o+ f% k+ Q; {- i" j - 1 Z3 x# x1 F; {3 X1 E' ?! O
- CLI
6 C$ N$ D% R7 Z5 d Y( X - JMP Loop
- t8 t) F- P5 P+ \( v9 Z& ]$ b% {3 | - 7 f2 G) w6 G8 h3 T
- ;==============================" b! L: Z1 F4 m7 J6 P1 L
- ;死循环, 等待NMI中断# W, s$ M% y3 A" ]! w5 N7 O
- Loop
" v# N/ Z4 D& ]7 r9 w0 h- g - JMP Loop3 x* h0 n: w8 l! [2 |2 w
- 1 _0 U) O: o/ V
- ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967
: F# I; A/ h, x - b D6 z! h7 g" B6 z, B1 B0 L7 x
- ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)! A- }' J, }6 h" B
- BEGIN_LINE_CYCLES_START = 32768 - (4103)
* ?7 e0 X2 T4 q1 N1 [3 U0 H - ;==================================================/ M' F2 [3 l- H6 V
- ;NMI中断处理 w6 e S6 c$ M( M$ Y0 _" d/ k5 ]
- NmiProgram+ u; `8 v1 O' C- S; Y
- PHA
+ x3 y3 q8 [) ?! X0 [( h - TXA) _7 C. N& H4 C" O" [ O& {
- PHA
+ g9 `3 D6 A6 r- b- g1 ? - TYA* M" u) L! @9 H0 `* J' n
- PHA) a& t$ K6 d3 ~/ V }
-
: ^9 W3 A9 ~+ Z% B - BIT PPU_STATUS
m. g4 O0 s6 I- g4 @ - , m/ G5 Y6 h8 r3 o F
- LDA #$004 T5 `1 _3 s! i2 o( ~; }' l
- STA IRQ_Index
1 t, Z M: h! t - ! } U5 v9 o2 r8 o1 F
- ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
- u# Q6 V+ [& g& |" U0 h: f - LDA #LOW(BEGIN_LINE_CYCLES_START)% W" [3 q- L1 Z. \
- STA M19_IRQ_COUNT_L- y) H$ Z6 Q0 s! L& ?
- LDA #HIGH(BEGIN_LINE_CYCLES_START)( _( W4 c5 z4 R! Z6 s0 N; A
- ORA #$80
; @0 Z& Q3 b" c: i1 R - STA M19_IRQ_COUNT_H
& d+ ?* e& ]" M# ` - CLI5 E4 ~, x8 O5 J3 t
- " D: L8 K O u
- ;关闭PPU控制
6 h$ h+ I" k; V( y5 } - LDA #$00
h5 |; b8 W$ a8 V3 t$ E" U. t1 e - STA PPU_CTRL
D# t: n/ F0 \: t8 M" `, t K - 6 H4 F, l8 N A4 ^, I
- ;处理PPU
" v* t% j) `) c4 }- Y - JSR PPU_Process
: {% m, E! S6 d -
: G& @: k8 N$ c8 Q - ;开启PPU控制
/ p1 e. r- s# d+ X% n% a5 C - LDA PPU_Ctrl_Buf. a: W& x3 D7 K4 \# Y; \: i, X. R
- STA PPU_CTRL& T- m3 V) F6 H3 t5 |
- 2 S# n/ _4 W; [3 T" ~% Y
- ;手柄处理! I6 E: h6 Z6 k" I
- JSR GamepadProcess
! Y) N7 Q+ ^( s3 z1 E* M - . H( A+ \( I2 d g2 I v' z8 x5 v
- LDA #$00
9 L% p0 m c9 o5 Z8 { i# }+ d - STA IRQ_Index' |* d( O3 F* Y
-
& r( t6 q8 `+ g6 [) C4 [. N. I$ v' I - PLA
; ~7 D0 p0 l# G: A, H% [7 R - TAY0 r- S2 \; D5 l2 @+ |7 v6 u! g. x
- PLA
; B4 I5 _) o" h% t o - TAX* H9 f6 U0 g& o7 G5 F0 j
- PLA
& w: W0 z, A! C0 j* N8 c - RTI/ Y* J" t5 F0 n$ Y
- 7 V# \9 x) o. D! x- ?$ |2 D6 X
- ;每行扫描线113.679 l! n- p3 I/ M h1 o1 i9 [* ~: ?
- ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967); A) l0 D5 I+ A1 n
- BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
8 j5 Y1 s. Z6 A& g( K2 M/ h - ;==================================================( E+ j: L/ Z1 a; i8 W
- ;IRQ中断处理 [: U6 Y6 K0 x/ F3 o
- IrqProgram& N' j, b, |9 @/ }/ b; {0 c
- PHA
( o& `" G/ h' y. R# n5 M: K - TXA C( O% s5 s* G. `+ E4 u( l
- PHA
# N7 s% ^7 r' p1 p - TYA6 y5 j# a# C, x& n# k
- PHA* q# e% S3 M8 i# ^- n0 _8 m. k
- $ r6 z: W! V$ T4 u g. G' H3 y; v
- ;16条扫描线后触发IRQ/ ^- n. `/ S9 p# v
- LDA #LOW(BEGIN_LINE_CYCLES)
& x6 m6 d. |3 X. h* L* V - STA M19_IRQ_COUNT_L8 Q3 @$ I8 A) ^3 s
- LDA #HIGH(BEGIN_LINE_CYCLES)" c& `' h7 [6 p; i9 e/ o
- ORA #$80
4 L5 ]1 i& h9 U7 C, [ - STA M19_IRQ_COUNT_H# {: {0 b! E3 n/ S9 A6 S& @
- 9 {$ X4 I' \1 K7 |* g
- LDA <IRQ_Index
$ j9 i H/ I4 K! F3 m - BNE * + 4
1 @5 \7 {- P& j - INC <PPU_Scroll_H3 @* b/ k# F. i) _5 P6 J
- 4 g P0 x/ w8 o5 x8 G7 L7 R
- ;设置屏幕滚动
! q. p2 S% a; @% q9 \' P0 x3 q! e0 N - LDA <IRQ_Index3 k( E& y* b6 C
- AND #$01. k% ]: y# X4 z7 F
- BEQ Irq_Scroll_Right! t, V" T" n; g
9 s8 g0 ^6 I+ f9 ^- O2 E- Irq_Scroll_Left
; ^+ x, z+ p$ A3 m% G - BIT PPU_STATUS
' l1 e, ~2 r. [! Z+ a+ B# u Q - LDA <PPU_Scroll_H. E+ X- K+ o2 s4 p. R
- STA PPU_SCROLL: g; d) v$ y0 Z7 j. i& F# R) Y
- STA PPU_SCROLL
5 q6 K0 U' S6 Z - JMP Irq_Scroll_Over) l3 Q! o$ u9 i
-
- p* e% f% ~% f/ V& z o - Irq_Scroll_Right! n( f4 D; {7 d! k, \
- SEC
1 z0 R& F2 _. a) g$ C - SBC <PPU_Scroll_H
- N3 D; e- u$ l! g% J u% u/ |+ v - STA PPU_SCROLL
" J, l* s s; J- b. g0 O - STA PPU_SCROLL+ v7 R0 j5 x0 X7 z S |6 { Y
- Irq_Scroll_Over4 @, ~( W5 v; ~& z
- 3 m0 O; a2 V0 ]/ v' b+ i
- INC <IRQ_Index
' j/ d2 |* \: f: `& I1 q! m% O% B) c -
* a- w" Y p) i7 C1 O/ N7 i! ^- O - LDA <IRQ_Index, {9 P8 F' Y6 F) N$ e
- CMP #142 e# Z( y, m M
- BCC * + 10
' { O! L4 o9 i - LDA #$002 _6 L4 M' l3 t5 ~
- STA M19_IRQ_COUNT_L0 x6 L3 K+ {/ Y$ L
- STA M19_IRQ_COUNT_H
1 i* N5 O& P. E- u( z7 p -
4 ~+ A2 T+ { ^% T% @' S A - IrqProgramEnd# r; K' t8 R. L% j3 D# @
- PLA
* o/ @( P7 S% I& i W - TAY
$ w: w+ W* t# J r8 ]# S+ h3 ?, S - PLA
. a% }# [4 F2 z7 u - TAX
" r6 ?) o' G& J! Z+ R, H& c0 V4 a% b - PLA, C4 t) g3 d, }/ m7 Y0 E
- RTI( Z7 ]. d$ C, K/ u* K
-
6 g$ r0 [' t& o" i, {1 e! `* E - ;==================================================
$ `8 r. {' D" Y7 V - ;中断表
, t# F% [. r0 B7 u - .ORG $FFFA
6 V" c: j& I& C - .WORD NmiProgram, l; ^1 V! Q" r, Q+ j- F o
- .WORD ResetProgram
. ]' e% b7 H. a5 K" A8 v# Q( X; ~ - .WORD IrqProgram
复制代码
+ L- v- p4 m0 t1 {4 N |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|