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