|
- ;[FC音乐][MMC5 IRQ]$ I) Y) D4 }* s) a
- ;FlameCyclone 202307107 g6 d4 r; H( i5 O5 u, ~- j
- & Y+ F3 N8 ?, W) n* P5 C+ t) V/ U
- ;文件头- E! L0 A$ K/ I3 m' a
- ;======================================================================
& h2 j0 @* [9 N - .INESPRG 4 ;16KB PRG 数量
) \6 K9 Y. q9 A% ~7 p7 O - .INESCHR 1 ;8KB CHR 数量
6 {* k) }0 e) ^ - .INESMAP 5 ;mapper 5# P. [/ h' L; |4 [; ^& }& L
- .INESMIR 1 ;命名表镜像 0水平 1垂直
0 N& u/ @$ r' o7 y
w e5 W, w* ?2 ^1 K% l- ;必要条件
" D# {! L# S% g$ I - ;1.持有CHR ROM
6 O* ?* A% v* {6 W7 k6 j3 k - ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000 K7 L/ @, d0 q8 X, K' M
- ;3.精灵内存(OAM)不为空- h1 |1 D( w2 R( B* I
% y% k. s1 e2 E' W- ;==================================================3 J3 n! k5 M9 L
- ;NES端口常量( c. p. B* E& W
- PPU_CTRL = $2000 ;PPU控制寄存器5 p% Q7 Z( N% c
- PPU_MASK = $2001 ;PPU掩码寄存器
0 Q s. H$ R ?2 k T9 @, w$ u - PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位8 |: h, d) y: S% k8 T4 T
- PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
5 h0 g- k& h# [% u( |. S$ P - PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加18 {+ R0 v; s. [% v% f* n/ Q
- PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
4 T' [/ g) I1 \$ U: ]& r$ J9 X - PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加4 \8 U/ G v |. K
- PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 ) D+ }3 e0 @( }
- OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
6 U8 l8 z' X! x% N" L$ r; G/ h0 u8 X - APU_STATUS = $4015 ;声音通道切换
3 K S$ o0 x) M& W% q - JOY1_FRAME = $4016 ;手柄1 + 选通/ ]' h! ~2 L. N5 Q6 e, W) k
- JOY2_FRAME = $4017 ;手柄2 + 选通! A4 y p8 s7 z) ]0 E! \2 g! @
. H/ P" o" h# y7 k, D J; U. W- ;==================================================7 n7 e: b. z# w
- ;MMC5端口常量
6 `$ ^) d3 k) e6 g% n' J - MMC5_PRG_MODE = $5100; 0: 32KB 1: 16KB * 2 2: 16KB + 8 * 2 3: 8*4# T' ` U- p' ~& s7 z8 L! J
- MMC5_CHR_MODE = $5101; 0: 8KB 1: 4KB * 2 2: 2KB * 4 3: 1KB * 8* s. O. A: a! d1 w* @& n+ b9 J
- MMC5_PRG_RAM_PROTECT_1 = $5102;
) o) `* P( {6 p* { - MMC5_PRG_RAM_PROTECT_2 = $5103;0 S+ ~# W" i9 x* O" u# k1 Q* j
- MMC5_EX_RAM_MODE = $5104; 0: Write Only 1: Write Only 2: RW 3:R
; b( n3 U6 g2 l, P: u5 ~3 [/ v - MMC5_NT_MAPPING = $5105;
2 T2 q: v7 S4 Y - MMC5_FILL_MODE_TILE = $51067 A9 H. i- g& q! R) h
- MMC5_FILL_MODE_COLOR = $5107( f8 L- e6 v3 f
# J K( O. A6 p3 \! ]- MMC5_PRG_BANK_6000 = $5113
, [6 `2 u( z9 q4 Q1 E8 W - MMC5_PRG_BANK_8000 = $5114( \4 K a6 h0 t
- MMC5_PRG_BANK_A000 = $51150 j% T, P. }- R$ W3 \0 S
- MMC5_PRG_BANK_C000 = $5116
6 S5 M0 W+ B% ]" O - MMC5_PRG_BANK_E000 = $5117
: t& ?! G5 S& H7 a3 m$ x - ) a! q- v- A, ]2 C& h7 ~2 }7 p& _
- MMC5_CHR_BANK_0000 = $5120* ~8 V! b. j) A. [- [+ I" b
- MMC5_CHR_BANK_0400 = $5121; w2 ?: n( A9 l
- MMC5_CHR_BANK_0800 = $5122) v4 l+ Y A) L
- MMC5_CHR_BANK_0C00 = $5123
* {/ N+ H' @! f* \$ \; d - MMC5_CHR_BANK_1000 = $5124
t# B9 K. g- `( L; A - MMC5_CHR_BANK_1400 = $5125" i. P7 Y* A8 |; U# E0 v( D
- MMC5_CHR_BANK_1800 = $5126
% Q2 p% |4 m* N v) z - MMC5_CHR_BANK_1C00 = $5127
; ]( E0 Q, r8 e4 t
9 G" \# m9 q: q P& \- MMC5_CHR_BANK_0000_1000 = $5128
7 f5 C1 S' M! B$ C" I7 v/ P0 H" d - MMC5_CHR_BANK_0400_1400 = $5129% h& T8 M, W# b& V
- MMC5_CHR_BANK_0800_1800 = $512A
/ x' y: Q' e m3 |' t- S: S8 [$ L v# H - MMC5_CHR_BANK_0C00_1C00 = $512B
) E- x' w7 y& k7 X! x! [$ \ -
1 M$ l, m/ z6 o& u- I3 e* H - MMC5_CHR_BANK_UPPER = $51301 X4 O5 o- I3 y: w
- MMC5_V_SPLIT_MODE = $5200
) W" c8 ]; v7 m* y - MMC5_V_SPLIT_SCROLL = $5201! C) t% l; O, z
- MMC5_V_SPLIT_BANK = $5202
* Q# m: o5 ]6 z -
) K9 k. X8 |" F [; y8 @ - MMC5_IRQ_SCAN_CMP = $5203
+ p0 S) O/ Y9 ?, O2 \" E6 t - MMC5_IRQ_STATUS = $5204
) V* [, T% L2 _) p# k u5 b - MMC5_MULTIPLIER_A = $5205
( w4 C1 F& W& Y9 q- G' q - MMC5_MULTIPLIER_B = $5206
8 X/ ?7 c% o" n( }# E h8 h -
8 c9 C3 E M. D+ D5 j5 K+ R Z - MMC5A_CL3_SL3_DATA = $5207
* z3 r4 q8 t- q! X5 n% J - MMC5A_CL3_SL3_STATUS = $5208) r2 D0 R1 K8 h; e
- MMC5A_IRQ_TIMER_LSB = $52099 M! ` k& }8 V& f7 K+ b3 M+ T, K8 N2 m
- MMC5A_IRQ_TIMER_MSB = $520A. a9 l& e% t& P+ q7 C
& c5 r1 [ F9 { x- m* Z- ;==================================================
: p: c% M. H4 ? - ;程序块配置
& y# c0 t: U' } - BANK_DATA_MASK = $07
/ p9 V( T# G: A" A- K! ] - ;--------------------------------------------------
; ?" M( @2 N/ k! {/ S- }$ w - RESET_BANK = $07
9 M$ U+ b$ V; G0 y* n- ` - RESET_ADDR = $FC00
7 m( P& F% @9 k7 u2 E
' O }! m( q. N# i1 p- ;==================================================
/ v5 v5 R* v; l+ ?5 A9 Z - ;图像块配置
% M8 P6 _ {' y( @/ Q! | - CHR_DATA_BANK = $083 \5 `" l& V% W8 u6 c+ V, _
- " `! U) P a9 W3 n! q/ z
- ;==================================================
. H1 D7 J1 ?# W! p" ] - ;零页内存地址配置
+ E# M4 a r* }3 X - Use_Ram_Addr = $80
- {' L, l, {# I$ G# F1 l2 c - PPU_Ctrl_Buf = Use_Ram_Addr: e" i* }( G& ]0 m1 Z
- PPU_Msak_Buf = PPU_Ctrl_Buf + $01
" G2 O' p1 d$ M" w - PPU_Scroll_H = PPU_Msak_Buf + $01+ U7 e1 l* G: L* s5 s
- PPU_Scroll_V = PPU_Scroll_H + $01
& [; b# Y* r+ J1 I) I - FC_Data_L = PPU_Scroll_V + $01+ Q$ @. {5 w' p
- FC_Data_H = FC_Data_L + $01$ O, R) \7 B$ o& x- `
- FC_Data_Buf = FC_Data_H + $01
0 D3 e7 V" t+ d$ a, N9 I& r! F+ v - ;==================================================
$ V( Q; c1 M) R+ f+ q( C - ! M5 s: g8 s! W" @( p: v
- GAMEPAD_MERGE_FLAG = $049 @ y7 h ~- O! F* N
, `/ c/ p. [7 u! P7 ~6 T- Gamepad_Keep = FC_Data_Buf + 1
+ |! R$ X) u% K. b0 G# ?$ g, ^ - Gamepad_Once = Gamepad_Keep + 2( e0 d8 O6 ]) K
- Gamepad_Temp = Gamepad_Once + 2+ w) s" Q5 k1 D( C2 ]' o) w
- ; p" ?/ T6 }+ t% N q$ H0 y
- Gamepad_0_State = Gamepad_Temp + 2% w( l) z2 K% Z* n& l
- Gamepad_1_State = Gamepad_0_State + 1* l3 Z2 c% B3 f9 K
- Gamepad_0_Value = Gamepad_1_State + 1
% |: L: |. ] U& J% p2 b4 M- t3 w - Gamepad_1_Value = Gamepad_0_Value + 1" j; L) e% i9 z; A7 ~6 N% U5 @
- Gamepad_Port_Value = Gamepad_1_Value + 1
1 @2 _- R8 |" O4 x1 K - Gamepad_Merge = Gamepad_Port_Value + 1
: h5 E2 ~5 Z$ v - 9 V, T6 j h- R5 N5 c+ d
- ;==================================================/ c: g0 X3 ^4 f& m5 X5 ]
- IRQ_Index = Gamepad_Merge + $01* n4 v: `/ ]; ?$ w7 X# Z
- ;==================================================
, S5 z, E% f2 L9 Q6 j
7 [' W7 Z. L$ M; e M8 z/ I- ;CHR图形数据
/ J1 f t5 X. h+ j - ;==================================================2 G% w! u5 C$ F& | b7 [
- .BANK CHR_DATA_BANK
# \. O$ s$ z( L# w) C - .INCBIN "chr_bank/chr_data.chr"
q! b; d% G4 Q! s: b- j -
8 l% ^+ c" R: [! _1 D! T - .BANK RESET_BANK & BANK_DATA_MASK* M8 @" L* Z; n' y
- .ORG RESET_ADDR
1 g& ^2 N" A3 z6 Q. K' v4 U. @ - , S& G/ X9 B. b& V4 C# Z3 ^, [
- ;--------------------------------------------------8 P9 Y& p% K8 K: d! k# y
- Attributes_Data
& C$ ]* i1 p# w, k; I. f& k; B$ p - ;命名表属性
$ i9 W$ Q* @5 w: D - .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$000 y! b; w: Q; F# j
- .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
1 q$ p) G5 U! n3 W" L* e - .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
% s0 |: b( S; @7 Z - .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
3 X/ a) I0 }8 E! r5 t' ~4 t - ;--------------------------------------------------
6 t& U$ ` E- o: w' ~8 Z - ;调色板数据
4 t# F M% V3 V4 [" u, d C - Palette_Data4 @1 ~" S$ C) n; X8 \' c& B: k( y
- .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F/ j: v% S$ Q0 Q# R
- .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F R) d2 B: K m, z: t
* V& G! o K" g }- ;==================================================: b6 s b+ J7 s7 f. P' ]
- ;命名表初始化
, Y, D; a% U, O g, H1 s - Init_Name_Table
& N& q1 ?; Y0 ]2 _" P - LDA #$20' ]9 b. `, X( z$ Y
- STA PPU_ADDRESS
3 a4 N" n$ `3 V' p2 E - LDA #$00
' F2 W4 ?& D; x9 M - STA PPU_ADDRESS
6 r+ T4 H E; L- E. ^' w7 B" B2 T - LDA #$00
4 Q% ^& x' q& Q - LDY #$00# L* J/ I7 I" W* P, f
- LDX #$102 c! ]6 ]6 M( E+ [2 h
- Init_Name_Table_Write
; s1 ?. |% n6 m4 D3 o+ F$ | - STA PPU_DATA4 G* @7 s* U! F2 V
- INY
& ~) C' C4 @ b/ D3 |/ u# f - BNE Init_Name_Table_Write
% G$ Y5 l1 I6 z/ E9 |% c0 Z - DEX1 [* N# r# v; G, ]% Y7 W7 p
- BNE Init_Name_Table_Write
: |3 \- B2 n- m& W8 o3 N9 A+ } - RTS
1 v$ l( [2 G6 r3 C6 m; W -
6 m6 U9 M* P. N6 J+ R5 z2 Q - ;==================================================7 T; j$ V6 J% t2 B p! b: T
- ;调色板初始化# _2 f9 t1 V5 Q4 n
- Init_Palette4 o" E# z& ]! p. x% ^
- BIT PPU_STATUS" m+ }' B {6 z }$ z
- LDA #$3F3 l* `9 B& e. F" F1 q3 ]
- STA PPU_ADDRESS( m) F# L1 n8 c# g% P
- LDA #$00% ~- H( g9 F6 J( m; N5 d5 \+ s
- STA PPU_ADDRESS
- N9 Z9 s3 \7 V# |4 e - LDX #$00: h0 w! D2 Z# K# J. h" T7 B
- Init_Palette_Write. n- |( K. T3 Y& J" N* f' t6 \
- LDA Palette_Data,X/ q h1 P# l7 ?& f. j& P( S9 t
- STA PPU_DATA
, q( U% \5 R1 ^ D - INX v1 n) |1 h2 o' N- L& I
- CPX #$20
1 n5 O3 \5 X8 K/ `# E c j' j5 @ - BCC Init_Palette_Write0 q; \+ j2 K3 P' r, W
- RTS
" q% B/ x0 K7 v* E' C* J+ F - ' C" Z: b+ \7 J/ u+ S8 ~
- ;==================================================
* B/ g% G6 o/ R' Z$ p( s1 g - ;设置命名表属性
( G+ {4 @2 w5 b% [2 T" a - Init_NameTable_Attributes
& O a% l4 ?2 i' o( D' ~ - BIT PPU_STATUS2 t) ^! l( E, t# z7 G
- LDA #$23
/ `& h0 c8 T* [4 r) }% d6 W8 ? - STA PPU_ADDRESS8 p& `) w w! \0 B( C
- LDA #$C03 k1 [: ?% L0 E$ |. [
- STA PPU_ADDRESS
$ Q, C. |+ r! K* Y) `& t - LDX #$00* t5 x4 D7 Q2 [$ Z+ ?
- Init_NameTable_Attributes_Write: N! v F( n$ ~1 k- F' S8 b
- LDA Attributes_Data,X7 L) S/ ~7 I2 t3 c z1 v
- STA PPU_DATA
5 b! {3 Z4 N1 j/ e7 n - INX/ r, f- g `5 @9 O
- CPX #$40
( a5 M) x W, Y8 W: K; ] - BCC Init_NameTable_Attributes_Write
- g6 ?* P! o. g# o: h7 d K8 C - RTS
z5 Z8 N& @+ I! Z/ r' D+ D- Q+ Y
( E' y' |; h5 B" J- ;==================================================
0 b5 v3 {+ P* z5 V9 |& _; k4 f) A - ;初始化命名表文本
0 q( g' ]1 X, p5 z; D4 B" I E( q - Init_Name_Table_Text
: X! L+ M* @+ s: I- A" T - BIT PPU_STATUS1 d2 M* z! q3 B# c# ? Q
- LDA #$20) i* z5 {. ?/ [. Q* m
- STA PPU_ADDRESS, l: Z. k/ d* _( [; D/ ?& k
- LDA #$00
$ G5 }& I! y! ]2 }/ X4 n - STA PPU_ADDRESS# O v" `) `+ y0 y( T
- LDA #$00- A$ L: v0 X( c9 S, E: F
- STA FC_Data_Buf) o" Y/ v2 Y, i: J8 Y/ s
- LDY #30+ o* S- w8 v. Z4 m
- Init_Name_Table_Text_Write
; H# h% [5 S) Y; {. { - LDX #32' u) U/ o! n7 L7 ^) v8 Y
- Init_Name_Table_Text_Write_Char
) s. t+ c; k$ ^! I - LDA #'0'
! T1 M% y# N: O. b; [4 s- A - CLC
/ _9 q' B0 I" u3 w - ADC FC_Data_Buf7 [7 v, P# [) o" S
- STA PPU_DATA
0 w7 g1 [% W5 @4 [6 H; Q - DEX
' [4 M, S3 u d# u) H - LDA #$14" F7 r7 l: c# X' Z
- STA PPU_DATA: p9 O! l0 U) o1 F
- DEX
% o7 O3 u8 W: |" G R: `7 F - BNE Init_Name_Table_Text_Write_Char
' v f. y4 K5 T; E2 Y# ] - INC FC_Data_Buf
! J* [4 N7 F$ L" L - DEY* E8 R6 |5 Z; R5 n* g% Q
- BNE Init_Name_Table_Text_Write2 C. Z: V" Y3 O5 ^8 o; j# Z
- RTS
! y3 U, a5 f6 d1 @( ~
1 S8 [5 ^; Y# x3 U. t, m e- ;==============================
2 L' p; ~, b/ e: G7 H; u: g - Init_OAM_Ram;初始化精灵内存
/ ?$ o% D& d- O0 d - LDX #$00
2 C @* `; x& R% j3 S0 B5 N - LDA #$00 O8 J5 n! _+ L! [: }. q8 |
- STA PPU_OAM_ADDR
4 d0 o" l1 m; F* h1 s# d - LDA #$F86 s+ a" l9 B1 n7 k
- Init_OAM_Ram_Write h3 A5 g J/ X! F* T; @5 g, p
- STA PPU_OAM_DATA
! k! U( ]6 \: `; I6 } z8 m' R - INX# ?0 K9 L4 o9 {" ^
- BNE Init_OAM_Ram_Write
# _; d. W* ?3 I7 u- W- E - RTS; @# ]2 G& W* z+ z4 |
- ' ?+ c, [0 X- \; v7 p& c
- GamepadProcess;手柄处理
, ^, n. |9 y! O; u - JSR GamepadDatacan
1 {3 \/ W0 `3 K% t$ u) l/ i - LDA <Gamepad_0_Value- ?, {+ B# O1 l, R
- STA <Gamepad_0_State6 G- ]% _6 Z! [4 o# q! x
- LDA <Gamepad_1_Value
9 m* f& s/ @7 R2 ]" L7 W) { - STA <Gamepad_1_State
6 F" ^' Z- s' ^$ b$ j& R - JSR GamepadDatacan+ ]% q* m. w. F( X% k- L" Q' ?" C
- LDX #$01
1 b0 G0 c7 W+ g+ @ - GamepadMergeCheck;合并手柄输入检查
1 @/ X1 {: _6 P, g - LDA <Gamepad_0_Value,X
9 q& p3 X; } \ - CMP <Gamepad_0_State,X' M; A$ E- A+ X+ s
- BEQ GamepadMergeInput( K% J+ K/ J5 _+ @
- LDA <Gamepad_Temp,X. l$ Y5 _. w/ `; R* w
- STA <Gamepad_0_Value,X
' ]- `- b, ]+ C* [% D4 l1 I; h$ d. Q - GamepadMergeInput;合并手柄输入5 |1 L* h R0 L2 C
- DEX/ B& |7 U4 c2 A7 b9 Z( O4 _( _
- BPL GamepadMergeCheck
- v6 w- a2 a) G - LDA <Gamepad_Merge/ ^- h: A9 `3 A0 W6 h( J+ ]3 M8 y
- AND #GAMEPAD_MERGE_FLAG- N1 l" q% l- x7 i
- BNE GamepadStateProcess' W3 I/ a0 I2 S! x/ P6 v0 C( R$ [+ |
- LDA <Gamepad_0_Value
( N8 E3 W+ \% o, L: w - ORA <Gamepad_1_Value5 @1 p5 q/ l+ Q- b2 f
- STA <Gamepad_0_Value# a% M* D; Z- h" b
- GamepadStateProcess;手柄状态处理* v: J1 o4 z' j% v) s
- LDX #$01! v; w" M3 L4 J) m
- GamepadStateSave;手柄状态保存& o7 U3 m9 s/ K+ W. J2 E
- LDA <Gamepad_0_Value,X9 X. K9 g% i) r, O% R* D* ^
- TAY4 }6 H: \: {( u5 H7 `1 d! A
- EOR <Gamepad_Temp,X2 m( S8 \% C% K! L; k2 y
- AND <Gamepad_0_Value,X
- N% B+ p% q, X' t0 m - STA <Gamepad_Once,X
/ P W% a; F) c% [2 g - STY <Gamepad_Keep,X9 E+ C7 P7 Z6 x9 C3 h+ }* s' o/ y& h
- STY <Gamepad_Temp,X
6 g) y8 @; _* Q' Z - DEX; W! d2 P2 D- N4 h$ W
- BPL GamepadStateSave
5 Y8 U: _: i7 B( z- f4 [1 ^1 f - RTS
3 P0 Y5 |. F! H0 E; t/ ~8 w+ L$ V
" P6 w8 u3 ~8 m: O; Z# p- GamepadDatacan;手柄数据扫描. S3 N- |+ b% z3 ~ O
- LDX #$012 h5 `* _8 d- s/ a. u' U$ }
- STX $4016# b* f# {. l# z. i- @1 u6 d8 n
- DEX
" o$ Q8 c# w4 W) c: H/ U - STX $4016+ B" c1 h4 y b$ b9 ~/ Z0 S
- LDY #$08! M/ m! _! ]2 p3 N1 J
- GamepadPortScan;手柄端口扫描" e+ t1 _ m% x5 v3 V
- LDA $4016/ Z$ B* V9 a3 b; s8 O( r: [4 @7 F
- STA <Gamepad_Port_Value4 c! H0 Z- \+ O$ j" y
- LSR A
( E* `% R7 }4 E; G+ B4 I! Z - ORA <Gamepad_Port_Value
$ p) I& M9 @+ T* Y$ G/ C/ r - LSR A
+ p; M, g' J$ d# F1 [9 W0 N - ROL <Gamepad_0_Value
& a0 b+ S2 `5 S, q - LDA $4017
" I: S, s4 ^+ z& c$ A - STA <Gamepad_Port_Value
( m: F' r m! K9 j7 I( @9 o7 o - LSR A
9 z4 C' C8 i% ?5 N0 J - ORA <Gamepad_Port_Value( x% g( F$ ^# ?; B7 _7 s, N
- LSR A
% M V4 s1 [, v8 z$ W3 o* u - ROL <Gamepad_1_Value. ^ u' |" o) O
- DEY. p0 s! @4 k# O7 s9 i* b( j2 K
- BNE GamepadPortScan
! V% i: I U- t - RTS
. \( K8 i: R; K" I; e* V -
" v- i8 |: L% G - ;==================================================
3 t1 T$ u) T/ e. O; } - ;PPU处理
8 [# u1 `0 z* v# a( t - PPU_Process& x" ~7 R7 n# s$ O& |3 v' ^. ^$ V
- LDA #$00) z0 C1 ~2 G9 ]( L6 }1 G1 T( C
- STA PPU_MASK% C. j2 |: z Z9 N5 G! B6 K
-
2 H& z/ s& n" Y5 g+ _# e - BIT PPU_STATUS
" \* A: O* O: m2 [+ Q - LDA #$20
; x- O7 m& o8 f: t - STA PPU_ADDRESS
/ h/ e4 F$ J" B5 W9 A - LDA #$00
1 f$ ~$ Z: F7 [- x7 G - STA PPU_ADDRESS
, ]( \7 B0 ~/ F6 E) v; ` l -
& U0 Y3 i9 o+ V/ g - STA PPU_SCROLL5 I) C% P; Y* ~& J* d. k
- STA PPU_SCROLL9 I9 A1 y7 {& A Q3 @
-
3 {& S( N/ H' t l1 ] - LDA PPU_Msak_Buf& |7 P2 j; g5 G& u
- STA PPU_MASK
+ f: m2 j& ^, V) \. v - / A4 `" g) A( i+ C% g
- RTS
2 V3 t* W4 [7 O - 3 J( l y- L+ M: u" u+ i
- ;==============================
/ k; J* K- U! t( k) {% n: z% z - Time_For_Vblank;延时等待" R) F3 W. z1 y- V
- LDA PPU_STATUS
0 q0 m+ }5 `4 Z& j, _. R - BPL Time_For_Vblank
. i* j" X( ]# \; ]% S - RTS* X+ p2 \" ^. j# Y, R' B+ |" m
-
* v/ G/ Z; S% N+ P @7 G+ A - ;==================================================
, B+ i0 @& @" P: N - ;初始化MMC59 W( y- w! C$ b' w
- Init_MMC54 n* H( _; W; C" J; F
) _0 P- Y% W/ A8 J5 R" U* G7 a- ;设置一下6000-7FFF的RAM$ d* } Y T6 g L3 M7 ^: H% V$ w0 l0 H
- LDA #$00# n3 \% @# }" h
- STA MMC5_PRG_BANK_6000' [/ p% n0 G9 x7 S5 G7 i; F9 J' M
- # Z7 { r) v% L9 D, M/ f* M3 i$ B
- ;开启 PRG RAM 写入
% F9 b, P* b j" w [" a - LDA #$02 L2 B O+ F' t* |
- STA MMC5_PRG_RAM_PROTECT_1
B+ W+ E6 J4 d4 A - LDA #$01
0 k* J- V- h- j2 K& ]1 Y - STA MMC5_PRG_RAM_PROTECT_2
# G. r- \9 R* a- T -
7 {% b: i0 D, S - ;启用 1KB 扩展RAM ($5C00-$5FFF)
- y" o6 f7 S0 }. x4 t - LDA #$02 }2 W3 D1 E+ p2 [
- STA MMC5_EX_RAM_MODE
1 \6 ~0 r2 p- y3 ~% P -
- u* M2 s0 ]" ^ k# {1 U - ;设置 CHR. ^. {! I1 Q0 n' {
- LDA #$00
' ]) D# [2 Q. U r5 @; J - STA MMC5_CHR_BANK_00006 T% F$ j: I7 F
- LDA #$01
1 o5 P- ]+ l9 m; U' V9 d6 G c - STA MMC5_CHR_BANK_0400" {1 I; J/ i& o
- LDA #$02
; V+ v: ^' [6 e5 n, Q - STA MMC5_CHR_BANK_0800) x v1 m) r% f- M# m" R' a
- LDA #$03
* @# E @1 o Q) Y8 z5 c( } - STA MMC5_CHR_BANK_0C00, z' @! w$ g" [9 Q+ R
- LDA #$04
8 R8 u( M" F. L h" W: m# t6 B - STA MMC5_CHR_BANK_1000
! f0 c; w# a6 @6 ^$ W5 b - LDA #$05
3 [7 N0 k- o' g* z - STA MMC5_CHR_BANK_14006 u/ P3 K8 f/ m0 C9 n
- LDA #$065 ~' s1 R! D/ a- [: ^
- STA MMC5_CHR_BANK_18001 a. Q4 U* L! k2 Y
- LDA #$079 E# U1 b7 |# V5 [( V
- STA MMC5_CHR_BANK_1C00
# _' h4 x( i9 _+ a' ~ -
$ N4 }& J" n" S7 l/ ~, ?& T - ;设置屏幕镜像
G) Z& }9 Z9 C7 B) [7 Z, ^ - LDA #$50) I5 q" {& }/ U8 G' \4 k" V6 |
- STA MMC5_NT_MAPPING4 F* p( k6 a' s4 @7 Y
-
G8 J' l/ h6 l& h. a9 Z# i - ;禁用IRQ+ G E$ S, f2 Z1 _8 F
- LDA #$00
2 w, U! h2 o( I/ h! s/ Q4 h. T - STA MMC5_IRQ_SCAN_CMP* h }7 L$ a+ k5 w$ o. a2 B
- STA MMC5_IRQ_STATUS, q4 {; T4 E7 D+ ^4 p, h; |9 @* z0 L- c
-
4 d9 }3 t* J" g' w. [* r; Q a - RTS( C! M [1 A" c/ u B3 X; P
- 0 v3 p8 r2 E& w1 q3 w0 a
- ;==================================================, \( a* ~9 {7 K. c9 D4 a5 b
- ;重置中断处理1 l( O6 |- R1 \! `1 _
- ResetProgram% k. e, ~& V" `: K1 T4 q
- SEI
6 V+ M4 j8 ]( j& k5 ^2 z8 |- t - CLD
8 G" ?3 j5 z1 `6 b% W9 I' N - LDA #$003 C e2 H4 l6 O7 W3 K/ g0 [& Z/ W
- STA PPU_CTRL4 D( l4 S) h! [9 D
- STA PPU_MASK
! H1 u/ z7 b& V! s$ Z A" Z* ` - STA PPU_STATUS
( V3 \; W6 }7 N" q - STA JOY2_FRAME% X# ?. P# A8 l* J& n% G& i7 {
- STA APU_STATUS4 b6 J/ {- U1 [
- : E/ i& k! F$ O" C m) F( d
- LDA #$C0) N8 F! \( Y; R: A6 k3 A% R4 }. t9 n
- STA JOY2_FRAME: `/ \. r5 a q5 j8 M7 y9 U
-
% e$ E+ Z0 O) v - ;等待vblank4 X$ ^" Y0 k: ~( u9 G. _
- LDX #$02/ [+ w9 o+ d; K! q; k6 w
- Vblank_Wait_1
% s$ y8 t g3 H - BIT PPU_STATUS6 \ d i: r9 |
- BPL Vblank_Wait_14 ^# d: o- F2 }# |0 w# n
- Vblank_Wait_2
: p4 W/ {: g3 v. @1 l6 g - BIT PPU_STATUS* K9 }: v1 [' E1 k8 Y8 c
- BMI Vblank_Wait_21 k& N' G* u/ P) {0 l
- DEX$ A( t+ o( ]4 w4 Y, q2 z
- BNE Vblank_Wait_1
% J* c- D- `1 j) L5 N: K; J - + G: U/ E: ^4 @- d: x/ L
- LDX #$FF
4 q, e# p4 ~6 B9 D8 j J - TXS
- V7 n5 G) ?) J6 N -
, T2 U F) A/ |8 T$ \/ T1 I2 |/ F - ;初始化MMC58 I9 r7 ^& O1 V2 I
- JSR Init_MMC5
/ i; j9 b( ?3 ?& ^ - 8 Z+ L+ u9 Y- W! a a" D- W
- ;==============================
1 B5 G' H, U! m; E& {1 s' M6 A. j - ;RAM初始化
; N5 S. W. H, p# L S Q - Nes_Ram_Init/ ?# ^; L5 S2 Z% R" a
- LDY #$00
6 X2 F( L* n2 H% L7 } - LDX #$08
" l( Q; h7 X% B - LDA #$00
/ r$ B* Z. `4 k, r* h - STA <$00
3 q) y; |( q' j* _; ~3 H& A - STA <$01
5 C( g8 _1 Q) [ z4 V; T; f - Nes_Ram_Init_Write5 e4 |8 I# D# `6 u8 N
- STA [$00],Y
! K0 X6 n, s9 m/ k3 [ - INY6 r: W1 J+ R3 _5 q" v1 _
- BNE Nes_Ram_Init_Write2 f0 x; ?0 M( r+ R
- INC <$011 L/ [- H% ^! ]
- DEX2 ` [# r2 Q7 n. c
- BNE Nes_Ram_Init_Write
2 w4 y. M# W% ~) ^. t% t7 l - % K3 {, O0 o( m/ z% @
- ;初始化命名表" m! D$ I( t: c6 Z4 E# b6 q
- JSR Init_Name_Table
' Q, \' C- P& V8 c8 f( i - ' [9 A3 @7 ~& }- c
- ;初始化调色板" L* d3 Y8 |0 {2 m2 V
- JSR Init_Palette
# H3 n: y8 d& L" _# m - " q7 N) x# }+ O, m' `) b
- ;初始化命名表属性
. R! q4 Q& l$ R; `7 ~- g* j3 Q& v0 U! p - JSR Init_NameTable_Attributes
2 }* ?4 x& c3 B& q7 X -
0 D2 V& p/ y- q - ;初始化精灵内存. [& R1 b" {& j- U( n' i, @
- JSR Init_OAM_Ram
' u/ I8 G+ j" Y, F2 J - 9 c1 {3 w, K8 K. H
- ;在屏幕上写点东西1 k0 P6 S3 s8 y& x# f
- JSR Init_Name_Table_Text3 }4 j3 Z- k/ R/ G! r
- 2 r+ V8 w& v# _9 B4 H
- JSR Time_For_Vblank. V9 ^. `; ~1 r7 w. }
- ;开启PPU控制7 w& l5 O7 S- k( ?2 p' F" T
- LDA #$88; K$ z* A% Q Y+ B0 ^, j2 Q) _, k
- STA PPU_Ctrl_Buf3 @1 g" ?. X! M6 D3 u+ I7 ]
- STA PPU_CTRL
0 w2 |9 o4 B9 i2 o; h: a -
* {+ G+ N7 n( Q) j - ;开启PPU显示6 z9 e* g: z0 s1 b; E
- LDA #$1E
3 B T; U3 [- G- h f. | - STA PPU_Msak_Buf* U% T& k3 P; E. d( `( @8 G/ z( [: l
- " W, ~5 A9 M* t# p+ k) R x- q# ?
- CLI
! E& }; j" ~% Q - JMP Loop5 t3 N& M7 P6 D) M
- + q2 t* {- I/ l. d6 @0 ~
- ;==============================5 Y* h* {4 h; |$ }, [, b9 a; w( \2 W
- ;死循环, 等待NMI中断. ~2 P1 J! H9 r
- Loop
, b; J8 d, J% b9 x. O! k4 D- i# ] - JMP Loop
; i5 h5 d& w+ A8 m3 h" M - : G9 P# Q( Y& ]) J$ _1 d
- ;==================================================
- A* c$ w- V6 b0 T6 Z5 f" c - ;NMI中断处理# e, m* Z4 I# m# {
- NmiProgram& d( ?4 k5 w! D6 a* H
- PHA
% k7 d' J9 b2 X8 @ - TXA
6 x0 W! r9 P* k3 Y4 k - PHA8 r5 ]6 Q) C: W7 r' i. J
- TYA+ ^ q& m* o, |
- PHA1 _; v/ R! e( |, F5 ]7 @# K
- 6 \' W5 q8 _: q0 U: `/ Z! _
- BIT PPU_STATUS( f f: O$ T8 G" l% d
- , N% }: [" A s
- ;启动IRQ中断, 第16条扫描线触发2 w, B5 ~- X, O# U* ~/ m& Z
- LDA #16
6 D! f6 C5 A' E/ w! O - STA MMC5_IRQ_SCAN_CMP
4 @, `1 \. @) z8 h D- W$ f - LDA #$80$ G( m8 u- G0 ^5 J* E; O
- STA MMC5_IRQ_STATUS* @) M2 N8 z! m- v- V$ a8 M
- CLI
! K7 p( L" K6 S, N# m8 h K9 M - % b9 H: F' B. X0 Q
- ;关闭PPU控制
6 u- G& Z4 k5 O - LDA #$00
: j5 t9 Y) O3 h9 ? - STA PPU_CTRL
! z% k. E& K" u( ?2 }# u! f% m) C- _ -
+ C, t& N. y5 i* o9 S8 b! F! O, K- T - ;处理PPU
& M2 a! v/ ^/ m% Z& t# P3 q; Q4 S - JSR PPU_Process
% W; W# ~0 E& |" B R( X* _ -
: r* [( u* Z( A) i6 E c; N! F( S - ;开启PPU控制' x4 s' b' a- K+ F- L2 e
- LDA PPU_Ctrl_Buf
/ ~1 S6 d0 }0 H% n. p% N - STA PPU_CTRL
; N6 k( ^: B7 |. i; I# \ - 3 y) A( t/ F4 E. P) [5 @
- ;手柄处理
8 }) S& d. B, z# Z - JSR GamepadProcess7 u. B, W2 J& s: V; K7 |5 `
-
2 Y+ ?& C8 z) E# P2 m* v6 n - LDA #$00
/ o+ P' }$ M3 o8 n5 K3 z$ |5 \ - STA IRQ_Index: r3 ^+ U& C: K8 ?# I2 w
-
: i# v6 S; z, ~1 ~ - PLA1 z0 o* `+ ]1 T* Z$ N
- TAY
5 ?' b6 N2 B# e2 M* K- Q8 F9 I - PLA' v! K# q' T; z0 t
- TAX
: ~ |5 |6 h# l7 K) s; j+ [# \ - PLA
8 t1 M d9 A6 j - RTI
# S Y: ?, S! t$ P/ p5 M
2 W3 q/ ^5 [7 D7 Q3 ]; W- ;==================================================& ^. H+ o+ J. H+ K- `
- ;IRQ中断处理
) c% R: ^, g1 U c - IrqProgram
; Z0 D% o: P8 o% ?8 n - PHA
; J. ~* G$ K) k3 p - TXA; a# I& M3 A5 t5 n- B; s: m$ [
- PHA( g" H- n0 Z9 g( L; K& [5 F/ y. F
- TYA. {0 ]% a1 i, m6 w
- PHA ~3 K. f% j+ T+ Z6 t: g( G
- 4 W7 U) n& j6 Z* a
- ;确认IRQ8 B3 [" V" w" Z# g6 y
- LDA MMC5_IRQ_STATUS' j7 c" a! G. ~
-
4 k6 C& e1 ]! J( h, B- {5 ]7 C9 r - ;允许下个IRQ触发; P! u0 t3 E: S& @8 V' l
- LDA #$80& o) z, M7 J% ?. S6 s
- STA MMC5_IRQ_STATUS# [4 f* \; C8 Y) z! C' @
-
( u% [% p q# j0 a7 ? - ;IRQ处理, 每隔16条扫描线触发( ` w! m1 Q/ c$ t% q, J
- LDA <IRQ_Index
) S4 I6 W G9 L9 U2 ^) p& J - CLC
' B6 I& C, H' G6 j5 E0 X - ADC #$02
. u4 @8 h* O; w( R% v M - ASL A9 r2 N; D2 u' Y* h4 W' q
- ASL A
/ x( Y" m! \3 m0 }, L- | - ASL A
( v. P% u: L7 ^/ R/ C4 e - ASL A3 _4 @7 n5 r& x) O5 W( N
- STA MMC5_IRQ_SCAN_CMP
- a" W% ]( p& h -
3 z( }7 E$ K; r0 q. Y) A - LDA <IRQ_Index j3 G8 u" ]" {; E- h3 Y
- BNE * + 4) [7 c1 l& r3 z' _( `
- INC <PPU_Scroll_H5 F. Y8 X9 c9 W8 g) A
-
4 F' W1 p x$ ?) X* H( j2 u - ;设置屏幕滚动% a9 H: f* e% U/ Q' y
- LDA <IRQ_Index; S1 _; j2 s. C& Z7 ]: N
- AND #$011 \( n4 F: I7 Z( U
- BEQ Irq_Scroll_Right' Q& E* b, m( C; }2 `6 k
) I9 f X1 U* W- W" I# k+ o6 O* [* C0 h* U- Irq_Scroll_Left# A' V1 X8 ]/ D) U3 x4 r9 @& D4 z1 x& ~
- BIT PPU_STATUS
E" x" A4 |- m - LDA <PPU_Scroll_H
' B6 T6 R; f7 H# { - STA PPU_SCROLL: n8 S* o4 x ~/ X7 @5 T
- STA PPU_SCROLL
0 S- P G9 r# I, A- w - JMP Irq_Scroll_Over/ q7 _+ O# ~( M8 i' G
- * m7 s2 c- `' ~+ O8 u' S
- Irq_Scroll_Right% V0 `! ]2 k! p: x5 w+ ^ Q' B) |
- SEC7 N' @' c5 o7 I( X$ d) T" F
- SBC <PPU_Scroll_H
! ?* |; p) O8 k$ p! M5 U! c; c - STA PPU_SCROLL1 M9 R( e/ e/ a8 q
- STA PPU_SCROLL
( M7 s" K" U6 L/ H - Irq_Scroll_Over1 ^0 \ G" v( b2 G
- 6 x9 o1 A! a2 l! |* B2 ]
- INC <IRQ_Index F* B; k9 H3 E( A$ y. E, f/ |
-
. t( N; h, b5 L' g+ y, I0 t( `2 X - LDA <IRQ_Index
w1 V; X* c+ U; Z! ` - CMP #14- Q4 B) R4 {! ?
- BCC * + 55 O0 g+ g; J$ @
- ;关闭IRQ/ T: A. |: @9 ^6 q/ n' D, m5 [
- LDA #$00
$ T+ | f0 w1 n" b9 P - STA MMC5_IRQ_STATUS
! C: H3 q3 ^! a# f - $ c6 Z& Z" G" I. G: y4 u
- IrqProgramEnd- V2 R2 z M ~5 J
- PLA
. m, @. M4 V6 \2 Y - TAY/ }$ m$ C0 ?- C% v9 n
- PLA
* u, M) ]! D. g) K$ k - TAX7 f# T6 p9 h" Z; C6 A, k* |
- PLA% f- s' m: K2 t; [
- RTI
6 w6 Y8 ?9 c! i4 t -
4 K" C Z) P. n" n S' W b7 |- V - ;==================================================2 m' M- s4 g+ {* d% d! T+ d
- ;中断表7 R5 b9 }3 O" o3 h4 v
- .ORG $FFFA
5 }: f5 K' j ?4 R - .WORD NmiProgram
8 S# H. X- y$ l4 r$ ?0 z4 n - .WORD ResetProgram; u, x4 r' e0 r6 C7 M1 ]! c8 \
- .WORD IrqProgram
复制代码
4 h( y j* p! k1 J! }; L8 J |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|