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