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