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