|
|
- ;[FC音乐][MMC5 IRQ]
8 J# q0 Z* @: y - ;FlameCyclone 20230710
+ w. \, ^9 T, y9 k - 5 z( a0 O H( Y* _8 V! B2 m7 D
- ;文件头
! P9 B, J, G$ J" f2 Z3 H - ;======================================================================
8 B5 D- |) s/ o$ V- k$ y - .INESPRG 4 ;16KB PRG 数量
5 P! W& z4 _! C - .INESCHR 1 ;8KB CHR 数量4 [ V9 Q, d% |+ t
- .INESMAP 5 ;mapper 5: b4 |' W) c* K
- .INESMIR 1 ;命名表镜像 0水平 1垂直+ j. v8 Y$ q) E4 q
- * K9 ?6 m! a+ m( P; K
- ;必要条件
9 N, B( K0 D4 ~7 U( {1 F+ @* F! D; S - ;1.持有CHR ROM
" A3 k; q, W3 ] - ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
T$ ?& l7 {2 g+ ?8 X9 [8 Y - ;3.精灵内存(OAM)不为空
' H3 Z5 v" p1 E' {3 f
! s; y3 y( u9 B$ J+ e0 l- ;==================================================# B6 h" h: D4 a* k$ }- K
- ;NES端口常量
: P0 A. x, |5 W: m. {( h - PPU_CTRL = $2000 ;PPU控制寄存器/ S9 K2 m- K& z" p/ t0 C
- PPU_MASK = $2001 ;PPU掩码寄存器 m r2 A( B o" F, T
- PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位
?1 U( [, j w+ A B" z - PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加10 h- w2 @; V- A
- PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加11 f6 d( N) ^5 Z2 d% s% Y
- PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
; ^) H2 y% }0 Y) {2 W) U/ Q/ y1 ` - PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加+ H/ z% B8 B8 D7 [+ i; f7 P
- PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 # J; N. ]: M3 Y
- OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存8 x" J6 i( n4 T% K3 J- ]: o
- APU_STATUS = $4015 ;声音通道切换
+ Q! U. t0 e& _8 ^5 W - JOY1_FRAME = $4016 ;手柄1 + 选通+ \7 y5 _/ ~- N. x( D) N, K3 v$ l8 ^
- JOY2_FRAME = $4017 ;手柄2 + 选通
' X" B+ n! [3 h" \8 a) C
8 V+ [; p2 ?1 H6 b9 Z. s y- ;==================================================
' q( l( ^3 A( U* l' k& E - ;MMC5端口常量( w9 W8 F" r( x2 Z* ~
- MMC5_PRG_MODE = $5100; 0: 32KB 1: 16KB * 2 2: 16KB + 8 * 2 3: 8*4; q& h1 p3 V; `5 R
- MMC5_CHR_MODE = $5101; 0: 8KB 1: 4KB * 2 2: 2KB * 4 3: 1KB * 8
, q' h+ N# Z8 k5 X# |3 I0 P q! [ - MMC5_PRG_RAM_PROTECT_1 = $5102;& [( m" J# ~/ U, A. l
- MMC5_PRG_RAM_PROTECT_2 = $5103;
0 m1 w& [5 c7 I - MMC5_EX_RAM_MODE = $5104; 0: Write Only 1: Write Only 2: RW 3:R
9 u$ R( e6 y2 B; O# D - MMC5_NT_MAPPING = $5105;& Q9 l' j5 `$ O/ m. I1 a1 R W0 h
- MMC5_FILL_MODE_TILE = $5106
7 x0 h: z$ [6 K+ w - MMC5_FILL_MODE_COLOR = $5107
1 b! X7 ^4 r" P: y: L5 }
' ]6 Q6 _( s. C& L& m9 v1 R/ y- MMC5_PRG_BANK_6000 = $5113
3 Y0 S8 S0 H; i9 ^/ F$ x; G5 v% p* Z$ d - MMC5_PRG_BANK_8000 = $5114+ `: ~& o5 H$ r; Y4 P
- MMC5_PRG_BANK_A000 = $5115
0 C: m1 m. ?( o - MMC5_PRG_BANK_C000 = $5116
) X5 V6 n$ n) }: j$ h6 Q1 L. h - MMC5_PRG_BANK_E000 = $5117
2 L& L, R" c" a4 P# \! b -
2 R5 Y+ w1 b1 w0 f3 ] - MMC5_CHR_BANK_0000 = $5120
: c# h+ Y' L& M d7 Q( B; U+ j, q - MMC5_CHR_BANK_0400 = $51214 g" u) R1 a0 m) I+ b( ~0 g
- MMC5_CHR_BANK_0800 = $5122
. y7 g; w3 V+ \ - MMC5_CHR_BANK_0C00 = $5123* j6 S" W, b8 @$ k/ |2 [. f
- MMC5_CHR_BANK_1000 = $51244 Z4 W* U' I# Q
- MMC5_CHR_BANK_1400 = $5125
, J- y+ g& l/ w8 I' t - MMC5_CHR_BANK_1800 = $5126. x/ p. M2 R; j5 W) A9 U
- MMC5_CHR_BANK_1C00 = $5127
8 c1 T4 a" z Z9 M - # A( [' }; b) I7 x, b
- MMC5_CHR_BANK_0000_1000 = $5128
# Z) X6 I6 g5 c) [: n - MMC5_CHR_BANK_0400_1400 = $51296 b0 C- {( H9 ` o* S
- MMC5_CHR_BANK_0800_1800 = $512A
4 [! o! A, E6 F' A, g4 `9 j4 i - MMC5_CHR_BANK_0C00_1C00 = $512B
1 v, l6 P( }4 v2 g7 |8 C% H -
T# `( y2 q/ \- P: X - MMC5_CHR_BANK_UPPER = $5130
, U) i+ T! f! ]9 h2 p8 w+ s, l1 ^1 Q - MMC5_V_SPLIT_MODE = $5200
: R# }# E" j! ~9 S9 Q1 k) |. q - MMC5_V_SPLIT_SCROLL = $5201
# e3 ?) f3 [# j- C* g - MMC5_V_SPLIT_BANK = $5202
: r8 A/ X/ `/ \. d3 k' I1 O - 5 U; x: l( s2 v' D
- MMC5_IRQ_SCAN_CMP = $5203
: W8 r3 _) N7 u E0 X0 ~ - MMC5_IRQ_STATUS = $5204! X3 L5 F+ y8 n9 l
- MMC5_MULTIPLIER_A = $5205# f2 f! ]) ~. ~: q. ?) q
- MMC5_MULTIPLIER_B = $5206
4 b+ K( [/ C( b+ C+ w$ B - . R @0 m& {; W$ `& Q" k5 p3 u
- MMC5A_CL3_SL3_DATA = $5207
# t Q. ]* |: G( g0 K - MMC5A_CL3_SL3_STATUS = $52085 g8 W- \/ x+ U6 d* W4 V- t1 [8 S
- MMC5A_IRQ_TIMER_LSB = $5209: T8 F) |& g6 u2 S
- MMC5A_IRQ_TIMER_MSB = $520A
( t, s. L. s3 s8 {' r! K. w
8 v" o, s: {. B! n$ e* h2 k4 h7 U- ;==================================================
+ b2 x4 H0 c P) F+ d! | - ;程序块配置- n* t/ k- ~5 K$ T, R
- BANK_DATA_MASK = $07
P5 J1 P! q0 q* { - ;--------------------------------------------------* F, t' X" r. W, Z. o
- RESET_BANK = $07
/ r3 B8 I# S" x! f' _8 P - RESET_ADDR = $FC00$ r( @; g& @. d- q0 b% M1 o
- ; z) i; l) ~6 _3 Z# B
- ;==================================================
2 B+ Z2 C1 n4 o/ Z# m2 }! _ - ;图像块配置1 j' A# Y; z" p& G
- CHR_DATA_BANK = $080 S' L# v1 g) R
! d1 T' l' J3 _" i- ;================================================== N: ?# R- d* w3 X4 k
- ;零页内存地址配置, p, D; H# A j4 j" t
- Use_Ram_Addr = $809 e. W) N& ~- e7 j+ b* C1 V
- PPU_Ctrl_Buf = Use_Ram_Addr
- a/ A2 W% t3 Q; e) g - PPU_Msak_Buf = PPU_Ctrl_Buf + $01
% ^! K! G! c4 `: k - PPU_Scroll_H = PPU_Msak_Buf + $01( Y" N2 K( C0 N4 K* R `
- PPU_Scroll_V = PPU_Scroll_H + $01
1 o' n N$ V3 s3 T: S# R$ |% _2 B/ J3 z - FC_Data_L = PPU_Scroll_V + $01. J/ x: W- `/ d) L6 |- D1 X4 Q2 E
- FC_Data_H = FC_Data_L + $01
; f% w6 l1 B8 X, P( H0 ?, e - FC_Data_Buf = FC_Data_H + $01
& |, e3 j! B& B - ;==================================================# M9 _7 t, L# n8 l( X1 b* w! M; `
- " O8 B/ U+ R4 `
- GAMEPAD_MERGE_FLAG = $04
# K/ ~9 R$ F9 D. m9 H3 t - % P( g2 Y) s4 C |+ X3 o
- Gamepad_Keep = FC_Data_Buf + 1$ T/ n; X# x# E' \9 f! b
- Gamepad_Once = Gamepad_Keep + 2; i) Q/ o1 F" U% Z( O# \( u
- Gamepad_Temp = Gamepad_Once + 2
1 \# k5 c4 |/ p) B - 6 u4 i! u) ^* l$ d6 u7 H
- Gamepad_0_State = Gamepad_Temp + 2% ~# U2 l7 _" k/ v; H
- Gamepad_1_State = Gamepad_0_State + 16 s1 L+ |* F w
- Gamepad_0_Value = Gamepad_1_State + 1+ R& a! p) L( a* l- q7 y
- Gamepad_1_Value = Gamepad_0_Value + 1
; N# q4 \: ~$ t# w4 y - Gamepad_Port_Value = Gamepad_1_Value + 1) i* U1 W/ Y5 k& ^ c
- Gamepad_Merge = Gamepad_Port_Value + 18 P7 X4 M* J4 `3 S1 r. | p, U
- 9 i: R. G6 ^% B
- ;==================================================
9 b! l; [/ H4 D - IRQ_Index = Gamepad_Merge + $015 k( x/ c, l, |
- ;==================================================% @$ I$ ^* ?: L3 k: s" s1 H
- # B) w5 y4 z. Z$ y
- ;CHR图形数据3 ^ x" z" p6 A' f1 `! P, n6 B! @4 }5 q
- ;==================================================6 I7 _8 m( x0 f) y- Q& m
- .BANK CHR_DATA_BANK/ l- m& c8 c- K8 Y! k
- .INCBIN "chr_bank/chr_data.chr"
\) ]$ _' N8 E+ D# T0 i7 }* [ - e& @/ A' e8 a1 u7 G! V
- .BANK RESET_BANK & BANK_DATA_MASK* S8 S$ k/ e g
- .ORG RESET_ADDR
- e* m/ t0 }1 K* w6 h. b7 W' {5 c - , V- ]% u- j) `. U m9 Y) p N
- ;--------------------------------------------------
4 {. Z5 u$ b( S- c5 Y0 r - Attributes_Data; i* w1 v) ]7 {( B2 m- p
- ;命名表属性/ {4 F& q# p' m" ~, b/ d5 W
- .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00) `) L2 ~+ D: E( b) U, B% ]9 x W
- .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA p( ]6 e, j( k" h6 T( \
- .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
9 W7 J4 k* ^" U; R8 @2 w - .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
* l/ b1 D. Y2 L: {+ [/ D1 j - ;--------------------------------------------------
3 y! i+ Z/ @, k- s& V. c3 v' L X - ;调色板数据
1 d2 E5 x% y! E8 w9 h - Palette_Data
A7 G8 L8 h& \2 C2 q - .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F v* B8 o& p* p" p- m2 s6 H
- .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F; m0 e" O0 C2 Q( U
- * ?8 t; f2 P7 }1 d& k, _: @2 V
- ;==================================================
- z0 ?- _1 R7 u4 c6 N# g - ;命名表初始化
( w! t. E6 x4 r' `% h - Init_Name_Table
7 o, _; p+ `/ T% i - LDA #$20. x# }+ V" z0 D- W9 t$ ~- G
- STA PPU_ADDRESS" E$ Y1 W3 e4 B* j- C0 c+ J
- LDA #$00
9 X6 g1 M) T! x } - STA PPU_ADDRESS
; n* t2 j# ?5 e( Q - LDA #$006 h4 F' }$ x3 X F, }7 {
- LDY #$00$ C8 E+ \: `7 ^$ Z" x& S& L6 k
- LDX #$10
9 U9 a, p6 v( r1 p! ]" _# y* \ - Init_Name_Table_Write
7 ]( i, S* ?: Q( E - STA PPU_DATA
$ Q# O6 |6 g" A3 H/ q - INY# B" `1 ^, C1 A# d& r
- BNE Init_Name_Table_Write
3 Y, q p/ f. |# P: } - DEX) X8 |8 B8 u1 m* C7 |6 B
- BNE Init_Name_Table_Write* T' a' M4 s: b6 Z1 _* Z
- RTS
# |/ {: K0 e: D9 X+ q -
8 B" i# J! h, G) f - ;================================================== T8 v0 `4 D' n8 T
- ;调色板初始化
+ v: K n" V4 }+ S - Init_Palette
m" I3 w1 m& ` - BIT PPU_STATUS
& p# K8 W& ?$ l- V - LDA #$3F
! ]$ @/ f3 _8 ~( k - STA PPU_ADDRESS2 U) W$ X$ ]; w9 ~
- LDA #$00& z+ L' {+ f' Z8 |& Q, n3 a
- STA PPU_ADDRESS8 A% Z% C7 b7 v k" g- f
- LDX #$007 L! c3 E, y& N* e$ y
- Init_Palette_Write
& J9 b; S! x& a' A2 |0 g* a - LDA Palette_Data,X& r4 }- ]0 u5 s! O
- STA PPU_DATA
; k. w M/ N2 u, C. D - INX7 b* H: T' P4 R
- CPX #$20) F8 b7 z% D9 x" o( @( e) X% Q; V
- BCC Init_Palette_Write6 X8 {: Z$ V* D+ x
- RTS
% Y F' _, m7 Q; M C9 l: a' X+ z - * p1 {% K! Z5 C8 t
- ;==================================================
3 a4 r) z" i1 M1 S& f" P9 g' U - ;设置命名表属性
% [) [' |! M2 g d; P - Init_NameTable_Attributes
3 d4 r [, w9 |; j - BIT PPU_STATUS. K% \, a* M. g* A4 w) X7 z
- LDA #$23
9 p0 c* O' u) }5 O, ~- E, O7 t1 ]: j" v - STA PPU_ADDRESS
& z1 d( [- [; T9 l/ b( N+ M - LDA #$C04 s) x4 ^# m/ g0 W( |' M( F
- STA PPU_ADDRESS9 S% @, U% b+ }8 ?7 K
- LDX #$00, N' q5 g S% J" X
- Init_NameTable_Attributes_Write
2 {- ]9 n' f) ]* k - LDA Attributes_Data,X# O3 H4 X6 O7 k# ~$ Q- ]
- STA PPU_DATA
5 t4 D' U4 b7 a) c - INX$ z+ O$ a% P+ V8 K/ E/ ^ y
- CPX #$40
5 E3 _6 m! e6 M! ]. ^* s - BCC Init_NameTable_Attributes_Write
0 B0 v7 Y. W. a) p. j. z - RTS, r3 A1 d# @4 m; S
$ q) w W9 e/ A4 F* E- ;==================================================
6 Y6 Y0 N* _* e, Y1 v6 c! a - ;初始化命名表文本
& } r) b3 F- P9 n/ F8 e# j5 N: d4 m - Init_Name_Table_Text7 ?9 l$ i) r+ k8 k2 m
- BIT PPU_STATUS; z" p$ Z1 `* x) e4 f5 z! e9 m3 H$ v
- LDA #$20
; D) t0 w7 a# g$ K - STA PPU_ADDRESS) f4 c4 c) t- f6 G% Z ? _
- LDA #$00
8 Z6 w# l* u& N2 t0 t/ e - STA PPU_ADDRESS
3 f* b; e; o0 B; U; m - LDA #$00
3 b1 R% c x m - STA FC_Data_Buf
1 w) R1 h' }7 Y3 m ` - LDY #30
/ N7 Y( H) s% Y9 b; I+ M# ]# O - Init_Name_Table_Text_Write' f* J% t, a; p. K9 A' h: M0 E; K
- LDX #32
{3 H r9 \# C- G: F5 i - Init_Name_Table_Text_Write_Char
, s( Q; Y1 [ {; |* D+ w- [ - LDA #'0') x8 f3 E C' p' I1 ]; U
- CLC
_8 G5 g( n& E2 _9 F) g - ADC FC_Data_Buf, ^: A9 D; W0 v
- STA PPU_DATA9 P' H4 n$ X$ {5 J; g% M# |- ]: e
- DEX) a9 z( z/ y$ D* z0 L, C
- LDA #$14 {9 N& ?+ N9 W4 W$ F4 A2 N
- STA PPU_DATA7 ]' l }% W |
- DEX
; O' `( w* b m _/ H5 e - BNE Init_Name_Table_Text_Write_Char7 h2 k: a2 E. F5 e; O$ t
- INC FC_Data_Buf- w7 i& X2 k5 C0 p' v j" N
- DEY1 ~9 d" k0 c2 r c! m
- BNE Init_Name_Table_Text_Write7 F) v7 i" J' L" A5 q1 q
- RTS5 o9 f% t) v, T" ]- G
- ( q O9 ^; r' x2 t# v- h" r- K
- ;==============================/ u& B8 V" p; r9 U) c6 x! L- P( y
- Init_OAM_Ram;初始化精灵内存9 }( v# x6 F/ l6 v3 X# B
- LDX #$00' a2 m0 g( z9 m8 ~4 y6 F! a
- LDA #$002 K, b" i/ M2 ?3 H4 q2 ]. {
- STA PPU_OAM_ADDR
* ^% h* F! Q5 G, k: { - LDA #$F8
- _( j3 r) `2 q- B, S( F - Init_OAM_Ram_Write
9 b. s6 j3 _% j; V' ?$ R& B - STA PPU_OAM_DATA9 Q) I$ R, @: o* Q" g4 m. E
- INX4 D4 y! N$ t1 A4 S* l$ C
- BNE Init_OAM_Ram_Write
t1 ?3 k( z7 O {3 z - RTS
& k0 m# e3 x8 \6 v; K - ; L$ X" A* T0 h
- GamepadProcess;手柄处理
2 v$ n* I/ y6 o& e! u5 w% [( \ - JSR GamepadDatacan! ^# R2 @4 @+ W4 I8 |. \) v
- LDA <Gamepad_0_Value6 T8 b5 }" _2 K% y3 Q5 _7 n- w
- STA <Gamepad_0_State
1 f% l! w( A: w. E4 d - LDA <Gamepad_1_Value
! F# n+ D4 z3 g - STA <Gamepad_1_State
& g1 }1 W# r' x. M1 U* k! N& h9 H - JSR GamepadDatacan
% H3 c+ T& Q! c- N O0 E: O( X - LDX #$014 Q; C* t3 }8 J% [3 z& D
- GamepadMergeCheck;合并手柄输入检查& _$ o% T) h6 C# M, B) r
- LDA <Gamepad_0_Value,X
7 _7 B% Z9 M, p" ` - CMP <Gamepad_0_State,X4 N6 S2 P- \' {
- BEQ GamepadMergeInput G% s! b5 c( e U5 R! K7 ~
- LDA <Gamepad_Temp,X
8 Q3 [6 K+ |9 w6 @! R: T7 F. T- t - STA <Gamepad_0_Value,X0 r D' T6 P: }; p; V) ]
- GamepadMergeInput;合并手柄输入
1 D% @6 m- q' r# Z5 I - DEX
& o( c0 {0 C5 W; }4 k1 r - BPL GamepadMergeCheck2 \: j% F% b( t( B" c7 [) D
- LDA <Gamepad_Merge
+ |2 L3 |- O( J0 L. Y* T7 U* b - AND #GAMEPAD_MERGE_FLAG
/ i; |$ u0 a7 d/ X7 u - BNE GamepadStateProcess
4 v" k% C$ K/ M! Q: N, B - LDA <Gamepad_0_Value
5 ^; o4 O& n! d# |8 B - ORA <Gamepad_1_Value
& r, y! b9 N( a7 W8 X% I - STA <Gamepad_0_Value& l- B$ l7 ?( a3 ^
- GamepadStateProcess;手柄状态处理
8 S. p' B- H3 g% T8 t3 d - LDX #$010 ]3 r7 m3 Y' {. @1 g5 \9 R
- GamepadStateSave;手柄状态保存: z6 j: [0 X2 O& `
- LDA <Gamepad_0_Value,X) q% E' ^- I* O* @) b+ N( o/ y6 g
- TAY
4 i* t H0 G& @0 \. q - EOR <Gamepad_Temp,X3 ~( G8 Y. ~2 v) f2 B% z
- AND <Gamepad_0_Value,X
( B, v& b$ \2 O' P, ]7 O. j7 n2 L - STA <Gamepad_Once,X- f3 w H( v B ]& E
- STY <Gamepad_Keep,X1 J" H1 d- A( G: J. }) J* G
- STY <Gamepad_Temp,X
( i# V' T$ {" G/ |6 U2 \! U - DEX) D9 U6 `1 X$ u( d$ s
- BPL GamepadStateSave
7 z* B5 t y x \6 Y r" e1 \ - RTS) T4 ~( [# [) P5 u1 D8 C& O3 S# I
( Q+ \; D$ s0 m% ~5 v( Y8 R- GamepadDatacan;手柄数据扫描$ T4 {0 Z- O9 n- F* X9 k. C( N: g
- LDX #$01
4 x! P; X4 r( r/ L7 N; U - STX $4016; g. E" d# E4 B( v
- DEX
8 M$ R/ x) {7 H. c, Z - STX $4016
- F* \( h) B: d2 E - LDY #$08
% s. h3 N8 {: }# m9 d G - GamepadPortScan;手柄端口扫描
- F+ ^8 ^) C0 a5 \% f, r5 Q - LDA $40165 _, w' W! t! A! C
- STA <Gamepad_Port_Value
! F P7 k. \- R7 L& _6 B4 \ - LSR A/ @4 b9 V0 {7 D6 x
- ORA <Gamepad_Port_Value ?4 \' e* p- ^! _+ T" `4 c
- LSR A5 l( S# ]9 n/ o8 [ j
- ROL <Gamepad_0_Value! b& `. s* _8 e& ^3 _5 F
- LDA $4017, c/ V9 b+ M% M6 \$ j$ D9 x
- STA <Gamepad_Port_Value
% D9 ~* b0 Z9 U p, x* f" W- _, c - LSR A
7 H. \& ~5 s6 ?# e - ORA <Gamepad_Port_Value
1 M+ N6 ~" Z) h% I, s% s! j" ]* e - LSR A( C. v- b" o( p4 ]1 v* ]
- ROL <Gamepad_1_Value
0 L7 y5 B+ T; |0 X _ - DEY
2 j( J9 n' E, z* G" @ - BNE GamepadPortScan
; w) a/ R$ b# i% c, n# F - RTS
+ W$ g" q) I J" q -
$ V5 j# N0 [" U6 R6 Y" P2 i$ F - ;==================================================4 H/ W# ^- T% E( j, O
- ;PPU处理9 C) f+ L3 W1 x6 I" n- c' i3 R1 l, {
- PPU_Process4 C6 r3 b, @( p
- LDA #$00
$ i" D/ h6 x2 } - STA PPU_MASK
' v0 i" K9 m; O/ }$ _3 C) [* g -
% Z3 d2 b, V1 |+ a; R( a" u& J - BIT PPU_STATUS
* i9 ]. `8 X; O9 } @; A - LDA #$203 r9 Y9 B/ O) I( ^9 z
- STA PPU_ADDRESS
5 x3 i. ?4 T) _, _8 L, M - LDA #$00
3 z# z- k. }4 ]$ X" ^. X$ H - STA PPU_ADDRESS
6 r7 t0 T2 R* Q/ Q - 5 G9 z, V' |) z
- STA PPU_SCROLL
- |. q6 Q9 G/ M' w5 w4 D/ g0 g - STA PPU_SCROLL+ B8 Y W3 G; {6 M- H8 Q
- 9 Z# H8 K* \' S
- LDA PPU_Msak_Buf
' ?4 G' ~9 G/ d s; o+ m - STA PPU_MASK' |+ [' L+ [8 x$ Y9 @ ~
- 2 t# f" I# R9 @+ v
- RTS
# [1 p) {* d" Q9 l% E- N -
3 m$ D2 P6 W' V/ R- M - ;==============================
6 |4 N, h4 \) h& W' {( A2 c4 y. ~ - Time_For_Vblank;延时等待( p) g4 w2 d. g- `
- LDA PPU_STATUS- t/ N% R& ]3 R z: P* N. R
- BPL Time_For_Vblank4 s* C9 b+ q* t5 a% u
- RTS
1 M, G7 c2 w' t+ g0 y -
4 p" ~+ `' ]$ i g2 N4 ]* w - ;==================================================
; F6 Y3 i, j( t3 Z+ g: Q5 _ - ;初始化MMC5+ ?! A; v! b1 F8 |
- Init_MMC57 _* t. t6 [# _7 o4 z
- ; e& J+ ~$ N! H! g
- ;设置一下6000-7FFF的RAM7 F7 c5 k3 D" j' v+ b
- LDA #$00
# |0 X! Y8 `" B& ] - STA MMC5_PRG_BANK_60007 H6 U1 P" F4 _* }: ~, }4 h
- 5 W( @, ~+ x- G7 _0 B4 }: h: b
- ;开启 PRG RAM 写入
1 _5 n3 e7 T: |4 L2 { - LDA #$02
4 y! @- i9 ?( W9 U9 \6 H" g - STA MMC5_PRG_RAM_PROTECT_1( g* v2 ]9 U" B
- LDA #$01
6 w! b2 a% ]" k8 p+ i9 [ - STA MMC5_PRG_RAM_PROTECT_2
$ \; x; x+ N/ I8 M, U4 q -
0 G8 N b6 e- l; T - ;启用 1KB 扩展RAM ($5C00-$5FFF)3 b5 b$ R2 O) G2 `3 f5 \2 t6 I
- LDA #$02
, f5 R0 j- @: l - STA MMC5_EX_RAM_MODE5 K& Z* R" \2 t' C" O. C* m
- ' f* a& y0 d" g
- ;设置 CHR4 M+ }# w7 l4 f; y/ E
- LDA #$00
7 w& w* `! h. Q& a - STA MMC5_CHR_BANK_0000
3 W2 {9 `5 h8 f: W, M - LDA #$01' R% k+ a& J4 X- j: s
- STA MMC5_CHR_BANK_0400
: |3 g: l, O: ?8 U- y- q: e8 A - LDA #$02
" F8 U- ~, x0 V3 @3 w1 w7 }: J - STA MMC5_CHR_BANK_0800
6 L5 G4 d9 S- g0 G; d - LDA #$03
, D' ^1 H+ J5 O8 I - STA MMC5_CHR_BANK_0C002 T0 A. n7 e( l
- LDA #$04
( b5 w$ R) N J+ k& P. f; _' C - STA MMC5_CHR_BANK_10008 m+ x1 n2 L v |* Z# O, w1 J/ B- M
- LDA #$05& V0 z' e8 a4 H! {2 m2 e
- STA MMC5_CHR_BANK_1400
. U: ^& [/ v# D( c3 ^8 i" f/ y - LDA #$06+ s4 i: y4 \: o: K# @( _; f( z+ O) F' k
- STA MMC5_CHR_BANK_1800/ T4 U' \3 g: K4 z
- LDA #$07" G6 x; E+ Q% Y, g+ L5 W
- STA MMC5_CHR_BANK_1C00
4 Z, ^8 T0 }0 o% V -
7 }- n8 r2 y j0 q8 [# p1 Z - ;设置屏幕镜像
w% u0 ~6 }9 E/ j8 O+ C5 E - LDA #$50
3 i# U! R, |7 E4 e" q6 V - STA MMC5_NT_MAPPING
2 `. n s4 z' f; g. K1 _2 ~ - : C& ~( Z' o G7 @/ ^
- ;禁用IRQ
; ^$ I7 a Y) s% B* C) a, v - LDA #$00
6 a: a0 n# c6 g: z - STA MMC5_IRQ_SCAN_CMP1 c1 R% F& ^% ?" y! B
- STA MMC5_IRQ_STATUS
) F+ q* u4 a6 Q - ) U0 e9 c. s6 z8 K z
- RTS
% a+ W' v# a2 D6 c/ o' t2 X$ G" ` - . L7 R' d: s r* ~, A, ^
- ;==================================================
4 g1 |: C/ f% `. H z: Z5 y8 R3 L - ;重置中断处理 L: _! r# h0 K3 V
- ResetProgram1 z! f& I' L; L6 |" b* l4 e1 n* b! G1 a
- SEI" i9 a- o6 M! f+ k0 q! j+ o
- CLD
# @( E, f1 Y ~0 P - LDA #$00* ^7 I& q( d" ^* g3 T' y
- STA PPU_CTRL
: U- t# Y. h6 i" u4 C - STA PPU_MASK
7 c7 p7 [& `( b( a4 l0 z2 F: b - STA PPU_STATUS
8 w2 B# q9 `% d) X3 Q1 f - STA JOY2_FRAME1 ~, J8 O% y5 D, E
- STA APU_STATUS8 k. q1 {9 S$ Q4 y' i0 m( g
-
# M- _2 o# ~2 c6 U. M! V - LDA #$C05 L. ]+ f8 b& S( q% W7 M
- STA JOY2_FRAME5 O- T7 V) a8 b, C+ Y( H n% `
-
. R# |1 B7 S3 k8 e% }# P - ;等待vblank( g# E" `# @3 M7 W+ {6 Q$ T
- LDX #$026 u: \: F! c6 u' i% W% ~4 S4 C
- Vblank_Wait_1" Q4 g N4 m# H
- BIT PPU_STATUS5 ^7 b" b6 g9 p3 S
- BPL Vblank_Wait_1! v# F8 x ?: X Q8 L/ Y9 L
- Vblank_Wait_29 r7 y/ \: W+ c% i, c! t
- BIT PPU_STATUS
+ Y0 R. K. ^; Y% Z: m - BMI Vblank_Wait_2' I5 l% U6 p" g' ?) U
- DEX- @9 c. |) r$ i! b
- BNE Vblank_Wait_1
3 k0 p l' K) | - * R( p' ]# X* f% p2 E( Y& M
- LDX #$FF% J H( W$ G' I @) x6 I
- TXS
( ^% r3 E5 u' j, b8 G# U -
' o2 }& w) U6 y - ;初始化MMC5' W. G" d) X) U3 ]
- JSR Init_MMC5
0 D" G( I/ H \) S4 c -
& T S V$ U4 F4 Q j5 O. v - ;==============================
7 d2 z5 K5 F9 A - ;RAM初始化
) Y6 Q- e* B1 N - Nes_Ram_Init0 ^( J5 `; O8 T, i, S
- LDY #$00$ u' f9 n `- ]/ [# }
- LDX #$08
. d7 ^! O' Z& u: S* ^ - LDA #$00
2 s# R" o4 x% o% r( |$ ~- y, s - STA <$00
& _# c5 \* l v! }! o - STA <$01
+ w% P g8 n. ]% }' v" ^+ v. t - Nes_Ram_Init_Write% i' d# @! C1 U# k6 N
- STA [$00],Y
. p( H) o: ~8 p) W8 o m/ y6 u2 i - INY# ?3 a. |; l1 W6 ^( y* ^, D% D8 W
- BNE Nes_Ram_Init_Write! L' ?7 G5 r) F$ y' L# X5 g- o
- INC <$01
' }0 \; \4 |4 N - DEX
) E. A9 T4 S& M, t - BNE Nes_Ram_Init_Write
# M, D) U W" h; G) B -
6 G0 l b+ F% ^2 S - ;初始化命名表
7 n0 r' ]- F, V% e' W - JSR Init_Name_Table# C7 q5 N, u) O% M; r5 x8 |6 s
-
6 U4 `+ G- A2 L - ;初始化调色板/ L% D6 n. G% E! a9 \+ B0 Y
- JSR Init_Palette
. e- P/ B8 p6 H. W* E -
/ M3 F7 A) U) h- ~6 G0 @ - ;初始化命名表属性% ]; D% e3 `, M% x. J
- JSR Init_NameTable_Attributes7 w) u$ C7 Q8 S" h# Q
-
1 v5 p' \: ?" [( s; o% U - ;初始化精灵内存0 \% A% D2 q. u- a6 k+ l' _" v! ~
- JSR Init_OAM_Ram
. |& F, _- A+ Q, W) ] -
( o5 m* H( b5 P/ j5 Y. Z - ;在屏幕上写点东西
@2 D# E( _ c+ Z( e% \/ K/ I8 m - JSR Init_Name_Table_Text
. Z0 X& v+ A3 K1 E - ; W* p: z4 H) ]% [ y
- JSR Time_For_Vblank2 _( E) [" ]- m: y6 K) q
- ;开启PPU控制! _* T6 U8 ^3 Y: P! N. s- N
- LDA #$88
! K# _) l* N$ t8 |$ } - STA PPU_Ctrl_Buf
! c* a5 m" O2 v1 I - STA PPU_CTRL* I9 \& V- o; d c" x3 }0 R0 S, b7 f' c
- " ]! U7 \' d O% ]. P1 g
- ;开启PPU显示0 }6 q% G, Q8 P! g. }
- LDA #$1E
2 ?: b D4 K) O5 v - STA PPU_Msak_Buf$ c) L0 `$ N7 D/ y7 W: x( ~+ L" z
-
, H- Y, t) @( l% r% [ - CLI
9 e/ r/ V6 C) |3 e7 |) B: v3 v) Q, U - JMP Loop. X( G+ y) _9 V( ?/ O( K2 `
-
. z0 X1 ]8 K2 [ x# J- G& Z9 U# [ - ;==============================1 X% q& C" j) d! ^) M- }) _
- ;死循环, 等待NMI中断% B4 b) w% W9 j
- Loop: S& T$ z- H" v0 [, Z
- JMP Loop
) H3 j* ]2 T' W- ?4 E3 t$ [
# g4 V# X1 I2 r( B- g9 ]- ;==================================================
2 I" B6 R& \' t3 p! ^0 b6 a - ;NMI中断处理9 r: ?- B- U' q9 P; o+ t
- NmiProgram6 p6 w( H* p* S* A
- PHA6 }. [/ w: h) i
- TXA
: W2 ]2 h6 l4 T: a5 K. W) L% H - PHA
5 @/ b# }5 [) H; s6 U - TYA
8 _; x/ E9 Y( W - PHA2 {" B6 r$ z! w% {2 ]) W# g4 G& i
- ; Z. P S$ [. ^' P
- BIT PPU_STATUS4 k; j; ?$ m* v+ O2 a6 A
-
) A# }* X& H7 v. @ - ;启动IRQ中断, 第16条扫描线触发& O! V8 u9 g7 |2 C8 t7 r
- LDA #16
/ {# G. M" u. U# M% `! Z - STA MMC5_IRQ_SCAN_CMP% h5 T {' R1 U" R) l1 z
- LDA #$80
# N9 J1 Q6 {" \ - STA MMC5_IRQ_STATUS
, Q4 G: m4 `* h& x - CLI
+ x+ K7 n1 t% y+ B+ B' h - & e3 v# ^( w+ X. F8 h; X
- ;关闭PPU控制/ @! ]1 T. m( X) @5 G- o, Z
- LDA #$00: k1 m4 K. f5 H( r2 w% n F
- STA PPU_CTRL
0 s+ F) h0 t0 p - 4 M$ L8 t) u- H% f
- ;处理PPU& G& m3 o" w' A
- JSR PPU_Process
. ^( ]8 ]6 Y/ U6 {2 z2 ?1 O - " `+ J. A; H( Q }- X9 K+ m
- ;开启PPU控制
3 ~4 P: t, ?9 _- H0 K. A2 z$ ~ - LDA PPU_Ctrl_Buf
! h) A5 A) Z( [% {9 ] - STA PPU_CTRL: K( i. s3 l3 W0 r1 y
-
* `! ^& \8 T; H9 S - ;手柄处理
# b+ n' {; {2 G; L8 P1 N - JSR GamepadProcess
! t7 Y& R9 Q b5 L; H7 V* |& l7 e* Z - 4 Q- H E( m& H+ g8 ^
- LDA #$00( P, q5 Z, S3 t- Y. L' P
- STA IRQ_Index) E, s. k! o7 N; G7 [1 H; v
-
% S9 u. ?0 W; ?; ~ - PLA% ^$ C! Y3 {" [; z9 {, [" ]
- TAY
. P' O, C/ P7 p- e' R4 [ - PLA6 C1 @+ m9 D6 E5 r* P# N
- TAX; A3 m# K$ N- A2 j0 }- A
- PLA4 Z/ P* ?% ^* m* b6 S" Z3 `* r
- RTI" ]* s+ c2 Y- u! j2 a- _
- : ^; {7 _4 W2 x3 |( Z
- ;==================================================
6 O x$ }4 p. E - ;IRQ中断处理
5 U6 F( p Y2 @% M8 ^ - IrqProgram, ~2 n% v/ b! A R7 S; w, x
- PHA
' h8 \" W& G& X* B. v, J - TXA6 D3 O0 k( ?7 u
- PHA
: ?6 n0 }; v% X X: H! M7 b9 _* I - TYA
. C0 E8 w0 b3 r. z# C) v - PHA
, T! m- _3 [0 r5 v9 s -
8 m; \& R$ S/ h% a7 ` - ;确认IRQ
" }# ?6 {* }5 G0 L6 {$ I2 |' W - LDA MMC5_IRQ_STATUS
" |3 W0 Z/ T s8 e# A/ a2 d9 h' B - 6 T8 \0 L {; s
- ;允许下个IRQ触发, E a6 Y2 s4 T, |/ I
- LDA #$806 |, u: U+ ]6 k. C& N
- STA MMC5_IRQ_STATUS
- U* t* W' Y3 C; f8 w$ s! P - 5 d, ~) D9 d1 o- G
- ;IRQ处理, 每隔16条扫描线触发1 o9 N- H- Q+ d/ g5 B5 K; f2 o
- LDA <IRQ_Index
% L5 Q U" ~/ s - CLC6 ~# v. C( ^! ?# V; \$ D. l
- ADC #$02; i+ ]) ^; Z* |% W' Y6 m
- ASL A
4 m; c/ Q6 |8 Z# ~9 H - ASL A6 c0 O) |# M8 U9 ?9 I) }
- ASL A8 s8 |/ `9 b- _
- ASL A0 l1 J3 @1 G) z' T1 [2 V( ]7 x0 ?
- STA MMC5_IRQ_SCAN_CMP
4 I6 b% Q! l% \! I; `, Y -
6 ~5 e4 U! X5 z! M& l - LDA <IRQ_Index
5 z: i, C/ w! v9 x: n0 w - BNE * + 4! F+ Q7 y% j6 G
- INC <PPU_Scroll_H9 P2 C+ D. r' U4 F4 ]
-
* G: ]. Q) P2 n5 t; H- F - ;设置屏幕滚动
/ z% G7 f7 t" l - LDA <IRQ_Index
5 y+ u$ o( x- v. q) K$ ~% p - AND #$015 D! @2 u Y: b. S
- BEQ Irq_Scroll_Right7 m/ h$ t0 Y! r- v: y5 t- U1 g
" g) |1 `7 P- P! @- Irq_Scroll_Left
& u6 {( a* J# n4 Q' k5 y - BIT PPU_STATUS7 P, o1 S4 y# E/ h% T
- LDA <PPU_Scroll_H: z7 ~( B: ~1 `7 U
- STA PPU_SCROLL& e/ m: z6 m3 J; h# f1 v$ }
- STA PPU_SCROLL E9 a: _ M9 k. J0 |$ M6 ]5 O
- JMP Irq_Scroll_Over
% R' a2 R* e! b3 U -
! e" f: N2 e" B: _% d - Irq_Scroll_Right9 e& R3 H" I4 d+ E3 T
- SEC4 D) O, i- {) @
- SBC <PPU_Scroll_H6 t; z9 L; w4 t' t
- STA PPU_SCROLL* M* o4 r9 R, D" p0 @4 S
- STA PPU_SCROLL6 |9 W0 Q# ` R( E& W
- Irq_Scroll_Over
! K# i. s* @3 ~6 K" _ -
W3 R: M& N, Q: c1 @ - INC <IRQ_Index
9 S A' i7 r+ R -
* l" a" v* q0 z$ f4 v - LDA <IRQ_Index
# X: y4 Y% K1 O9 Z% [8 w1 [& @! a; U - CMP #14) k# h3 P9 {# Q9 n. b" w f
- BCC * + 5, e1 l, n# x" [; [1 c5 Y
- ;关闭IRQ% _1 V1 c; ?6 o) d3 i
- LDA #$006 h( ?3 G, a6 U; M _2 c" L8 g
- STA MMC5_IRQ_STATUS% R+ G5 j6 L: N4 c# R
-
$ O5 m0 G e5 o2 g - IrqProgramEnd
" h) {" q4 u& \3 }2 b! L; q - PLA
1 t, ~3 B4 H2 D' u; w - TAY
/ ~) }/ j) B8 U - PLA/ E& p* [) c' F$ F" G5 w6 x
- TAX! D. w2 d4 e6 |6 c. }+ Y4 a+ Z
- PLA! R q' x: |& }! q. N3 v9 M' J, ]
- RTI+ q9 N1 s0 V& W
-
5 o: ] W: [3 Q% m- m$ d - ;==================================================/ A4 j5 U+ m& b4 j
- ;中断表* A$ ~* W( e& q9 N' c! C, v
- .ORG $FFFA
" r& `. }3 r7 L2 ]! Q - .WORD NmiProgram; a: u x3 ~* b8 b
- .WORD ResetProgram" d' `# N7 Y/ j7 D) o% W
- .WORD IrqProgram
复制代码 9 L3 `& {4 [$ m
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|