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