|
- ;[FC][Mapper19 IRQ], x, f! L( i9 h5 B; Q+ J
- ;FlameCyclone 20230710% z" j+ n9 y2 G" z& g3 L& E+ f* J
$ R# m) q9 I6 v" G% N- ;文件头
/ o( V' s- \. ]4 f# a - ;======================================================================
' b8 u6 Y2 B+ a. S" [- A( w$ n5 z% B - .INESPRG 4 ;16KB PRG 数量* y( I7 q$ Z7 P& a9 n
- .INESCHR 1 ;8KB CHR 数量
" Z- V4 Q7 s5 ~0 h3 l( e0 E - .INESMAP 19 ;mapper 19
8 ?; I4 i* c# f) t( y4 C - .INESMIR 1 ;命名表镜像 0水平 1垂直
3 j2 N1 Z/ a8 ]& W, t - 5 q2 ^5 o9 N! U8 y7 B: O3 u6 d
- ;必要条件4 I% v" G) P6 s! g
- ;1.持有CHR ROM
4 ]+ e. \* L' T5 p; C - ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000. P1 m: K+ b3 ]+ `! z
- ;3.精灵内存(OAM)不为空
6 Y3 D+ p3 S. z. m - 6 W9 a1 \* u6 I' h2 J& x9 k6 C
- ;==================================================
; d M+ Q& T' p1 T% u5 U/ s5 V7 k - ;NES端口常量
' B* ^( e0 n) d: a4 j - PPU_CTRL = $2000 ;PPU控制寄存器
- s6 r1 ]$ u9 M9 k0 {+ W7 G - PPU_MASK = $2001 ;PPU掩码寄存器
! O% w# u8 x2 P - PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位3 O9 A- l9 | v7 l
- PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
* t1 I0 N3 r! I9 f - PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1: J6 t+ y* S3 a2 R8 m. u! q
- PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
% s3 [9 r: A. u- G1 U/ C) [+ c - PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
5 U4 c# x; o+ b9 P, N4 ^5 \ - PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32
h3 V. k# g/ i7 ? - OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
# `" U6 N3 E% h( X1 P! L - APU_STATUS = $4015 ;声音通道切换6 ]' n7 f' P& }% v9 F% V* U
- JOY1_FRAME = $4016 ;手柄1 + 选通
! @. ~6 p5 s6 z6 d" | - JOY2_FRAME = $4017 ;手柄2 + 选通 P' e# g# t$ W" H
- 3 h$ F4 h* F. z% j O" U
- ;==================================================
& h; U9 M6 `% }2 v, g - ;MAPPER 19端口常量- c {* d) L- {8 r
- M19_CHR_0000 = $8000- ^+ v" \) \/ B! S1 j4 N
- M19_CHR_0400 = $8800, V% V" Y3 L. d& W+ n
- M19_CHR_0800 = $9000
/ x" R+ B: _+ F6 a' u" g - M19_CHR_0C00 = $9800
! G: F, L2 V* d4 _1 }9 T" t# G8 y - M19_CHR_1000 = $A000' L* e7 V* ~, G! ~0 \% w
- M19_CHR_1400 = $A8007 b! _- W: o, I! N) Y* @! }$ ?) ?
- M19_CHR_1800 = $B000# Z/ Q; ^6 [2 F7 b% h
- M19_CHR_1C00 = $B800
q: x8 _: q$ {' |1 k - M19_NT_2000 = $C000
* g6 \) g- c0 @5 k; [: ^7 d - M19_NT_2400 = $C800
- Y2 y& {7 w4 o - M19_NT_2800 = $D000
; L9 i) m$ j, g5 n; r! Y; C - M19_NT_2C00 = $D800# z# _; {$ z, |+ ^
- M19_PRG_8000 = $E000
8 k$ s; h) W( ~3 n" M - M19_PRG_A000 = $E800
8 y4 ]5 a0 i ~$ \ d - M19_PRG_C000 = $F000
% X, `) a# T- k - M19_IRQ_COUNT_L = $50008 T. q. X& G+ |" {
- M19_IRQ_COUNT_H = $5800
+ @. K$ ] o, i# z" d/ ?+ S - ; s* O- w( G' C' a! y; i
- ;==================================================' y9 {) U$ k2 P: c; T8 y
- ;程序块配置9 [- }9 T4 h7 l
- BANK_DATA_MASK = $07; E$ M: Q; B8 G7 M, P. v
- ;--------------------------------------------------6 Q3 I8 U R. q/ {
- RESET_BANK = $072 \, X/ l; q2 [
- RESET_ADDR = $FC00
3 g) S% }; p' A6 R( a% i! F
/ z4 C2 [% G; n2 W& @ |# Q- ;==================================================
8 j* o. ?: t* G% F* U - ;图像块配置1 T ~8 h0 X: j) Z
- CHR_DATA_BANK = $08; |2 y! |' ^% W2 n
- $ H9 h5 z; V) I/ @
- ;==================================================
/ o0 G* B1 p3 l) ~# C5 P; z0 F% e! V - ;零页内存地址配置
Y6 z( a7 S1 Y - Use_Ram_Addr = $80. _& R) w8 S$ ^: n: v7 s
- PPU_Ctrl_Buf = Use_Ram_Addr* |) T8 E8 B8 {2 F
- PPU_Msak_Buf = PPU_Ctrl_Buf + $01- _# e6 Y+ U9 Q& U
- PPU_Scroll_H = PPU_Msak_Buf + $01
5 ^% O3 R; j8 B, I: g1 m - PPU_Scroll_V = PPU_Scroll_H + $014 a5 W/ D% ~. V. [/ p1 L
- FC_Data_L = PPU_Scroll_V + $012 t9 j. }1 I0 w o2 }( G5 O9 x: q
- FC_Data_H = FC_Data_L + $01* X7 R# w: g1 c5 N* [8 {) W
- FC_Data_Buf = FC_Data_H + $01% F9 J( L, H3 K
- ;==================================================
5 D) q9 d1 F" v _4 D( U
- ^! @% g5 V# t% L# {& C/ V- GAMEPAD_MERGE_FLAG = $04
/ n9 ^3 A0 t9 r% N' ] - 0 G7 R, x1 Z1 K: u; |/ K
- Gamepad_Keep = FC_Data_Buf + 1, a7 x# @! H5 K0 m3 E
- Gamepad_Once = Gamepad_Keep + 2( m, @. x% u- J
- Gamepad_Temp = Gamepad_Once + 2( F/ c" q7 v4 M, p/ z
- % K# b$ ? d8 Z D
- Gamepad_0_State = Gamepad_Temp + 2
5 r$ W$ `: |% q2 f - Gamepad_1_State = Gamepad_0_State + 1
& S; L' m6 z* @, P0 N( H& M - Gamepad_0_Value = Gamepad_1_State + 1
' u1 a Q7 o- w - Gamepad_1_Value = Gamepad_0_Value + 13 P1 n$ M& Q2 ^+ ]: z# r
- Gamepad_Port_Value = Gamepad_1_Value + 1/ v/ [3 | g( a' D( f4 D
- Gamepad_Merge = Gamepad_Port_Value + 1( s2 O$ M1 J1 B* ~; z
* J- u; i1 S( t) J7 k- ;==================================================
0 j) `: F- T% _: `; v9 K# `( g3 J+ C - IRQ_Index = Gamepad_Merge + $01
$ s6 C) f% d3 a% d f - ;==================================================6 Y: w6 N6 u5 T, D. X2 E
1 `% O* }2 O) Z2 J- F# x- ;CHR图形数据7 ]) i# I) \) d
- ;==================================================
. M3 H' `/ i. ?3 `$ V5 V - .BANK CHR_DATA_BANK. S* l1 s% X! y- T
- .INCBIN "chr_bank/chr_data.chr"* Z+ Q1 M% N2 [
-
# r3 \- V& k+ W - .BANK RESET_BANK & BANK_DATA_MASK
( X" J1 G$ s+ l+ k- K - .ORG RESET_ADDR" n% b" Z7 f6 W% F/ X9 x& y
- 5 Q# l; {! z; K7 C
- ;--------------------------------------------------' y2 o5 C' Q2 g/ F) o
- Attributes_Data
' w- _4 b7 n* d4 i. D; ? - ;命名表属性
; u; P& W' P1 z* `! P+ E - .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
, F! M# R+ d% K1 U - .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA8 B& `: T7 E; g: b: m
- .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA* T# u; T0 Q# l! L. l* m5 `5 _
- .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
% w0 u$ j3 M% n) A) }7 D6 A - ;--------------------------------------------------
6 t- o8 X6 b K# M6 l3 r7 p - ;调色板数据
+ I5 c" k1 z) @1 r9 k* P$ z - Palette_Data
. `) p( ^" Q) g' i - .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F
2 J5 j# Z$ D* l% u - .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
5 q$ f( e+ N: @. s e% m. { - 3 O% S- f+ z u7 e
- ;==================================================) ~4 j* z( G/ I6 {* q
- ;命名表初始化
3 q" K" _! I# J- E, ^ - Init_Name_Table
* Q: s0 N4 v: }6 q4 r# H. N7 Z - LDA #$20
- A% c& x$ x7 Z! g# O - STA PPU_ADDRESS6 ~) ]2 M$ N5 y: l) D; m
- LDA #$00% g& g- Z0 `) f
- STA PPU_ADDRESS
% g Q/ L0 M5 j/ ? - LDA #$00. B' [( ~) @$ `+ p
- LDY #$00
5 U( i9 ?: m; A/ q7 C: I - LDX #$105 `7 ~% S0 d% m+ Q
- Init_Name_Table_Write
+ {7 W4 F3 J% N$ d9 R0 S - STA PPU_DATA
6 u1 O+ P* m, K - INY- F3 t; [% t: M7 s5 s6 l- P
- BNE Init_Name_Table_Write6 A+ } d6 e+ C1 @% l0 I2 v* \
- DEX
9 Q4 T, Z- m, I3 o1 q - BNE Init_Name_Table_Write: K1 u) ~; I; u7 X
- RTS
) r# Z( t& I+ w! M9 ?, D& d - 7 [( f' _4 V+ U) |
- ;==================================================
8 ?7 }) a9 G0 h# \! H3 S# k( G - ;调色板初始化- m/ A( X9 h3 z4 I3 q! w- }' ]
- Init_Palette
5 V' v' o1 { k y* N - BIT PPU_STATUS
2 P* V, Y% O1 F- v - LDA #$3F* ]" P$ ?' _- ~; o) o5 N+ a
- STA PPU_ADDRESS% t9 ]4 j1 g/ q' v6 ~1 j
- LDA #$006 ~0 U# ^$ ?3 O5 `! {, X' f
- STA PPU_ADDRESS- L+ X2 U* l; d$ O+ x% S
- LDX #$000 X& b* x* e6 f
- Init_Palette_Write
1 Q9 N$ z1 u# A$ b0 ~ B - LDA Palette_Data,X
4 W$ ~5 i7 @& G; A& Q - STA PPU_DATA
5 I* A3 f; p8 z) x - INX
4 _( ~& U9 C' \, h w* P - CPX #$20" m" R& M) B( k3 [
- BCC Init_Palette_Write
2 N+ R( M% C4 v" W: D - RTS
, V4 h- W9 |8 c! E/ v, f - ! i1 Y# I" `4 \
- ;==================================================, j; N: S3 R2 [
- ;设置命名表属性3 ^/ x$ G7 ~6 y$ r
- Init_NameTable_Attributes4 A. ]& r# o: I+ w* q/ c
- BIT PPU_STATUS
8 n9 g& x3 F1 y' N5 V - LDA #$23
3 n6 Y8 r( x w$ ]3 w; @- z C - STA PPU_ADDRESS
; M* R1 b* x+ f. F' ?7 _ m. B - LDA #$C0- [0 z! K( T! l2 {
- STA PPU_ADDRESS
2 \" V, K2 m7 q( F& @ - LDX #$00
: l0 z/ S6 w7 V! h6 x0 u - Init_NameTable_Attributes_Write
& |3 @# y2 f# _& U5 N1 { - LDA Attributes_Data,X
) U; i9 \$ H& J& ] - STA PPU_DATA
: C9 L: V. m$ e/ v - INX
: O* P5 p3 N, Y' v. p; {, e2 T - CPX #$40; u3 Z. k U( P. H$ `
- BCC Init_NameTable_Attributes_Write
; J8 A( @% L3 V/ D1 ^# [ - RTS9 l; f0 {; d% z( R" E
$ w/ h! k3 G% S8 A# _- ;==================================================; b; J( G' {9 ~5 \2 e7 P( P8 x
- ;初始化命名表文本8 n2 V9 T" G$ \
- Init_Name_Table_Text
/ [: p# @2 o3 ~" j% i0 E - BIT PPU_STATUS
3 Q9 Q; S- G. d2 o - LDA #$20
/ I0 O z7 n) @: O5 h: w - STA PPU_ADDRESS
) m, V4 B' l! ]8 ]3 n9 q - LDA #$00
0 Y6 p0 j, O/ { - STA PPU_ADDRESS
l# C2 j# J6 G- E% R - LDA #$00# M! i/ ]3 M1 ^* J" _
- STA FC_Data_Buf- Z# j) e2 [3 }- R
- LDY #30
, ]+ ^/ Q& d, j3 @& w - Init_Name_Table_Text_Write4 s- w4 l& _( L$ F$ H
- LDX #32
$ j2 C; N9 Q. S8 t - Init_Name_Table_Text_Write_Char
6 \/ t) |/ g. I7 N' o8 z - LDA #'0'% T8 L- m! k% _ F; K" W: ~
- CLC
! G& ~3 `: m! } - ADC FC_Data_Buf
. Z5 d. W2 {9 M; g) s8 H0 ]9 v - STA PPU_DATA
: c/ X% u2 C9 a2 l3 B: v' T - DEX+ M' ?, X- ~6 j
- LDA #$14+ C2 Z+ a9 |" Y7 a: j
- STA PPU_DATA3 m: y4 [ {2 v6 a+ t7 B& Z1 \
- DEX7 k0 H9 K$ i$ f
- BNE Init_Name_Table_Text_Write_Char0 L' t( C! V; m! `, c* q, w* l
- INC FC_Data_Buf
' j5 T- p7 l/ n$ a# E6 ?& s - DEY& B0 ]* r, F3 g" P& i, r" R4 w# ~% D* v
- BNE Init_Name_Table_Text_Write
9 Q' f4 D6 |! U; L$ m( C - RTS8 N% A3 T% y; O3 p/ e6 o
- 6 V2 g1 C9 C. D& T0 M" E. M$ v
- ;==============================: z$ u7 R5 G" Q! K& p
- Init_OAM_Ram;初始化精灵内存) T5 _8 T8 \" W8 ]+ {3 `$ A
- LDX #$002 S! F9 ?& k( M
- LDA #$00
7 A3 o o; u# n - STA PPU_OAM_ADDR
6 X. j% s, \. u$ z4 X - LDA #$F8/ D7 b( h1 ]' @& F/ W
- Init_OAM_Ram_Write! M: V2 i& k; P6 P
- STA PPU_OAM_DATA0 `7 u5 r( d) h
- INX
6 m; \1 f& J a, V( f L! Y - BNE Init_OAM_Ram_Write F% c9 Q. j5 `- Z2 [
- RTS
. S4 L6 ~& ?+ X$ p0 r - ) O, R0 ]# i( n+ @1 [
- GamepadProcess;手柄处理
: A# q: h/ g% } - JSR GamepadDatacan
' P, P3 H: B7 Z% S/ W - LDA <Gamepad_0_Value
5 U- H0 y6 o4 j6 L! W/ z6 ^: R - STA <Gamepad_0_State( m: x# _$ `. C( {
- LDA <Gamepad_1_Value
4 _2 k! \! s1 ]+ E) a - STA <Gamepad_1_State
" G! {8 V! }" k8 W2 M: F - JSR GamepadDatacan
: I* f; w- a& ^ - LDX #$01
* H; x9 V9 i A0 a- U$ p - GamepadMergeCheck;合并手柄输入检查
" ~, u, U6 q9 | - LDA <Gamepad_0_Value,X9 E- U2 p+ M7 z: |& @8 C. Z: O
- CMP <Gamepad_0_State,X" b/ d4 x8 R) F7 ^- E, O
- BEQ GamepadMergeInput. i* L6 d7 j6 t9 Y. @* o
- LDA <Gamepad_Temp,X
& e) y" X/ y3 U4 ~6 C - STA <Gamepad_0_Value,X: w; H0 y6 ` p E% M q
- GamepadMergeInput;合并手柄输入
9 L* a$ ~: } B5 c4 j' k) A' h - DEX- j% C& ]; T% U' i
- BPL GamepadMergeCheck3 o9 R: F! G0 r9 d: v+ v, R7 B( L
- LDA <Gamepad_Merge
. H; p9 {: k$ i- \% s& ^1 Q - AND #GAMEPAD_MERGE_FLAG
/ N8 y P/ i) S- i+ v. o - BNE GamepadStateProcess O! I/ x" D+ P7 E y
- LDA <Gamepad_0_Value r+ m8 B0 b$ }# J$ f# t
- ORA <Gamepad_1_Value1 ]7 r: r! b% v
- STA <Gamepad_0_Value$ O% b5 k' }/ z$ L
- GamepadStateProcess;手柄状态处理
$ z3 K: j. x# H: M - LDX #$01
6 r. T9 V) c$ ]" j4 `) m& E - GamepadStateSave;手柄状态保存6 E- H0 S+ l7 S% @, m
- LDA <Gamepad_0_Value,X
! p( A( ^: ^' a0 t - TAY
; h" X4 W$ a4 ?7 i: o1 ?9 ` Z6 j - EOR <Gamepad_Temp,X
' \' {. r( }! g5 ~ - AND <Gamepad_0_Value,X
! \4 C! d. U" }2 p; q' Z: Q - STA <Gamepad_Once,X/ N) b: G5 K; {
- STY <Gamepad_Keep,X
' G V/ q, D% U - STY <Gamepad_Temp,X! i; l# W" O. S5 ]- G
- DEX* u# K0 \2 B4 t9 r
- BPL GamepadStateSave7 U$ q2 Z) E1 [! g5 v& x
- RTS
* W: j+ s1 f' U/ `7 U8 R# w, [) O - O8 M# q/ |" h/ L) D
- GamepadDatacan;手柄数据扫描( P6 r! K! W6 M. M; d J ^
- LDX #$01
8 b8 ]) D3 v/ h" z2 G( q0 V' u3 H - STX $4016
" e! i+ h! U9 E4 t4 I8 S( V - DEX4 ~" t4 H# }* M5 F2 U0 j1 K% j
- STX $4016& S$ T( @9 H1 b# G
- LDY #$08
% X% p% ~! x& O* C" q4 D# } - GamepadPortScan;手柄端口扫描
1 M X$ a; J8 Q j$ m& {4 z - LDA $4016
& Q# O+ S1 D) n O - STA <Gamepad_Port_Value
m* k+ L! E5 X5 x - LSR A2 \, u6 V3 f* x# Q0 N9 x' f" o! H
- ORA <Gamepad_Port_Value
# F# G) r; d2 u9 M - LSR A% X1 B2 X. r( |7 {7 q6 ~8 Z
- ROL <Gamepad_0_Value6 |' Y" v* }( Q; l+ n
- LDA $4017
8 ?- z- ?9 t5 n0 p; T; g( X3 U" d - STA <Gamepad_Port_Value: o& W; Z+ O8 O$ p
- LSR A
: w0 V( T# K/ M. H - ORA <Gamepad_Port_Value! z( W( o9 A9 f! {! Z: d! ?
- LSR A
0 _6 t/ S$ M1 a6 ? - ROL <Gamepad_1_Value
! C/ o' T7 u' k4 \ - DEY
: w/ T( K3 r1 Y+ V - BNE GamepadPortScan7 ^) ^8 M7 [. ?
- RTS: M* z7 x) V0 g$ z
-
^2 j" w6 a. A! J2 f( X4 U7 A - ;==================================================( Y: h; p$ K- f, A
- ;PPU处理* B2 w% N4 f1 F5 [3 g p
- PPU_Process4 `- k: J! T- H8 E& m
- LDA #$00- I# i$ M3 Z7 @$ B
- STA PPU_MASK: X+ m; |. X$ O5 R$ M. e5 V5 W6 Q
-
: \) N' k$ ~1 j T - BIT PPU_STATUS t! L! Z# P+ l X e0 K- F) J/ n
- LDA #$20% L$ D8 R* A. L7 @
- STA PPU_ADDRESS
$ a% J$ ~8 ^2 x8 u" T5 E - LDA #$00
( {/ C8 V. h+ |: z - STA PPU_ADDRESS0 O% \) ]! X5 c+ {/ M4 p2 D- J& \- g
-
' a0 y q/ A: k1 J' |9 Y+ R$ ` - STA PPU_SCROLL" e" y9 ^& z2 S/ S7 ~4 U7 ^
- STA PPU_SCROLL
5 S8 V1 }8 _6 V - ; t- _) E9 c( [7 T
- LDA PPU_Msak_Buf
4 P7 g1 Q3 R6 k2 O$ i% _2 w - STA PPU_MASK$ m" u& p& v) W- S# c% V+ C3 P
- . z" v/ i8 f4 ~: u4 D# e3 A
- RTS
6 p- P" W2 y7 B -
. v& A- `2 }4 N/ N& g! e - ;==============================9 E$ _ L5 o u6 W/ ~5 v/ q
- Time_For_Vblank;延时等待9 B* R* q7 d4 `1 P. y. c* a; I1 V9 i
- LDA PPU_STATUS) G5 w& \7 _7 T" d+ j
- BPL Time_For_Vblank
. L2 Y) w) S8 k$ }+ l9 x - RTS
9 y. ^5 a: P9 c) w. ~" J -
: X8 \# C$ ^/ ^# B M' v. |4 q - ;==============================
s" V' W# |3 K0 A. r/ c - ;初始化MAPPER19* ^1 ]" L" N" U; K
- Init_Mapper19
2 \9 s( {8 K# P - LDA #$00- _) S) v% X" W5 g8 ~/ T
- STA M19_CHR_0000# j z, ?/ D3 y0 D' A# ~! ~ @- L
- LDA #$01 L( y, J7 y) k2 m. _& N
- STA M19_CHR_0400( T8 i4 \- s( a* F
- LDA #$02
% N- L0 `& b* @6 Q - STA M19_CHR_0800
8 s5 Q" w$ I5 z; }9 D4 n. x - LDA #$038 N% I6 ~5 ^$ o! c
- STA M19_CHR_0C001 `0 n/ f9 x- s" R% R! c) `7 \
- LDA #$048 E4 E, ?3 x" I! V% Y- p+ { R
- STA M19_CHR_1000
7 p* H0 ?8 j1 V) i+ \ - LDA #$052 `- ^, K9 I9 c# R! _
- STA M19_CHR_1400
1 h S1 u( \/ u( ]+ V4 U& A ]/ J - LDA #$06) }" |0 ]: o4 @* ~
- STA M19_CHR_1800. A0 E/ p) z* g5 i
- LDA #$079 \4 K/ l9 P% L& S# x& h
- STA M19_CHR_1C00
a/ B' U8 V( Y$ y% ]8 p -
! [* @2 u% F- O, a) _. N - ;禁用IRQ
9 h: q# a4 d$ \0 C - LDA M19_IRQ_COUNT_H
% t! @* D: n r4 |. a6 T - AND #$7F
% x1 t' U1 w( m, K - STA M19_IRQ_COUNT_H
: c" w( ^: N7 } R - |& I8 O2 Y a1 w' ?
- ;命名表
1 q4 W) {$ P, `1 ^% |# L - LDA #$E0
0 _6 s- u! B8 |& o2 n+ O/ o2 W - STA M19_NT_2000! s" G6 M: o& M" }8 O& j
- STA M19_NT_2400
Q+ n6 J: I8 M, f -
- O: r9 ]( E3 g- p& Y8 q- @/ q - ;命名表
X% C- } d! B. Q2 t - LDA #$E1
' Y$ O* i1 t* B3 L - STA M19_NT_2800+ r. h) r: z& U/ x# k; ~
- STA M19_NT_2C00$ g/ n" m/ q2 ~# G$ G7 }/ U
-
9 _5 Q% ^5 k0 t' U - RTS
- U! e; a# p+ Y9 p5 l -
+ C! u+ E2 d+ r' x - ;==================================================
8 L/ |5 R* F2 t$ l - ;重置中断处理2 w7 U# @+ A+ l9 Q; Y$ z
- ResetProgram+ G* j/ s6 P' {; e
- SEI
3 D( t/ v) E. g- P - CLD
% s! M9 s @+ A* e" f! `& _ - LDA #$00
, }6 Z0 |3 Z+ y8 ~4 Q! G( T: V - STA PPU_CTRL& ?) x4 O$ k1 y
- STA PPU_MASK
) F3 M" e" i0 ~% Y. m+ A - STA PPU_STATUS
, n6 V% _4 `" _/ @+ r+ B - STA JOY2_FRAME( j! s& f: `5 l+ @( r+ v: e5 D) ~
- STA APU_STATUS6 t+ Q* C/ W4 } Q: W2 d0 Z% _
- 1 o+ J% c, }% n/ w# X( _
- LDA #$C0
5 F5 Z" ?7 x, C! Z- Z) } - STA JOY2_FRAME# D4 a0 g- Z4 k0 y0 w
- % _. l, X S( o1 A( Z# g
- ;等待vblank
: ]/ s$ K' C* w$ T& v$ x - LDX #$02
8 y! _+ Q) B' D9 i - Vblank_Wait_19 w: C; s0 w8 X, A. D" K- C6 [
- BIT PPU_STATUS: F; @0 {8 z# B
- BPL Vblank_Wait_16 S, n5 p6 j+ l/ w; v# |
- Vblank_Wait_2- s% T" q8 D, k$ P( K" t3 r
- BIT PPU_STATUS; t* ]( c" S3 D, _% h
- BMI Vblank_Wait_21 v( l6 e+ ^ T" `$ e% _( v
- DEX
0 M6 j/ S& m& B6 x - BNE Vblank_Wait_1) B" A* U/ S3 H6 d+ b1 z
- 2 g" i) u# Q/ P- C. ^
- LDX #$FF
4 b, `- a; Y2 L8 ]! A - TXS/ O1 P# `3 B$ k3 T- t
-
. L% Y, ]+ ^) L% Z2 g - ;初始化MAPPER19
% q; A! E7 |' Z6 l4 g - JSR Init_Mapper19; S/ v, I& a {! F
- : L' b* r% k1 c8 a) m
- ;==============================+ _. o1 a% A0 ^$ H- x2 F
- ;RAM初始化3 |$ r! u: W" g$ p
- Nes_Ram_Init
; o. Q8 j" e5 M, }. u - LDY #$00% c6 @& W% H: t+ O
- LDX #$08
) x8 K0 u% J1 N - LDA #$00 q1 O; u& z ~9 v; E/ H) ~; \* n
- STA <$00
+ E! {! P5 d# K - STA <$01
/ p! R, c; a# r& ?, D# b; B/ T - Nes_Ram_Init_Write( J* G3 m9 |" J
- STA [$00],Y
% A2 Z3 K) @/ P% U# ] - INY( `6 C. q" `( G k
- BNE Nes_Ram_Init_Write+ _" y6 z' A: q" T# r3 k+ Y9 l% Q2 V
- INC <$01
r7 y. h! j9 C5 [" n - DEX
4 w& I5 @2 E% C2 P' j& b - BNE Nes_Ram_Init_Write
- C/ D; z( |- i7 s4 \/ }) z - : ?" U! x3 o6 Z
- ;初始化命名表
" {% j. F4 z1 b O( B3 C; h" G: K - JSR Init_Name_Table6 n2 k2 m- o4 X" Q
- 6 S% G+ n2 @- J4 P( a
- ;初始化调色板* W }( r' \6 b' D( M% H! p; z
- JSR Init_Palette
, j4 d, L+ {5 D- R0 D# F: z - 6 t+ b+ {& u, Q, `( o. M! o
- ;初始化命名表属性
2 ]! A" y- C# j3 v7 a& g- u* h7 A - JSR Init_NameTable_Attributes
! j: b( \& \% \" D -
" `% Q5 B+ Y O% g - ;初始化精灵内存$ }. @+ ?, Q% |: }; d N* D$ J
- JSR Init_OAM_Ram. ~, o8 Q8 Q5 F
-
0 [! k: w2 @6 Q - ;在屏幕上写点东西
" b; Z4 g# G ?+ j4 E - JSR Init_Name_Table_Text2 v2 I$ S- k$ r, B5 j& G
- & F; q) U& b+ K$ b
- JSR Time_For_Vblank' J1 ~/ H. ]+ v& d
- ;开启PPU控制
0 s$ f' }1 j3 { - LDA #$A8
{, G+ O. r" C - STA PPU_Ctrl_Buf" K; Z6 {1 h8 E7 `* ?0 @, i! S
- STA PPU_CTRL0 d# e) h; C5 r4 U2 d5 A7 v
-
5 Q1 A0 |- w8 u4 h - ;开启PPU显示9 ~+ `$ h) m j. _1 ~2 M
- LDA #$1E
$ Q' g/ v1 C' x4 e) [- }1 p - STA PPU_Msak_Buf$ I9 i% E: b/ Y3 S/ A9 D
- ) u/ C5 q4 } X+ G
- CLI# K& I/ `$ H; `7 e; u
- JMP Loop
& d0 p9 b. t4 I. H5 o! T8 H - : Q3 Z9 D! W& ^
- ;==============================
& d6 S5 l, p9 t$ g - ;死循环, 等待NMI中断
3 X' N" ?2 ~; R9 E) P( r - Loop
4 m( [5 f+ E0 v! v; @: _ v) r/ @ - JMP Loop
% K( [2 Z( |& X
, Y' U! z5 H Z: I- G$ L- ;每行扫描线1789772.5Hz / (262 * 59.94) = 113.967. _( q* l# U9 r) R
- 1 e) _! d1 l% Q9 v+ x$ [
- ;BEGIN_LINE_CYCLES_START = 32768 - ((260 - 240 + 16) * 113.967)& d* m4 s" f/ i: g7 L
- BEGIN_LINE_CYCLES_START = 32768 - (4103)
* I" h; m& K* M: y" k3 A7 w - ;==================================================+ Q, G1 P$ ?/ g+ s9 p) ~1 a
- ;NMI中断处理4 w3 U( {8 \) J" `& F
- NmiProgram7 x( [. K1 c$ n9 u
- PHA. W7 b2 b. V: o6 x j2 V. p7 E. x
- TXA" y) w! r2 m% t* T4 h! Q t5 o
- PHA
1 u- p$ k# {1 o p5 b0 D9 B - TYA
+ H. N4 L. W/ S6 ^7 Y1 } - PHA2 O/ q, [9 H+ Y- G
- ' w( e+ U. _$ E& V% _
- BIT PPU_STATUS
4 d3 c7 y9 r0 k3 o& g! ^4 t -
f9 A- n% s7 p; t# r# } - LDA #$00
w+ a+ e" _+ m( m1 [, ] - STA IRQ_Index- ]6 M9 ^7 e) g, V. l/ p: ]
-
5 Z- L7 u- F2 }. E* c1 `0 e - ;Mapper 19 的IRQ是基于CPU周期的, 为了IRQ稳定, 首先开启IRQ, 避免PPU处理周期不稳定导致IRQ抖动
2 s* _6 u" l0 y u1 o2 ~ - LDA #LOW(BEGIN_LINE_CYCLES_START)
. m2 S: z" ~( m5 a9 ], v+ {9 p& A - STA M19_IRQ_COUNT_L
3 d( e9 I) w* Z - LDA #HIGH(BEGIN_LINE_CYCLES_START)
) R r$ ~& ~7 I - ORA #$80
8 ]& [( g. A" M J% D - STA M19_IRQ_COUNT_H
N2 z' g3 D8 J. D: Y, O8 ~ ~ - CLI
3 J5 g4 s5 l- @5 W/ Q0 h( c$ T3 X - 1 i; `9 m) A9 K8 Q) b) D# |$ J$ Q" @
- ;关闭PPU控制
7 h+ k- V6 P* | - LDA #$00- H0 Q! R3 [) D- q9 K
- STA PPU_CTRL6 w' n* F/ i, u- D5 P: m' B2 y
-
% [2 N6 ^0 V- i- e7 L) T - ;处理PPU
! T3 O; T+ i- R1 D* j6 A! s# E/ I - JSR PPU_Process, }4 {/ x' T( F! d. G
-
8 x* q) B3 X. W! ]" _ - ;开启PPU控制8 r/ x( A" `; `$ E3 a2 K
- LDA PPU_Ctrl_Buf
" T4 h) b% }: K! m - STA PPU_CTRL
, a% _, t( C$ L! f" q# y -
! g- U7 l) {- V. D2 v - ;手柄处理
; T6 F! e+ L ^& N - JSR GamepadProcess
6 c* m% k% d0 A& j# ?. H% J -
, f% J* i& C8 I8 ~ - LDA #$00
1 x9 X, S9 R3 _+ U' D% J - STA IRQ_Index
& T7 u6 \& O. f! m - 0 J) g/ T$ t j8 ?
- PLA
3 P, J; Y8 G; F* e, b9 w - TAY z- e* w: @7 D! w2 m: ?1 {& l3 @
- PLA' R* h" p1 |9 \8 B
- TAX
# O8 W- g) ^' ~' _ - PLA
) `6 H$ F c5 c8 I4 J; S* B - RTI# j u6 Q7 x4 k5 P( ^' N4 F
- 8 F' d: K! d3 o
- ;每行扫描线113.67( m1 c+ x& h. [1 a, E6 y5 o
- ;BEGIN_LINE_CYCLES = 32768 - (16 * 113.967)) M& B% N7 U5 E. M1 D
- BEGIN_LINE_CYCLES = 32768 - (1824) + 27 + 7
8 B% v. y7 q" D1 T) x - ;==================================================
: l) Q" r4 P6 L# u% g* l8 l! l3 K8 s - ;IRQ中断处理
* }% P! _( M+ ^( z; Q - IrqProgram
8 Z+ Y& M( q5 `3 c3 H1 V# r$ K8 P - PHA
, _5 [ {2 ]. ^0 `! K6 T. Z, g - TXA
& ^# z1 P: G$ T+ t$ `4 s - PHA
) E6 C; P: H K8 t# S* r- M - TYA# Z/ x2 o: W/ X3 x2 u. J" Q
- PHA1 k6 K- [. u, B, e! o$ l }
-
7 w' q2 G; l$ ]3 |- @, ]6 T - ;16条扫描线后触发IRQ
) l4 r0 J, o% k, L, u3 K - LDA #LOW(BEGIN_LINE_CYCLES)" t# P3 X! E. ] I! @
- STA M19_IRQ_COUNT_L3 Q- d/ }5 d3 s0 J/ a
- LDA #HIGH(BEGIN_LINE_CYCLES)
) R/ E) A5 t/ g( I - ORA #$805 a0 N: @6 s' N* ^7 O) A
- STA M19_IRQ_COUNT_H2 |5 |2 A' [4 ~, X7 T" g
-
! v1 F6 M' y& S d8 Y5 x4 A6 Y! b - LDA <IRQ_Index
$ u" e3 S8 M2 j. k" K9 z - BNE * + 43 @# @; k& \4 y) T; y7 n3 l
- INC <PPU_Scroll_H5 O# Q: P# v" O1 \ v3 j
- 3 j5 j Y) M0 u
- ;设置屏幕滚动& |* _2 K" @' R5 |
- LDA <IRQ_Index
* [! A% X( _* q* K - AND #$01; [1 J' V/ V5 O+ O5 ~
- BEQ Irq_Scroll_Right
% K- ^7 G/ r" i! P- c) N
+ A0 B. w4 _2 N% V1 o `- Irq_Scroll_Left7 l9 e- p( F4 `' b. z$ w* [
- BIT PPU_STATUS
5 A6 a& b$ T' a; Y) f& S1 s4 t - LDA <PPU_Scroll_H
6 ~3 S/ t' H! s. @. R2 a - STA PPU_SCROLL
) _; ?7 T& x% g$ b9 t2 ` - STA PPU_SCROLL5 p/ ]1 |: @! ^# H1 N- f& {" J
- JMP Irq_Scroll_Over0 {1 j+ `) Z$ t
-
; T) W! a" C! q/ F: @/ K# W* B - Irq_Scroll_Right
. E+ y2 U- X/ \* u - SEC
3 \0 J* q! ?/ M$ p. ~8 p! n - SBC <PPU_Scroll_H
" S, l& m' C+ T( \5 j - STA PPU_SCROLL/ l+ d, @( I& u( h
- STA PPU_SCROLL4 U1 ] Q4 H; \5 t# ]0 j/ Q. L
- Irq_Scroll_Over
) q- \+ I, P" N$ }$ J$ A3 B9 L - : n+ t' d+ x+ J k3 `7 K
- INC <IRQ_Index5 G- [/ V8 B4 C
-
) i) ?5 ~5 z5 C3 j* ] - LDA <IRQ_Index, J$ ^& o2 I4 f, Z+ Q9 n
- CMP #14# }& D: [% p( u4 M4 k
- BCC * + 10
. V4 z! O) j. V* ` - LDA #$00, _; U; w. |5 u+ Q- _
- STA M19_IRQ_COUNT_L
) U+ b0 q9 |/ @6 y1 \5 b - STA M19_IRQ_COUNT_H0 y2 y8 M f7 R, M1 a) s
- % F# y. j, O& p- ?9 f' t" `& g: K
- IrqProgramEnd
+ Z& ?: p6 C! l, k* Z - PLA$ a8 a9 b% p! e1 L
- TAY2 L. r0 ~" X- ]6 U" k+ _
- PLA
+ X/ O; P% f: d* [" a - TAX# B3 Y, {, y/ ? W
- PLA
+ ^% d; z/ L, B9 o - RTI p1 K# \0 U9 |# Z3 F
-
# d- V$ S7 E! I/ ~6 | - ;==================================================0 ^" w. c3 H ~
- ;中断表
5 P4 _( a5 w# y0 _+ V - .ORG $FFFA- m U _' ^3 ~; E2 X* `
- .WORD NmiProgram! M& x) w c, n& u
- .WORD ResetProgram
2 B9 ~8 q* f5 W% x - .WORD IrqProgram
复制代码
9 v" n7 N. C) w; }8 F |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|