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