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