|
- ;[FC音乐][MMC5 IRQ]
H7 m( A+ p5 ^" w - ;FlameCyclone 20230710* M9 F3 @% ^6 d) q; F i, a4 s$ M; x
' M3 A6 w! m& K( ~- ;文件头
* K* N# M. [- O t6 F v4 Y - ;======================================================================
- I* f$ Z2 u! B0 ? e, S J - .INESPRG 4 ;16KB PRG 数量9 t3 w' |. ?* l, U) h6 q' k$ k
- .INESCHR 1 ;8KB CHR 数量
: F% D) Q& N4 ^ - .INESMAP 5 ;mapper 5
' B6 O% ^5 {$ v) \7 W - .INESMIR 1 ;命名表镜像 0水平 1垂直) B) p4 d4 W5 X3 e1 U9 B/ O
* D& U4 R; N. v. t) M5 n9 u- ;必要条件
! r6 I/ T8 P P* b* @( \5 c - ;1.持有CHR ROM* y1 _, I) S/ h
- ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000
% ~& w9 S6 x. N! N5 @0 { ^ - ;3.精灵内存(OAM)不为空9 m2 a. U; O5 ]3 i" q
- . ~7 H1 _% n, ]7 \. C
- ;==================================================
. \* z9 }* N; ^& H6 p5 ~4 g - ;NES端口常量
: M4 z3 C+ n& o y9 w7 C: T- L* P - PPU_CTRL = $2000 ;PPU控制寄存器
2 z7 }/ y* x' C5 M - PPU_MASK = $2001 ;PPU掩码寄存器
; y4 C$ |$ w+ Y# R9 V! l, i1 I - PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位# C* X- Y1 }2 e% X
- PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
0 F, A" T# ?, `7 [" s1 ~" C - PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1" r/ X1 {8 G2 R% G: G! U n
- PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 - f ^4 [- I6 ?6 k8 b$ D* j
- PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
# I5 J: ^/ E4 k( W - PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 5 z. g* Y0 x; |( k. V* F+ b
- OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存! d! Y8 }* u- |1 Z
- APU_STATUS = $4015 ;声音通道切换: R! g/ j, H9 ?6 ? o+ |3 _; X
- JOY1_FRAME = $4016 ;手柄1 + 选通
' s5 ~# z- ~: [6 W4 _. ]4 K! c - JOY2_FRAME = $4017 ;手柄2 + 选通
; b9 _2 s: E0 t) }; G
/ |' z1 g& E5 _- ;==================================================' j) P9 F' v' \/ d; R
- ;MMC5端口常量
9 C% u$ e: v J+ Z" G b - MMC5_PRG_MODE = $5100; 0: 32KB 1: 16KB * 2 2: 16KB + 8 * 2 3: 8*44 m6 b( M1 h. P( e1 r' v9 s
- MMC5_CHR_MODE = $5101; 0: 8KB 1: 4KB * 2 2: 2KB * 4 3: 1KB * 85 f5 k7 d3 h1 @- }" u3 Z) \
- MMC5_PRG_RAM_PROTECT_1 = $5102;- H0 q `7 P1 k: T9 c. R5 i5 U' `
- MMC5_PRG_RAM_PROTECT_2 = $5103;/ f! S! F" t9 Q) a" y1 r4 Z
- MMC5_EX_RAM_MODE = $5104; 0: Write Only 1: Write Only 2: RW 3:R$ B& r( r- n5 `5 F' ]8 T& v
- MMC5_NT_MAPPING = $5105;
+ _# Q/ z; O0 Z p5 k - MMC5_FILL_MODE_TILE = $51064 T. w5 L0 L3 u
- MMC5_FILL_MODE_COLOR = $5107
; J) Z! ~: z5 u3 e# C- F
: X+ A2 {- j+ i, N- E- MMC5_PRG_BANK_6000 = $51138 h+ c4 g" \* w' i
- MMC5_PRG_BANK_8000 = $5114
* J) e! F: S; x' b/ m - MMC5_PRG_BANK_A000 = $5115/ C8 c8 B5 F# D
- MMC5_PRG_BANK_C000 = $5116% k& C7 ]2 H& ~! L- k
- MMC5_PRG_BANK_E000 = $5117
3 ^; C& w G" {9 i+ C - 8 X3 l" l/ P% ~, n
- MMC5_CHR_BANK_0000 = $5120
! j5 u' S# i" v# R$ a( C - MMC5_CHR_BANK_0400 = $51210 t6 O4 x8 ~* A: r; J* V
- MMC5_CHR_BANK_0800 = $5122" }0 ^; ]7 `/ |; s8 ?
- MMC5_CHR_BANK_0C00 = $5123
0 `+ d% w0 f2 w' n: r - MMC5_CHR_BANK_1000 = $51246 R* [+ W- _$ t& k& d/ L" I& L- h
- MMC5_CHR_BANK_1400 = $5125
/ w1 h' x0 n t$ o1 G, w7 o - MMC5_CHR_BANK_1800 = $5126
# ~) e1 {$ ?7 S - MMC5_CHR_BANK_1C00 = $51272 ]* o- N4 u0 C5 Q: Q5 y. @" U
) N# K( v, y3 X# Y; G4 |- MMC5_CHR_BANK_0000_1000 = $5128
# e! l5 T' c. o - MMC5_CHR_BANK_0400_1400 = $5129+ P8 N/ V. L! j6 n2 o6 ]
- MMC5_CHR_BANK_0800_1800 = $512A6 ]* T% j2 Q5 F
- MMC5_CHR_BANK_0C00_1C00 = $512B* Y3 i$ g! s9 p. [
- 3 X2 [; b$ o& C) o2 w
- MMC5_CHR_BANK_UPPER = $5130/ x( T. e f! w' F1 Z8 L6 [
- MMC5_V_SPLIT_MODE = $5200- C# Y/ m6 M- S6 M# l0 H
- MMC5_V_SPLIT_SCROLL = $5201
; p: M/ V6 l- Q- ~ - MMC5_V_SPLIT_BANK = $5202# A! Y4 T9 N5 B% ~6 F. [- o/ {
-
- d0 ^0 m; M* r5 Q: j H - MMC5_IRQ_SCAN_CMP = $52034 }, D6 w Z- O4 b2 H% ~
- MMC5_IRQ_STATUS = $52041 u k& F. N/ n/ C# m8 J
- MMC5_MULTIPLIER_A = $5205
% ^% O8 {& _$ l+ o, O8 m - MMC5_MULTIPLIER_B = $5206' A- }9 i7 \' N+ D
- & L+ C6 M$ O, \/ W
- MMC5A_CL3_SL3_DATA = $5207% o2 ^1 @/ q y8 w2 ?( g
- MMC5A_CL3_SL3_STATUS = $5208
/ O2 D! J# v0 L# V+ r+ H- b - MMC5A_IRQ_TIMER_LSB = $5209
' _. V9 l# k( p - MMC5A_IRQ_TIMER_MSB = $520A) c J0 S$ |: A6 g# i
- 1 o0 P) o7 `- ~
- ;==================================================
+ T$ P4 m& P" x# x5 ?; y - ;程序块配置
4 k0 J) z3 `3 Y, c, R - BANK_DATA_MASK = $07
( u" Z- T/ K% c' O! }9 A - ;--------------------------------------------------
e1 A) t( K( ]8 C - RESET_BANK = $07
' {4 A" g8 A+ O1 C2 j$ c# c - RESET_ADDR = $FC005 L0 L/ L. J: k3 |
! ~0 }$ o1 n1 g2 j9 D- F; ?- ;==================================================
( C6 l; w4 x0 { Q- C+ z - ;图像块配置
- f1 d2 P3 S3 z. F6 P - CHR_DATA_BANK = $08
! g2 @: Z/ C! W# I2 N( j - 3 t2 |( {6 ]* O1 A/ r! i
- ;==================================================7 E" l- p! m- z4 {) W- N
- ;零页内存地址配置' A* Z8 ^' c2 g$ X1 f
- Use_Ram_Addr = $80
7 X- y& C/ p& }" X; X - PPU_Ctrl_Buf = Use_Ram_Addr8 V1 k9 F$ h: ]- t% p- Q" }1 f+ F
- PPU_Msak_Buf = PPU_Ctrl_Buf + $01
7 i! N$ R9 y( z' f: V- w0 Z5 D - PPU_Scroll_H = PPU_Msak_Buf + $016 o4 v3 \8 z) w% J( [$ p; o$ T* S9 g
- PPU_Scroll_V = PPU_Scroll_H + $01- k+ \7 o( {( y4 Y2 E
- FC_Data_L = PPU_Scroll_V + $01
% H! i% ]/ S# p2 Y- r6 { - FC_Data_H = FC_Data_L + $01
+ F1 L4 O7 q' S' X- Y& M# q3 q* I - FC_Data_Buf = FC_Data_H + $012 f, R' A. P. r) ^& i. X/ }
- ;==================================================6 S y, ^8 e4 j* B0 z
; s. L+ B2 [0 K2 s: K X+ o+ U- GAMEPAD_MERGE_FLAG = $04+ Q- ^/ ~ k' J# m, q2 s9 e
- # \0 { w+ J! }. D+ j
- Gamepad_Keep = FC_Data_Buf + 1: e' \+ x/ _3 E; v$ y ~4 f. W2 [
- Gamepad_Once = Gamepad_Keep + 29 f. }5 g" i5 q: |+ s) g
- Gamepad_Temp = Gamepad_Once + 2
, X7 V( q! g( m5 W0 z' N8 Z - 9 o! X$ b1 q; f9 g4 ]* H6 |: p
- Gamepad_0_State = Gamepad_Temp + 2; ^6 E9 {9 B2 f# G5 m- _8 D% ?
- Gamepad_1_State = Gamepad_0_State + 1
- o# b' M ^2 B7 G& q, L - Gamepad_0_Value = Gamepad_1_State + 1# c1 g. H! V% f% S0 t
- Gamepad_1_Value = Gamepad_0_Value + 1% {# X$ L) K3 P B
- Gamepad_Port_Value = Gamepad_1_Value + 1
1 \1 G& q* l5 S$ u* R3 @ - Gamepad_Merge = Gamepad_Port_Value + 1
3 y' s* d, r8 d" g - ! _; [- y6 d5 N
- ;==================================================! Q6 r r" F& ]
- IRQ_Index = Gamepad_Merge + $01
5 F$ E* L* a' u( J - ;================================================== O7 d# Q4 S) f/ n% C# c, M+ N9 K
- . I5 @1 ^( |) g: z
- ;CHR图形数据5 d0 S& {; ^8 ]: B! @. [
- ;==================================================
% X4 i# K) {0 N8 M% R: C2 t3 s% o - .BANK CHR_DATA_BANK+ J" q( D7 l% s9 A1 ^( {) N
- .INCBIN "chr_bank/chr_data.chr"* B f3 X" K6 H3 Z% s$ m
- " d7 n( B* e8 y- B5 T7 v
- .BANK RESET_BANK & BANK_DATA_MASK
q; d3 |7 y9 v. n5 f+ R1 w - .ORG RESET_ADDR6 y6 L$ b, N& M2 C1 x& E
- 3 `' B8 S% ]; I( _: i
- ;--------------------------------------------------
/ L0 [8 T6 w% x4 w - Attributes_Data& Q1 F9 e0 D" W4 _
- ;命名表属性$ j g$ A) K6 F( Y$ e! P/ t; x
- .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00" S% D; X% I2 s* m. g8 B9 t
- .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
2 N% N9 L4 L# Z3 l B+ } - .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
' ~: v% k' O V - .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
/ D- ~1 x0 x1 o8 I- O - ;--------------------------------------------------+ {; A$ T6 `" x" }1 ?
- ;调色板数据
! H4 @) y( g) J' N" K+ J - Palette_Data
+ `1 y! |# _, w ^2 n7 D+ A! Z - .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F9 `( v, @9 x$ c# m
- .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
) f, K9 {' \! s" y5 r9 o( u - , B2 t* ]3 v3 T5 X) E1 N1 q: z
- ;==================================================& U& g% r- X5 h* P( F
- ;命名表初始化
, J+ R& |* K6 _" w q9 x - Init_Name_Table
7 I) X2 o- r5 o; I - LDA #$20
: `( ?7 V) g- p t- j - STA PPU_ADDRESS
" q5 V1 V I0 z6 j" r5 s, h - LDA #$001 V, `/ s; b+ }4 s! k* X, e7 p
- STA PPU_ADDRESS
1 ?) v5 x9 w3 j' D" i' I - LDA #$00
/ W* m7 S. T# o& }# W \; W - LDY #$006 {# V, I" B- W% O7 ^- S. Y) ^0 s
- LDX #$10- v! a: \; r6 |) p( L5 T
- Init_Name_Table_Write
* ~4 X4 m _* G) }% p5 d7 Q) U! B: L - STA PPU_DATA
! w, }7 V7 Z" y+ h& g ?2 V p" v - INY
2 w% f! A* p. o. A0 { J - BNE Init_Name_Table_Write
$ i: z$ }7 n) [; K$ H5 d& R - DEX
! C+ {$ i9 e# u: J3 D+ q - BNE Init_Name_Table_Write n; X1 P, H5 O/ u& Y
- RTS
) F* }. n, o5 J7 K) H# N -
+ v* _9 A x H' ~ - ;==================================================
- v: A1 a4 _, B( l& M - ;调色板初始化- y5 t7 d" |) f: }3 S! B: Y
- Init_Palette
# U! q Y5 q3 Z8 ]# S! O( t - BIT PPU_STATUS
E9 C. q2 e3 s& | - LDA #$3F3 [0 s! d/ D, m' s5 `! h
- STA PPU_ADDRESS* x0 N% S- I. m1 ]9 S
- LDA #$00
$ p! `, F7 e9 B/ f) P - STA PPU_ADDRESS7 z$ N$ Q2 c B# S
- LDX #$00& }8 L9 c* S7 P* g- C' b
- Init_Palette_Write$ e7 B( ~; j0 }6 q* h' ~
- LDA Palette_Data,X
4 p6 B: m& i7 O! r4 E - STA PPU_DATA
. e ?5 t5 Q9 l! P - INX
: U. h$ c% J: q: W - CPX #$20
9 q( N" d% D* O - BCC Init_Palette_Write) U/ ^- S! j* f; J+ P
- RTS' R/ z1 O% [9 Q' l5 T/ K' U' S! r
- . r3 |' N! L# Q* s. T
- ;==================================================
0 k5 U$ P& c4 H" e - ;设置命名表属性
, t5 R w% m- M( K' N - Init_NameTable_Attributes5 ~9 q% l& [2 S/ A+ \! X. _
- BIT PPU_STATUS- g) y3 y) [6 \
- LDA #$233 D. V/ ^( p0 V% y, g+ J# p) o
- STA PPU_ADDRESS
" p1 L! y4 E Z+ i! R! |" Y - LDA #$C00 [! }$ f+ r9 }3 f% |
- STA PPU_ADDRESS2 i$ P% _, P6 x* r+ r, G' [
- LDX #$001 e: s) ?) D& s
- Init_NameTable_Attributes_Write6 n+ h1 C2 z- \
- LDA Attributes_Data,X) e9 w+ p4 _5 r
- STA PPU_DATA
" J" }5 D, F' K - INX
8 U; P+ p, M. V! {4 s9 { - CPX #$405 K9 r4 Z; _( d* p5 C* a! a% n7 G; v
- BCC Init_NameTable_Attributes_Write' d1 F/ E# C; Y. @( B
- RTS) e% k- E {% Y: t. n) Y
- 5 u+ e+ p0 B% U5 P+ U5 q( [. k
- ;==================================================
. }+ v# {1 B8 e3 r% }& { - ;初始化命名表文本
$ p1 M7 u* P6 N4 O% J6 n - Init_Name_Table_Text7 d7 u# @" I6 n2 a0 U) B/ o
- BIT PPU_STATUS/ F+ t9 P4 @1 {; s3 q; U* T
- LDA #$202 ] k1 Q: r1 ~+ ?/ m7 D5 m! l4 A
- STA PPU_ADDRESS
2 p' j3 ^! o1 y$ O - LDA #$00
. w: R. X z4 X! ` - STA PPU_ADDRESS- P# t9 I' k7 `- }
- LDA #$00
5 k* Q% n4 |% v - STA FC_Data_Buf
5 g ]7 n5 t9 i1 z( k - LDY #304 V& y! }6 z5 ~# t, N
- Init_Name_Table_Text_Write
7 d+ ~, R+ F) f# ~! R' M5 C2 i - LDX #321 N4 @1 H' `8 W+ g7 N; R
- Init_Name_Table_Text_Write_Char
5 @) D8 E6 `- \3 R; S( w - LDA #'0'- p4 f0 S$ _& [6 N T
- CLC* l8 S; p7 a) w) |
- ADC FC_Data_Buf
/ T. |2 ^7 e; j J( G2 A - STA PPU_DATA
8 Z* j& ^# |1 a t - DEX
6 C) X8 I7 m2 b2 ~- p - LDA #$14
" o+ \) I" T9 K6 h' u - STA PPU_DATA
! |) Y1 k: `, p# a# D - DEX! ?) g+ c' i4 _% P/ w
- BNE Init_Name_Table_Text_Write_Char
# I: B7 N7 N; Q# G( a8 P! Y* O! @ - INC FC_Data_Buf3 s% j8 u+ W. i
- DEY8 C" s9 U$ i) B
- BNE Init_Name_Table_Text_Write
O; q5 O {3 u& O - RTS! S6 D5 c( H8 g, z6 d* d
1 s0 R" ~0 X2 f- t' L- ;==============================# q; L$ B% i$ W# g
- Init_OAM_Ram;初始化精灵内存
0 A" o, T- T/ k' a: p - LDX #$00! @( A6 R. l2 q. j6 W
- LDA #$00" H o. P2 k3 k2 e8 m. O# b4 K) U
- STA PPU_OAM_ADDR
' T$ F! G% a! x5 a3 }( | - LDA #$F8
4 R! H' r& ^2 Y - Init_OAM_Ram_Write
& h; N! d; h$ p9 J7 A. L- { - STA PPU_OAM_DATA
. ?& F+ }" b3 J( a - INX
. n6 S) R+ r' u! Z1 ~, a- l1 r - BNE Init_OAM_Ram_Write
4 f; }9 W; a: e - RTS1 h7 A* ~) A" V- B( W
- / Y4 b7 Q6 a; `2 k3 c
- GamepadProcess;手柄处理
* x6 Y5 `) ^# s; E# \" |7 l - JSR GamepadDatacan3 Y) t) F& Q* O- Q/ |! G
- LDA <Gamepad_0_Value
6 f0 o1 h) }6 d4 `8 ^. k - STA <Gamepad_0_State3 X9 t7 ^, K( E5 f& O
- LDA <Gamepad_1_Value u7 J4 Y B [8 t( ?' k; M: G
- STA <Gamepad_1_State3 }& \" Z$ p) z/ V
- JSR GamepadDatacan2 N" X/ s8 q& G# ~5 r" X, X% {) r
- LDX #$01
; D# r5 }& v3 O7 B - GamepadMergeCheck;合并手柄输入检查
! N& T8 |/ U: W) J- E - LDA <Gamepad_0_Value,X
' }9 m3 L: [: K* [8 c! _" z1 v - CMP <Gamepad_0_State,X
1 K% i- U5 K: ?& F/ a0 M7 Q - BEQ GamepadMergeInput
6 m& N4 k/ T& x- u) F9 C0 D - LDA <Gamepad_Temp,X
2 G( v: Y7 F& X; [6 C - STA <Gamepad_0_Value,X
. b' U) M/ a- P7 V - GamepadMergeInput;合并手柄输入
! `3 @- j- N: R, `8 F. r4 k6 A: B - DEX
9 ^6 I0 u6 M3 y - BPL GamepadMergeCheck
' j" g3 c0 m4 Z$ B - LDA <Gamepad_Merge- k ^* \! m4 k) ~; I. F
- AND #GAMEPAD_MERGE_FLAG
v7 B8 r$ B' T4 @& _6 }# ^+ H; X; q t5 n - BNE GamepadStateProcess
k" V- |/ W* Q+ e" A0 ^6 N - LDA <Gamepad_0_Value1 i+ V, O, ]1 D0 |1 Q5 Q3 X9 \0 ]
- ORA <Gamepad_1_Value- V9 p) Z9 E$ y- |, k" D; L1 r
- STA <Gamepad_0_Value0 D! [) X) _, q
- GamepadStateProcess;手柄状态处理
Z" n0 f8 D+ G - LDX #$01
4 ^7 D; m9 i7 r5 z2 o& ~ - GamepadStateSave;手柄状态保存, c* g6 w- P4 W$ g) @' _" H$ v2 s
- LDA <Gamepad_0_Value,X7 d& a4 P; U* Z3 |) R5 A! ~0 m; S
- TAY
E" W8 D' c; g1 d - EOR <Gamepad_Temp,X( c* Y& R1 n$ _, k
- AND <Gamepad_0_Value,X; W8 w2 B' S; O8 O6 Y ~+ _) o. [' ~
- STA <Gamepad_Once,X
! n1 ^. N) H( p n - STY <Gamepad_Keep,X3 G8 H0 _) \: q& U" h0 y3 W
- STY <Gamepad_Temp,X3 J1 ? M6 } f! X i
- DEX7 E) ]8 t- Y( m4 L. z% u$ d
- BPL GamepadStateSave
) S9 @, W: g0 S. l - RTS
* k+ t2 m/ n# F0 L% @
7 B# e* l7 t; W9 U# k @! V- GamepadDatacan;手柄数据扫描+ ^$ _1 y7 Z* }) b- `/ {& T
- LDX #$01
4 `* N* B% x6 Y; g, o+ z - STX $4016& j* y. z) q1 X- v% `) o3 N
- DEX
2 v7 ]3 X- V. a# J2 d - STX $4016: F, X. A$ a* @8 T- v) X/ m# O
- LDY #$08
6 K- J5 x- U1 g! d - GamepadPortScan;手柄端口扫描
0 |! p. X1 |" g2 Z% x |$ ?; K+ {; m - LDA $4016! q& F3 p: i/ L+ A$ i
- STA <Gamepad_Port_Value
& Z6 ` l0 v- V2 s% @( { - LSR A
4 G5 C1 G: t* x - ORA <Gamepad_Port_Value& j1 u/ @8 J& A. J7 v
- LSR A4 s6 ~& x( v2 o3 K g; `7 L
- ROL <Gamepad_0_Value
% P, Y( U" M- [+ Y9 X% h* A" L. K - LDA $4017
/ S6 b8 v6 V/ J& \+ P g+ s/ i - STA <Gamepad_Port_Value7 x' E- J: k3 [, `; E/ M
- LSR A( M5 z ]4 ?: l
- ORA <Gamepad_Port_Value
6 z2 c3 w }9 {, K! q - LSR A- i/ }* F* T; v
- ROL <Gamepad_1_Value* d! r! J0 s8 i; M# e5 q& U! `6 K; a6 ]
- DEY$ n, O K" j# d1 M, G
- BNE GamepadPortScan4 j$ K i4 j" V$ \
- RTS
" D# }! h8 }* M% O -
) I+ k0 L# Y$ E% D - ;==================================================7 q& p% N+ ?# w5 M
- ;PPU处理% A7 a r- D3 V
- PPU_Process
/ U' Y6 p/ b l2 v* t - LDA #$00
& E! B1 d$ ]( d1 | - STA PPU_MASK5 G1 r2 W% u9 m$ w. V7 N7 z. w
- 5 ]7 c! G/ D& k# u. s* W& {
- BIT PPU_STATUS: z* e0 h% V4 J9 {: G8 E
- LDA #$20
/ v6 A9 w) L5 P x2 k - STA PPU_ADDRESS
9 }: g, l& r/ @" q3 i. q - LDA #$002 M% r) `* ?; y) q% d
- STA PPU_ADDRESS
, \1 B' g0 Z% ]% q/ ], Z8 _0 } - ; V( V' N6 Z+ o- `
- STA PPU_SCROLL
2 Q. r, J0 v) \3 p2 t5 G - STA PPU_SCROLL
. P/ L8 A6 q# U/ g3 h+ R -
) B) @6 Y5 e3 L1 e9 E6 S$ P - LDA PPU_Msak_Buf
; L0 v- S G, } - STA PPU_MASK
8 l! c! `" q1 {% f# s
9 ~; U8 H6 c: w- RTS) A' s( M) G1 v% E* c- ^- Z+ H
- 1 j4 z9 i6 ]% M. p$ k* V/ C$ m2 W; ^
- ;==============================
6 z* L# i }* N- O c! a" | - Time_For_Vblank;延时等待! X8 y! ?" o- q" P4 I- A
- LDA PPU_STATUS9 P- i( i- }1 p4 B% c/ g
- BPL Time_For_Vblank
; [; _8 ^6 D3 T" Q8 X - RTS( r- K9 Y3 ~4 n8 V
-
/ \4 g; v* t! F0 r6 e8 r - ;==================================================
3 C0 W t8 t4 R( C - ;初始化MMC5
1 x% h. J1 F. {* M2 X - Init_MMC5' R" T G0 O3 ?- r, u
- ( g" I. h3 F2 H4 P7 G
- ;设置一下6000-7FFF的RAM
7 u: [7 B/ m; O. C# P! W - LDA #$00
( x7 Q }1 k- Y2 W* C. G - STA MMC5_PRG_BANK_6000
" d; v! ^) v% l5 w -
3 j5 j+ K" d, B - ;开启 PRG RAM 写入
8 Q/ ~* p+ }* ~( B6 S# I - LDA #$02
) A! _3 w: |" k6 C$ y% e" d - STA MMC5_PRG_RAM_PROTECT_1
( [0 A8 J8 F Y7 s W0 ^ - LDA #$017 O. ?3 K8 \( U H/ a( f
- STA MMC5_PRG_RAM_PROTECT_2
: N* F8 C, m# ~7 E. M1 s4 q/ p! M+ A -
: Q' A% ~& d+ O+ x& h2 B4 l" T - ;启用 1KB 扩展RAM ($5C00-$5FFF)
! l. x( I5 i9 `- n( n. B7 e( B | - LDA #$02
; r7 t, C* ]6 u" L - STA MMC5_EX_RAM_MODE. C/ _- ^7 z0 y( v
- 8 ]0 }, T* p" D I Y
- ;设置 CHR
$ Y0 B. G3 b8 n - LDA #$00/ J0 e" i' B8 I$ S9 \" z
- STA MMC5_CHR_BANK_00008 m r0 `, W" W% Q
- LDA #$01
0 [" O( {( n4 Z( `, w! B5 ?& x - STA MMC5_CHR_BANK_0400
4 a$ n2 f8 i' [: U3 R$ @$ W4 S& V) v# o - LDA #$02" [+ `, u6 Z+ j1 ]
- STA MMC5_CHR_BANK_08007 U4 `) z9 F" Q3 \! d, ^
- LDA #$03
& K* M6 ]8 o q$ A" U, A% S - STA MMC5_CHR_BANK_0C00. _0 @& C* u3 O4 g, v, }3 C; s9 b
- LDA #$04; L6 D1 N# _( G# f& X
- STA MMC5_CHR_BANK_1000
4 q9 {' d( N; N! U2 \; A - LDA #$05, O4 ?3 ~5 W5 J
- STA MMC5_CHR_BANK_1400
: k4 Q! n: H* \& T7 P2 T) `( F6 ? - LDA #$06% E# Q/ u8 z2 m+ F/ N& k
- STA MMC5_CHR_BANK_1800$ W$ T+ ~) ~8 }) ]
- LDA #$07. r `# Y ], A8 L- L
- STA MMC5_CHR_BANK_1C00
. N9 d+ s' u( B( D7 d# M4 ?6 v - + @/ o8 }8 }) {0 ]( e5 d1 `
- ;设置屏幕镜像
+ k) H3 | }5 W& y; P. G - LDA #$506 K( I: m( h* n r6 p
- STA MMC5_NT_MAPPING
6 T0 X' q, E) A y. k; X3 \ - , Q* O9 n; d8 c' G+ [
- ;禁用IRQ
' Q/ `1 ?5 ~$ n% F3 I* V+ k" z - LDA #$00
4 z; O- g+ \# T4 V5 f2 ^ - STA MMC5_IRQ_SCAN_CMP* c# Z2 F; m2 S. V; V' J
- STA MMC5_IRQ_STATUS
4 C2 v% z) k1 C0 Q% v3 w -
( M5 Y/ Y* h/ I1 `3 ~ - RTS. n/ W% F7 J5 w' g. V' {5 R
- # A2 f8 u P1 B
- ;==================================================
5 M7 Q2 w+ ^& @6 D - ;重置中断处理 g# R/ V) I- c
- ResetProgram0 g b, N* q/ I4 W- l9 \+ _( D/ v" H
- SEI7 N/ q3 Q- C6 }+ e- }: H5 b/ b- K
- CLD
9 f5 C* w9 E" R- l, ?6 o - LDA #$00
* }) t* U$ `. X - STA PPU_CTRL
: v! z7 d6 W( {# N$ g - STA PPU_MASK& V; X: d5 f9 }& u1 I4 Q' s
- STA PPU_STATUS
, E. Q- |6 g; ~! y+ E: B - STA JOY2_FRAME2 _) o% D( R& F/ f
- STA APU_STATUS
" y: a4 }9 y8 a -
6 b0 b0 o& k+ v - LDA #$C0
9 J0 _ s4 B6 w& D/ [ - STA JOY2_FRAME
5 b5 G: {, D) O% l! E' S - ( h9 m# w" N" K5 B4 M$ z; G% F* U$ M
- ;等待vblank
* C6 ?& [6 v! E& b - LDX #$02( D {" {, O" O& f
- Vblank_Wait_1
w/ T+ g7 K' J& U - BIT PPU_STATUS
" c+ A, F3 w3 J0 h - BPL Vblank_Wait_1
; L) @, r" f0 k* o; T7 N8 Z* [ - Vblank_Wait_2/ c b& D, M P/ r# G
- BIT PPU_STATUS
! k" R( a: V0 _; {, r y - BMI Vblank_Wait_2! V! A) c& i/ G% P
- DEX
- G1 p# u/ u) G/ g - BNE Vblank_Wait_1
; f! @& ~5 ` k0 V0 E9 g6 ` -
8 `! C# o+ E$ b; j& X - LDX #$FF
# |: D- n$ }, z5 R& N - TXS9 I* g% A# f$ k9 K
- * i' M" |- z7 ?: E; v$ R1 t6 B
- ;初始化MMC5
- |" h0 G! o% H" D" s4 N - JSR Init_MMC5
7 g. }" J- v( C5 Z3 C - 5 _1 j& @* x; `8 o. `* c
- ;==============================
+ D; a$ o* u# L/ Y9 b - ;RAM初始化
' p. j' E/ y3 J - Nes_Ram_Init
! V% C/ b! b6 m( z - LDY #$00
) m( R4 e8 |: c& B- s - LDX #$08
% D5 Z8 E3 N6 ?. u3 J h; q3 I: R - LDA #$00
$ U8 o6 b& M6 y1 { - STA <$00
% g/ f0 U4 e7 d - STA <$01, ^7 n) j) D/ c1 `9 ~/ i
- Nes_Ram_Init_Write+ F9 H1 o% T0 s( F
- STA [$00],Y+ G5 U* M' O( \
- INY
8 y5 j4 L! ~0 n# \- N% D - BNE Nes_Ram_Init_Write
9 A( M& a- g( t6 r9 r# P - INC <$01
" U8 w2 P& u4 V5 ~ - DEX0 R4 ~% j5 l: l: V
- BNE Nes_Ram_Init_Write, E0 K3 z$ U2 F# u+ ?. v) @1 ~, l
-
+ L% e' g- g5 _+ Y( o) a) B - ;初始化命名表2 ?! o9 _% P* U4 J
- JSR Init_Name_Table
6 n/ w2 N/ e P2 } - ' y7 R8 C( {, H% e
- ;初始化调色板
1 P; w' u( w" u1 m$ ?1 D1 {/ ~ - JSR Init_Palette
$ M6 I4 x' a. p0 f! o) g9 Y - ^) E! K. M/ p4 m
- ;初始化命名表属性; f5 }7 E' m7 e* H, \* n x
- JSR Init_NameTable_Attributes
7 f, A* J3 p2 J! X. n2 D% p" e6 S - 1 O* l1 k* Y3 p& [% l' j( f2 N
- ;初始化精灵内存" o$ a4 h2 x. b( \5 @
- JSR Init_OAM_Ram
% t H" J3 `, L1 ? - ; i8 P6 ]8 ^; \ O( d \3 I7 c
- ;在屏幕上写点东西4 m- u8 o0 C# Y5 x2 X2 r' J* w
- JSR Init_Name_Table_Text* U% G- O7 A e5 z2 d; k: R
- ) R# A) w' }5 V. ^& s' O2 G
- JSR Time_For_Vblank
( o* f0 N% N+ }5 I" T; K - ;开启PPU控制3 y$ K- V& U2 U7 Z' D
- LDA #$88
, M0 a; Q9 z" ] - STA PPU_Ctrl_Buf8 f$ c2 z7 n6 {. C( ]3 j
- STA PPU_CTRL
" M& n& Y: Q" v. o, ]2 R -
! p! E4 R1 ^8 C2 m& V. E - ;开启PPU显示2 o+ ^. o$ U3 g7 l% W; D, y
- LDA #$1E
, L. }% M0 m5 p8 }% K - STA PPU_Msak_Buf
1 ^! k+ M9 y5 U9 B -
2 u. e) N/ F4 t R - CLI7 n% ?. F4 P; o
- JMP Loop; `, H7 v5 \4 t9 T; V" n; s4 w
-
4 \% w; q4 r5 A8 J3 Z, w x5 p/ m - ;==============================: T4 s x0 o' U2 s z& d+ z
- ;死循环, 等待NMI中断
/ ^, F& f3 Y: P2 `& s/ z" m' ^ - Loop# _: _7 a! V6 J3 E4 a% F- \; C
- JMP Loop3 G# b9 [$ ^/ ~; A6 }
- ; L+ V2 K6 f! Y. ^
- ;==================================================- \% d' y2 i1 F0 s! i% P& y8 x0 D
- ;NMI中断处理. \0 Y4 t5 F5 L9 M8 Y. w; X7 N8 G h
- NmiProgram0 D' Z- c R8 ^+ e! C/ j3 A9 ?5 u
- PHA! s0 }9 ]# r8 F
- TXA1 I* O; c# ~5 X) O5 Y1 _ \( k. y
- PHA( X, r) F( r2 H. W2 _& {2 A7 m! b
- TYA
. E, J5 R/ u: m9 ]4 \1 ] - PHA7 p- M2 n, j" T, O
- : o) `& o' p, M. a" T' ~6 B; J
- BIT PPU_STATUS
6 t B) \( y% w -
7 i! b) D! W8 X% ?5 V" e. D" b - ;启动IRQ中断, 第16条扫描线触发
' y8 ~: s$ i0 J# @( B! g - LDA #16: u% r! |; I. Q4 w1 R- m: P r+ V
- STA MMC5_IRQ_SCAN_CMP
3 [/ Z- N9 [' T" z - LDA #$80! m+ w( Q% `- k: b
- STA MMC5_IRQ_STATUS
& {! H) H" U6 D4 y5 b% X' C - CLI
; ]9 `1 U- B; |% p c# P -
! M! @! V* S4 \2 j. x/ g - ;关闭PPU控制' H; X3 a9 S. c; K8 x h
- LDA #$00
$ ?/ h# c: B' U( r8 v - STA PPU_CTRL
# V, b3 a- {! @" g- L& D4 y -
" @0 {; {' }9 S, b0 W - ;处理PPU
) o& B: {4 \7 ?6 f2 t5 ~* p - JSR PPU_Process
$ b* F6 K( h" ^ -
c1 S S, y5 e, v! M& D - ;开启PPU控制
: d, b/ A' @! o. L- `) _, c. V! ` - LDA PPU_Ctrl_Buf
; Z+ V1 l9 t0 A# g' @ - STA PPU_CTRL
$ @; M- }. J7 L- Z$ ]2 F7 n -
3 i# H) j/ |0 \9 l - ;手柄处理
' ]: s5 a! k9 d, B - JSR GamepadProcess* f2 U! z8 P+ t
- 9 }0 ~" V/ G4 l$ s9 E. H& M# z$ L( a
- LDA #$00
2 h2 S0 t" b& ? - STA IRQ_Index
9 H/ l8 ?7 G/ a( G+ f& j" x. d - - y+ _ M+ O# v
- PLA
) }$ g6 c. R; R1 u% q - TAY& L! f4 n+ p* ]* }8 U
- PLA F/ S7 H- @+ B' K7 G3 c
- TAX
$ D& M+ w5 b. T1 B - PLA
2 G& m' d. y7 K; |7 ]& | - RTI
6 r! D) H5 n6 |4 M# M8 J. d' j% I5 U
( p2 {2 [- O6 n* b- ;==================================================
, n6 y! j- v! R2 A2 N3 C& O% ~1 p - ;IRQ中断处理
. S3 m D# F- A2 x' W/ u, w. M5 N- p- Q- D - IrqProgram
% F* Q5 O( W/ p - PHA
" R# v; s9 F8 K - TXA
, C( K8 M# L0 g/ ~0 M2 b) X% F5 ? - PHA
% q! y6 i0 T8 M L - TYA
, Q7 j2 X- z* X. J - PHA
* |3 o" j1 h) D+ [6 O1 n( P5 k - 9 S$ M. S& l# H6 `: \2 k
- ;确认IRQ+ L' V: y/ y& T7 _3 f3 a' ], T) L- F
- LDA MMC5_IRQ_STATUS
; T8 B4 d; h E3 ?: y/ H -
6 F3 L: V$ G, L3 k; W# Y" j9 j8 f) \ - ;允许下个IRQ触发
0 o6 ?) t/ S& y' o - LDA #$80
" L8 t; D! A X4 p' ~ - STA MMC5_IRQ_STATUS1 w* E( i. C2 O, r( y
-
( E0 W' U6 `! I( L" V - ;IRQ处理, 每隔16条扫描线触发4 W9 I3 M5 T1 j8 D0 v9 c$ I5 l h" U
- LDA <IRQ_Index0 L& s8 K+ z" m; Z4 p7 l9 W0 Z
- CLC8 Y8 r* V' Q8 n7 U6 E& V8 x
- ADC #$02/ {' D$ Z; D; X( i1 p+ N) w1 B
- ASL A2 d i, S. v3 c7 N4 H+ y
- ASL A
# e/ c) ^- Z7 Q4 x - ASL A9 O$ O$ t2 M3 a* l
- ASL A' }* Y5 s& p: g/ n
- STA MMC5_IRQ_SCAN_CMP8 g: I2 T9 w) ]% r5 o# _
- ; z( R% O6 J% f6 e# p
- LDA <IRQ_Index: ~ {9 Z+ S" z2 F
- BNE * + 46 z7 E8 o/ A% z
- INC <PPU_Scroll_H
4 ~7 e; U$ x. _' {' i! V -
+ V7 Q G* U ], Y/ j2 D- H9 P( @ - ;设置屏幕滚动! @7 L* Z: b6 i8 a2 ~% z
- LDA <IRQ_Index7 H9 @, ?5 [/ A4 M) [" N
- AND #$01' d% F0 z8 \3 V& E5 W4 ?2 F' h
- BEQ Irq_Scroll_Right
+ u, X5 @# y* M5 D( P) N
/ x$ m& l/ o; y" `- Irq_Scroll_Left r8 ? o' M" e& ~
- BIT PPU_STATUS* U8 x8 ^6 K, @$ E( L" |
- LDA <PPU_Scroll_H5 W4 G2 k1 c' r9 A
- STA PPU_SCROLL
! |) P# ?: B* w5 a2 q } - STA PPU_SCROLL
! N4 `. `4 h7 W - JMP Irq_Scroll_Over
$ D$ X3 Y; |- K* X. ^ t - % L1 I$ D/ T6 n
- Irq_Scroll_Right
& F/ ~) ~$ o8 J - SEC2 I; e+ F* ~! S- h
- SBC <PPU_Scroll_H
2 o9 x* v y8 ^# G - STA PPU_SCROLL
0 Y5 r* h! }" [- L - STA PPU_SCROLL
6 O3 B" y$ c0 |9 z1 H/ z - Irq_Scroll_Over
: E$ T) w# [7 y, M - 3 N, L7 I8 V8 G- b
- INC <IRQ_Index
: ?- s# j; C, V& \6 ` - $ m& J+ R, |" v( j; \9 p4 Y* F$ S
- LDA <IRQ_Index% k" f4 I4 E* ] L# D; g. |
- CMP #14" G# T, w& q; q' }
- BCC * + 5
6 a, ]( |. o% p. d8 C2 w4 V - ;关闭IRQ0 v! }7 v6 t# l O, S( x
- LDA #$00
: _! p2 x9 ?6 ]" u - STA MMC5_IRQ_STATUS3 \3 ^ k* i3 v
-
2 [2 D4 d( ^4 i" ] - IrqProgramEnd/ s" V* z" w2 B5 K: Y, ^& O1 @
- PLA: c) R! X+ e: k$ d* U$ b3 x. c, A
- TAY
7 T$ z3 _3 a/ X - PLA
, [" K- v) o# H; b+ w8 |5 u# [5 A# n5 i - TAX8 s& `$ t9 O8 I g9 @; N- d
- PLA. t5 J; c1 ~$ `+ \9 K! ^ A
- RTI
' n' C, i, P8 _5 T6 O - , Y+ O u; x0 E! ~: A% y9 l
- ;==================================================) y6 q9 [9 J2 l4 k
- ;中断表$ _% p6 g1 q" l9 X
- .ORG $FFFA! u7 C& h4 M$ V
- .WORD NmiProgram3 ] {9 z Z5 }# ^( F3 l+ H
- .WORD ResetProgram' ]% F5 h, H" h: x. e# a
- .WORD IrqProgram
复制代码 # t7 Y) k; Y" i! l5 \1 @/ D2 s4 R
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|