|
|
- ;[FC][MMC3 精灵碰撞]& n. b- O& h \2 T2 C1 D
- ;FlameCyclone 20230710
! M% K! W$ h0 J8 C j: k - 9 T+ w+ S5 u8 I3 [. G) w
- ;文件头3 w. C) T/ ^! R% T4 i
- ;======================================================================
9 H8 i. J: y, } W+ W9 A. r0 x - .INESPRG 4 ;16KB PRG 数量
5 a& O' h' t5 U G9 j - .INESCHR 1 ;8KB CHR 数量
/ `/ t+ E; [4 j! c _# x* \ - .INESMAP 4 ;mapper 4& W- O$ B( p7 Z1 G# A$ ?5 Q9 g
- .INESMIR 1 ;命名表镜像 0水平 1垂直& @4 o1 b4 D" T0 ?
- " Z* X3 ?( a S0 g
- ;必要条件' g$ G A4 w i6 m7 h
- ;1.持有CHR ROM/ u& [& T" Y+ C6 n( g( M4 }- k
- ;2.背景Tile和精灵Tile必须使用不同的图案表, 如背景图案$0000, 精灵图案$10008 N9 y7 H' h9 t$ p0 w
- ;3.精灵内存(OAM)不为空
$ y3 W# i7 I9 M( o( K - 6 o# F6 l. b6 F1 T4 W
- ;==================================================
5 w& i- m1 v( h9 S2 } - ;NES端口常量$ `! p# |1 u" z' P2 {4 j" B
- PPU_CTRL = $2000 ;PPU控制寄存器# u& T3 o& X/ O' J& Y
- PPU_MASK = $2001 ;PPU掩码寄存器
/ q3 F- _) w7 M' f/ _% v - PPU_STATUS = $2002 ;PPU状态寄存器:读取后PPU_SCROLL和PPU_ADDRESS被复位,下一个写到PPU_SCROLL的数据是水平的,写到PPU_ADDRESS的数据是高位% x6 l) ]5 N2 g/ ~3 ^
- PPU_OAM_ADDR = $2003 ;精灵RAM地址:用来设置通过PPU_OAM_DATA访问的256字节精灵RAM地址。每次访问PPU_OAM_DATA后该地址增加1
/ n" p/ W! t9 r, }- E3 H - PPU_OAM_DATA = $2004 ;精灵RAM数据:用来读/写精灵内存。地址通过PPU_OAM_ADDR来设置,每次访问后地址增加1, @' t$ P" g, H8 x/ ]: b% k
- PPU_SCROLL = $2005 ;屏幕滚动偏移:第一个写的值会进入垂直滚动寄存器(若>239,被忽略)。第二个值出现在水平滚动寄存器 - v4 i" N+ c. M. ?7 u" S- J, P
- PPU_ADDRESS = $2006 ;VRAM地址:设置PPU_DATA访问的VRAM地址。第一个写地址的高6位。第二个写低8位。每次访问PPU_DATA后地址增加
5 \& s3 c% F5 Z$ @. t$ {% E: Q! R0 e: y - PPU_DATA = $2007 ;VRAM数据:用来访问VRAM数据,通过PPU_ADDRESS设置的地址在每次访问之后会增加1或32 : Y" ]4 ~/ H- U: P: k) n4 q& o
- OAM_DMA = $4014 ;DMA访问精灵RAM:通过写一个值xx到这个端口,引起CPU内存地址为$xx00-$xxFF的区域传送到精灵内存0 y" `" i# [. ?+ i( H1 P7 G
- APU_STATUS = $4015 ;声音通道切换, N% s1 o5 k* T. P3 _* _: F2 s
- JOY1_FRAME = $4016 ;手柄1 + 选通
$ i c- k7 e* h- s0 @5 V5 Q2 c - JOY2_FRAME = $4017 ;手柄2 + 选通2 @, o b3 D: w4 z: n4 T1 Z
- * j6 S$ N: H) ?! g0 P
- ;==================================================4 A( }& k9 O. R2 R
- ;MMC3端口常量; v3 G) {! X* H7 n3 E
- MMC3_BANK_CTRL = $80004 p2 f/ J9 i( ~; X% K# L
- MMC3_BANK_DATA = $80012 Z5 E' a- h0 q3 s2 Q o9 i3 q. Z
- MMC3_MIRRORING = $A000
7 V4 a2 v K( T! D! @# i% r3 i# x - MMC3_PRG_RAM_PROTECT = $A001- @ t s3 Q. X @
- MMC3_IRQ_LATCH = $C000( k% n' a+ @! |6 ] o V
- MMC3_IRQ_RELOAD = $C0010 O, h/ [4 Y" M9 X! z# ^
- MMC3_IRQ_DISABLE = $E0001 p8 H4 X; t2 v' w
- MMC3_IRQ_ENABLE = $E001$ i& @ _3 _- w% V
+ ~9 z0 M0 d: B- [- ;==================================================, c* E) o7 q; L1 ?+ O7 K' E9 Z
- ;程序块配置& v9 O: e% f. m: L
- BANK_DATA_MASK = $07- _2 p+ ^/ k: s: V! ~* v# \4 `
- ;--------------------------------------------------
% {6 i9 t" f+ N - RESET_BANK = $07* E' V/ l8 h% ]" p" ?- g h5 ?- {, ~
- RESET_ADDR = $FC00
, y8 n# K/ {+ v! P4 A
, G! m3 D5 ^7 h& a/ ~. @8 G+ B- ;==================================================& y6 b0 o* P( W: b: _, |
- ;图像块配置
( J! A8 ?- b, U* | - CHR_DATA_BANK = $08
# O) t6 f7 a( I' n5 g6 G
1 m$ `+ j* q) f! [- ;==================================================6 W4 r# x( B: d" k( O a
- ;零页内存地址配置4 S9 v* ^8 h% L1 f5 F, C& a. Z
- Use_Ram_Addr = $80# n8 w/ z, |" S+ T& _0 G. B
- PPU_Ctrl_Buf = Use_Ram_Addr# T5 L' K; Z6 _6 p& j
- PPU_Msak_Buf = PPU_Ctrl_Buf + $01. [* d$ o& }* w/ F
- PPU_Scroll_H = PPU_Msak_Buf + $01* |8 Z: Q4 n/ M6 S- ` F) ?* {0 J
- PPU_Scroll_V = PPU_Scroll_H + $01" L* `! N% V4 k8 y
- FC_Data_L = PPU_Scroll_V + $01' R* m1 i; s0 l+ g8 O# O
- FC_Data_H = FC_Data_L + $01
! a0 @/ d* S# E8 C$ K% ^ - FC_Data_Buf = FC_Data_H + $01* U3 f+ [; m6 b/ `! D" S
- ;==================================================
- V5 G: {/ t% Z3 r# ^ - ( c5 X7 P5 S6 E* |. d. t! G3 F
- GAMEPAD_MERGE_FLAG = $04" X0 [, U6 R6 X- F0 h0 v8 r+ ~& |
. w$ O9 ~! n a9 E8 T" c- Gamepad_Keep = FC_Data_Buf + 1+ `9 G, a3 X/ A: j4 y9 \3 k" t$ y
- Gamepad_Once = Gamepad_Keep + 2, u! j" _% o! O( B
- Gamepad_Temp = Gamepad_Once + 2
9 a1 I+ i/ S4 }8 ?1 X0 a - 0 g' v) G5 R" o! q- [) Z
- Gamepad_0_State = Gamepad_Temp + 2! D; {- g* | h G, r; t
- Gamepad_1_State = Gamepad_0_State + 1: |. s. R8 j ~ H
- Gamepad_0_Value = Gamepad_1_State + 16 O0 R4 c* {& g" Z) I/ B6 ]7 R
- Gamepad_1_Value = Gamepad_0_Value + 1: C J3 f# s# ]# D3 [# h/ y
- Gamepad_Port_Value = Gamepad_1_Value + 1( U. ?5 L$ z* W4 ?. f4 T) {
- Gamepad_Merge = Gamepad_Port_Value + 1
" _8 j4 j- I- P
6 s7 G2 a" R1 Z2 Z- ;==================================================
8 t/ I/ t0 W& F8 ]$ e8 h5 } - IRQ_Index = Gamepad_Merge + $01
1 Z; N8 s- }7 A2 p7 h e2 `+ A1 u - Sprite_0_Y = IRQ_Index + $018 P2 |; I7 `" v4 s+ y
- Sprite_0_Tile = Sprite_0_Y + $017 b' ~( S1 p/ f! f, ^) p% H% z9 \: C
- Sprite_0_Mode = Sprite_0_Tile + $01
& Q) v( H( o- W# w5 |* i - Sprite_0_X = Sprite_0_Mode + $01
, C% t9 ?! i/ E - Sprite_0_Hit_Move_Direction = Sprite_0_X + $01
. i; o( S. L+ q2 I8 K- I- ] - ;==================================================
( ]9 l q1 r: T; [( j
1 E2 k) n& w E2 A1 _: \5 v- ;CHR图形数据
/ b T7 n/ M* e! H! f1 l - ;==================================================
: p8 n" o3 B: W- o8 R \ - .BANK CHR_DATA_BANK! q( r/ _. W: F. ]4 `, }# h
- .INCBIN "chr_bank/chr_data.chr"
0 f# X( {, f* C5 D$ G+ j -
2 \+ q9 Z. _# \+ ^3 V3 m) l$ X - .BANK RESET_BANK & BANK_DATA_MASK
/ I9 F5 c- N$ r6 Z - .ORG RESET_ADDR! t7 V$ \% ^, W. q3 h; d
-
2 _& p s% u2 I) `2 F; n - ;--------------------------------------------------2 Z: | K& H% h$ `) B) L, U' ~) p& k
- Attributes_Data
/ I. _: k1 \; }/ }6 w/ ?( W4 W - ;命名表属性
6 P e0 S6 e9 V& d1 E2 k7 R - .DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$001 p" v# w5 c9 Z: ~8 J$ c& q, ]8 M
- .DB $50,$50,$50,$50,$50,$50,$50,$50,$FF,$FF,$FF,$FF,$BB,$AA,$AA,$AA2 C. Q2 L2 F* Z t4 o
- .DB $0F,$0F,$0F,$0F,$0B,$0A,$0A,$0A,$AA,$AA,$AA,$AA,$AA,$AA,$AA,$AA8 `4 {/ S5 J# V& ]+ h* @
- .DB $AA,$AA,$AA,$AA,$AA,$AA,$AA,$55,$55,$55,$55,$55,$55,$55,$55,$55
3 _) O5 P: s* }7 w - ;--------------------------------------------------
2 e2 U; r- m4 q! g% S- b5 s' B" t - ;调色板数据
/ Q; ?. c" ~5 u9 p+ p - Palette_Data$ z! b: y1 g. Z
- .DB $0F,$27,$20,$0F,$0F,$24,$20,$0F,$0F,$21,$20,$0F,$0F,$25,$20,$0F- z, I8 z# J' p o! E" C& I+ c
- .DB $0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F,$0F,$24,$20,$0F+ W6 a% k7 P9 K5 p' M
9 [' Z4 f! f( c# B5 a# }" y+ r- ;==================================================" q# ]" P; Q; G I
- ;命名表初始化
K: N' W% e( p! C# e - Init_Name_Table+ E8 ]) l9 C: ~+ m, y2 d
- LDA #$209 L% O0 H. D2 L& F' f5 K
- STA PPU_ADDRESS
/ z/ g0 R* A* C- W - LDA #$00
0 {6 K$ }0 Q, V; @( b0 J - STA PPU_ADDRESS
x- ^ t( D/ y7 j, ]/ ~ - LDA #$000 Q- \* \9 q0 U4 y. U5 h& N
- LDY #$00
& }5 _ Q' O# Z8 c8 B0 j; y% t - LDX #$10( a; R/ K4 D+ E# ?8 a/ {
- Init_Name_Table_Write \$ a+ c/ X% D; T
- STA PPU_DATA6 f# E, _* _) ?# `
- INY
- w6 e) D* e4 V4 | - BNE Init_Name_Table_Write0 K/ T4 U* Q- s; e7 L0 Q# }
- DEX* C* \' g- `# d
- BNE Init_Name_Table_Write- c2 v0 L1 W1 Z; K0 F% e
- RTS
$ K) p/ ]8 P6 C - , v$ W! ^" S0 Y% w/ e; S
- ;==================================================
" H& A) |( U. |# r& D1 J! [ - ;调色板初始化' v! K, R+ Q3 l+ V' C
- Init_Palette* e G; y) c# \ I* O* l
- BIT PPU_STATUS/ h4 G3 ?% p, K0 w+ ]/ f5 V, _
- LDA #$3F
+ e* t$ p! u( l3 |' z6 f+ A - STA PPU_ADDRESS2 B6 r& s! K( ~* c7 `
- LDA #$00
& {" o4 ]0 n2 c/ ^5 ? - STA PPU_ADDRESS- u* x9 i) U& ?% c0 Q5 t' f
- LDX #$002 } q8 p- O& f1 ]
- Init_Palette_Write
+ D; e( y5 D6 ~5 O. M( e - LDA Palette_Data,X
& s0 t5 Y) e; Z! A; W - STA PPU_DATA
8 i y/ ], O7 S% @1 J - INX, k6 x7 o& V. D1 A
- CPX #$200 G& f) _. x4 G. T$ q' Y* R
- BCC Init_Palette_Write, I8 N" m1 s- V P( _
- RTS1 {8 T& j; c1 f5 i/ `
-
7 \; F' ~$ g! [" Y# W; K4 j6 |7 Y - ;==================================================
1 n- O4 A- \1 M7 t9 D - ;设置命名表属性
/ O+ l8 ]- n- _; m6 ~4 | - Init_NameTable_Attributes0 s1 j. o4 e4 d) h; j# T! J
- BIT PPU_STATUS
F* J' x( d4 f2 t% K: }, i J1 S - LDA #$23% i' B) D# E+ V; l0 s
- STA PPU_ADDRESS" D& H! P0 `* i; f* m
- LDA #$C0 n: ~% q: W7 [6 G
- STA PPU_ADDRESS
/ _, `+ L/ r1 U0 b% d' h - LDX #$00
- t1 z- w. Y0 I, s - Init_NameTable_Attributes_Write. ^ I- I0 o4 w0 \! t) [" [
- LDA Attributes_Data,X8 O* [; ~" X) |( ~. {
- STA PPU_DATA
_1 m+ Q6 w1 e2 D - INX: U- q$ _/ Y9 ^1 v5 C, J0 l% `
- CPX #$40
, C, N9 ~2 S; t+ ~ - BCC Init_NameTable_Attributes_Write
% _+ h$ T" u# W - RTS
4 j; Z) B: j; _& @8 a% x
2 O& e( D* d, g9 _! B- ;==================================================4 S) {3 h, I2 i8 p7 S9 B# i
- ;初始化命名表文本
7 z3 C8 f5 q, W9 b' H* e/ v' d - Init_Name_Table_Text
8 Y8 @- ^8 o! f; y - BIT PPU_STATUS
( l& D8 }/ u8 l1 c! { - LDA #$208 |5 H, d. [0 |) E% p- ^9 b
- STA PPU_ADDRESS
5 y; w8 o n* G8 [4 C# J4 W c( S - LDA #$00! B3 v! t- T2 ], Z
- STA PPU_ADDRESS
! z; R3 N5 Z5 p( w5 |) C - LDA #$00. o% s/ j0 m" s7 Z+ A* j+ K" \) ~
- STA FC_Data_Buf! d F0 q1 z% {& Q6 B* d3 S" ^6 }8 c! A
- LDY #30: l2 k. C% c/ p. e: |# |
- Init_Name_Table_Text_Write
9 t. ?+ R: g- V+ _ - LDX #32
) ~5 ?, C: L4 E% q% O - Init_Name_Table_Text_Write_Char
& P* H% ?( w- H5 n3 X: b - LDA #'0'
6 W' b+ k. [" s& C: i; W - CLC: s- E5 D5 ]7 N/ M
- ADC FC_Data_Buf
# Q& \) b, w! I( \4 x1 U4 y, ]2 s - STA PPU_DATA. G& m0 ]! e3 T) N8 l
- DEX
}, E8 l5 v3 ?8 E& O6 D. G* [ - LDA #$14) ~# k9 m1 `* }' w5 f6 Y$ g
- STA PPU_DATA
( O$ U7 s- N% o P) ~9 X& c - DEX
) G" G) w @$ G3 w - BNE Init_Name_Table_Text_Write_Char" E/ \6 V7 z- Z0 R; F
- INC FC_Data_Buf
2 Y; r! N# {3 c* g; w* k# N7 x - DEY, n! @. A( V6 U+ Z9 U2 c
- BNE Init_Name_Table_Text_Write8 S$ @& |' f* r
- RTS
9 l/ d$ R/ T X, |4 Q
) d7 J. b; h, b7 }/ s, `3 g- ;==============================8 G3 H6 x* m8 S! i: y
- Init_OAM_Ram;初始化精灵内存
, b5 v$ M* E1 a3 ]& g - LDX #$00
4 B) L& z$ _+ K3 f( X5 }& h - LDA #$000 ^0 n. E3 ^5 }- l
- STA PPU_OAM_ADDR
5 X$ Z9 Q% F; _$ B ~! Y$ ~ - LDA #$F8
* |. H" s# N& _# C/ O! ? - Init_OAM_Ram_Write+ t4 x: d/ L: C
- STA PPU_OAM_DATA+ ^, ]6 K# M/ C! L
- INX
$ M$ X0 x2 W: w4 e$ G, }( I, ]* c - BNE Init_OAM_Ram_Write# Y1 @) E7 H- I1 v4 i# M
- RTS7 _0 N. c1 S) g ?. [7 J3 K9 ~( S
- + t+ `3 G6 S1 l+ l6 f/ q# k
- GamepadProcess;手柄处理9 m+ o, a( Z: `( \/ G' N: |
- JSR GamepadDatacan' k; f H* @3 U
- LDA <Gamepad_0_Value+ u) Z+ \/ I* G# E. S+ I4 o6 X6 @
- STA <Gamepad_0_State
: v) I% v4 Y2 f) T6 @- | - LDA <Gamepad_1_Value
# d C, T$ B& X - STA <Gamepad_1_State3 F: ~" `4 B, H9 s1 g
- JSR GamepadDatacan
; B2 U1 Y+ B0 d8 K - LDX #$01
/ a2 d! X! Y4 g0 Y+ {$ j7 ` - GamepadMergeCheck;合并手柄输入检查
$ r+ S2 Q' m) F- h - LDA <Gamepad_0_Value,X
$ _# N. \/ c" a- R3 B" Z - CMP <Gamepad_0_State,X* n: I, y/ p! p# f5 J
- BEQ GamepadMergeInput, R! u; P3 S0 `1 G5 N
- LDA <Gamepad_Temp,X( Y! p( x; d7 w2 P% }- O
- STA <Gamepad_0_Value,X
) D' f6 t* A- [" F( @& w- \1 \. l - GamepadMergeInput;合并手柄输入
r: s$ F4 d, g. p; | - DEX
~8 a( _8 M8 Y7 y; ] - BPL GamepadMergeCheck* O! T& J" i/ Z7 m# x. h% Y5 d
- LDA <Gamepad_Merge: M! J: S" z U& m; y8 c. H, C0 ]
- AND #GAMEPAD_MERGE_FLAG# E9 N2 x; I, _. O& V9 |
- BNE GamepadStateProcess; P- N0 H9 i% e; o5 b! T3 j
- LDA <Gamepad_0_Value
# d5 Q9 ^# I; C) {$ v+ D& ~3 Q - ORA <Gamepad_1_Value
. O; f" g& R8 u( E - STA <Gamepad_0_Value
' V8 o7 O, Q5 K9 t: r/ G - GamepadStateProcess;手柄状态处理 c9 |* u* X; C* x7 s x- M0 z# w5 a
- LDX #$01
( ~# K7 \6 i: p! ]$ ]3 a - GamepadStateSave;手柄状态保存
: c& Z/ a9 f3 c( B$ m - LDA <Gamepad_0_Value,X
1 c+ R* ~/ K9 V# J( \4 P+ r0 b - TAY9 ?- c4 i7 a& g
- EOR <Gamepad_Temp,X% f" E V7 M9 V2 A% x! P4 r& F
- AND <Gamepad_0_Value,X
& ]. { _2 E1 [$ U& h% Y( | - STA <Gamepad_Once,X& U& X/ O, @ k& e- D0 q+ G
- STY <Gamepad_Keep,X
( v7 {1 B: d; l8 ?9 L7 L( q% F - STY <Gamepad_Temp,X+ S- d* @/ T# ^: w9 D! G( v
- DEX9 K ^* J: V/ L7 y0 y. w9 U( w( u! O
- BPL GamepadStateSave
" Q1 E Z5 s6 _! E/ D - RTS
' ]2 ~. \9 e ?7 X( z3 h/ [' r' t% d - 9 l5 T( m- {4 b) `" G
- GamepadDatacan;手柄数据扫描
" L1 Y) q4 j: ?0 l+ n7 k - LDX #$01 c5 e' D) W4 B; Z- n8 f7 q
- STX $4016: r- E7 f# N0 F" z% q% h' M6 k. i
- DEX9 M$ a' d5 _) j
- STX $4016
: H7 c6 E R: ^2 a% Z1 y# ^; w/ @5 s - LDY #$08
, R) k$ R. R" B6 @4 p - GamepadPortScan;手柄端口扫描 ?/ [( @# c; B& ~8 Y3 V
- LDA $4016
3 z) T/ k/ F0 r2 f& |# S) w" _' b - STA <Gamepad_Port_Value ~! h) _) W2 i) [. S% b
- LSR A
+ `5 h6 ? e! V L" |4 ^3 V. d - ORA <Gamepad_Port_Value8 r: H7 `- h7 z4 D' S( r
- LSR A
3 s: m& M! Y! k1 j4 I9 g5 d% \ - ROL <Gamepad_0_Value" a5 d. w# r. Z
- LDA $4017
+ l" {1 s/ D, ?0 \3 E/ _ - STA <Gamepad_Port_Value
7 G$ S% t. d0 V1 a6 ^! X - LSR A
8 Q2 ^+ z& y/ x, h/ E$ O - ORA <Gamepad_Port_Value( q/ i# @/ c" S. i. X( l. e0 r
- LSR A+ q i. [2 g" b) S) m9 w
- ROL <Gamepad_1_Value
# r( l9 [" ~2 |% M - DEY
/ K5 k% h7 O: ? - BNE GamepadPortScan
6 G' d z% s3 f/ ^: z! c# p& H - RTS
$ Y9 x. }& R: [$ C% W3 E$ T, E1 ~ - 8 p2 o6 s* O' e
- ;==================================================* [# Z& `) c# E$ w0 l- o
- ;PPU处理% D9 H% ?! B p5 s B9 d: p w5 [
- PPU_Process7 y% k0 g k, A; B2 {( |) `, j% f
- LDA #$00
2 F6 F/ U2 |% _ - STA PPU_MASK8 r$ ?7 L% _+ _, ]/ A
-
7 C! ~! h# s9 _. ]8 ~ - BIT PPU_STATUS
- o! @/ X2 ]( B# D% `, y$ l, A - LDA #$20
: K; d9 p) x* b - STA PPU_ADDRESS
8 X; z% ^5 G% O {4 v$ G - LDA #$000 L* m0 e' f9 e# _5 G
- STA PPU_ADDRESS1 n6 ^2 a" R+ [0 Z8 [4 C2 T: [
-
6 p" R5 @2 X! a$ Q; a) l0 r9 T - STA PPU_SCROLL
% c; f7 q; A! G: y- p' B' z7 y9 E - STA PPU_SCROLL" Y. B2 B/ D6 ^7 J6 O2 n/ o$ s# `; u: G
- 9 G7 E7 J9 A; {1 P( [5 }4 y
- LDA PPU_Msak_Buf
5 x+ t7 q0 N2 Q- @/ j - STA PPU_MASK
2 v8 P% o1 _$ c. r9 w: K _$ e4 ~ - ; n; I# Q, m/ P, U
- RTS
# t. Z/ `0 { V2 ]1 c - / T& X) E- G J( b: U
- ;==============================: d* |. ~0 B0 ~: I5 E
- Time_For_Vblank;延时等待( ]- S) ?3 D l1 u0 y% b
- LDA PPU_STATUS
+ F) d8 i: m O) H- x; L# V6 v - BPL Time_For_Vblank
( B* T) _- ^9 ]6 Q - RTS
0 Q8 s* t, j% ^# i6 f, i. U -
9 f* }# }" U) _& E) a - ;==================================================
3 w# v0 m. z) l' r! K - ;初始化MMC3
* k& Y; c) O9 P/ k - Init_MMC3
0 U# _8 v7 [) f3 M+ Z$ f - STA MMC3_IRQ_DISABLE
/ E( c5 t0 v4 [6 ]" \! b) F& u -
8 ~- {1 g: W4 W+ H - ;设置MMC3水平镜像# s1 r, o% D- G& S8 D
- LDA #$01
: q8 M2 u4 v. w- l1 _ - STA MMC3_MIRRORING$ l" J- X9 p; k ?6 B
- " @( Q' e- b4 x
- LDX #$051 E6 X; J# Q2 N+ [5 d
- Init_MMC3_Chr_Bank_Write( f2 j4 H7 Z" C# i4 Z1 |, u
- STX MMC3_BANK_CTRL
! ^! p3 V1 ^+ } - LDA MMC3_Chr_Bank_Data,X0 M: |0 s7 a/ K! ~% I
- STA MMC3_BANK_DATA* G- N- |4 j X; Z5 s9 r. r
- DEX
. X4 A* s% j1 d$ j - BPL Init_MMC3_Chr_Bank_Write8 G( Q" d. V4 F# J9 S
- RTS' \: ]+ ?' k: W! s( V5 T( u
- ;--------------------------------------------------
6 ^( I: ^6 H+ {* @ D- F$ a) S - MMC3_Chr_Bank_Data6 D, k/ Z/ T4 k2 h# v! i3 k
- .DB $00,$02,$04,$05,$06,$07# w& l. h6 I6 J, |4 d4 c+ o( `7 S
1 f) ?* p( ^: n) n- ;==================================================' d* y: s# |. \/ a/ g
- ;重置中断处理
% G9 |2 |! q Y$ l - ResetProgram' [+ p; i3 w( A7 r0 p
- SEI! H* H0 g% Q W! f# [" R
- CLD( k; V* l* @: ^$ m9 ~% }# q
- LDA #$00
/ B( z4 ^) I/ o+ n8 a - STA PPU_CTRL
6 O/ z. D% z! b - STA PPU_MASK M. i. \! G) z# N8 L3 S2 L3 V
- STA PPU_STATUS: B) R. H4 }1 G' F4 _
- STA JOY2_FRAME b. U; F7 O! G. y2 |9 ^
- STA APU_STATUS
. {" I$ H5 C2 a9 S5 K' N -
) E) X& b( R9 b1 z - LDA #$C0) v( ~; E5 \0 {, F, p& C
- STA JOY2_FRAME2 [/ O* O% Y" b( C+ z0 p( S6 V
- * t2 k+ m" }; p6 R
- ;等待vblank
+ ^ V/ D8 D6 F+ v% F* k6 x q - LDX #$02
# y% r! r5 f) Y6 I, g - Vblank_Wait_1! k! d( F9 X2 W; w
- BIT PPU_STATUS
' ~# R& f; u1 s6 _. @1 p; T% s6 @ - BPL Vblank_Wait_12 w1 W; `" v* |$ ]
- Vblank_Wait_2
* J; s g# ~ a$ y* ]3 ` - BIT PPU_STATUS+ c7 \4 t0 e+ d v8 X
- BMI Vblank_Wait_23 p5 o" y, X! u P6 v4 L" A3 V: [6 Z
- DEX3 U; o- h6 y" ?2 U/ [8 A- |# b
- BNE Vblank_Wait_1
2 y3 m; b* V1 @ -
' s1 ?& H. {* @0 a# ~* Q( |) K) t - LDX #$FF( k6 D3 x7 a: J/ M* z
- TXS
+ n& B* m, Q; Q { -
) Y1 o- N, v P; f7 \ - ;初始化MMC3$ T" G, T3 K8 _# z7 [
- JSR Init_MMC3
" u) v% K7 n3 R7 l Q - 0 ^$ ]! R8 _ M0 }
- ;==============================
/ c+ g$ \- u0 a ?% C - ;RAM初始化. L, J$ N! A3 |$ A
- Nes_Ram_Init" L( V) A1 A# \' j
- LDY #$00; ~/ g8 w, {6 S
- LDX #$08
+ n- \( x, p4 q) u9 Q - LDA #$00: J% K) }9 b4 q3 h5 K
- STA <$00
! z; T+ V+ |2 F3 S - STA <$01
( x" T$ ^/ z0 v - Nes_Ram_Init_Write
! M C9 b& w. |. r - STA [$00],Y% y& m* r- a; R
- INY
$ D. e5 p( Q' L" f& i - BNE Nes_Ram_Init_Write& G$ g( u. S( i' `4 f. j: ]
- INC <$01' y8 N( L. V9 f
- DEX5 V1 w' W( D+ A8 _
- BNE Nes_Ram_Init_Write! c. Z3 D0 D! ]+ g' _
-
+ R6 l* u5 F& I8 q& D; ? x - ;初始化命名表: T' Z* B# e2 \. U4 I6 N1 D
- JSR Init_Name_Table0 P) g, G; V7 O# C% N* m
- " j/ v% @: S2 U. O1 Z
- ;初始化调色板
8 F! h& F0 {. N5 p7 v3 k7 i" k5 _ - JSR Init_Palette, i: W5 i3 X* a* F
-
! v9 C2 d5 U* |+ Z, m2 W% ^ - ;初始化命名表属性
& v" l7 ^5 l" i4 u1 A0 O0 S0 B" f5 k - JSR Init_NameTable_Attributes% l9 c: g/ H. t+ Y6 Q
-
1 E+ R, Y3 K J* ?# S: A( Y; O+ v - ;初始化精灵内存
+ T' ^3 S5 z. Z" P - JSR Init_OAM_Ram
( i) k3 M/ b2 `, e3 e -
. B: q+ m5 M& X, X o' ^7 R - ;在屏幕上写点东西
" F" @: I# s4 q/ ?; K8 V- j0 E - JSR Init_Name_Table_Text
4 h' B u* J" U1 k {: C1 K% M, D -
0 f) l- V( G3 @ b: B* c, e - JSR Time_For_Vblank
c: q3 a% f$ _6 D# r - ;开启PPU控制# p7 Q [/ U+ F# g. r$ `" i; B
- LDA #$80+ G9 V( k6 x9 o7 ^
- STA PPU_Ctrl_Buf
( G3 E1 O8 m2 @ k( a1 X/ A) h. X - STA PPU_CTRL
+ J9 N3 o2 [, X - , W. t- B0 r* S3 i# `+ y2 h1 u
- ;开启PPU显示$ x% ~- z# G k: y7 f
- LDA #$1E
6 n$ _( ]! h) w0 Z0 X `' Y - STA PPU_Msak_Buf
! e. \7 M# P) m* H; f9 A' |' ]- p, J -
( `+ u" h8 T$ p4 Y& [) U6 {/ F - LDA #778 a- @ B: s- k2 p* G+ J2 ~
- STA Sprite_0_Y
0 C4 @4 y0 L( s: @ b1 d8 x - LDA #$1E6 V& D* c# C3 ]4 \# r
- STA Sprite_0_Tile% f7 o( M; _& i$ i4 o; H8 E
- LDA #$20
, r( E$ |3 y4 p2 x - STA Sprite_0_Mode
, P" y- S- _; J' Z - LDA #$00
$ d" A: J8 e$ U7 f) Q - STA Sprite_0_X. ^0 b( R% T& X* h9 Z5 N% V4 y/ o* Z
- 6 j. @9 |' D0 k$ m
- CLI
/ b% p6 v( T7 `! _ - JMP Loop
- i; S1 T8 c) E- j - ) t' _% T; a% n$ Z
- ;==============================
3 p3 r4 Q5 }) P - ;死循环, 等待NMI中断
' h1 [, {- e4 t$ O9 F9 \ - Loop0 o- T0 r4 p8 O: v( x0 l3 Y" V1 ]0 B
- JMP Loop" a8 `% u9 w$ _5 t
- # v6 `8 p0 ~, |, \( ~. X K* {8 w
- ;==================================================( b. L* i1 G* u: ~7 t% q
- ;NMI中断处理3 Q+ F9 [+ _5 q$ J* c
- NmiProgram
7 U, \& E8 X( h) B S7 q0 x - PHA* ~$ D, ?; q+ _
- TXA& I( g$ \/ t# u( d' [. t2 v: G% u
- PHA
6 u1 J# t n# s3 G! B - TYA
# p7 l; M& i8 [* G- _) i - PHA0 V$ o3 X) d9 L* ~0 g9 R; S
- ; l% H) X+ T9 H& u0 a2 N- }
- BIT PPU_STATUS
3 K( t F, f2 f6 u! T- x( j -
$ }/ @' _( F I J' ? - ;关闭PPU控制
9 v" S F2 z' [% [: M - LDA #$00
1 M7 M Z+ S4 M# h5 C' Y - STA PPU_CTRL
9 T O& \. X+ _+ |) ]8 y# Y- Q" e: C - ) \4 Y$ D/ p4 l7 z! w8 I
- ;处理PPU: S4 X! _( u6 o: G
- JSR PPU_Process
$ J8 h" \! c; C: W. a- C/ c8 h -
* k9 E' g) d" }: K/ B( t - LDA #$00% {6 l% j& ]# ^( @% U" y
- STA PPU_OAM_ADDR
c8 D" `: K! ]9 M - LDA <Sprite_0_Y
3 u! j2 o- ]8 Q4 O d - STA PPU_OAM_DATA% B: Z% u3 v2 r6 c
- LDA <Sprite_0_Tile4 ^( _( C1 r8 n- |
- STA PPU_OAM_DATA
& j; S2 k% x! a1 p* \+ f- | - LDA <Sprite_0_Mode8 t& U0 s! O& {7 G
- STA PPU_OAM_DATA' X. \9 o/ a @
- LDA <Sprite_0_X! l" e" G) B% c& i! u
- STA PPU_OAM_DATA5 |- F/ A4 c" A5 \$ u3 r1 J
- 5 y1 h, v8 D7 q: E
- ;开启PPU控制
) ?+ j& L( a2 E - LDA PPU_Ctrl_Buf/ B/ S4 t2 I8 B/ \
- STA PPU_CTRL) b, ?% k6 ~! }3 Y' o* G2 U) N
-
* ?+ j; B7 f* [- L, V( w8 G - ;屏幕滚动
9 d0 L5 i: r+ i* H; F' p+ T) H - LDA <PPU_Scroll_H% ]3 g$ ^+ F2 ]9 c- a2 A; i1 k4 w0 C
- STA PPU_SCROLL: s c+ ]: e2 d/ z9 Y: C6 O
- LDA #$00
# L5 G1 T [+ \" M9 l4 f) \ - STA PPU_SCROLL
}) P" n( k' N7 n -
L) Q; `1 z" M# u( b. L1 O - ;手柄处理! I7 e1 J- ~2 o8 h F
- JSR GamepadProcess4 d1 \. c' e" N8 Z7 e7 ?
- 8 A+ R9 I! |# l" R
- INC <PPU_Scroll_H
- W8 z7 d7 F( x1 Y' w* h -
$ p6 j' z3 _& G5 k2 N$ }5 t9 ~$ \/ Z - ;启动0号精灵碰撞检测% X& r( ]+ X p/ v2 t. x2 q' H! `
- LDA #$01
7 P) Z% ?# y) j( a+ Q - STA Sprite_0_Hit_Move_Direction
7 W6 ^3 D! n6 d9 u6 r6 R2 W - JSR Sprite_Hit_Test
# w. @. ]# ?3 U: w - 3 b/ h! d1 A- v. p# Q( n
- PLA
: P' ]. {, E: V - TAY* ~9 B7 W& I4 {) K v% q1 u
- PLA
r7 y! h b+ @, ?4 [) e - TAX
0 {4 E0 o1 A$ h4 |8 F - PLA5 P; S$ [' s9 F0 Q
- RTI
/ l8 e( L6 f: W
0 V" u9 w" O( @: a6 C: p6 E; S4 d0 J- ;==============================
/ b% ^ h" P& I# x( h( n - ;0号精灵碰撞测试
D" R8 w: b! Z/ b - Sprite_Hit_Test
1 [7 k( ~) b7 C5 M - ! t! ^9 l1 ~, u( b' C1 M# Y
- ;------------------------------
, X6 c- k1 G! L3 Y( y2 _$ F - ;等待0号精灵碰撞状态取消 d6 J" ?% T) G
- LDA PPU_STATUS
5 C- u/ C2 o5 \+ S9 J* e - ASL A) c7 z. n7 |" U+ ^7 e
- BMI * - 4' x7 F+ Y! i- A) b( Q- q# N
-
F) _- {% r! `5 [8 f& N - ;------------------------------
2 n: H1 Q; K0 W0 W( x T4 v - ;等待0号精灵碰撞发生 y$ @3 r" K, G9 ?( G+ @: ~+ I
- LDA PPU_STATUS; K5 P+ e! C0 D! d6 _9 q, F1 s8 w
- ASl A) X4 c& i& S( h0 n3 ?+ ~) O7 P, q3 U4 d
- BPL * - 4
4 |$ k4 E: F6 B N' Z; | - , H! E0 d; y$ a+ K
- ;------------------------------
4 k" i' [0 w" \- I3 A: \ - ;行消隐等待! O7 S, N, e: A
- Sprite_Hit_Scroll_Wait
* y% H! Z K+ v8 f) T - LDX #$28
5 h* V _8 J) n! _& W; k; @" b5 K - DEX1 m' S, p/ {9 E7 W+ p) n; d
- BNE * - 1+ P- N' P/ n: ^6 Z- ~$ _
-
) P8 ]: \# j* e3 X# K - LDA Sprite_0_Hit_Move_Direction; E |% H; ?& f+ `$ c' A
- AND #$012 z6 h5 y! V; O7 P, M
- BNE Sprite_Hit_Scroll_Set_Right
+ F% S8 C' K, S9 Y# [ - $ ? t% k6 B0 u& ]
- ;------------------------------* | y1 {4 l0 W% @6 w. q) Y
- ;分割画面向左滚动( X% k$ }; D; ]. s; o
- Sprite_Hit_Scroll_Set_Left, K2 h0 r" _! q! I& g. a3 y
- LDA PPU_STATUS9 W! w" Q( w0 q2 U7 w7 d
- LDA <PPU_Scroll_H
$ P |' v6 k* q - STA PPU_SCROLL: g: O! l w/ ?3 j+ w5 A
- LDA #$000 q4 d& {$ J. h
- STA PPU_SCROLL
& p' A" A! V Q# b' L' G - RTS
! o4 a4 @: A( _* C, h: v - ) Q E' W5 x, R' h' B, H) G; ~
- ;------------------------------) Z/ J, F, V9 s1 J
- ;分割画面向右滚动: U5 z/ w3 E& d7 m# G
- Sprite_Hit_Scroll_Set_Right
( e. P4 i7 A' C - LDA PPU_STATUS. l9 B0 u3 A4 I$ M. t; ~
- LDA #$00/ _/ D5 g/ U; H6 ~+ {3 S* x+ s
- SEC5 x0 d$ A& O; J- Y! [9 Q& T) x
- SBC <PPU_Scroll_H
$ _$ w6 s! D0 \; b4 Q - STA PPU_SCROLL
o6 r, A/ m3 m V. E - LDA #$009 k- r$ }* c& O! ^, ?* |9 s
- STA PPU_SCROLL
) d) @. s: ?3 Q; v$ A3 d& [, q - RTS
! D' _% ]7 h+ i: |8 h - * c/ O3 V8 z9 X8 o
- ;==================================================; x) D7 r) R: E. k) V) u& P; z/ g
- ;IRQ中断处理
& F* p8 K' I: _6 X6 u% ? - IrqProgram# |4 R. ?2 {6 Q3 o& ^4 M/ G
- PHA& K- r4 P8 E" V: D
- TXA) C+ `4 P8 G: R# G; m) H+ K+ |& X
- PHA
, t0 K5 m, L, h - TYA
: H6 F" p* K4 c- A+ F/ B+ Z; n5 b% I E - PHA
5 l$ t8 u- [0 g% q9 N0 g - 0 s7 p H2 f T: ?
- ;关闭IRQ
) D: `. ~. w2 [! q - STA MMC3_IRQ_DISABLE
c( X d7 g2 g' o: b3 D3 x -
5 X1 H6 A2 Y- l2 H! `" e8 O - ;允许下个IRQ触发2 C4 w6 E- ~* e5 b8 L
- STA MMC3_IRQ_ENABLE
1 r: D1 L( @8 ^2 O- t5 a -
d& n) Q* `9 A* V& x8 v - ;IRQ处理, 15线后继续触发
' e- x# j. N, m2 w) _9 U: v- K6 n# h - LDA #158 C/ ]0 f" |; i0 E+ R6 Z4 Z
- STA MMC3_IRQ_LATCH0 X5 }" ~% M- ]# L- B
- ! j8 c5 w- P i
- LDA <IRQ_Index4 I* a5 z# b* h
- BNE * + 41 I3 q1 S& h5 M% n
- INC <PPU_Scroll_H, P7 K8 a+ t4 J, i4 g5 Q
- / _. e7 S# B9 C8 R& X8 {& K0 u; R
- ;设置屏幕滚动. F- ?- L) M4 ]/ R4 d
- LDA <IRQ_Index) ~1 R' ~2 d4 E! e$ p
- AND #$016 j% C: W5 E# X5 F; v
- BEQ Irq_Scroll_Right6 ^9 z+ B ?$ a- o3 D2 |. O( _
- 3 O1 a( \/ C$ M* B1 l; F7 e
- Irq_Scroll_Left
* B2 O8 b/ W' z8 a/ Z7 J" A - BIT PPU_STATUS" E5 c$ e0 X+ g' E6 V/ P! c
- LDA <PPU_Scroll_H
" E. I( T" a4 c" K - STA PPU_SCROLL
2 i; G ~# s8 D: B" c - STA PPU_SCROLL5 C+ z" Q6 Q1 B
- JMP Irq_Scroll_Over
# m5 ~6 X) R t2 x2 d+ L - ' x3 a& K7 B) j$ b( B5 d# y" F
- Irq_Scroll_Right
% T! q- v4 |+ L; T) z - SEC1 @, P' V- L" o, l7 |! {+ w7 j
- SBC <PPU_Scroll_H A% Y6 `; l; q0 Q
- STA PPU_SCROLL
4 ?! _5 c6 F" u3 q% ` - STA PPU_SCROLL
" N3 }5 n+ w" v: e - Irq_Scroll_Over
# n( U& R B- M" o5 h- I) E -
1 h7 e4 @ j+ i) W4 ? K# ? - INC <IRQ_Index E. _- K- r+ G5 R* J6 h2 @
- " |4 f, e( }" a
- LDA <IRQ_Index
' A* y- _4 x" z - CMP #14
- K: C/ f* z8 w0 m6 @3 k9 x/ k) Q - BCC * + 54 |; C1 [$ I$ C: T% J# U
- ;关闭IRQ
& E( l# V1 \, t* H; n' P - STA MMC3_IRQ_DISABLE6 R6 a' V: O, S4 S
- , W& _0 P$ z2 I! \+ d
- IrqProgramEnd: p' u I* \/ E; |4 P! @+ q3 C
- PLA
" Y E' a1 G2 s - TAY% S4 x; D. n5 D6 r2 S( ~
- PLA6 j$ r( W @, h, O3 Z
- TAX
1 ^) m8 h" u4 {& z7 d7 [ - PLA
6 i5 j0 g# `' n9 ? - RTI
9 l: F% C- G9 L7 a6 u/ l - 1 T; V, v) ]+ `9 _" L* o
- ;==================================================
' ]; u' t) T* T4 |7 f9 j: C - ;中断表
9 H- y2 I' q3 i* m( S) Q - .ORG $FFFA
; A( }& M; D9 G - .WORD NmiProgram
: l% t; Q( E3 N7 j( F; p, w+ \% ^ - .WORD ResetProgram
8 e* R1 M8 D6 p - .WORD IrqProgram
复制代码
0 m4 i, O" {, `2 Q6 ~ |
评分
-
1
查看全部评分
-
|