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