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