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