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