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