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