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