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