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