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