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