|
- ;[FC][MMC3 精灵碰撞]: k7 O- ]" ?" X, ]3 j
- ;FlameCyclone 20230710
: F' N7 |9 G9 O2 C! ] - U, E4 o$ @3 u6 T! G
- ;文件头. I# i. O3 V9 E- ?: p# ?. Q
- ;======================================================================
7 Z3 Q9 z; d' y" X( o& F9 E2 t - .INESPRG 4 ;16KB PRG 数量' \; x* [. F2 M M) k
- .INESCHR 1 ;8KB CHR 数量: l2 O) B7 h" X& s" ^3 m4 F$ L
- .INESMAP 4 ;mapper 4 h# G% [/ l b- ^" U3 L& p
- .INESMIR 1 ;命名表镜像 0水平 1垂直
$ U& `8 b; s3 m/ _; d - $ I# [) _) T( L5 M
- ;必要条件
. ], c$ t* c0 N2 i6 @# i" |# y - ;1.持有CHR ROM8 e: |& a+ Q0 A; C
- ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$1000' {3 t9 G8 ~6 _
- ;3.精灵内存(OAM)不为空* b: c* u7 ~) G. p1 C
- e0 D4 [' \7 D( p
- ;==================================================
9 M7 p* o/ F1 Q8 G; o, d - ;NES端口常量6 g6 l5 E5 L2 z
- PPU_CTRL = $2000 ;PPU控制寄存器7 l& w* h- l& s% o" N. v
- PPU_MASK = $2001 ;PPU掩码寄存器
: L. i9 |' `: L- \+ Y! h5 p, C( [ - PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位" ?6 _! y2 k3 Y, ]
- PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
) p- M2 m0 h6 C1 ^: a2 K- P8 X- d - PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1$ }& g' S( n) U5 _
- PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器
0 r9 \6 K- t ^ - PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
' A$ s5 b6 z" Z* U7 _. p - PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 $ ?5 Z, z! |+ z8 z
- OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存
- N* ^# c& Q* R1 n/ D7 `& | - APU_STATUS = $4015 ;声音通道切换6 r9 k( W8 C# u* @6 ^
- JOY1_FRAME = $4016 ;手柄1 + 选通
/ B8 ~6 ^! ?" G& R m! s - JOY2_FRAME = $4017 ;手柄2 + 选通2 w P( M. @* V6 n- R
- }& ]+ O( A% d9 d: `" I- ;==================================================. ?2 z* Z) d5 v) ^- Z/ C/ v
- ;MMC3端口常量
1 L9 R9 C- f4 Y& |. S - MMC3_BANK_CTRL = $8000
1 P% ~( S- H$ k* S, O- l - MMC3_BANK_DATA = $8001
( A1 \4 k: ]0 R( m2 ? - MMC3_MIRRORING = $A000/ a* _0 S# Z4 C$ j# x
- MMC3_PRG_RAM_PROTECT = $A001
7 x I [- {0 X) W. w; Q; K - MMC3_IRQ_LATCH = $C000% V# y0 b% W2 n1 L5 A1 W8 Q6 K
- MMC3_IRQ_RELOAD = $C001$ W% D$ |( [) _0 F# G+ |
- MMC3_IRQ_DISABLE = $E000
6 P7 D1 M8 K: i8 | - MMC3_IRQ_ENABLE = $E001
5 B- [7 L3 X) g
1 u0 `7 V% }, Z* g. [4 X- ;==================================================& B+ i" t! I1 n ?. S
- ;程序块配置6 }: [% R0 F' P. \: W; y8 N; }( e
- BANK_DATA_MASK = $072 k5 m$ c: t7 E% N9 _
- ;--------------------------------------------------
6 p9 c; W4 T! R$ P! q, P$ C - RESET_BANK = $07; H( g( n- _7 g. c: l3 y
- RESET_ADDR = $FC00" L+ [/ O1 P, _/ D( m
& {+ z5 v- m' N6 {! l6 Y4 h- ;==================================================& O" }/ w# K8 O6 }
- ;图像块配置
1 B1 {, E) X8 p+ r8 g9 ^) N* Q - CHR_DATA_BANK = $087 o& p; t ^; W# g
- 1 [6 l0 y% t7 [ x$ x$ C
- ;==================================================7 [ |* g( X% i, [
- ;零页内存地址配置
6 t* n$ K& v; } - Use_Ram_Addr = $80
q8 g( n& N/ N( v- ~ - PPU_Ctrl_Buf = Use_Ram_Addr$ l1 |) k" s7 J1 g& {
- PPU_Msak_Buf = PPU_Ctrl_Buf + $01: b- o/ o, l; j0 b
- PPU_Scroll_H = PPU_Msak_Buf + $01! m, E0 d6 Q5 i) F' | {% Y
- PPU_Scroll_V = PPU_Scroll_H + $01( I1 c* N$ I+ g! K8 |% E* T; x
- FC_Data_L = PPU_Scroll_V + $010 w* G% ]7 _6 e% {4 X+ c
- FC_Data_H = FC_Data_L + $01( l" ]7 `; a0 ]3 f# R4 i7 r8 R
- FC_Data_Buf = FC_Data_H + $01$ D3 c1 O4 A" [
- ;==================================================
# ?" g8 M# I( C6 [+ O& c
8 t% O$ B& ?4 w' e- GAMEPAD_MERGE_FLAG = $04
2 O7 M* S4 ~1 E' o
4 P* B- \. h5 M( F. {- Gamepad_Keep = FC_Data_Buf + 1* T; U9 ]* l3 w4 S' o h m
- Gamepad_Once = Gamepad_Keep + 2( F! E* v2 b: j+ d9 V4 s# d; w. Y
- Gamepad_Temp = Gamepad_Once + 2# M. D+ K0 }& @3 E
-
6 t4 g3 L; |" v. X9 @% r - Gamepad_0_State = Gamepad_Temp + 2* n0 q9 T. t- x9 y5 W7 d) ?, z
- Gamepad_1_State = Gamepad_0_State + 17 \8 [" w1 ?6 F4 I6 y8 |& B# E, H2 t2 t
- Gamepad_0_Value = Gamepad_1_State + 1" R& ^$ F/ y; H
- Gamepad_1_Value = Gamepad_0_Value + 1
_9 b) T+ p+ _' h0 R" v - Gamepad_Port_Value = Gamepad_1_Value + 1
( i/ T. w# A( I# n0 r9 c - Gamepad_Merge = Gamepad_Port_Value + 1
; G- V# ^. A' d' C) I- x
( f" o( R- j4 o6 f- ;==================================================9 Z# ~& F2 f: J- @
- IRQ_Index = Gamepad_Merge + $01
: Q( f, t9 s4 E7 T. ]. D6 _; Q7 N - Sprite_0_Y = IRQ_Index + $01/ c6 z! {$ }$ K$ [
- Sprite_0_Tile = Sprite_0_Y + $01
& s+ W z; |* {# w! G - Sprite_0_Mode = Sprite_0_Tile + $01
# p% Z/ M" P1 p9 `- g - Sprite_0_X = Sprite_0_Mode + $01- v7 G: ^& K5 L
- Sprite_0_Hit_Move_Direction = Sprite_0_X + $01+ ^- _, l% ^" A9 {: p0 n9 C& M
- ;==================================================4 t% y+ ]* C1 p1 d# _6 a; g
- 6 t+ _! h* d+ B8 ]0 X
- ;CHR图形数据7 ^" v1 z" z! e; w% e6 ~) B
- ;==================================================
+ J- i X8 [6 z1 H3 F' r8 ?/ ]# z3 A - .BANK CHR_DATA_BANK
# E& N# O' X9 F) `1 H1 a - .INCBIN "chr_bank/chr_data.chr"
4 r" d# K) O) @. _5 c( e. D! i - 5 f( A% T& C7 x H5 ~
- .BANK RESET_BANK & BANK_DATA_MASK& T& \" W/ L) M! V, ^4 ^/ r& a6 ]
- .ORG RESET_ADDR
2 \- n% Y( _" T# X - 4 j' Z( k! M! a# \& G/ {$ Y& i
- ;--------------------------------------------------
( S2 @9 z* y7 d9 I. q4 E4 p - Attributes_Data! ?5 q( i! k* y, Z
- ;命名表属性
- @1 L" J! j" t# N - .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$005 R2 W0 F5 @2 X2 }) n1 O2 I* y
- .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA
% _; n, K4 G/ q - .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA
9 Y* \# d/ U2 L2 K - .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55 x! E. r2 C& r5 `4 P
- ;--------------------------------------------------
" C J% L$ G, H5 ~ - ;调色板数据
+ j) s* c. s9 N4 f0 {6 k - Palette_Data
7 B4 F" ]7 Q @" I4 \ - .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F( w' X' h" V4 g" D; T/ [* V: r
- .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F
+ y" [2 M/ ^5 T1 c- }4 o; ?6 ^
7 p8 C% C" o9 R H/ a* G- ;==================================================, Q# D" y/ P% d3 g* \2 U7 i
- ;命名表初始化
) M) O9 b6 B: L- w9 H9 f1 F/ _ - Init_Name_Table
+ G$ t3 F6 A M4 O0 u% ^" t5 Z - LDA #$20& k9 n- `3 T F" S/ c1 Y+ o5 _% y! b' {
- STA PPU_ADDRESS+ o1 t( C$ R' ?" ~3 R6 u
- LDA #$00) r, p. _6 a% t9 r, Q4 Q9 t
- STA PPU_ADDRESS
$ N' X3 \6 S1 q/ L) f, N; c - LDA #$002 m6 y8 y4 k5 k8 [$ h
- LDY #$00
! Z0 Z6 ^5 K$ N9 o8 [, r1 B - LDX #$10
& k/ X. w8 C2 P9 V0 k - Init_Name_Table_Write9 I! J. Y, s) ?! o% `) U% S W7 U
- STA PPU_DATA
9 a% r @5 G9 k' S. @ - INY
7 f' G. i! S0 k8 _8 A" y - BNE Init_Name_Table_Write3 C! B( A9 p) o. X3 Z
- DEX
4 H, a( S/ D7 B1 C - BNE Init_Name_Table_Write4 ]- I& ?7 [( `2 O& ~
- RTS: b$ t- Z; q# m/ m* P8 P
- . u7 B9 J, {" W- `) ^- u( Q) T& Y
- ;==================================================
: x) g% T% Y0 [ - ;调色板初始化- @, ^# z# H9 S6 q8 Z3 o& E- d# ?
- Init_Palette
2 @* q4 w. ^! l3 g. ? - BIT PPU_STATUS
6 Y0 d7 q; z Y1 o$ b# k" a+ `. f - LDA #$3F$ r4 Y/ g u0 |9 e2 j% I
- STA PPU_ADDRESS
' M7 a- x4 ^: D) M1 p- M - LDA #$00
- o$ a& _/ l. s' { - STA PPU_ADDRESS D& o/ t1 k- q- e. z9 o
- LDX #$008 V3 @) s; Z* n* I0 H- Z
- Init_Palette_Write
2 ^: `$ i* o, D0 b( B. C - LDA Palette_Data,X9 t" `! J. {) p) g/ J. K$ A! J
- STA PPU_DATA$ G; p3 U5 V6 c& r$ D
- INX. h$ {6 g/ m# H) W
- CPX #$20& X8 y4 \" W0 y8 Q
- BCC Init_Palette_Write
9 M5 P: Z% j+ x6 r& N8 C - RTS
' t0 U5 y6 U3 T* x, h -
! _) j$ C& P: t' {: b6 f2 S - ;==================================================. [# x" \3 L; l7 V9 E, e- d# _
- ;设置命名表属性8 W" i3 `4 E( \5 ^' B* a5 i1 ~
- Init_NameTable_Attributes/ }4 a4 _3 j+ o! A
- BIT PPU_STATUS, O+ L( W- W5 h
- LDA #$236 O, w$ k. r1 E* l6 ^
- STA PPU_ADDRESS# T1 g& U z, `: ~( _. b
- LDA #$C0' j7 g* }0 v! Q% a' e( S# c
- STA PPU_ADDRESS8 z% \, v& _2 V% k) F9 _% o& k
- LDX #$00/ ~0 b* D& A$ U
- Init_NameTable_Attributes_Write
/ W4 n6 X3 s) H7 D5 e - LDA Attributes_Data,X
. C! o& S) L! K# @( k& E - STA PPU_DATA
3 G7 Y% X+ F! x. r - INX6 u/ P7 s1 h3 z5 v) I" X) B Y
- CPX #$40
+ u- S8 K# b6 N! C3 q4 D& ^: i0 o- u - BCC Init_NameTable_Attributes_Write Z9 n: Z6 w+ ~6 R2 Z
- RTS! f6 w y: {8 T" H& N
& u% N9 o& ]0 ?' I; ~- ;==================================================) p. r5 D" O" U, _7 ]- s, N# K
- ;初始化命名表文本
5 j7 f: w6 ^* f0 L( M0 j - Init_Name_Table_Text
! h" t/ z! Q! q+ r( y - BIT PPU_STATUS2 Z; x7 W/ S) Y7 P8 N6 j% h9 a/ I
- LDA #$20$ S# d2 m* t: _
- STA PPU_ADDRESS! ], ^) P& h' |; s1 S
- LDA #$00: v* ^$ @- b) Q$ `1 h+ V B
- STA PPU_ADDRESS
, p: Y. P$ e c9 i4 G) V6 b - LDA #$001 F& i9 |: N1 r- S. x
- STA FC_Data_Buf
( i R- a; A. q. A0 o - LDY #30' }, }0 \ Q0 k: i7 d- t
- Init_Name_Table_Text_Write$ n4 u$ S# {: c; z; o( j1 }% |
- LDX #32& d) W) R4 E, l9 l, R1 z
- Init_Name_Table_Text_Write_Char3 j; R6 _8 A3 m. F6 C- w0 N
- LDA #'0'
2 ]) l: ^+ h* D6 O U" C - CLC7 H0 Q7 ~ H, y! v% k- x8 w k/ @" a; W
- ADC FC_Data_Buf3 v# S* ~: f# _+ D( A
- STA PPU_DATA# p% b* w+ Q5 b, n& X3 W
- DEX7 F9 q+ w: j4 x( M2 {
- LDA #$14# m2 Q% o% \% U5 p
- STA PPU_DATA
* c, g( [6 w6 Y - DEX2 E! D' C' J- K% S, v5 b P# |) r
- BNE Init_Name_Table_Text_Write_Char
) ^4 J- R% l Z/ U2 b - INC FC_Data_Buf2 c/ T8 g) N/ R
- DEY9 L. t3 W; T7 J% I. p- b
- BNE Init_Name_Table_Text_Write# Z0 _$ s8 F9 L4 |8 o% w
- RTS
) m* O% H) ~* C1 S+ t* n - * C ^0 _! I P" ~8 z' r; D
- ;==============================
( B& \$ a! L- }2 l( t - Init_OAM_Ram;初始化精灵内存
) o$ i8 ?8 a3 s) J - LDX #$00
0 ]& P7 ?& ~; u5 q - LDA #$002 T8 e* d7 W0 S) k% |9 w
- STA PPU_OAM_ADDR% o1 Q/ g4 K/ b: l0 w
- LDA #$F8
( i- I& D4 n, M$ V( U - Init_OAM_Ram_Write2 t( O3 X; d5 \, ?
- STA PPU_OAM_DATA
) g- B6 ?+ \+ N. Z! t - INX
0 D5 P1 H0 K8 D% t5 _5 j - BNE Init_OAM_Ram_Write/ @0 O. E8 i Z
- RTS" n+ h: j0 b: F( q8 m: i
-
1 @: T9 s% G. ^& f w/ n8 ? - GamepadProcess;手柄处理* L. j" F1 c( w" V
- JSR GamepadDatacan W+ @' `5 Q3 T4 a n5 B+ P) q" q! G
- LDA <Gamepad_0_Value
4 U# ~7 b' B1 A" T3 a3 [+ I - STA <Gamepad_0_State A+ i$ e& }! Y3 W" q1 K
- LDA <Gamepad_1_Value V$ K$ E7 k4 l. f+ E* @9 C+ M
- STA <Gamepad_1_State
/ R4 i2 ~5 L4 a0 n' x9 V& { - JSR GamepadDatacan& }4 H4 n# R6 e( y! M' r9 u* e1 X8 b
- LDX #$01! J0 D$ Y/ w7 w* F+ u# @, O, X
- GamepadMergeCheck;合并手柄输入检查8 m- |- t+ m( l2 h9 W5 s6 G# ~9 P
- LDA <Gamepad_0_Value,X4 Z/ ^; f5 ?- x7 `
- CMP <Gamepad_0_State,X6 I2 Q$ [% J* W
- BEQ GamepadMergeInput" E) ]1 `. G. f! k
- LDA <Gamepad_Temp,X( M; F- b# H# v! S: Q; ^/ p
- STA <Gamepad_0_Value,X; M, K/ W/ d( ^8 ?9 ]1 s* }( T7 V
- GamepadMergeInput;合并手柄输入# l& ~! s; |0 }; y( L, \& h; L
- DEX0 R) n+ r$ A' p
- BPL GamepadMergeCheck
! U' j W5 Y* T5 M1 l/ n/ G1 S9 s$ x - LDA <Gamepad_Merge
9 m+ |, _, J) O - AND #GAMEPAD_MERGE_FLAG
9 H( F f$ u4 T+ w4 @+ F7 O) K& h - BNE GamepadStateProcess
9 H+ Q' p& Z$ [9 o - LDA <Gamepad_0_Value
5 Q3 m5 b' G) Y. {1 g# h - ORA <Gamepad_1_Value
* ?$ [- t7 {! u% S( M7 q - STA <Gamepad_0_Value
) c1 h) ~8 w' }) F) R - GamepadStateProcess;手柄状态处理
4 p: P; ~) @. [. W) Z6 Q* k8 C - LDX #$01* R9 T3 A5 e+ _2 o a
- GamepadStateSave;手柄状态保存
) D7 S6 Q* I1 s: `' X - LDA <Gamepad_0_Value,X; @. }1 f+ u' g% n
- TAY
9 Z% N% v: v9 h1 I - EOR <Gamepad_Temp,X+ i! }& X& _! c( @
- AND <Gamepad_0_Value,X5 H' a: a6 h' |0 H7 k: }1 |# C9 J% n
- STA <Gamepad_Once,X
i- d2 a6 H) ?1 h - STY <Gamepad_Keep,X& m: A% s- I. `' x) q3 i
- STY <Gamepad_Temp,X
4 S2 V7 j% P8 s# F1 I" T - DEX3 S4 u/ [) Z6 s0 A! X! V& ~1 d
- BPL GamepadStateSave5 z. J3 C* {& \3 {
- RTS
/ W& S- N: `+ ^8 r" ]
! V: ?" V) `/ c/ A( M. n- GamepadDatacan;手柄数据扫描
5 g4 r; D8 H$ [& p4 g - LDX #$016 L+ y" S! g1 o
- STX $4016) ?& q& X6 r \: p$ h, p
- DEX
1 `7 q |2 U3 W: d+ v1 H - STX $4016
$ }0 \6 j S( N- @ - LDY #$08 E7 \' e, \- h$ s. O. n8 X" S
- GamepadPortScan;手柄端口扫描
% ~ s& V! q. {; C( F! u5 C - LDA $4016
5 S. J% b, f; _% R - STA <Gamepad_Port_Value
$ `7 P4 w" w/ A, v! E+ r3 r9 l0 D - LSR A
$ h3 X6 G1 W2 v, m1 Q. N - ORA <Gamepad_Port_Value4 O ^, i$ c" Z9 Q; b2 u$ y( j" o
- LSR A3 t. _* Q. f% U2 Q
- ROL <Gamepad_0_Value
! l. C8 F* D4 r3 ]. r* P - LDA $40176 b9 E* b+ O+ y- y, D9 V
- STA <Gamepad_Port_Value
" ~9 A" Y3 e1 ~+ B, t8 F1 h4 Q5 ~ - LSR A
- R- A+ z8 f/ L/ W - ORA <Gamepad_Port_Value* r5 l# `) o* x
- LSR A5 C2 E, O0 L- g. O3 b2 ]4 R
- ROL <Gamepad_1_Value: ^2 U: c0 Z. t0 {( k" \/ p7 }9 }8 s+ F
- DEY6 q/ `/ K @- F; P" ~' }! B1 G8 f
- BNE GamepadPortScan
; z- ]$ _4 R/ t2 F* H: w7 h - RTS
( F# w& A# ]( S0 r -
' ?: Q( q. K9 ?/ U1 d$ S% e" {( F - ;==================================================
& |& { l! Q& B# K) u% a" m - ;PPU处理9 J6 C) g( p$ Z9 T c
- PPU_Process0 F5 d+ q/ C9 l) l4 Y
- LDA #$00! {% M+ Q# n* D3 V& h" a7 |% W( G: f
- STA PPU_MASK4 P& H1 L9 q9 \1 p; f
-
+ i9 e% h5 ~. O- a# C - BIT PPU_STATUS
; a0 t' z+ O' P8 |, [0 Q3 m; J! h - LDA #$20
3 k# j- d9 r: \& a& R3 Y8 u - STA PPU_ADDRESS
3 G: S' }8 L' R) M: a9 S - LDA #$00
, g% O+ e0 o% ~$ A/ i, W - STA PPU_ADDRESS
. E$ m$ M! X) G I: ? -
3 _" k2 B- J$ w1 z - STA PPU_SCROLL
2 t& j+ D; Q. W: r1 { - STA PPU_SCROLL
: t# N! U# g* [& Z - $ P- C3 q7 u& r
- LDA PPU_Msak_Buf
2 N3 l/ @7 h2 b2 ^ - STA PPU_MASK
( h/ ^& ?1 C5 ?: \4 [" n( q - , z6 z: h# j1 W
- RTS0 [: w/ E7 Z! `$ x0 ^+ }
-
# x" V1 a' {; f6 j( k2 t9 Q8 k - ;==============================! i4 m5 b) K2 q/ U" e3 _
- Time_For_Vblank;延时等待" _- a) a" u2 }& x4 M" k7 F
- LDA PPU_STATUS
t/ q9 f' C5 n% c - BPL Time_For_Vblank+ B t }6 c0 f, j9 W9 {
- RTS
* a: f) t4 S8 w4 D+ k2 f6 S - * X1 |# w9 b; e O2 f+ |6 o
- ;==================================================
+ E3 l: o2 A% A- R: H4 m w# _4 l' h/ d - ;初始化MMC34 o! m5 D+ l/ V6 G3 J) e4 D& N. F% g
- Init_MMC3) R0 ?" R# Z; V) X) y
- STA MMC3_IRQ_DISABLE
1 C* u# X" p' e3 ? - : F' N. W5 L$ U& i9 C( w! A3 S o
- ;设置MMC3水平镜像$ U! j. Y% r8 |' z" T4 J9 G& D
- LDA #$01% Z5 ~; g! w: @1 [3 x' H/ Y3 }
- STA MMC3_MIRRORING, E! p6 d$ b t) p g7 `
- * m9 V, Y) u' i7 i! r: d: {1 c
- LDX #$05) E- _3 ~4 P5 M, C9 M l1 H
- Init_MMC3_Chr_Bank_Write5 r' P; p# G" d# E, L
- STX MMC3_BANK_CTRL2 k8 y8 z; Z! F* c, k4 ^
- LDA MMC3_Chr_Bank_Data,X
( ?& T: \. u& `9 L6 p; e - STA MMC3_BANK_DATA& Q4 b, P0 N" O! o' A. l
- DEX
1 u; o2 g2 ?! D, C# i( P - BPL Init_MMC3_Chr_Bank_Write
- z. j0 ^- N9 R& t5 T - RTS5 [5 L+ j, s7 O$ K6 u
- ;-------------------------------------------------- O- O8 S+ u7 P: A
- MMC3_Chr_Bank_Data
M' ?% y6 L1 {1 M6 ]9 a - .DB $00,$02,$04,$05,$06,$071 }! L* x2 w; ^5 E w/ ~
) Z8 ]; W% t' `. o1 u. \- ;==================================================/ y A( m2 o# m) V
- ;重置中断处理
: K. ^8 [) x3 h+ N% p$ B0 G - ResetProgram
4 ?6 t: T- f: \ - SEI9 e$ c: v) U: Y
- CLD* @1 q- \* l. q/ r
- LDA #$00
% K" o& Q4 m& x7 U% ? - STA PPU_CTRL* m% [* D9 N; w$ `
- STA PPU_MASK
+ z8 B8 F5 c* q4 [% |! { - STA PPU_STATUS
# w* M* P; N4 ?3 E4 }! `2 K, Q0 `% ^ - STA JOY2_FRAME
9 Q" k# p8 C5 g - STA APU_STATUS& w, C4 d4 r4 G# Y, s% F! `- [
-
' V6 r2 o' Q: s( F& `9 U' l - LDA #$C00 S$ @9 w& z" l4 g: P& E. k
- STA JOY2_FRAME' M- o. J" F0 P- O' y9 |; x/ s3 [( V
-
, i/ }0 Y4 U. A4 J2 m+ V - ;等待vblank; ~# r7 f+ D3 W) i. F! Q" W
- LDX #$02' H) }0 a/ d) i% _1 Z: T
- Vblank_Wait_1, {! v0 e6 m- o- a( \
- BIT PPU_STATUS4 \3 ]% x& d: B0 k" p. j7 _2 s
- BPL Vblank_Wait_1
( Q x4 c C, L% L J - Vblank_Wait_2
! G' P0 l C0 k, B$ q0 R4 O0 r - BIT PPU_STATUS- X J# _2 s( K7 l" e: z7 i5 C
- BMI Vblank_Wait_2) |4 X9 ?' I( [/ Z
- DEX/ j7 P g5 u$ D1 ?5 r2 Y, p) M
- BNE Vblank_Wait_1: u5 ^7 E; g- ]6 [; p
- 0 p# [+ `7 P' r Q% B+ `: E% [* z- p' x
- LDX #$FF& ~ r+ {9 R! Z
- TXS. t9 k) f; M5 |
- 8 h @; d. w% I+ c1 U- s$ Z+ S
- ;初始化MMC3
, ]5 c* o7 y {; ] - JSR Init_MMC3
* j4 T& Q; U6 H5 \! ] - 9 s- }( u+ A; S* q! e5 a
- ;==============================5 a6 t* N( ~4 w8 K/ ^ V' h+ k
- ;RAM初始化/ |+ |: O% v9 Y7 a2 q" s6 j) m
- Nes_Ram_Init: `4 T$ n y) W9 K! O
- LDY #$00. ^& A* m" Z) I( z1 X
- LDX #$08
% ~9 p5 h' b. s( ]3 x# v - LDA #$00
( d) y2 s2 I7 Q- r( I+ J* }. b0 [ - STA <$000 f) c3 @1 Z8 R* \- M( h. j! H
- STA <$01' t* o( _/ c8 `
- Nes_Ram_Init_Write9 A1 }# E+ m, t, x- F4 {
- STA [$00],Y
8 U9 B- a( j1 o - INY
! V% [: S# t7 h9 @, m5 k - BNE Nes_Ram_Init_Write5 B F. U8 [' Q3 p' W0 V
- INC <$01
! |' J* x' J C. b# R# L- M - DEX8 j& n% I6 i( k* \4 w
- BNE Nes_Ram_Init_Write
: ?* k* P1 F4 ]7 F% J+ j -
# m% x. @' F) R$ v$ r+ y - ;初始化命名表
( f0 V4 f% R- P% F. v" t* _# e - JSR Init_Name_Table
2 N( R8 {. ^6 d - |8 o& @7 y$ B
- ;初始化调色板+ J7 b0 T7 s$ N3 e' l
- JSR Init_Palette
9 m; T8 U( ~8 d0 l& d' o -
. O G7 Z4 m) n: ^! S2 h - ;初始化命名表属性, R+ i, ~+ D- S! ~! d' S$ n
- JSR Init_NameTable_Attributes* ^! o! |" D0 d6 E: F+ s% e0 c _
- * o2 i7 B. C- k" W7 C( T6 a& S
- ;初始化精灵内存3 T; |9 {8 q$ W( ]
- JSR Init_OAM_Ram7 C& u* W) v9 Y3 W0 D: i- u5 G
-
" D4 D- y9 W3 D) m - ;在屏幕上写点东西+ G7 e+ D2 ^4 G3 D( k
- JSR Init_Name_Table_Text; w: L- ]. I0 z
- ; m/ `+ ?8 v4 U% e& B
- JSR Time_For_Vblank
# @/ Q2 V& l) j0 T - ;开启PPU控制' i" y( d/ Y7 Z7 M5 m
- LDA #$80
3 v! A4 z$ f4 P5 t# _" d- ? - STA PPU_Ctrl_Buf
8 ^4 j' B; `2 }3 m: L - STA PPU_CTRL" L# ?) n3 [6 h, Z
- " O; C# D6 k! g: e4 O
- ;开启PPU显示) I O+ ]6 x P7 ]4 M$ \
- LDA #$1E
- {: ^# I2 f$ d. I - STA PPU_Msak_Buf9 }3 k& p, r+ V7 K/ a) @
- " G7 @/ C2 x4 `- R5 a3 A
- LDA #77+ Z) G( N* |1 A) R! m) L% g/ V& g
- STA Sprite_0_Y
. H) D1 ^! W- R: n* g$ t% Q+ d - LDA #$1E
- v% l. K: t: a- K1 x& b - STA Sprite_0_Tile! T% \ ?( n( W# j8 T
- LDA #$20
! S% O7 P Q2 K, @& j - STA Sprite_0_Mode
. {* z& C! S! E% T# Q$ Z - LDA #$00
) b* j4 R7 {+ s, a/ r9 _) P a - STA Sprite_0_X1 j, p( G' R* m9 W0 ~
-
$ ]' l2 z) o8 p. I5 k - CLI2 Q' N$ @4 i7 v
- JMP Loop7 f3 B, S% E/ X0 e% w! P
- _+ _6 t" w, Z0 g
- ;==============================
2 Z! w/ X6 X# }* W; e - ;死循环, 等待NMI中断
( i& C& t) l5 k4 \. Y3 u' { - Loop
$ l& a" H6 v9 m - JMP Loop
. v! k9 b+ J! ~. m; a2 L& Y - ' u% D% g% N9 @) [4 {- D" Q
- ;==================================================2 G$ A3 Y) P3 _0 ~& |6 k
- ;NMI中断处理. F( y4 s; q7 ]3 g; S
- NmiProgram
3 N! d, J$ I# L- m; U' k1 b2 _# e - PHA
! Q- Q% Y# x7 ]$ F' s - TXA1 f1 x/ l4 F$ T9 E" v6 G8 d
- PHA
/ |6 ^, C! o; D) b, ~ - TYA9 A, _; Y0 _. R4 M3 S& F$ ^7 W
- PHA3 g, L A% }8 w$ p! ~6 A
- + f4 m& A( r6 t+ t/ X
- BIT PPU_STATUS4 t, k& x& b$ A$ ~6 z& w
-
! Z" N7 X* {. u$ R' X - ;关闭PPU控制
$ T% K+ V2 [, t9 w; |4 f& y - LDA #$00
$ Q( Y2 T D6 k - STA PPU_CTRL& H/ }$ k/ c, D2 v9 C6 F+ m
- # r6 i8 g; Q9 l( c7 |
- ;处理PPU; ^0 t, i8 `: _
- JSR PPU_Process; U, I# ~5 K4 y t7 v
- ( L9 J% v: J2 I4 k( r4 |$ P4 r7 X
- LDA #$005 q* ]9 s5 j" [7 y7 A
- STA PPU_OAM_ADDR
6 ]1 t& b" G8 g$ q9 E - LDA <Sprite_0_Y
# m; k) e# [3 o" U4 t+ l4 L4 m8 o - STA PPU_OAM_DATA' O% @4 O& @& h
- LDA <Sprite_0_Tile
5 \ ^. U8 a2 E% i) Z - STA PPU_OAM_DATA4 ^! r2 r" U$ J+ V5 ]$ z
- LDA <Sprite_0_Mode: T2 w3 S( c( ]: s& E
- STA PPU_OAM_DATA
1 k/ T6 V9 Z2 N7 A! m - LDA <Sprite_0_X! O f5 |& z0 I2 p
- STA PPU_OAM_DATA6 ^+ M! g2 W9 p) V
-
2 d! V7 l7 V' \/ ^ - ;开启PPU控制
3 W, W/ @+ c: Y1 O' p - LDA PPU_Ctrl_Buf { ~- I% G) g; R- ~8 o: G6 t
- STA PPU_CTRL4 J. Q" \* z# q1 _$ V" Q
-
: o% P/ e& U4 x/ s: [ - ;屏幕滚动# _! K9 w6 s. E7 h4 H) \3 p# q
- LDA <PPU_Scroll_H; o9 g$ x% b6 z O8 k
- STA PPU_SCROLL$ z. k7 ~* t% ~7 ~+ K/ S
- LDA #$00
3 s4 t# Q4 l8 ` - STA PPU_SCROLL' \8 |+ n7 e1 \0 B4 H# V
- 9 h+ m+ z4 a; T. b7 R
- ;手柄处理: @1 r1 U0 i) s3 g4 F8 a g
- JSR GamepadProcess0 R" W7 @" D% j$ j0 Y
-
/ m' o6 u/ `% } - INC <PPU_Scroll_H! [6 [8 t: d, O4 O1 P0 K
- $ p8 V; i" c5 I: Y- e
- ;启动0号精灵碰撞检测6 f$ v* O/ p) N' V
- LDA #$016 M, t( p' Y# H
- STA Sprite_0_Hit_Move_Direction
0 E0 r* r) ^+ i" F/ `) ] - JSR Sprite_Hit_Test" q) }: x& V+ q) h/ L, h6 Z
-
, Q C+ Q( ]" D - PLA
' z( G$ ^9 t2 c9 T1 f - TAY8 t5 Q$ P% D$ T6 g$ F
- PLA
- V( w" v& f/ t, Q$ t/ K - TAX
* B) A$ a/ Q$ G3 e( g+ K" U# { - PLA
$ i2 N2 p$ k I# r - RTI
: w0 ^, n" O! T7 G% e6 g7 ? - ( X5 O e6 X$ ?9 J
- ;==============================
9 D9 L i4 V2 H( x8 Z! ^* l - ;0号精灵碰撞测试
- D, w; k+ V/ W/ v7 a - Sprite_Hit_Test% ]" y/ M. }( v; k$ a6 S
, j+ v" ~' C8 F& n0 F2 |7 e; d0 _4 ^+ P- ;------------------------------
2 X j8 c1 ^- { - ;等待0号精灵碰撞状态取消& ~. ]; ` [" i# `) t/ f5 t
- LDA PPU_STATUS0 ^* G; n8 \) p& Z, M; |
- ASL A
4 W3 i- ?2 M; i - BMI * - 4, Y7 ?5 D$ j; q; R7 q4 M
- ! D# i* Q& H* m% [
- ;------------------------------2 o. t& d3 B7 K+ b/ t# J
- ;等待0号精灵碰撞发生
( x) y6 ^( `7 q, E- q6 R* p& A - LDA PPU_STATUS) |* S( v5 r% t) H( q+ A
- ASl A2 E0 J! c8 K [% N, n4 E
- BPL * - 4
4 Z$ g4 N; }: l C - ) R$ ?1 ^/ @9 E( c2 U
- ;------------------------------
( E& a; S! c3 H: l+ |9 n2 x - ;行消隐等待
7 x; o) W/ G- R7 C# { - Sprite_Hit_Scroll_Wait
. J. R7 p9 U4 w - LDX #$283 g" o _3 H# D( e! T3 h4 Q. X
- DEX
/ h, }* [ L+ \9 d& S2 v5 N - BNE * - 1
# B1 }2 U! L/ F5 \( E: F; V7 c; l: | -
/ a0 I& y. ?- g# c$ H A/ ?0 G) V0 T - LDA Sprite_0_Hit_Move_Direction( m E9 P4 ^( }; w
- AND #$01
6 y1 {- |( H! h O' h - BNE Sprite_Hit_Scroll_Set_Right
2 O0 V* a! Q/ Z. Q. L - 4 Y" x5 }2 Q0 |0 t
- ;------------------------------. _9 K1 X# Q6 W+ w; N3 g! g# N* [6 n' {0 v
- ;分割画面向左滚动
, v+ v0 C' Z1 Q) [! J" Q* \ - Sprite_Hit_Scroll_Set_Left2 i' s8 }6 L L V: X) d* a; t% y
- LDA PPU_STATUS
0 I- P5 y$ M m! b6 H - LDA <PPU_Scroll_H, ~5 J, J; x1 u$ T
- STA PPU_SCROLL
% ]4 a+ W$ @. z4 m8 }3 d - LDA #$007 C+ K& z }7 a6 y6 v- }; D
- STA PPU_SCROLL9 z# z5 d; _$ R* o) P/ }) A
- RTS% e" B( \# s- _2 V/ ?2 ?! \, Q" o
- 1 l4 M* b+ E9 }6 T
- ;------------------------------$ ?! H+ p3 z- D7 x( T
- ;分割画面向右滚动! Z3 i- X3 v+ D' H# f
- Sprite_Hit_Scroll_Set_Right
" v6 M: `% e i, g; H+ B; Y2 i' s - LDA PPU_STATUS
( |8 K" ]0 W, M! W" l- C; L. `1 b2 C - LDA #$008 q6 j6 m( T! Q$ ^, U
- SEC
6 p% A6 o8 s8 ?9 Z8 k3 C - SBC <PPU_Scroll_H
5 ?% s7 _9 h. C" F/ b" n - STA PPU_SCROLL
! O2 ^) g7 @. Q& f' O' U, y - LDA #$007 s* N1 C% y! u& O
- STA PPU_SCROLL1 N6 T& ^+ P# K$ F! M
- RTS' L* c8 {# I" P% V9 E+ b
- # I6 S6 m ]( F9 Y
- ;==================================================- y" S% l: \7 K* F6 K
- ;IRQ中断处理( i( _& a* d& P1 W/ B9 p
- IrqProgram% q4 d/ ?0 n! i- H7 j" n) L
- PHA' `& Z: q4 O# A; p4 {3 H
- TXA1 O( V" Q/ }) g5 Q5 K( `5 z
- PHA
" _& @. b9 W7 p3 v# V - TYA
+ r5 @. h4 w" `+ n1 R9 M - PHA9 \% v0 a( {% ]0 t
- " R6 a* l0 O) S( q M
- ;关闭IRQ( E0 s1 j" e- Z3 u8 Q- v
- STA MMC3_IRQ_DISABLE# C% x7 o" p: v2 [, c
- / r3 F8 t/ M# Q8 [1 a, ?
- ;允许下个IRQ触发* T/ c J7 C! y: w6 J, {
- STA MMC3_IRQ_ENABLE' E# T* W0 S/ c. r
-
2 \ o2 ^" B7 \' \' ? - ;IRQ处理, 15线后继续触发
+ ]5 E; |" N6 a+ n - LDA #15% d. J0 @3 X+ v. m
- STA MMC3_IRQ_LATCH, T5 D, s3 |7 ^1 r! A* d- g+ `9 b% V
-
9 ?: S3 ]! Q: e' J/ F - LDA <IRQ_Index) W5 b6 r( S0 ^+ S7 F& [
- BNE * + 4
$ a8 X Q/ G' c! r# j - INC <PPU_Scroll_H
4 E2 `, Q# M6 K( L, w$ f -
u N6 M) u1 m5 C- U - ;设置屏幕滚动
3 N$ Y" _, |! f! l i - LDA <IRQ_Index) A6 f' `; O5 Y0 V5 w z
- AND #$01
$ z% a) D7 y j* r7 W! ^ - BEQ Irq_Scroll_Right! t5 R; v0 C" C$ q4 T
- 6 v% ]7 K6 e0 Q# q
- Irq_Scroll_Left8 {3 i( } X( g: N! b, l4 g
- BIT PPU_STATUS
1 e, }8 r- w/ d! _$ X - LDA <PPU_Scroll_H: \8 M7 B; P6 N" S# D& \
- STA PPU_SCROLL
* J3 B# ~; K! w' e( z1 ^ - STA PPU_SCROLL
( g. I2 x1 }/ F6 E8 e, i - JMP Irq_Scroll_Over
0 ?2 Z- R/ ?2 u -
0 h R9 p! z. W+ b2 Z, ]9 f# n" x - Irq_Scroll_Right
. o& J# e/ W$ y: [ - SEC
4 s! d! p& _- D } - SBC <PPU_Scroll_H
' @! v {1 L+ I0 y2 `6 \/ V2 y - STA PPU_SCROLL! z; m) H3 a, F! o; S! `- e0 d0 p
- STA PPU_SCROLL
; P. l* F, p! R) I - Irq_Scroll_Over
' A: D- X* B" ] -
L& ^; k# [* [ - INC <IRQ_Index
0 B$ O& r: B. ]/ n, f -
% |" j1 l1 ~( P6 S - LDA <IRQ_Index
. |0 C z/ ~/ X, D% {, ^ - CMP #14( K& q9 X G% C5 l
- BCC * + 56 z, u7 ?. r( D+ Y
- ;关闭IRQ
9 ]* T7 z. ^1 ~/ x - STA MMC3_IRQ_DISABLE
6 q6 _4 O& x; g$ |& W8 L3 v, F - % I' S6 E- S3 I% R) ?/ A
- IrqProgramEnd1 o) F1 ]% q$ k# T
- PLA- A# i: n3 ~* z* H/ g/ |7 W S
- TAY' t2 E7 q8 t' `0 j
- PLA P0 z7 U' z* `. j1 C
- TAX
2 N) b7 s6 O: q( N, d/ C) r0 D: l - PLA& P* R) G7 x7 q3 U0 w; Z" U
- RTI
6 [. o- m. F/ f+ i& j; p- y - 3 c+ ?' \4 V4 M U$ r0 a2 E
- ;==================================================) ]3 g, y* U3 `: _" f( z6 G
- ;中断表: I7 U3 u O+ r. P5 F
- .ORG $FFFA$ S! L/ E& r# q3 p+ R
- .WORD NmiProgram) m$ J- r8 K0 p8 H: b3 m
- .WORD ResetProgram
1 R2 r) J; g" l( G- O - .WORD IrqProgram
复制代码
0 x7 E8 A; J, |0 m. f3 Z |
评分
-
1
查看全部评分
-
|