|
本帖最后由 yandagui 于 2017-4-16 19:06 编辑
: c" ?. a8 o' |, [9 @# B" q/ f* x0 V# e5 v9 f% m% x# u9 a% V/ K& Z
Mapper23转Mapper4实例教程
8 a% a/ c! Z9 ~ W, i3 b8 h1 t9 A- ?+ x/ K6 N5 k# P: t; j
FlameCyclone 2017.4.14
. g) R- U6 `9 I+ b. W( o* A; u5 D
先看看Mapper23文档:& I; w' \' A1 x% n9 U% o8 n
- B9 Q r* t/ [$ sMapper 23
+ r/ o, a4 I/ F& ~0 j! W5 i! |$ ]$ j( g" v3 ?# f$ f0 m0 A' c# \6 {) \
$8000: 选择8KB的ROM存储体映射到$80006 {6 `8 Y2 L5 B1 g7 C- |
8 H* y, A! x, _/ i+ G( X
$9000: 0:垂直镜像/ [! E3 }" E% s, y9 p2 y
1:水平镜像) X- E; j1 v3 Q5 L
2:$2400镜像; j) n( D' |7 _$ l3 }9 B, |2 d
3:$2000镜像
8 K e7 e9 i( v, p4 n. Q( \ d! |8 D# X8 M" x0 e2 ^* Z
$A000: 选择8KB的ROM存储体映射到$A000
, s9 B' `7 v2 u, H. B2 |' A; o0 t4 L& I' {4 R% g* \& \
$B000: 选择1KB的VROM存储体映射到PPU的$0000(低4位)+ y5 g# R* v1 L. A0 T
$B001: 选择1KB的VROM存储体映射到PPU的$0000(高4位)
/ f7 o2 ]2 \, W$B002: 选择1KB的VROM存储体映射到PPU的$0400(低4位)
6 ~0 {' q- E/ ^3 @6 G$B003: 选择1KB的VROM存储体映射到PPU的$0400(高4位)$ d0 K* K* @3 X, a
2 a5 I/ v* E4 e7 q1 Z, g$C000: 选择1KB的VROM存储体映射到PPU的$0800(低4位)+ Y0 @. z4 |/ {" [* S: k3 Y( D# L& M, {
$C001: 选择1KB的VROM存储体映射到PPU的$0800(高4位)
) G3 Y8 f/ V# J# g8 l1 A! _5 ?$C002: 选择1KB的VROM存储体映射到PPU的$0C00(低4位)2 h5 U, E3 ?% Z0 x1 z
$C003: 选择1KB的VROM存储体映射到PPU的$0C00(高4位)6 n5 E+ U1 a x/ f/ c
1 r; t: T. W$ q, f# p+ d
$D000: 选择1KB的VROM存储体映射到PPU的$1000(低4位)0 p# k, i1 o+ N& U
$D001: 选择1KB的VROM存储体映射到PPU的$1000(高4位)& j( x G! N4 m" \5 z4 z! |' C
$D002: 选择1KB的VROM存储体映射到PPU的$1400(低4位)
2 t% w1 |( a; d( `$D003: 选择1KB的VROM存储体映射到PPU的$1400(高4位)
4 I2 L$ ~5 r4 d, U/ \
( ~0 J% Y a$ X/ I! ]0 E$E000: 选择1KB的VROM存储体映射到PPU的$1800(低4位)
9 K* v5 @6 ^: M8 @2 D0 U. q$E001: 选择1KB的VROM存储体映射到PPU的$1800(高4位)) v+ {% x( X4 `1 D
$E002: 选择1KB的VROM存储体映射到PPU的$1C00(低4位)1 D* p: ]' ~! m9 \6 Y- a
$E003: 选择1KB的VROM存储体映射到PPU的$1C00(高4位)0 Y% }! {+ h D- U" j, | ?
h U0 t7 T6 J再看看Mapper 4文档:
* m+ w# R8 U$ U+ J- j
8 W' e1 t) h1 J" hMapper 4
0 ~$ J" s/ _" n. ~; [
6 d# q q1 `( t$8000: 模式号3 w; B' v+ L0 x
位D0-D2:
& s/ _) s+ Q* l7 _ 0:选择2KB的VROM存储体映射到PPU的$0000
& M+ I* j6 R* ?# A) G 1:选择2KB的VROM存储体映射到PPU的$0800
' X# k3 m/ L( d2 l 2:选择1KB的VROM存储体映射到PPU的$10008 R7 W O2 K& e5 u
3:选择1KB的VROM存储体映射到PPU的$1400% {/ W) N: o( I7 G4 E
4:选择1KB的VROM存储体映射到PPU的$1800) C+ O1 m' w: C$ v) m |% e
5:选择1KB的VROM存储体映射到PPU的$1C00+ `9 j+ u8 V. H; o( s0 N& f
6:选择8KB的ROM存储体映射到$8000
, Y4 m1 {$ |; E. j( B7 c 7:选择8KB的ROM存储体映射到$A0000 X* M4 N, F1 t
位D6:
% b/ u4 a$ l) {" Y7 @9 W) u 0:允许擦写$8000和$A0004 E) m* Y/ H- D" i2 X
1:允许擦写$A000和$C0006 s O2 K4 I; V4 F
位D7:
" S5 x& d0 ?8 Y1 X 0:模式号D0-D2使用普通地址) n$ M$ o+ u8 _9 r0 N. o1 J/ D
1:模式号D0-D2地址异或$10001 P. V2 C, q4 W( t
, o4 {8 j2 l( }; H6 n1 Z$8001: 模式页面号+ Y1 `6 y- D6 _! B5 B0 _
写入一个数(00-07),切换存储体到对应地址- m- K0 l2 M) P6 p4 N9 M
6 x# B; p- O* u4 V: q1 c6 o }& l$A000: 镜像选择
1 K+ V9 G+ l1 n, Q' _) e 0:垂直镜像
" L$ {( g( R# B X- P 1:水平镜像
$ {) t# U; V' C; s/ _9 B. z* k; J, R6 }
$A001: SaveRAM 切换
- Z- l9 ?6 n/ N* i. l5 c/ I 0:禁用$6000-$7FFF* ~# O! A7 V$ P, k7 ]; }
1:启用$6000-$7FFF
/ g9 \/ B( M5 x" V
7 s" Z. T: |2 \+ u3 [% C, [$C000: IRQ计数器! b8 m; h: `2 V( k) N0 R
IRQ计数器的值存储在此处+ C0 i8 ]1 S" l+ C8 X3 W
6 ]4 q6 j8 n8 p0 E$C001: IRQ暂存器/ o( t# K- c2 U. z- z6 M& m! T& H
IRQ暂存器的值存储在此处6 M) j6 [* }5 N& J: q5 B! m, o
9 P0 X" J; V, x9 g# L
$E000: IRQ控制计数器0
4 u. w5 P. Z' x3 l2 ~" q d 向这里写入任何数来关闭IRQ,并从暂存器中拷贝数据开始计数,进入IRQ- u+ Z4 X) d0 ]& r4 U! ?
+ _9 T( Z/ G O, _8 K9 o! q
$E001: IRQ控制计数器1
0 \3 O+ x! U7 Q3 \& G4 U 向这里写入任何数,允许IRQ(退出IRQ,允许下一个IRQ进来)
9 G7 i }7 q$ e9 M8 E# w( h7 r8 x+ g& p
! K8 f# d/ Y; c& |5 i
' k* s \% B. Z" G转换思路:. s! K9 G c$ x' i, m* J2 V
将Mapper 23 的切bank 方式和切VRAM的方式修改成Mapper 4 的方式。2 C9 q6 t% I5 Z8 ^
2 q/ C6 i: O1 t7 j! [! @
修改实例:: X0 u# @5 l& F2 n1 R2 B, ]. g
Contra (J) 256KB Mapper 23
9 f+ _9 J+ P# h9 C7 a* o' d工具:7 u3 y& `2 Z7 M2 \0 e
1.FCEUX 2。2。3
8 @1 C0 q S# K3 {7 h2.HXD3 J1 g1 o- Z: V. m
先来看看这ROM的切bank方式:
6 O( N6 e: y& q3 W3 O+ m4 FF989:AD 00 80 LDA $8000 & W2 T. q( U: G. H3 f0 `% N+ r! u' |
F98C:8D EC 07 STA $07EC8 K* p3 y( }$ d) h, T1 ?
F98F:8C 00 80 STY $8000
" C7 i8 I: P; _: c* vF992:C8 INY
' K& R* M% C5 e' h. ^1 ?, E. DF993:8C 00 A0 STY $A000$ m8 r4 c. k1 N5 l B8 _
F996:60 RTS
1 ^# z$ P9 E' O3 z9 S4 M7 w* L1 ], d$ N$ g+ r2 K; L3 ?( ?
再看看它的切VRAM方式:0 t: S; q+ u& @0 H5 [ Y: s
FACE:AD F0 07 LDA $07F0
) S, v% n& L# J2 D' ?! T+ e- e! VFAD1:8D 00 B0 STA $B0000 g N: f+ H- E: x$ [1 c
FAD4:4A LSR
, Q4 [( w# e/ W1 n' iFAD5:4A LSR% R3 s" T; V7 ~* @
FAD6:4A LSR9 x2 X7 k2 e [! N6 h5 `
FAD7:4A LSR
+ P+ d& z! U' Q9 p+ lFAD8:8D 01 B0 STA $B0011 _$ `/ d/ a; b/ U6 L' C
FADB:AD F1 07 LDA $07F1
( y; d* [4 z, p2 G; aFADE:8D 02 B0 STA $B0024 S& P1 [6 w: G2 j
FAE1:4A LSR
2 F( k/ E1 i- _5 `& ?FAE2:4A LSR) G* a3 e! r h9 ]3 [, |
FAE3:4A LSR: b4 O. m! {7 l! y, W8 q, d
FAE4:4A LSR
2 r- Z @3 z' P/ Q @- i: o# _6 {+ CFAE5:8D 03 B0 STA $B003
( S3 X' k9 ^# n" NFAE8:AD F2 07 LDA $07F28 E- L3 W9 v; U
FAEB:8D 00 C0 STA $C000% _# [ m* S1 U7 N' c
FAEE:4A LSR
$ w. y2 Z; u) c4 C ~FAEF:4A LSR
. y0 M. m8 j/ o8 ?FAF0:4A LSR
2 V0 q( W& e. {6 |8 }. Z! OFAF1:4A LSR; K( S! R- Y; E# {7 a* y+ J' l
FAF2:8D 01 C0 STA $C0017 P b0 e3 k& i9 E; b1 R; b
FAF5:AD F3 07 LDA $07F3; I# \6 H# Y# X6 X7 ~' o( Z
FAF8:8D 02 C0 STA $C002
6 i( E5 H% Q, X4 b0 \- IFAFB:4A LSR# A' S: c4 j% a# [* R3 U
FAFC:4A LSR
5 H$ a/ r7 o+ b/ y; k9 e" [+ [: JFAFD:4A LSR; `6 u% e9 a& k
FAFE:4A LSR
3 C \" d1 i4 o* lFAFF:8D 03 C0 STA $C003
, T7 E. R; F, Z! eFB02:AD F4 07 LDA $07F4
! ~" Y/ d ^3 \9 eFB05:8D 00 D0 STA $D0005 c/ M) t# l% U- Q
FB08:4A LSR
3 {$ \7 ^5 ~/ }( H! q c5 U ~FB09:4A LSR
0 y! s/ D- b% Y/ {FB0A:4A LSR, s% U( f, E) ]. }+ r t- U! b, @4 Z
FB0B:4A LSR- v0 g; V+ ~! k& D9 l4 p7 w% f
FB0C:8D 01 D0 STA $D001
5 y" y, P9 _: w) S" D7 q* |3 i" XFB0F:AD F5 07 LDA $07F5
8 x6 Q! I0 v* w7 PFB12:8D 02 D0 STA $D002; c( H+ V; z1 k9 Z+ N4 Q1 p
FB15:4A LSR2 E0 Z4 p6 A4 y- a$ ]' L9 }+ K
FB16:4A LSR
n# _+ E8 ^* m j/ B1 P( fFB17:4A LSR8 G4 \1 _* _6 p& r! {* o) d4 k7 }
FB18:4A LSR
8 ? l9 W( V {( P8 K* kFB19:8D 03 D0 STA $D003
% m& }! p7 r8 o M" a0 aFB1C:AD F6 07 LDA $07F6
% X; D' r/ b K3 @FB1F:8D 00 E0 STA $E000
7 U( M" @0 a& a# e+ |FB22:4A LSR7 b9 B9 M3 u3 U9 b9 \2 b" f
FB23:4A LSR, i) w) F% l% m1 f& S9 p$ i
FB24:4A LSR
1 ?5 Z% W4 K. p; s- b' eFB25:4A LSR7 X( p; E8 h9 _; w' ~
FB26:8D 01 E0 STA $E001( ]5 L5 _) l0 e4 y
FB29:AD F7 07 LDA $07F75 a- p1 w9 m" f7 B; {/ ]
FB2C:8D 02 E0 STA $E002
' K+ d# @- Q' A* L) b3 x4 RFB2F:4A LSR
$ ~1 V) s; f% X* {; vFB30:4A LSR
r8 M+ L" s7 i. V3 JFB31:4A LSR
* s5 p6 b7 s' I: N7 o& Q3 Z& {" b- JFB32:4A LSR
& O0 |4 l: v) W6 A; YFB33:8D 03 E0 STA $E003& d5 u2 G6 |9 l+ I/ \3 _) T& d
FB36:A9 00 LDA #$00
/ {9 W* M# y2 h( @FB38:8D 00 90 STA $9000
+ Y& M1 S$ ?! K! J! w" A' kFB3B:60 RTS3 @6 r9 u+ q3 Q+ y+ y
; K1 p! G2 u. p
接下来修改切bank方式:6 w* p3 W/ p1 j ]4 r* w
FB2B:48 PHA
, W1 q2 ?' X, Y+ A6 L2 iFB2C:A9 06 LDA #$06
+ c) M& H3 Y* PFB2E:8D 00 80 STA $8000
2 i. y$ `1 T" z) u6 oFB31:68 PLA& A9 Z! j8 w# u) s: Y
FB32:8C 01 80 STY $8001
. p3 D1 y" M7 H2 ~5 HFB35:60 RTS
* I! ] D/ X2 ]2 X+ |1 q9 C$ O* A5 z; O4 Z/ P
FB36:48 PHA
/ @! J* u9 K7 C$ O8 _FB37:A9 07 LDA #$07
4 V( @& F& e( ^4 qFB39:8D 00 80 STA $8000 = #$14
6 |8 H" }8 d P+ F8 }FB3C:68 PLA
5 z- S2 O. x8 A0 v! ]FB3D:8C 01 80 STY $8001 = #$1D
7 X/ R, r+ C# K/ H* M& @ H+ v4 uFB40:60 RTS
0 E8 A1 e% G/ T6 [* A p+ Y
: S% }8 b1 d; P/ u还要把原ROM的对$8000和$A000进行写入操作的程序修改一下:* {2 I3 ?; p, b
F989:AD 00 80 LDA $8000
7 U# `0 f) W) E; z5 T; c. v3 IF98C:8D EC 07 STA $07EC
# I$ B. {- x6 {! ]F98F:20 2B FB JSR $FB2B
- h5 V1 ~* E5 O c: C: y' JF992:C8 INY
8 {6 T" {' j# b5 k( a5 NF993:20 36 FB JSR FB36
2 V$ } P* b3 lF996:60 RTS8 j) w7 q+ N4 r& Q/ Z( _0 R
* R- \1 a, U5 l, E G1 }9 @
再修改切VRAM程序:/ r3 f; g1 L3 Y7 X
FACE:A9 00 LDA #$00& Y' m! k' W* h6 b: t
FAD0:8D 00 80 STA $80003 y* w9 k9 h/ h- D8 F' z/ C
FAD3:AD F0 07 LDA $07F01 d* ]3 r9 W1 q3 w/ t5 \2 O
FAD6:C9 01 CMP #$01 ^1 W5 F& k5 ^/ E
FAD8:D0 11 BNE $FAEB. j/ K. i. Z' w# ^9 d: w0 z
FADA:AD F1 07 LDA $07F1& J. J- ?6 ]7 n. R9 E9 k& \: o) f
FADD:C9 04 CMP #$04
/ y1 M* F5 X; O" t& V( s3 G# FFADF:D0 04 BNE $FAE5
3 E% q- c/ F' d; i$ S& gFAE1:A9 80 LDA #$80
) W3 K3 l4 }" s( H: qFAE3:D0 06 BNE $FAEB
) g8 j# d7 `8 v7 \FAE5:C9 05 CMP #$05
# I. K4 T! z2 K! F6 K& {FAE7:D0 02 BNE $FAEB- r0 e% W$ y. h1 K7 b" O" O$ Q
FAE9:A9 82 LDA #$82
% w0 }5 F" t' c7 y# g0 T+ kFAEB:8D 01 80 STA $8001* M$ t5 W: z, q: U2 x {- H
FAEE:A9 01 LDA #$01
/ y5 u- Q: R" E UFAF0:8D 00 80 STA $8000
* e' K2 ?& ~. l- ^3 } l* {FAF3:AD F2 07 LDA $07F2* I4 y; M% [1 M; n2 c2 W3 z3 M
FAF6:8D 01 80 STA $80015 z+ S5 O2 Y6 T
FAF9:A9 02 LDA #$026 a; Q7 R+ t4 x3 x$ X5 G& E
FAFB:8D 00 80 STA $80004 F' u4 ^. g7 A. e
FAFE:AD F4 07 LDA $07F4, u7 B1 b/ n C' N" `( E# M
FB01:8D 01 80 STA $8001
! i6 M* C* V+ p/ e! tFB04:A9 03 LDA #$03
: D* a0 r* u% D: \' R$ HFB06:8D 00 80 STA $8000
/ z! I! r3 \( ^& [FB09:AD F5 07 LDA $07F53 U* z6 l! |8 U7 d- D
FB0C:8D 01 80 STA $8001( H$ ]2 |. h/ q
FB0F:A9 04 LDA #$040 u, q$ A# S* Q3 v" Q% i
FB11:8D 00 80 STA $8000
2 z" N$ {. K# J8 IFB14:AD F6 07 LDA $07F6
+ ~5 q9 `% ~/ R& BFB17:8D 01 80 STA $8001' N" X2 K: _, ~1 x
FB1A:A9 05 LDA #$052 N0 C# M; K& e! z/ A" U4 a6 X
FB1C:8D 00 80 STA $80008 m Q: }) G% I* i( [2 ~
FB1F:AD F7 07 LDA $07F7) ]" M% V P) u" i2 X; n. c
FB22:8D 01 80 STA $8001
) p" T: J9 j" A- g+ v ^FB25:A9 00 LDA #$00
3 |* e) r O7 ~- \8 n0 s" v' wFB27:8D 00 A0 STA $A000
& |, L8 h+ v; R4 _8 H+ mFB2A:60 RTS0 h2 \% b- T2 Y* B6 C- H- M
( r& y+ n- c u# I然后保存文件。) f; Y1 B3 v" w& R" J' T- X
使用HXD修改文件头:
: |7 d* m; l# ]4 s将Mapper 23
# A! }5 B: M+ S5 r06字节的高4位是Mapper号的低4位
! L! t* f* v3 U$ t2 C07字节的高4位是Mapper号的高4位
+ t. v6 B$ y! k" C1 v9 M组合起来就是0x17=1*16+7=23* j- `0 H2 Y; Y/ L7 E- ?3 v
' {9 P2 w' o: A修改成 Mapper 4
0 s; U# Q& ?5 H" H
1 H' A1 j% {0 @# D4 \% o0 E# Y. o8 [4 `
6 x# D- q$ a: s; C* S2 T# w
再次打开文件:
3 ?* c' y1 Z N5 L+ e' g: S( @' ^* Y
8 ^1 C6 f$ V* M9 ], q+ @0 O1 S" U* d可以正常运行
8 L6 z! `$ e" m' H, U7 E8 z% J$ H通过全面测试,发现出现精灵错乱:
, ]( L& y% E! e3 f第1关:% `2 g) _4 ?% ~! E6 i5 k
; L8 [6 p, x0 C# g5 V" u ?
" J* G3 I6 t& U$ C第2关:
1 u0 a" \" I6 e, e9 k1 `$ x6 \( ~2 E' n. y* x9 e8 x/ `1 F
任务失败后:
6 C& j3 A& A/ s3 \" E$ _1 P
1 p `) y$ L& }$ U' c通关后上飞机画面:9 |- U& e) X7 E: P$ p2 ^
; _% i( E& e# G' l$ }; z1 k5 }
这是为何呢?
1 K3 d) m" T$ ]$ b这是因为Mapper 23 中精灵VRAM切bank是一次切1KB* z* ]; @% |* a; [) g/ b5 Q% }
但是在Mapper 4中精灵VRAM切换却是一次切2KB,而且忽略bank号的D0位
7 {9 k i# x1 t% g比方bank 0和bank 1是同一个bank,同理bank 2和bank 3是同一个bank! p/ _1 J/ @* \ p4 @; v
也就是说- v; z0 ~* c+ e& H( {% Z
Mapper 23中的VRAM的2 f. J, h6 V, V6 N1 E
bank 0,bank 1,bank 2,bank 3: d- _; `: S5 n- n b5 x
在Mapper 4中对应的是6 W; W& l8 [. W
Bank 0,bank 0,bank 2, bank2
6 j% R' c1 ~" T5 d2 q- Q) W然后查找原来的ROM的切VRAM的程序:. F8 T4 {% `5 ~+ r: F
知道是从07F0-07F3切到精灵VRAM的:
! T4 i9 ]/ H& g如图所示:
0 n' m. T( O; |" @) J
1 W7 ^# u' O9 s6 ?
8 m/ C* Z* ~ I o0 P# |+ n) S作为对比,左边是原版,右边是修改。, O7 [# R) \! h0 h! b3 T
接下来是完善VRAM切换带来的问题,因为Mapper 4只能切2KB的bank,所以我们不能通过切bank程序解决问题。# m" N) P1 C( I6 K
通过测试知道1,3,5,6,7,8关的精灵VRAM排序如下(07F0-07F3):" f! e* g0 r7 f% `; @* C
01 04 06 07
% W: t' x4 S+ G第2,4关如下:1 C/ ~3 `7 m/ y5 W1 c6 }0 |
01 05 08 09
( r& u8 k, w$ T5 e; K任务失败时如下:$ @$ ]% ? _3 W/ H
32 00 00 1B
0 u2 O* p- v8 M5 N其中任务失败时对应的VRAM是07F3的1B,只要让07F2为1A或1B即可:
. k2 P9 `1 ^9 f+ s' T( _通过调试找到对07F2写入数据#$00时程序如下,于是修改C7E5的值为1A即可:' @# _# V5 j! [; K) E
: A. k2 {6 i' i# S7 ^8 {7 {转到ROM地址:
# N5 r+ D+ y! |$ D1 \5 N s
7 M2 o* X8 {/ |修改数据:' E8 V+ o V9 M. b9 `0 j
% Z% s. k$ g) C: a1 ~7 x; u% U重新失败后可以看到修复成功:
* a* f0 b1 P( A4 W, v! q# h# e3 l2 s: A
接下来是修复正常进行任务时的精灵错乱问题。
5 z3 o) t' z1 o, ?4 K首先运行Mapper 23版本,在1,3,5,6,7,8关任意一关的时候,将PPU导出来! t3 g) A' B+ J2 Z% s' F8 s8 i5 z
+ N3 D% K- K, N2 @; o: p, f5 P. l
6 B5 J1 D) U; Z5 W; v2 c8 c! A" D+ X0 T* h. @) E" s9 E1 }
5 [: ?. x1 `; {
然后用Hxd打开修改的Mapper 4的ROM和刚刚保存的PPU的数据文件:
! p, v% P! X+ x) k
" M. H7 \+ a+ t! h+ m' l/ Q在ROM文件头第05字节改为0x20:
4 |7 b* B: l+ D! B7 U) Z6 J! S8 }. p+ y& Y3 X1 g/ ~. C* ]
然后转到文件末尾,插入0x20000字节空字节:
a3 _5 V' _2 }- \) c) G" v+ @$ O! |+ ]0 ]9 M& _
, q. f. {* ~& o$ ]1 W& T4 [
, n7 l+ K9 _. e" D
0 X, F" h! J( l: H/ B) w然后将第1关的PPU数据的前面2KB数据选定:" F' z. B( Z7 O$ `% l, E
- M. q* L" S+ L: m# r+ u
$ ]6 o9 c% J7 i" f, w( u: b
0 Q0 j% w' F8 V复制之后以覆盖方式粘贴到ROM的40010,同样把第2关的PPU数据的前面2KB以覆盖方式粘贴到ROM的408105 V: d } m; m' M e/ _# l
0 m6 s9 k- _! |$ v
然后保存文件:8 p4 y b5 t; _8 `+ y
5 w0 n# o! l) A& d1 U0 h最后用FCEUX打开文件,添加07F0-07F3的写入断点
- O$ A3 h2 i( i& H# b) a& @2 a% G! k" u" C# G" {$ C" S/ c. u
地图预览后即将进入第一关画面时程序暂停了,可以知道此时准备将C793的数据写到07F0:
, w5 o" R, D j- B
+ [$ @8 R5 A. q' ^5 |4 b1 Z2 ^# |测试后知道将C793-0796写入到了07F0-07F3:
3 ?! c# E) D' l" ?% \* ~9 W# H4 J9 Q同理,经测试每4个字节一组,一共17组,其中01 04对应普通关卡精灵以及其BOSS关的精灵VRAM的bank号,01 05对应2,4关卡精灵以及其BOSS关的精灵VRAM的bank号,再加上一个通关后跳上飞机那段动画的精灵VRAM的bank号。
4 A! O- O$ c) h% L e# V9 J
- `1 y& D6 ^# O4 j0 }
2 q( k& o+ k5 J- p然后将文件中标记的01 04修改为 80 04,将01 05 修改为82 04即可:4 V! X( ]. r# \' @* L4 W
& P, h* X; `: h) L7 {& p. f
保存之后重新运行后效果如下:- _* X* F9 u3 r+ z8 g- `5 J
; A$ q( t2 X" i/ x# q) V8 S
. } g* K2 O- T+ t) q
; v0 E, _ L( [3 `' e当前使用的是FCEUX模拟器,如果用NEStopia玩的话一开始就死机了,这是因为这个ROM有文件保护吧,它会往$6000里写入数据:
( T4 p' R, I( I+ P7 H% _4 c8 U3 b3 L6 q* j/ K4 u4 I- k9 s! [8 C
F863:A0 03 LDY #$03
! ]6 X8 u* T$ X, uF865:98 TYA) P* z/ H# {; H* I
F866:29 01 AND #$01$ g: p" i' [* h2 z6 _' ]1 o7 e6 d
F868:8D E9 07 STA $07E9) f2 O% n- m V ~9 e" E2 ^
F86B:8D 00 60 STA $60002 a( Z1 v7 h/ P4 Y& s
F86E:AD 00 60 LDA $6000
4 q9 X0 ~2 A7 a2 ~F871:29 01 AND #$01' ?! F; o. O9 A
F873:CD E9 07 CMP $07E9
+ C1 L F- b5 k3 O/ lF876:D0 05 BNE $F87D2 z2 u* G5 e- h8 v3 t/ P9 c( i
F878:88 DEY
. R' t% |5 ?/ {F879:10 EA BPL $F865
" `6 R& I- t B$ z2 R% ZF87B:30 03 BMI $F880, A, Y' O c7 w5 w& n' I/ V: S
F87D:4C 00 00 JMP $0000
- D* g" R# H9 Z: c% h* N( yF880:A5 1A LDA $001A
5 [! } I& [5 l6 A- h; nF882:65 34 ADC $0034
, |5 _3 l( j0 t6 G0 ^F884:85 34 STA $0034
. p* i9 l* V4 {+ p, O+ _6 DF886:4C 80 F8 JMP $F880* Z5 ?% W+ w9 n
先取Y值=#$03
0 q- k. n3 j. N! z与#$01相与后得到#$01
; n D3 E- n' W写入到$07E9
4 I3 O+ ^. ?" Z* i9 i( M3 ?' B7 q写入到$6000. a3 z: y. V& R5 t& R2 K0 t
再读取$6000的数据和#$01相与后和$07E9的数据比较
3 c3 G4 E& h; }! j' [0 ^( h7 S不同的话跳过5字节
" g8 v! z; N: v3 \否则Y递减
; S5 L+ _& g* y9 y( H( g为正数就跳回0x100-0xEA=16字节) c- R, ?' o) H; I) L/ J n+ ?
为负数就跳过0x3字节, e) ^% g' H* A; e L( M; @! N
跳转到$0000(简直没有人性了,跳到这里死机,真想得出来)" `0 x6 v+ I# T$ h7 n+ V# M
3 T( Y7 h" w* b3 M% K4 c
正是因为这样,NEStopia运行FC时,6000-7FFF默认是不可写的,必须在ROM文件头第6字节的D1位置1设置ROM有SRAM,对于Mapper 4,还需要向$A001写入#$80来启用SRAM。0 e5 C8 o$ ]7 C' c) D5 h7 [: B- B
由于$6000不可写,因此想$6000写入#$01后$6000还是#$00,之后读取$07E9的#$01与之相比当然不同了,于是直接跳转到死机程序了。
& h! h8 }3 D$ ^5 l0 ?解决方法是把ROM中的所有的AD 00 60 29 01 CD E9 07 D0 05 88 10 EA 30 03 4C 00 002 G+ w5 U/ V: J+ a2 _7 {3 n% U
中的D0 05改为D0 00,然后保存即可。( x7 r: C8 x3 z
测试完美运行。9 l! z1 v# z' @' W+ N
& c' d7 m* [: s4 S, S3 @9 [/ u
0 \, r3 T, K2 u7 h
教程到此结束。
* z$ o0 M" q% q, c
# T, F8 ~$ w; Z |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|