|
|
本帖最后由 yandagui 于 2017-4-16 19:06 编辑
$ P* R3 y& \; D; w) _7 G9 n3 E
' D' h- F$ d3 K- d6 J9 I5 HMapper23转Mapper4实例教程
- m1 S- Y; k9 n* R
0 c9 i$ E. e( Z' \- w5 LFlameCyclone 2017.4.14
3 \/ W1 u7 r& x, B
- h! ?) i& p) B) S! }先看看Mapper23文档:$ f) \, _3 ~1 g0 }8 w
5 ]/ L" I* T- m- k# s( _
Mapper 23; i1 X, r* i- c1 d2 o# ~3 F% d1 X
6 s$ t4 v* u& P$8000: 选择8KB的ROM存储体映射到$8000: t2 K; z: e- I
- s+ n: x+ N+ ]1 X" {/ ]
$9000: 0:垂直镜像
3 A/ ~/ T: O4 e 1:水平镜像* F' p7 V. U2 n8 |+ y8 o
2:$2400镜像
1 @; v* E/ d; J 3:$2000镜像
) y4 s0 F9 ]" O7 J: I. z: |! q8 {1 K* Z! o* Q
$A000: 选择8KB的ROM存储体映射到$A0005 M$ @! T8 E$ W* H
8 i: b' s5 D, {, J x
$B000: 选择1KB的VROM存储体映射到PPU的$0000(低4位)
: @' I+ W0 ?* K5 ?8 l$B001: 选择1KB的VROM存储体映射到PPU的$0000(高4位)6 E/ b( J8 D: ^2 X% ]
$B002: 选择1KB的VROM存储体映射到PPU的$0400(低4位)2 k' P2 F) M2 _1 T v, k
$B003: 选择1KB的VROM存储体映射到PPU的$0400(高4位)
* u& Z; j0 z! @" a5 D0 o
$ y' p( d; Q" i1 e2 i# ?$C000: 选择1KB的VROM存储体映射到PPU的$0800(低4位)! B% W3 Y8 r! I% Y
$C001: 选择1KB的VROM存储体映射到PPU的$0800(高4位)
$ \+ H+ ]! b S% `; A$C002: 选择1KB的VROM存储体映射到PPU的$0C00(低4位)) \9 y8 T4 t8 d- R" t2 Q) U/ O" l8 [0 l
$C003: 选择1KB的VROM存储体映射到PPU的$0C00(高4位)5 l8 N9 T; ^% y8 Y% f0 W* ^( d
$ {/ [& v1 @) X; X$D000: 选择1KB的VROM存储体映射到PPU的$1000(低4位)( Y, z7 U7 \* w: G
$D001: 选择1KB的VROM存储体映射到PPU的$1000(高4位)
6 \+ V% v0 x( [8 |7 V$D002: 选择1KB的VROM存储体映射到PPU的$1400(低4位)/ Z$ I8 b3 {' ?
$D003: 选择1KB的VROM存储体映射到PPU的$1400(高4位). ~& U2 y" G7 q+ w
# G/ j, N# Z% N" J) M$E000: 选择1KB的VROM存储体映射到PPU的$1800(低4位)8 _! t; G w- h: H- Q! q" O$ l
$E001: 选择1KB的VROM存储体映射到PPU的$1800(高4位)
/ @1 A& R* @6 C! S+ `7 u$E002: 选择1KB的VROM存储体映射到PPU的$1C00(低4位)+ H9 k, T# }" r2 `4 q. ^$ b
$E003: 选择1KB的VROM存储体映射到PPU的$1C00(高4位) c' e& Q: P) O6 ~1 s9 t
' O5 [" z" o; e) L再看看Mapper 4文档:9 U* `6 N, X/ J. ~4 g
' _" x, E2 W5 R* m9 fMapper 4
* `( M' F) a7 W6 Q- L4 B9 P$ _8 N+ t1 n" E# [+ Y1 e+ `! T
$8000: 模式号! i2 I8 @" B1 g' l' M( s
位D0-D2:
4 {. m3 b2 g# T+ G 0:选择2KB的VROM存储体映射到PPU的$00009 ]: g& k* z" a. o) ~ e
1:选择2KB的VROM存储体映射到PPU的$0800. _9 ]7 F, z5 t
2:选择1KB的VROM存储体映射到PPU的$10009 d4 J( ]/ y# D# |+ C w
3:选择1KB的VROM存储体映射到PPU的$1400
, V; h' o- d! V3 D" {5 s& K 4:选择1KB的VROM存储体映射到PPU的$1800; W/ D) X0 @2 X
5:选择1KB的VROM存储体映射到PPU的$1C00
- ^2 X6 N$ F. k$ y" D, o 6:选择8KB的ROM存储体映射到$8000% k( A; i$ j- K. Y$ ]. @$ g$ d
7:选择8KB的ROM存储体映射到$A000
, Q1 B5 _3 z# R; _ 位D6:
' T% T6 u5 T+ ?7 m 0:允许擦写$8000和$A0002 p6 p3 U, e5 ]& j3 D$ t) P, T
1:允许擦写$A000和$C000
S q" Y9 y4 h _, w. T. J 位D7:0 r$ \. |( ]$ v
0:模式号D0-D2使用普通地址) A( r+ s4 W0 T+ M7 M
1:模式号D0-D2地址异或$1000
5 D I: c" g$ [+ B3 l' D
+ M! k, p; I; J$8001: 模式页面号
4 `4 ?- C& d& I, l9 X 写入一个数(00-07),切换存储体到对应地址9 _9 i# p2 ~2 y6 O7 L2 C2 X# t
& R- t2 ?6 ^! O: B; l# x6 ?% Q$A000: 镜像选择0 H$ {" R6 }( j. n6 p# t3 P
0:垂直镜像
, Z* S: u a/ i5 ]9 J6 U t t) b 1:水平镜像
3 a" B5 p4 i2 F# ~; c' G* k1 U* O/ x. ^) D/ ?
$A001: SaveRAM 切换
, s7 c. m9 |( |& h* F# R 0:禁用$6000-$7FFF$ G. X) r' h: _8 J- Z
1:启用$6000-$7FFF4 |0 r, {' G! b
; P/ v, I) ?3 p0 N' y$C000: IRQ计数器- y( F- _0 _6 F; K8 s
IRQ计数器的值存储在此处
; `) C+ U. v: p: m) V' u% h5 F; y: C5 E) S# M) R* j
$C001: IRQ暂存器
- `) k% _, T# }5 I IRQ暂存器的值存储在此处1 h3 e. _1 f2 g8 h8 @2 O, \& ?
: N$ G, V9 |5 E! u/ [. n
$E000: IRQ控制计数器02 H( r* y4 \/ z1 t+ W+ D
向这里写入任何数来关闭IRQ,并从暂存器中拷贝数据开始计数,进入IRQ
' D m& b4 m: Y1 ^! g/ Z) X7 t% U1 m/ ]3 P, {
$E001: IRQ控制计数器11 l/ K% g+ N$ {! Z7 I
向这里写入任何数,允许IRQ(退出IRQ,允许下一个IRQ进来)
% \4 h5 [# U) y, j5 E3 T; ] b' X( A+ S/ x
: T4 n$ r/ M& x/ t9 q& }
转换思路:
: L' H: { r2 k @* ^- C将Mapper 23 的切bank 方式和切VRAM的方式修改成Mapper 4 的方式。
) ?, \& g8 @; p# ]: J `/ D" e) u6 ~5 G# P- `2 y
修改实例:
8 b4 l" f4 D; rContra (J) 256KB Mapper 23" e- H' D# @5 J& u
工具:
) s# O2 P8 i/ G6 j( B4 a( I/ \1.FCEUX 2。2。3& | d+ K1 a' U- \
2.HXD
& O; V$ r. R2 w; R u先来看看这ROM的切bank方式:: V0 }. X3 X4 I
F989:AD 00 80 LDA $8000 2 C' F ^, G4 i* \
F98C:8D EC 07 STA $07EC
) b* o# X! k+ A! |1 P' T* vF98F:8C 00 80 STY $8000
5 \8 [% t; G+ JF992:C8 INY
; F! O6 }. _4 c( iF993:8C 00 A0 STY $A000; A9 I5 E* E. q" a6 L
F996:60 RTS
" W, P) h4 H" k) t2 V" e) X! Z* `$ s! b) N W% O) i
再看看它的切VRAM方式:
* a" ?) A; v5 p0 gFACE:AD F0 07 LDA $07F0
6 w. q# q4 @: o) TFAD1:8D 00 B0 STA $B000
" i& d5 J) D7 N: l7 {& f, x3 \$ h1 yFAD4:4A LSR5 u+ c$ @* f3 _9 ]# \4 \
FAD5:4A LSR5 R7 C5 x* i2 ]4 |+ C
FAD6:4A LSR
$ o$ N- I/ ]" o [: oFAD7:4A LSR: W: r# J3 h y% U6 X
FAD8:8D 01 B0 STA $B001
: X* q1 ~6 ]- H0 U1 k0 e6 g/ KFADB:AD F1 07 LDA $07F1 @3 A5 w( t" ^9 K+ ^
FADE:8D 02 B0 STA $B0026 o8 m) Q- c0 \
FAE1:4A LSR+ z6 Z+ p ~/ H: h+ Y6 y
FAE2:4A LSR
- W: ^# v& e( E$ m( @3 S8 I. ~/ U V RFAE3:4A LSR
. J* [8 G, F& C5 yFAE4:4A LSR
0 X6 k/ O1 }" _* h# @FAE5:8D 03 B0 STA $B003
* a5 m* a8 R$ B) h2 pFAE8:AD F2 07 LDA $07F27 Z2 y: s3 N! t0 J" [% v
FAEB:8D 00 C0 STA $C000" A! `, Z3 f. F, o& l* F' g
FAEE:4A LSR
7 ]1 D" P; w% w0 HFAEF:4A LSR
2 w0 ]5 y8 G2 ^+ R0 j& z% A1 \FAF0:4A LSR) p6 _3 e0 D+ c: N2 k1 K, L
FAF1:4A LSR& e% q0 _& l# R `5 e* K2 K
FAF2:8D 01 C0 STA $C0011 U5 v3 l8 U$ X* T) p$ p3 ~4 V
FAF5:AD F3 07 LDA $07F3( T* a4 |% J; p, R2 q0 M$ L
FAF8:8D 02 C0 STA $C002
, W/ X" }3 T+ o. X" YFAFB:4A LSR& e/ w" m/ n4 Q) t
FAFC:4A LSR) W; p. B$ d! y% t0 v
FAFD:4A LSR
7 I X( o1 G' T0 a. E3 k4 gFAFE:4A LSR
! |) v) U" }1 \) k, F5 GFAFF:8D 03 C0 STA $C003
* A/ W9 m e% W/ q m# y7 D# hFB02:AD F4 07 LDA $07F4: p0 y: M5 n4 P
FB05:8D 00 D0 STA $D000
I% N! V' @' b2 C$ n7 h" q" ]9 |& \: {FB08:4A LSR
4 ?1 |& ^% g! [1 bFB09:4A LSR) {& w5 \' L1 j+ a* S( t! q0 X/ q
FB0A:4A LSR
( F' {/ f9 c) k) z: k# o; v, AFB0B:4A LSR) t) Y8 `+ \; y
FB0C:8D 01 D0 STA $D001
* }! h3 q# w( \0 vFB0F:AD F5 07 LDA $07F5
" D6 p7 S2 w7 t R& PFB12:8D 02 D0 STA $D002. Y* W( {, L) P( C
FB15:4A LSR
" ]1 Q* Z" T n# m7 c5 \FB16:4A LSR
$ o' f/ W2 |" h; B" x) JFB17:4A LSR8 O3 l' F" ]6 v$ ?: K$ ] L, E. [
FB18:4A LSR
7 q. \2 U7 ~9 B) v/ n1 E* ?FB19:8D 03 D0 STA $D003
( D" S( Q9 y* {2 nFB1C:AD F6 07 LDA $07F6
& [+ t* r$ G+ `4 h+ m8 ZFB1F:8D 00 E0 STA $E000
5 l8 N# G6 J; B4 X0 r0 CFB22:4A LSR
: C/ Z# y5 z' R" J) T+ B+ t- |FB23:4A LSR% `2 n( B0 |5 m4 t7 Q3 @
FB24:4A LSR
1 i; N( c3 U1 w; H; tFB25:4A LSR
1 S1 m( j& H1 U- f# V& d, dFB26:8D 01 E0 STA $E0015 i$ G* O; z" u3 E
FB29:AD F7 07 LDA $07F7) B" z- I0 |9 ~+ ]8 @) A
FB2C:8D 02 E0 STA $E002' X4 R0 ^' v% B+ B
FB2F:4A LSR
8 j% c! @1 D% h8 ?FB30:4A LSR1 X+ Z# U/ J' M: I# j# _
FB31:4A LSR4 Y5 a ~) m0 h% s( \, h' H( Q
FB32:4A LSR
' M! w* d& @5 p/ x3 s5 wFB33:8D 03 E0 STA $E003
$ x; S: \% a4 j, PFB36:A9 00 LDA #$00
4 G9 F Y {4 l9 Y) pFB38:8D 00 90 STA $9000: r" F, D) B. t% f, s; N5 Z
FB3B:60 RTS7 E! H5 p9 d) k- F4 n
9 Z7 P! J4 d6 I: B. I接下来修改切bank方式:
3 w0 Z) g2 e* a+ vFB2B:48 PHA
. M& s ]% C. _- s% @8 oFB2C:A9 06 LDA #$06: m$ G8 u# m0 O4 m& a# I
FB2E:8D 00 80 STA $8000& V. @9 C( E( i6 g* x1 m
FB31:68 PLA ^) h# O" I! ^1 s( b# y
FB32:8C 01 80 STY $8001
7 k n$ f& c# ?7 k( sFB35:60 RTS
- I. B" h) }; I4 m
: W' _0 _, v" EFB36:48 PHA- W/ V, r* w F, g" S
FB37:A9 07 LDA #$07
, p( u4 u3 w1 f4 G. p; HFB39:8D 00 80 STA $8000 = #$14
. ^' E2 {# I* N0 M& H& tFB3C:68 PLA% u. D; s1 ]2 c9 d8 i0 K' q2 f( F0 Y
FB3D:8C 01 80 STY $8001 = #$1D
( x+ X! p1 p. sFB40:60 RTS) W% M* s) f# ^( J
7 h, {4 s2 A8 A
还要把原ROM的对$8000和$A000进行写入操作的程序修改一下:
Z1 z, ]3 g7 B* Q" [7 ^F989:AD 00 80 LDA $8000
# r' ?8 b6 d0 Q1 h2 DF98C:8D EC 07 STA $07EC
9 L( Q/ N2 e( x vF98F:20 2B FB JSR $FB2B
R, L4 W6 u o- _: QF992:C8 INY" U8 U% F- k+ `& L2 G
F993:20 36 FB JSR FB36) ~* R, z8 E' k1 H3 [
F996:60 RTS
& |5 J F0 y- x. v) E8 `$ f+ i! [6 K7 U7 n6 {
再修改切VRAM程序:
$ }; X" x3 p) r6 s# I6 q eFACE:A9 00 LDA #$00
2 B0 m9 I7 R6 Y6 K" ?% ~5 |FAD0:8D 00 80 STA $80001 s! {; G5 [1 p) m5 e: G* A
FAD3:AD F0 07 LDA $07F0# W/ i7 d, c& ?6 r8 l
FAD6:C9 01 CMP #$01. z% O8 M0 U6 k# r
FAD8:D0 11 BNE $FAEB
0 w* C! c3 {1 l4 t+ Z; bFADA:AD F1 07 LDA $07F1/ ?3 `$ l- C4 r5 K" R
FADD:C9 04 CMP #$043 L' p% h* n, W: i& J1 b- J. {
FADF:D0 04 BNE $FAE59 V; t* Y5 I) k+ L: G6 J/ B
FAE1:A9 80 LDA #$80( I A3 W. Z" f8 ~2 }5 k2 a' P
FAE3:D0 06 BNE $FAEB
% Z: Z3 y6 O! t9 d; t( hFAE5:C9 05 CMP #$05
& c! N6 Z- d6 tFAE7:D0 02 BNE $FAEB/ d3 m9 t3 }0 B8 J6 m0 J, B
FAE9:A9 82 LDA #$82
) a: U5 A# J: L' e( X0 S* IFAEB:8D 01 80 STA $8001
" S" O' I' S, r% y1 s& i' WFAEE:A9 01 LDA #$017 }/ l5 e( N. q, R+ [6 X" `
FAF0:8D 00 80 STA $8000
) f7 Y( ?- b. V; s! nFAF3:AD F2 07 LDA $07F20 l# p7 F& k. ?3 @: l d
FAF6:8D 01 80 STA $8001, G& P9 r+ G( ?9 |
FAF9:A9 02 LDA #$02& I' A( n' E* s7 U* C
FAFB:8D 00 80 STA $8000# |5 a: O; H+ m9 V* _
FAFE:AD F4 07 LDA $07F4
3 ^, |4 x3 j3 X' G- L8 nFB01:8D 01 80 STA $8001
4 b3 m5 o7 y4 ]( D5 D5 l: J2 yFB04:A9 03 LDA #$03
/ H( S, Z& z- r1 gFB06:8D 00 80 STA $8000/ F1 b) M" L) }3 X- y9 B
FB09:AD F5 07 LDA $07F57 a; C: C9 @1 V1 Q8 j3 J& ]: E
FB0C:8D 01 80 STA $8001
7 b# ~5 k" b: Z2 m: x5 ^FB0F:A9 04 LDA #$04- O6 e0 g9 ?6 V+ _
FB11:8D 00 80 STA $8000
; `: ^& S5 T, k) v9 N! cFB14:AD F6 07 LDA $07F64 T2 {! N- H$ Z& u% z" u7 F
FB17:8D 01 80 STA $80019 H& e+ X0 Q0 g- Y
FB1A:A9 05 LDA #$059 t+ b* ]1 Z' k9 @( P& N j
FB1C:8D 00 80 STA $8000
6 T w) r+ i$ uFB1F:AD F7 07 LDA $07F7
2 L: a3 n' e7 u) F% I) |FB22:8D 01 80 STA $80012 f4 ? T2 f' |$ G! {# _7 e( z$ z
FB25:A9 00 LDA #$00
% ]! w( @$ y4 \ r! C6 CFB27:8D 00 A0 STA $A000
0 e7 P. O( @) t) Q# IFB2A:60 RTS9 B* j( ]7 d1 s \2 }5 X4 f$ N6 i
4 h+ m( F2 k9 K) T& u1 ^$ |然后保存文件。
/ H5 l$ v S( S" m6 H使用HXD修改文件头:3 U& {# d' P. l4 ~4 d* _3 t6 P
将Mapper 23
: t& Q. k7 K) \. h06字节的高4位是Mapper号的低4位& S) H: h1 o/ `
07字节的高4位是Mapper号的高4位
: Q! a5 F2 s# c3 H' P8 d! ?组合起来就是0x17=1*16+7=23! W8 S# C( [1 O

1 M7 q A5 s0 n( G5 f( w4 w! f0 f$ {修改成 Mapper 4& q' t' N Y7 P9 ^+ X( v
' I9 a: c0 T! r9 d1 W; U- x8 Z3 I
5 c* [$ }) L7 D, A+ w
) U8 P6 G# i0 y! G: o$ ]再次打开文件:
! a8 A d# W9 |. m. p 4 q$ I. r6 G: D- Q
可以正常运行9 O1 {) Y$ V0 q: F
通过全面测试,发现出现精灵错乱:
8 T/ L5 w- A% J c6 \第1关:) `0 x0 L9 z: E5 s8 v* |0 a

, a* A6 u) E( q+ }- r f( X
6 k' F! M9 ^4 c第2关:
8 d9 e3 q% p$ ?* d) M2 O
/ ? ^7 S3 A- ~9 s任务失败后:
" W2 T1 J. Z! G, @0 ~! U # X8 y% o; z3 U/ F- u8 l k6 W
通关后上飞机画面:! r1 _# G; A/ Y

4 \( D* J+ w) `% _& D这是为何呢?1 z5 u) l1 J! l1 \" ]7 X3 q! ]
这是因为Mapper 23 中精灵VRAM切bank是一次切1KB
+ T ~& E/ E( O0 n% I) s* s但是在Mapper 4中精灵VRAM切换却是一次切2KB,而且忽略bank号的D0位$ H3 ]' A: Y( V
比方bank 0和bank 1是同一个bank,同理bank 2和bank 3是同一个bank
3 Y, G: ?, O1 h也就是说
9 s2 l0 V" t+ b0 CMapper 23中的VRAM的
/ j M& N% r% O: A: s9 a& z' jbank 0,bank 1,bank 2,bank 3/ D: @* U# N; u4 g% ~- L5 l
在Mapper 4中对应的是* R) R z3 X& k* Q: E
Bank 0,bank 0,bank 2, bank2, s7 m- V0 l, y, B$ k7 ?! [/ [
然后查找原来的ROM的切VRAM的程序:
5 A: F5 y, [# ^# d. D! _知道是从07F0-07F3切到精灵VRAM的:
, X* K+ W2 q1 J& a$ K: ^$ ]* [: t9 N如图所示: M! F% U" u* W% a" e/ ^7 w

( }0 w( o# `' q0 b. B - A X% v& e0 Z
作为对比,左边是原版,右边是修改。
1 x- ]6 [& m* @( Q, Y接下来是完善VRAM切换带来的问题,因为Mapper 4只能切2KB的bank,所以我们不能通过切bank程序解决问题。
7 H) q( c2 Y$ y5 n$ F/ y" p通过测试知道1,3,5,6,7,8关的精灵VRAM排序如下(07F0-07F3):
U6 e: p* k7 y; V9 v6 E* S01 04 06 07
: x: @/ d8 b$ ~" A! v, a第2,4关如下:0 `, y6 x, ^% t& w9 ~6 ]9 R
01 05 08 096 D1 M9 ^' I: C a7 i I- c
任务失败时如下:
; ]7 c0 ]4 o+ x32 00 00 1B
3 O- I, n) G$ P7 P1 y4 l# ]其中任务失败时对应的VRAM是07F3的1B,只要让07F2为1A或1B即可:- U6 ^1 u: m& H, O. ~9 t1 c3 f# b
通过调试找到对07F2写入数据#$00时程序如下,于是修改C7E5的值为1A即可:& i2 o: i5 U8 O+ @3 H1 {
% d6 s. |, E/ W5 P8 j8 S- Z5 M
转到ROM地址: ?( b- `6 \. o! q+ S9 W
0 u/ U P! j& p0 I% k4 Y
修改数据:
S$ y: N5 G9 K0 @. e' m 9 {3 n# o; S4 @( R# v! T; o0 H7 F
重新失败后可以看到修复成功:
6 u \; U' U- F y+ |
' R9 g; g/ {8 f" o0 u! j; j! l接下来是修复正常进行任务时的精灵错乱问题。: j4 C- x4 G7 a
首先运行Mapper 23版本,在1,3,5,6,7,8关任意一关的时候,将PPU导出来; u% s+ G5 c7 [' s4 |/ Z( u1 T

$ Q. s7 e# O$ l3 ~. s( O ! G; P5 |9 z' F, Q# w: }
% W9 K! T6 M. {% E; U6 j7 H
2 k7 I* Q& m- F' A5 U- E& Z' g9 \
然后用Hxd打开修改的Mapper 4的ROM和刚刚保存的PPU的数据文件:( r' v5 ]$ J; n. Z3 m; t l
7 x7 S: Z% E$ i& L1 Y, |+ \
在ROM文件头第05字节改为0x20:
# Q: q) ?- m0 e3 v, B% S
' E: b0 a3 E' `然后转到文件末尾,插入0x20000字节空字节:
8 q+ c8 L; z2 m6 v
' m9 s; H; g; C4 w W ( C" i- Y5 v N
* M0 s+ D% [9 F" m9 X+ c" s
) @ U- v( h. c
然后将第1关的PPU数据的前面2KB数据选定:5 K7 }, W& C& L$ |3 a# W
9 U! S+ n% g* d

1 P' x, _' }6 m( f1 U
% D0 \0 C# l1 J/ \复制之后以覆盖方式粘贴到ROM的40010,同样把第2关的PPU数据的前面2KB以覆盖方式粘贴到ROM的40810
5 ^/ X- A% L+ |& }+ ^. b
3 d/ ~. i7 R3 V6 z4 ^/ K8 {然后保存文件:
% X% Q2 ~9 k3 ~0 R3 f , ^' s' O i/ {* Z( _) H) u
最后用FCEUX打开文件,添加07F0-07F3的写入断点
" d5 l7 o3 G6 D/ C" K 4 b+ ]; G: [& z; X+ m7 _
地图预览后即将进入第一关画面时程序暂停了,可以知道此时准备将C793的数据写到07F0:
% m- |- `2 X. p# r; ?! y8 \ ) O( p' w" w, e4 r$ f/ I" f5 Z
测试后知道将C793-0796写入到了07F0-07F3:
' B8 ]& H4 F: E同理,经测试每4个字节一组,一共17组,其中01 04对应普通关卡精灵以及其BOSS关的精灵VRAM的bank号,01 05对应2,4关卡精灵以及其BOSS关的精灵VRAM的bank号,再加上一个通关后跳上飞机那段动画的精灵VRAM的bank号。6 H, A3 f# u3 T6 s/ n; S% }$ I
! |/ q( [$ D2 {* ^
# @6 y2 Q" U' k& G) z
然后将文件中标记的01 04修改为 80 04,将01 05 修改为82 04即可:. ~3 x5 J3 J# e# z/ _

) J: o% D! F' q8 F保存之后重新运行后效果如下:6 k, T$ z9 K+ V. k7 F+ C

! f, Q+ W7 V2 l% p# o( [ ( i8 J6 {, W& g, R. M" w

, ~- P9 w9 k$ o( n) W3 {; @当前使用的是FCEUX模拟器,如果用NEStopia玩的话一开始就死机了,这是因为这个ROM有文件保护吧,它会往$6000里写入数据:% f) \9 q- K) A: F j
+ |) |+ c- y( P2 ]/ H! h9 {
F863:A0 03 LDY #$03) A4 ~0 F; G m6 N' Y" _; f6 i# @4 Y
F865:98 TYA- W% n C5 P _6 T2 Z* x
F866:29 01 AND #$01
* E! Y7 o; }/ q! F' k3 cF868:8D E9 07 STA $07E9( T0 Q, X* ?& m; B+ p, G
F86B:8D 00 60 STA $6000( V7 M/ B B; T
F86E:AD 00 60 LDA $60001 _$ k) z1 n2 F% \" t
F871:29 01 AND #$01
2 f9 a+ a) F$ m8 |2 K5 \F873:CD E9 07 CMP $07E9! t7 d/ T6 e- v J
F876:D0 05 BNE $F87D0 \, z1 y: f$ {& @ B
F878:88 DEY
. _1 D0 W, W6 Q! b# q U: QF879:10 EA BPL $F865
4 @, R: X5 X6 Q& K" e1 u0 y% ]F87B:30 03 BMI $F880
0 t# E% A7 F: A1 |4 u* u2 l2 [9 uF87D:4C 00 00 JMP $0000) V: N% s$ B4 b' p
F880:A5 1A LDA $001A. V3 j3 q& r2 P( Z8 W+ n
F882:65 34 ADC $0034- c2 p3 V7 v( ?2 b9 Q
F884:85 34 STA $0034+ |$ f8 Q) n1 }3 D; _
F886:4C 80 F8 JMP $F880
9 P; a( f. n+ y9 N7 }先取Y值=#$03! W) k0 i3 {/ H6 f' q ~6 D+ r2 D. v
与#$01相与后得到#$01& m* b) q4 o2 X+ ?
写入到$07E9; Z' r G4 Z. Y3 Y- t/ v
写入到$6000. y1 m* [* ~) V; v0 J3 a- \3 h
再读取$6000的数据和#$01相与后和$07E9的数据比较
5 ?: v( `( n; z" K- s) \不同的话跳过5字节
m' [& R4 t/ K/ J! l7 j否则Y递减" H6 j, X( k. s3 C% o
为正数就跳回0x100-0xEA=16字节
' b( t2 a! J3 r7 u2 S为负数就跳过0x3字节
: v9 G( _5 c V/ e" l- J& l跳转到$0000(简直没有人性了,跳到这里死机,真想得出来)2 S; a- n0 _- K2 `7 d
* O- p6 q7 L" P/ w* o! y4 @正是因为这样,NEStopia运行FC时,6000-7FFF默认是不可写的,必须在ROM文件头第6字节的D1位置1设置ROM有SRAM,对于Mapper 4,还需要向$A001写入#$80来启用SRAM。
3 R6 U% J# r* N3 L: ?* k& S' r* L由于$6000不可写,因此想$6000写入#$01后$6000还是#$00,之后读取$07E9的#$01与之相比当然不同了,于是直接跳转到死机程序了。1 J" t- X4 N9 Z& P2 t' T
解决方法是把ROM中的所有的AD 00 60 29 01 CD E9 07 D0 05 88 10 EA 30 03 4C 00 00
1 R! S3 I) c1 a% V8 K; u) b中的D0 05改为D0 00,然后保存即可。% T8 {; L& p% c8 ]1 J) j4 Q: N
测试完美运行。7 m$ ^9 S9 e/ R
5 A. T' r' x( y/ B" b% j- |7 [8 W
( E/ q% W+ H, _, k2 l& R8 _* W2 Y
教程到此结束。' d H' I. ]( ?) ~$ @" I( f
) N+ V/ n6 o, p) U9 R
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|