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