|
|
本帖最后由 yandagui 于 2017-4-16 19:06 编辑
) \" l1 h: W: i" p) |1 j( y3 ^- C# K
Mapper23转Mapper4实例教程
! m5 j$ d% v1 C$ w( c) m7 W# S" W% F' p
FlameCyclone 2017.4.14
! S b$ @6 ?+ l8 I/ w: w! S: C) y. J0 {! t( A& P8 }) ~8 E2 H
先看看Mapper23文档:( e, u5 e. b1 x6 l9 [0 e/ o
- J& A0 }6 ]( A9 W: K- J5 M
Mapper 23
9 P/ T Y' i6 ]% e" t7 F; o2 U- m4 `2 n; J* }
$8000: 选择8KB的ROM存储体映射到$8000
+ e+ e: `' J) W( f5 l* k* P. z
$ i+ C0 A( l" z% {$9000: 0:垂直镜像
# I0 n- P. \) S `4 x 1:水平镜像! Y" M% e' M* s7 Z2 g7 j: U. P
2:$2400镜像
. h" H* t y8 q5 l9 }4 G 3:$2000镜像
, n+ f; S# v7 u* b! g
% L* e% S. {: G3 @$A000: 选择8KB的ROM存储体映射到$A000
& y' z- C( a, d" h3 y. u3 t. E5 y7 y
$B000: 选择1KB的VROM存储体映射到PPU的$0000(低4位)3 D8 J: t" Q: I6 i7 v- M" V
$B001: 选择1KB的VROM存储体映射到PPU的$0000(高4位)
: e5 @" \6 T9 ]9 w$B002: 选择1KB的VROM存储体映射到PPU的$0400(低4位)' R3 i% ~: [* Y" Z3 t# `
$B003: 选择1KB的VROM存储体映射到PPU的$0400(高4位)
. E! Z7 u/ T# q2 d% p) o( I' B
, t6 F; ^6 V! Q* K8 g$C000: 选择1KB的VROM存储体映射到PPU的$0800(低4位)
2 @! O$ H- W# z# B4 @# j$C001: 选择1KB的VROM存储体映射到PPU的$0800(高4位)
( q; ?( \8 A3 \% n- G- \$C002: 选择1KB的VROM存储体映射到PPU的$0C00(低4位) g. r3 [! z) B7 B/ K$ M
$C003: 选择1KB的VROM存储体映射到PPU的$0C00(高4位)
0 w9 S, [7 c! y8 a% A% U9 ` i; ?6 |8 O, n, n
$D000: 选择1KB的VROM存储体映射到PPU的$1000(低4位)# h) O* Z$ e" K3 V! y' \# }
$D001: 选择1KB的VROM存储体映射到PPU的$1000(高4位)
8 B- C4 v- ~) L3 P4 H0 W3 t$D002: 选择1KB的VROM存储体映射到PPU的$1400(低4位)
7 s2 ~( r! u! |) x: o3 b$D003: 选择1KB的VROM存储体映射到PPU的$1400(高4位)
8 f" C- w# x+ B) W) V
4 S( E) N: |& C5 \$ K/ N$E000: 选择1KB的VROM存储体映射到PPU的$1800(低4位)5 i% _( m; j4 ~5 r
$E001: 选择1KB的VROM存储体映射到PPU的$1800(高4位)
% i1 B- G4 S4 {5 a# N: @; X, R9 I$E002: 选择1KB的VROM存储体映射到PPU的$1C00(低4位)
) f9 z; ~$ }! b$E003: 选择1KB的VROM存储体映射到PPU的$1C00(高4位); h; G- T2 p( e5 `
& _) ? F/ E( U: ]$ |6 D
再看看Mapper 4文档:( y4 G% Y& L- Z; E) T, q4 A1 b
. ]3 _2 U g4 yMapper 42 `/ p i. a& h/ ` Y* H
% l) P0 \. S1 m0 j
$8000: 模式号8 D% }7 {8 ~$ J3 A0 e
位D0-D2:
% t# u7 S/ h: l9 K' n. `. ? 0:选择2KB的VROM存储体映射到PPU的$00004 Q: Q: a$ o7 `- `- J
1:选择2KB的VROM存储体映射到PPU的$0800
, `( |% s! r: R) H 2:选择1KB的VROM存储体映射到PPU的$1000
# N/ a1 W* n4 L$ J, t 3:选择1KB的VROM存储体映射到PPU的$14004 c0 G7 M1 {0 B8 s ?) c# G# m: {
4:选择1KB的VROM存储体映射到PPU的$1800+ b6 O4 s" H) Z3 R5 ?
5:选择1KB的VROM存储体映射到PPU的$1C00 o8 j- i& o4 B* O: a* B
6:选择8KB的ROM存储体映射到$80003 f. E+ N2 W$ B- o
7:选择8KB的ROM存储体映射到$A000
* C9 ~' f2 \4 a 位D6:/ ^, w4 A6 V3 P* v& |" q% M
0:允许擦写$8000和$A000
. ]% \6 P2 N$ f6 J 1:允许擦写$A000和$C000+ b# d# a/ h4 G, J8 m/ g7 t
位D7:* C% ^5 ~/ [3 p" G
0:模式号D0-D2使用普通地址
/ ?/ K" o. J: ]" |' R0 C 1:模式号D0-D2地址异或$1000
" D/ c. D) @3 E* a* c( Q: q2 N: A- w
$8001: 模式页面号
/ T- p% \, n4 V4 Z. M 写入一个数(00-07),切换存储体到对应地址' ?5 h5 [0 U/ V M5 ]6 w
- N, ~+ ^* ^+ ~$A000: 镜像选择5 X6 O' S8 y' B
0:垂直镜像6 t6 F# C: h! s; W
1:水平镜像9 C) O0 F* U$ A$ h* W
: E# j. L( P" h: C0 m
$A001: SaveRAM 切换. k# f8 I/ ^) S- y" P
0:禁用$6000-$7FFF
; o/ |" W9 @3 i4 U2 w9 A1 Z: n% R 1:启用$6000-$7FFF
% x! l7 C/ w, A8 @- e4 p+ Q/ D/ r
$C000: IRQ计数器. J7 ]$ k6 [8 F5 {) h8 t
IRQ计数器的值存储在此处
( x" W, t- y) N1 K6 J. l( R2 O; \" ]- W- n; E
$C001: IRQ暂存器 y) M5 `: @' H7 B. e l
IRQ暂存器的值存储在此处4 l/ f W! Y$ C9 d4 A) e
- d- r, X1 D* L: k+ S4 Y. A, g" i$E000: IRQ控制计数器0
7 q$ D2 ]! I7 W2 B& a3 r 向这里写入任何数来关闭IRQ,并从暂存器中拷贝数据开始计数,进入IRQ
3 ~2 c4 I- E8 ?2 f( d) \! t+ }* y5 m; n' Q$ O
$E001: IRQ控制计数器1
2 q) {0 s) F2 ] 向这里写入任何数,允许IRQ(退出IRQ,允许下一个IRQ进来)
8 A; c! g& c& ?3 N. s7 x
/ m% J" D9 i. M( P1 z2 r9 ?; m
! G: a. E! o* {' C3 |9 G转换思路:5 y2 `3 [0 F3 H6 ^( A
将Mapper 23 的切bank 方式和切VRAM的方式修改成Mapper 4 的方式。
- _6 J9 z# O0 F" F" B4 `: L+ ~1 a! h% Y5 R1 u7 `6 J) m
修改实例:; v2 X/ U& K1 e. b( R8 M
Contra (J) 256KB Mapper 23+ j6 v$ ?, y/ R, @7 f
工具:( @- S/ V4 Y( W, C1 o+ w
1.FCEUX 2。2。3( ~% D1 y$ G: c9 K; L# `0 U
2.HXD
( Z8 k' o! j# A# w4 q先来看看这ROM的切bank方式:9 E0 |/ z9 R! j+ n4 E
F989:AD 00 80 LDA $8000
/ L' s3 u( i- h4 Q% a. R3 FF98C:8D EC 07 STA $07EC! r/ z4 P3 j$ k
F98F:8C 00 80 STY $80003 S- o2 s! m( c+ w. R2 Q
F992:C8 INY. V* w5 U4 ]# ]: V, q4 w# L
F993:8C 00 A0 STY $A0000 T4 W2 t( `2 c7 J
F996:60 RTS
' I8 y; @+ n4 H: q* a8 a" S! }3 ]: ?! C+ |9 r6 ^
再看看它的切VRAM方式:
$ r2 P# ~9 U% c1 L* ? `FACE:AD F0 07 LDA $07F04 l5 W0 D* l3 ^7 d( m1 ?
FAD1:8D 00 B0 STA $B000# }" C! n) J# R8 B
FAD4:4A LSR
0 `1 Q; u& A: D! ^FAD5:4A LSR% K) K6 ^3 y* {& s- L
FAD6:4A LSR7 {8 \: c, f( x1 P7 N: S
FAD7:4A LSR
8 n! R' l0 F8 n. d6 l/ oFAD8:8D 01 B0 STA $B0016 f* W* Q( }0 h, G' w, A2 J( N, ?$ t
FADB:AD F1 07 LDA $07F1
9 R7 m' W0 \6 JFADE:8D 02 B0 STA $B002
1 `0 o: b: R( e1 O( P+ ]7 X9 NFAE1:4A LSR+ x2 L+ l# a0 }1 ^ d" e6 d5 B
FAE2:4A LSR
9 S3 l6 E8 a1 I) m uFAE3:4A LSR2 ]6 \" t" ?$ b- c0 J9 X* ]
FAE4:4A LSR6 D5 k/ d: q0 k/ s! k8 w
FAE5:8D 03 B0 STA $B003. n9 x" S/ M6 a
FAE8:AD F2 07 LDA $07F2
+ V) k, b- W/ T5 eFAEB:8D 00 C0 STA $C000. A1 H$ L- e3 ~* x
FAEE:4A LSR9 a, O* y [) _ L' F! T9 O G
FAEF:4A LSR+ H4 B* ], ~* D7 M! t
FAF0:4A LSR7 n5 ]2 y! M9 W( b) c/ l& e
FAF1:4A LSR9 S# L( w0 x$ Q: h" p
FAF2:8D 01 C0 STA $C001* \2 Q0 f+ D9 v- \
FAF5:AD F3 07 LDA $07F3
! J1 D; h7 m; L' t' UFAF8:8D 02 C0 STA $C002
& h- o- R. n$ O3 G5 b) d4 W; [7 tFAFB:4A LSR
- `1 k) M# a- l8 Y$ bFAFC:4A LSR
& T, Z, y6 O, n$ r0 L* VFAFD:4A LSR
* |% G6 Y( N/ O; o! ^6 QFAFE:4A LSR
. a, ?0 q k' t7 X6 rFAFF:8D 03 C0 STA $C003
9 I" f0 `: M- X3 ~( @$ SFB02:AD F4 07 LDA $07F42 q& D+ M9 C: a9 \0 R8 N$ B; P
FB05:8D 00 D0 STA $D0002 A! R# } c, `% J) q
FB08:4A LSR
5 d8 S% P, \7 f" H+ YFB09:4A LSR
6 \0 _9 L. C+ V6 vFB0A:4A LSR- N6 W/ B1 n R7 _5 s5 n
FB0B:4A LSR
5 D& p. c8 `1 F7 |$ m5 r/ ZFB0C:8D 01 D0 STA $D001
0 O5 Z' @; u7 |% R/ P2 XFB0F:AD F5 07 LDA $07F59 g5 o; T9 Y8 p1 R2 \0 H
FB12:8D 02 D0 STA $D0023 M) \& I# r) l
FB15:4A LSR& X7 z0 ]9 i3 f [' U8 F& _
FB16:4A LSR
( Y: Z- w8 p( s" y, R- |$ qFB17:4A LSR
1 P! V& s& I# H+ f9 L4 gFB18:4A LSR
- o- a# W: k8 `( }" _FB19:8D 03 D0 STA $D003
8 H1 T) u2 J5 L/ s' _& L9 x! G* bFB1C:AD F6 07 LDA $07F6! S# U* r$ Q: ]- r8 i
FB1F:8D 00 E0 STA $E000 |. I) H4 Z. x; S
FB22:4A LSR; O3 Q$ Z- B- O" v4 {* `, a# q
FB23:4A LSR/ A, ~3 _: G* y5 \( M3 Y# R
FB24:4A LSR9 N8 _7 ]$ z$ V3 g1 e0 A# g+ }8 y
FB25:4A LSR
% t0 T+ z9 [$ D/ ~3 q" L2 lFB26:8D 01 E0 STA $E001
5 ~. X5 }* k2 V# n+ P' t" OFB29:AD F7 07 LDA $07F7( a. C; t2 o7 F% S: ^ J+ Y: C+ t
FB2C:8D 02 E0 STA $E002
& j o5 Z3 x) U3 r3 R! ~FB2F:4A LSR) r7 T) i, c/ K! K1 F: O0 I! s
FB30:4A LSR) h* t& c. `7 m# f6 v; c# W
FB31:4A LSR7 a, @ ]) F; c& O2 O0 ^
FB32:4A LSR
. d% A/ T2 v- j7 lFB33:8D 03 E0 STA $E003: g& K- W; z( G: r* f! P
FB36:A9 00 LDA #$00
6 Y" S- ^7 K$ i) _+ ]FB38:8D 00 90 STA $9000% m" n' S8 l3 D' h( `# P
FB3B:60 RTS
0 j# Q* @/ ]3 g3 t+ C! d" l- V' i! x+ k9 H. _9 w& ~; V% r
接下来修改切bank方式:
$ v# F* Q! O9 K6 E7 hFB2B:48 PHA2 u2 y: S) C# X* j" w8 e( d
FB2C:A9 06 LDA #$06
# c( v6 w- S5 ^2 I" U$ {! t% PFB2E:8D 00 80 STA $8000; O9 Q5 `/ v4 U; T" z; L5 Y
FB31:68 PLA
( W; `0 C2 J* yFB32:8C 01 80 STY $8001
) N' m& S) w) HFB35:60 RTS! I! D+ d/ [" \- I& B
2 }6 n+ A8 H6 Q4 U
FB36:48 PHA
# q1 t& s6 ~2 ?0 t( g5 ^FB37:A9 07 LDA #$07
; [8 K. i) R# W4 f9 [ Y9 j* lFB39:8D 00 80 STA $8000 = #$14% A, i: L) J5 B/ r" _9 S) |5 H
FB3C:68 PLA
" y; G* [7 D5 ?1 O+ t9 E: iFB3D:8C 01 80 STY $8001 = #$1D
- m! F$ t7 S3 j: x% jFB40:60 RTS
8 v* @8 u+ C K. P2 J# l7 F% W' v) ~/ Y
还要把原ROM的对$8000和$A000进行写入操作的程序修改一下:' V* j4 ^: t$ ]" ?( p) W
F989:AD 00 80 LDA $8000 # [8 |' u& A. C! u5 g( Z; K
F98C:8D EC 07 STA $07EC
9 Q6 G0 x: C# N' O& `) f/ Y/ J+ gF98F:20 2B FB JSR $FB2B* H$ Q% ~/ h0 n8 z/ C- f# w# K
F992:C8 INY
. ?) l( {% c( X. M8 gF993:20 36 FB JSR FB36& V& M, U$ a( \. {, L
F996:60 RTS
7 ?9 {- _6 x/ V6 ]. o4 P5 X. v& T, N: _' t( F( ]5 i& Y
再修改切VRAM程序:
P2 Y5 i9 D. f: K; c* f9 i4 jFACE:A9 00 LDA #$00: _: G; w, B" w, a, p% q6 I
FAD0:8D 00 80 STA $8000! s# t6 ]1 W2 j5 _; U
FAD3:AD F0 07 LDA $07F0. m, ?& ~5 m: a0 u% R
FAD6:C9 01 CMP #$01
. v/ n N( B5 @$ D6 C0 G* K& VFAD8:D0 11 BNE $FAEB
7 E0 g4 X' K( b0 ]0 w; ?9 \) s+ _FADA:AD F1 07 LDA $07F1& q* h5 j2 l6 q6 C8 X- _: w
FADD:C9 04 CMP #$04) |6 j7 W9 ~8 R$ Q; a
FADF:D0 04 BNE $FAE5, I6 {$ o5 m7 T$ p
FAE1:A9 80 LDA #$803 _& ]$ H, X/ |! W4 b0 [3 F8 A
FAE3:D0 06 BNE $FAEB6 {* N; t {1 Z( ]& [* d0 B
FAE5:C9 05 CMP #$05
0 [0 a3 u o) i# ~% p. q5 ~' XFAE7:D0 02 BNE $FAEB2 Y5 g4 r/ j: @3 H5 g
FAE9:A9 82 LDA #$821 j \1 K# f; d0 T! V1 u* H- i
FAEB:8D 01 80 STA $80015 B8 t5 b( v$ `, }# C
FAEE:A9 01 LDA #$01
, M5 y; Q. \" z. @( D: G! GFAF0:8D 00 80 STA $8000: U" n6 V; ^3 f. j! E) Q- ~" I9 u
FAF3:AD F2 07 LDA $07F2
% {: }- |! {* U0 _; Z" ^* c; t, t0 YFAF6:8D 01 80 STA $8001" t0 r5 u' |- ^$ l' a- ^1 B
FAF9:A9 02 LDA #$026 Z" m- G% E! h9 E
FAFB:8D 00 80 STA $8000
7 [% W! ~* X, E, j" v+ L0 G; a% sFAFE:AD F4 07 LDA $07F47 e3 q3 P! U0 A9 {0 x7 n5 A
FB01:8D 01 80 STA $80010 O" k: w% l. h5 A1 B+ N
FB04:A9 03 LDA #$03
- }9 `, b5 Y) d3 v3 H5 W$ N+ QFB06:8D 00 80 STA $8000
, ^. u2 q, [ C1 Y2 W) v! r5 eFB09:AD F5 07 LDA $07F5$ b. o+ u& ], c, Q. a
FB0C:8D 01 80 STA $8001: C2 @* u; C A
FB0F:A9 04 LDA #$04( X5 j" j2 j0 T. z8 [$ F
FB11:8D 00 80 STA $80001 K0 l. Z- R* F* a# K
FB14:AD F6 07 LDA $07F6
8 E. U. [( E: G- jFB17:8D 01 80 STA $80017 }3 o/ V6 L% Z6 D' j
FB1A:A9 05 LDA #$05+ r* b- |' P7 l. n2 [) _
FB1C:8D 00 80 STA $8000- G& U9 T% f2 v3 r* U6 V% v& _1 N
FB1F:AD F7 07 LDA $07F7
, W `4 A8 S! _/ J3 ]FB22:8D 01 80 STA $8001
; Z. S& p+ V2 t jFB25:A9 00 LDA #$00
H# ]1 t% G( R! E7 ZFB27:8D 00 A0 STA $A000
' z- Z7 S' [8 ]( c( g6 d7 UFB2A:60 RTS
4 e( D% W0 A: K( n3 c- Z9 R8 K3 U) {9 g) {
然后保存文件。
/ Y5 A5 d* ], ~/ j8 H使用HXD修改文件头:5 f* l6 I9 O( y3 `! h
将Mapper 23
& C& Y( e# C# L* |; P06字节的高4位是Mapper号的低4位8 K' G4 i; T# c
07字节的高4位是Mapper号的高4位, z0 H5 w$ o6 V+ E8 ^
组合起来就是0x17=1*16+7=23
& B9 H" l! O% m5 W2 f
5 n* ^8 h' x/ v! l: }! v, I% W修改成 Mapper 4
# C3 U8 q% u- A l. A+ o
3 V: q0 A8 [8 ?' j% T6 P5 s9 G2 f) m& l
6 b8 t9 K3 g" k; u* ?5 E/ x- f
再次打开文件:
w8 g) O, q# d- H# O3 s& j7 B
$ {/ f/ |* q2 {. }4 l; L' b" S可以正常运行
: t/ v9 K& d$ Z( h5 q1 Q: G: |通过全面测试,发现出现精灵错乱:
9 Z! | c( ^# U' Z- X7 T第1关:
- ?2 V- n* ~5 x8 Z. ~ + i. D8 Y r' T2 g5 C8 u
9 ]* j% j) e7 v- ^6 i& m6 [第2关:
" B8 q+ l5 P: _! H; r0 j
$ H) ?$ l0 B* r+ Z" C* e5 H* v0 P* p任务失败后:. `% Z. H' D( J1 w

# s. x/ O/ }$ _( T$ J8 J; |通关后上飞机画面:) Q- d) J( D# `7 b+ \. C

8 y) K8 \) m5 D这是为何呢?6 m0 R: z; j6 ]2 ] @
这是因为Mapper 23 中精灵VRAM切bank是一次切1KB; b/ E4 O5 v# v! @9 a- q- e- R" X
但是在Mapper 4中精灵VRAM切换却是一次切2KB,而且忽略bank号的D0位4 X& T o4 u# r1 W% v4 c
比方bank 0和bank 1是同一个bank,同理bank 2和bank 3是同一个bank8 K& e) e6 {* a3 V" n
也就是说* t7 ~/ [/ M* `6 X6 j/ n; o6 o
Mapper 23中的VRAM的
" N R% S; [& W( e5 F7 Ebank 0,bank 1,bank 2,bank 3. Z/ y. `2 u$ C7 m# K4 b. P
在Mapper 4中对应的是+ Q: q" B* _0 g
Bank 0,bank 0,bank 2, bank26 ]4 S' `. T/ c
然后查找原来的ROM的切VRAM的程序:% P0 [" C2 E' ~; V( I. ^
知道是从07F0-07F3切到精灵VRAM的:9 F0 J8 s0 ]# {* B$ `4 J: ^
如图所示:" |; z4 e. F9 J% z
" b. c* ]: m; ^ N- w( `# s# e
 
T& d: }/ n8 A! I作为对比,左边是原版,右边是修改。% N3 ]( `6 S+ A' d- C
接下来是完善VRAM切换带来的问题,因为Mapper 4只能切2KB的bank,所以我们不能通过切bank程序解决问题。
9 v8 z2 x6 y/ ?: Z: [* b) ^通过测试知道1,3,5,6,7,8关的精灵VRAM排序如下(07F0-07F3):9 Z, S$ O, l: N$ B" l: q6 M! y
01 04 06 07* }/ E) S/ W0 [% H, \, x& x9 M
第2,4关如下:9 ~5 p$ c9 l" y7 G, ^" I* i; q
01 05 08 090 @- t" j$ K; T
任务失败时如下:
8 z/ W+ X6 T$ W) }, X32 00 00 1B
/ @+ g$ y; C; l$ d" D" E: ]% ]其中任务失败时对应的VRAM是07F3的1B,只要让07F2为1A或1B即可:
5 x1 R1 _9 U: @9 t: c通过调试找到对07F2写入数据#$00时程序如下,于是修改C7E5的值为1A即可:
8 Z* Q' B; q$ D+ U' J/ Y
: ?- G4 i9 h9 p/ C i转到ROM地址:
+ t* X: `! q3 T, H/ \
# H+ R1 P3 h1 e- ^5 M: ?; k# P+ X. t6 ^修改数据:
- }3 J9 I* [5 @' v0 h: _% t
9 x5 l9 t& h# `( M重新失败后可以看到修复成功:
" V( |8 L# k+ X z# s 2 B; B: X. r5 d% t- t) n3 L/ T" b
接下来是修复正常进行任务时的精灵错乱问题。& Z% x5 Z' @) Z8 Q
首先运行Mapper 23版本,在1,3,5,6,7,8关任意一关的时候,将PPU导出来6 q1 V9 y9 G2 v5 |

& c+ r6 l; u, i4 W! b! a6 m
], w1 f7 T. i4 y 2 F3 R5 S: M( h ^% h
) K& m% ^, }( p1 g; C \
然后用Hxd打开修改的Mapper 4的ROM和刚刚保存的PPU的数据文件:, d* R) G- k% G& @7 K, s
0 W/ y {9 N- f& T: `+ B
在ROM文件头第05字节改为0x20:
/ n" k& g/ P* g& L0 N k % z9 i0 N7 T- `- a) L1 l- W
然后转到文件末尾,插入0x20000字节空字节:. @* c* q! j$ G" k# }9 B
3 C3 c8 J% w( s& o! O
+ s' a! y7 ?6 o

& j' Q2 f6 P% q" L- {
- I( q% V& S" `然后将第1关的PPU数据的前面2KB数据选定:; Q0 U. P% F$ |( ^' i
, x& N8 {8 m9 g; X' T' o

" |8 C% ?* N6 @; Z D* K1 c% e |' R& U- E$ a, A" l0 I
复制之后以覆盖方式粘贴到ROM的40010,同样把第2关的PPU数据的前面2KB以覆盖方式粘贴到ROM的40810- t3 F" P8 `4 F0 m
- @1 x3 t+ u2 x: R
然后保存文件:+ D3 L- a3 j6 _; \ X

2 ]/ @) C% Y" b3 j3 M最后用FCEUX打开文件,添加07F0-07F3的写入断点
) ^; Z& ^% Z1 `9 ?/ `' K1 z3 o* ^
3 f5 M+ m& R! h* ]" {2 Z5 Z地图预览后即将进入第一关画面时程序暂停了,可以知道此时准备将C793的数据写到07F0:( V/ Y6 K1 W3 H( F7 n" \ I
( I x7 G9 C' ? W
测试后知道将C793-0796写入到了07F0-07F3:* b" r2 {" L/ [$ Y$ X+ h
同理,经测试每4个字节一组,一共17组,其中01 04对应普通关卡精灵以及其BOSS关的精灵VRAM的bank号,01 05对应2,4关卡精灵以及其BOSS关的精灵VRAM的bank号,再加上一个通关后跳上飞机那段动画的精灵VRAM的bank号。
! Y0 `$ p7 z; \5 |) [' O5 m; j
% V( t0 K4 `" Z1 W
7 Y7 y3 f/ C+ s然后将文件中标记的01 04修改为 80 04,将01 05 修改为82 04即可:. ]4 p) U2 m0 z7 k3 h7 z& J1 `

+ l9 F9 e' b" @' }* X保存之后重新运行后效果如下:) Q* c" A, | |2 H, `" j

% f" u8 j- _0 e. h
% y S6 d1 ~, w- f2 o7 h 3 b* f; Y" c) _* y
当前使用的是FCEUX模拟器,如果用NEStopia玩的话一开始就死机了,这是因为这个ROM有文件保护吧,它会往$6000里写入数据:
2 s7 v; s r$ n1 n( a" m9 b$ O# J 0 `2 L0 m+ _0 p) m6 x% S
F863:A0 03 LDY #$03
. _8 N1 p( d& P, M! o- I5 CF865:98 TYA
2 N" }- f/ M# Z5 q6 PF866:29 01 AND #$01
; @- A1 g, \8 J, @ Y; GF868:8D E9 07 STA $07E9
5 q. }' }' D/ c( n; G. bF86B:8D 00 60 STA $6000( O5 @: \/ F b0 Y
F86E:AD 00 60 LDA $6000# q2 z9 Y0 O( n9 w9 s5 i0 \
F871:29 01 AND #$01& e( H! z" u# u) A- c' O
F873:CD E9 07 CMP $07E9
7 P3 M' s, w1 d8 `# TF876:D0 05 BNE $F87D7 @# |& H% g; @ K& v+ M
F878:88 DEY
. b" l* U% {* J9 ~) O! E% |5 @7 YF879:10 EA BPL $F8654 x, D( y, C& d# o. }
F87B:30 03 BMI $F8801 J# L9 G6 f3 z
F87D:4C 00 00 JMP $0000( e: O& ] a& |% h( v" P# g
F880:A5 1A LDA $001A0 U1 K, m0 ~% n! w( b$ D
F882:65 34 ADC $0034
- X9 w2 h& ]4 ZF884:85 34 STA $00345 ^# ^ v% P' \7 b2 y+ r
F886:4C 80 F8 JMP $F880* K1 r8 M4 T8 S; f2 G
先取Y值=#$03
* N4 I" ~! g, D4 J$ \: |与#$01相与后得到#$019 m. ^/ v, l& Z. N" O
写入到$07E9
' e" C$ D, U+ ^2 X$ V写入到$6000
" R: f( w) n; Q- `3 m1 M! b再读取$6000的数据和#$01相与后和$07E9的数据比较
+ k1 o4 n) x1 Q7 f不同的话跳过5字节
: z% K0 q% \( T# f否则Y递减- k2 k" L" e7 t: [7 S5 W* O
为正数就跳回0x100-0xEA=16字节, K$ P& L' X/ D! Y& c U8 _# L
为负数就跳过0x3字节
$ K- K) \7 w4 Z* F+ g) L0 N跳转到$0000(简直没有人性了,跳到这里死机,真想得出来)5 r1 [7 F8 e/ c0 q3 ~
7 q: B3 l5 m: x% S6 _! K
正是因为这样,NEStopia运行FC时,6000-7FFF默认是不可写的,必须在ROM文件头第6字节的D1位置1设置ROM有SRAM,对于Mapper 4,还需要向$A001写入#$80来启用SRAM。$ C- j6 H$ h! N6 w6 Q
由于$6000不可写,因此想$6000写入#$01后$6000还是#$00,之后读取$07E9的#$01与之相比当然不同了,于是直接跳转到死机程序了。 |) c0 i" f$ W) Q6 }! A" b! g5 I' f8 r
解决方法是把ROM中的所有的AD 00 60 29 01 CD E9 07 D0 05 88 10 EA 30 03 4C 00 00
/ |# _/ e* _' X0 |6 \& [中的D0 05改为D0 00,然后保存即可。
9 k" A# z9 f* {0 ~测试完美运行。
# [/ s) }) _9 C+ K* j% Z8 c : F; T3 z6 F/ A) s/ d
3 S: i* L$ d) h- X) c
教程到此结束。* w+ A; H( q; o6 v+ d6 w* w4 O
" z5 o6 B- Q: K. N |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|