|
本帖最后由 yandagui 于 2017-4-16 19:06 编辑
. Z" o1 r$ O' {0 V6 f' ]' S3 l
% J/ X' T0 q8 m. IMapper23转Mapper4实例教程
# G- H6 C8 @$ h# f# e) i9 C! U" \, Z; J; m/ `. a, I
FlameCyclone 2017.4.14( \+ m9 c {. t3 ~# J: ~
: ]3 D1 a/ }0 s( f) Q" ^" B7 g# G& D先看看Mapper23文档:
3 a* K) i# z6 y7 C1 t! U& `
5 `: p$ C0 m1 oMapper 23. p: J1 J0 k$ X2 i' Z& M! }
3 E/ S3 d1 \9 ?) y( r5 Q: g- k$8000: 选择8KB的ROM存储体映射到$8000
. m3 o3 j, a# A9 ? s8 a" ]) Q" ?' H+ A* t" o9 a
$9000: 0:垂直镜像
; _1 k; m! W3 c7 c1 u2 _' O) n 1:水平镜像
# d( o7 g, A/ ~2 N! T8 K( z/ A 2:$2400镜像
7 V1 c( m. L( k7 m 3:$2000镜像
/ R+ z% u/ B. g( f; g; w e/ ]9 q2 A' x6 C
$A000: 选择8KB的ROM存储体映射到$A000- ]' N) x" [( u$ o: n
& _# z- h8 m3 s. ^. q% }& u
$B000: 选择1KB的VROM存储体映射到PPU的$0000(低4位)2 N, A+ J9 o2 Q
$B001: 选择1KB的VROM存储体映射到PPU的$0000(高4位)
# M3 N# C- ~: d$B002: 选择1KB的VROM存储体映射到PPU的$0400(低4位)9 m/ `, u2 C N9 G5 q1 D i- P
$B003: 选择1KB的VROM存储体映射到PPU的$0400(高4位)
/ {8 ]/ [# E7 V5 }( q( |, j8 o+ V k" p4 ~* V: N6 P( ~
$C000: 选择1KB的VROM存储体映射到PPU的$0800(低4位)+ K6 Q$ w& g4 X8 B8 c
$C001: 选择1KB的VROM存储体映射到PPU的$0800(高4位)
/ o& U- [+ E" B [$C002: 选择1KB的VROM存储体映射到PPU的$0C00(低4位)1 a" U; r4 R* _/ }& v
$C003: 选择1KB的VROM存储体映射到PPU的$0C00(高4位)+ a* J# R- y5 x: y
8 m4 u9 |6 c/ c8 A* J$D000: 选择1KB的VROM存储体映射到PPU的$1000(低4位)- y1 {, n4 V0 Y7 V, p+ E
$D001: 选择1KB的VROM存储体映射到PPU的$1000(高4位)
3 I+ q O3 Z' D6 @9 \1 y$D002: 选择1KB的VROM存储体映射到PPU的$1400(低4位)/ v: |: [7 K. P8 K
$D003: 选择1KB的VROM存储体映射到PPU的$1400(高4位)
9 U: P. m, t9 @ t2 a# q
4 q) m8 i7 \4 h8 W( {$E000: 选择1KB的VROM存储体映射到PPU的$1800(低4位)
z' T; F* U! o: l" R3 o+ [. K$E001: 选择1KB的VROM存储体映射到PPU的$1800(高4位)
' x/ e2 @, J4 b4 U" A$E002: 选择1KB的VROM存储体映射到PPU的$1C00(低4位)
4 M* s, B5 {! g6 ?% @/ Z$E003: 选择1KB的VROM存储体映射到PPU的$1C00(高4位)0 I* N# R& O: w! b* E; I7 a. I0 w
% C; N- J8 `2 D0 E; X再看看Mapper 4文档:
% L5 W8 u, L, Q0 d6 R/ d0 f
}+ Y7 W# }- g8 p$ C* A5 u( @Mapper 4
3 n3 D* J) ]* y" r- W' L* u0 I& c% x; ^; _ d
$8000: 模式号
2 R: P) _7 y- e; ~3 b$ P$ x9 J 位D0-D2:
& c' Z3 b+ U/ F4 B! G& G* c8 w 0:选择2KB的VROM存储体映射到PPU的$0000
, M! q, b& d; {1 D# d; r! J 1:选择2KB的VROM存储体映射到PPU的$0800- |; u; E& x* K6 W9 c
2:选择1KB的VROM存储体映射到PPU的$1000* t& y3 w& o* u- a h
3:选择1KB的VROM存储体映射到PPU的$1400# y5 B+ q/ o, f) q" g4 f
4:选择1KB的VROM存储体映射到PPU的$18009 g2 e! w- Y( G) O* \& F$ c
5:选择1KB的VROM存储体映射到PPU的$1C00 s: _3 i6 Y# v% T
6:选择8KB的ROM存储体映射到$8000
9 s; C+ @8 b# z" \& y( y 7:选择8KB的ROM存储体映射到$A0006 _1 n: W j5 c( d: I
位D6:2 k/ d% Y; W4 g% M$ r
0:允许擦写$8000和$A000) V: f1 M: b$ t5 k6 u5 X: V
1:允许擦写$A000和$C000
, ~: }& O* z- E' a' y U 位D7:7 |7 j- ]+ g$ v$ P* n
0:模式号D0-D2使用普通地址
7 ~0 }3 l/ X* b, b% f! N 1:模式号D0-D2地址异或$1000
+ X7 e }* a2 Q, L
2 s# h6 L( c7 w: C$8001: 模式页面号
1 v. X* Y) [7 v# R7 |# |3 `9 a. k 写入一个数(00-07),切换存储体到对应地址
' f; ^3 ~% o+ o3 T2 u
9 p9 S X% G! U5 g$A000: 镜像选择; @* C: E+ l q" R$ O5 ~
0:垂直镜像. g- u- E- Y) q( h6 R8 T
1:水平镜像
5 |: K: `( U) l$ L! @
* i5 H9 U: ^& c# a$A001: SaveRAM 切换% w3 G; a( d* \( Z! N4 D
0:禁用$6000-$7FFF
7 t1 J s: L+ j4 `8 N4 ?5 p( e 1:启用$6000-$7FFF
5 J; E9 F6 D3 u5 ?0 o7 H% y" H0 Q% U: V/ U. q2 a" K. A0 N
$C000: IRQ计数器" b% [/ R. p5 Q) N: v9 Y
IRQ计数器的值存储在此处! j( U; e% L: [$ k- Q
/ X9 c# p0 e+ N: M% g$C001: IRQ暂存器/ l* A$ A R* \% {& Y: e5 }
IRQ暂存器的值存储在此处
! m3 B! E C6 M# i( U2 m5 n6 W& V9 V, E+ N3 H" ?$ a
$E000: IRQ控制计数器0& ]: r j/ E. @8 a3 a
向这里写入任何数来关闭IRQ,并从暂存器中拷贝数据开始计数,进入IRQ
8 ^. T% G0 I; R$ D% I1 z ]! Y( w+ E5 u: |8 y% R
$E001: IRQ控制计数器12 V; L. i0 X5 C/ M( ~* }! I
向这里写入任何数,允许IRQ(退出IRQ,允许下一个IRQ进来)
( I' P5 c& {, q2 R2 y* A/ X! U" `. w# P7 f
1 A2 K1 t% r' a& `9 d
转换思路:( J, D6 j" X+ m, _. K2 k* C7 ^
将Mapper 23 的切bank 方式和切VRAM的方式修改成Mapper 4 的方式。
- v8 Q6 }9 n4 I" a! J$ H( B _5 d6 `7 U3 j
修改实例:* r+ P5 v: g( I [" P) H; ^; D
Contra (J) 256KB Mapper 23
- H2 b Q, a* Z' E工具:
8 A8 e. k: Y& x: d! j I1.FCEUX 2。2。3
% l, A" R; ]) D- t2.HXD
6 E' g1 Z+ s& A2 N5 l先来看看这ROM的切bank方式:
( K" b1 |+ B+ u XF989:AD 00 80 LDA $8000
9 G' Q; m7 l9 l/ r; cF98C:8D EC 07 STA $07EC" i, |: a h, s u& W M; }; G
F98F:8C 00 80 STY $8000
, ]8 g) F% g- p! K% K+ X6 yF992:C8 INY
: u+ m# S9 T4 UF993:8C 00 A0 STY $A000
, B6 T1 O; E7 @& g$ V. R/ aF996:60 RTS4 C' K" `5 K8 ]5 t0 a% z
& m/ |4 j) ?4 y1 r* h: i再看看它的切VRAM方式:* V' ?2 [* x$ {8 } ]
FACE:AD F0 07 LDA $07F0
) J8 V3 J! [3 O7 W" F& u' ?( FFAD1:8D 00 B0 STA $B000$ K2 g: ~8 @/ J! a" C! t
FAD4:4A LSR
) W7 m/ ]9 r% J6 O$ y/ i. Q0 ?FAD5:4A LSR" ?4 |$ w% |, j( |3 ~" `$ h( _
FAD6:4A LSR
% Z4 o4 L. k6 M+ _FAD7:4A LSR5 C4 Q+ @% z+ h T. ^4 j2 ]+ Y
FAD8:8D 01 B0 STA $B001
0 \( `! [$ L1 s$ h4 b# x0 Z. S" wFADB:AD F1 07 LDA $07F1; P0 r5 e2 c4 V% |
FADE:8D 02 B0 STA $B002
' N3 e) L# P4 y. N0 q, {5 Q4 ZFAE1:4A LSR
/ r, g8 Q# g9 b+ H. DFAE2:4A LSR
8 ]) W7 Y4 T$ N6 W5 D( E. K1 b" ^: C! oFAE3:4A LSR
* u/ o* {* a. j {( E7 ~FAE4:4A LSR" N( b& B% h7 I0 I" f+ h" { W X
FAE5:8D 03 B0 STA $B0037 I3 {2 _/ t+ m5 K- o$ G
FAE8:AD F2 07 LDA $07F2. Y- h7 U" x. C$ r+ i
FAEB:8D 00 C0 STA $C0008 j) D, l/ t2 A
FAEE:4A LSR
# J A1 h* l. A' C, D/ H+ r4 ]FAEF:4A LSR: D- D+ A" }- S3 k U5 | n- b
FAF0:4A LSR
) l3 w2 s# g5 _% C# XFAF1:4A LSR
" u6 m0 I/ }% B- n" i+ b0 m7 PFAF2:8D 01 C0 STA $C001 j( {4 r: P! A, K
FAF5:AD F3 07 LDA $07F3
7 G) v9 p n) [, x1 r% j& QFAF8:8D 02 C0 STA $C002 R2 W f6 T$ f- u+ V/ V
FAFB:4A LSR
A% F, G) W% M# Y5 @. }5 N, N) ~FAFC:4A LSR9 h0 N+ B7 u" Q. I1 H, b! A' x; g9 p
FAFD:4A LSR, e9 r0 H' t. t) I
FAFE:4A LSR$ T* A, j+ |$ \- j
FAFF:8D 03 C0 STA $C0038 r. G( C* R* [9 X! ^' H9 v
FB02:AD F4 07 LDA $07F4
+ N o# E- H9 i4 O/ e hFB05:8D 00 D0 STA $D0009 I+ H/ P3 }% \% w% q2 J: n0 R+ R! ~0 i" [
FB08:4A LSR
% c: M6 Z4 c0 U& xFB09:4A LSR! H* B. n* k) ]( i8 [6 \
FB0A:4A LSR
5 ~8 e5 S, U! vFB0B:4A LSR2 @% B& a O, P$ L( m
FB0C:8D 01 D0 STA $D001
+ N% S; Y9 m8 |: F( u% P! t# F; bFB0F:AD F5 07 LDA $07F5
0 y) T0 s- J" U) fFB12:8D 02 D0 STA $D002
/ z6 Y. H1 X+ c Z$ Y. NFB15:4A LSR6 Y( j7 k) z$ X6 {' L6 z% u
FB16:4A LSR
! K, O1 h" T% ?8 `' \" ]% tFB17:4A LSR0 S6 H( _2 O+ M% Q a+ x* U
FB18:4A LSR
. S2 H# g5 t" l0 |FB19:8D 03 D0 STA $D003
T( W2 f: I& N2 w9 yFB1C:AD F6 07 LDA $07F6
! A8 R2 F" p0 [3 k" wFB1F:8D 00 E0 STA $E000* a3 L1 G" S& k# B$ @/ D1 H, V
FB22:4A LSR, t$ I. T+ p3 R0 `
FB23:4A LSR
7 A2 r* i3 ^8 Q! A( {FB24:4A LSR6 L' K' l1 Z% v/ y! l
FB25:4A LSR
4 I6 d, T; v/ j* {) yFB26:8D 01 E0 STA $E001
8 X$ U9 M9 U1 F( WFB29:AD F7 07 LDA $07F7
; |3 Y2 J' E# u5 ]5 C# jFB2C:8D 02 E0 STA $E002, a8 D; t/ D! U6 e, _
FB2F:4A LSR# \! Q5 g h1 W0 ^+ ?
FB30:4A LSR% d l7 R, H4 k: K V9 y; Z0 s5 C
FB31:4A LSR, v" z$ H9 l, |2 t/ X( h
FB32:4A LSR1 j$ p& m& |0 J2 L1 W( T4 H5 E
FB33:8D 03 E0 STA $E003
8 i, h: ]2 ^: o& N/ U! q9 `' g5 ]FB36:A9 00 LDA #$00
. f; f+ a& g# [0 r& B4 j* eFB38:8D 00 90 STA $9000# n8 B$ ?) }- \# H$ x9 R$ m1 A
FB3B:60 RTS
T. R( T$ C9 f5 c0 N6 U6 p$ } Z2 ]! b& h- ]% E
接下来修改切bank方式:" o# i. D) t* ~; S- j
FB2B:48 PHA; q- F4 N& q4 ^' j
FB2C:A9 06 LDA #$06
3 m+ Y6 `/ z, u5 t$ T2 `FB2E:8D 00 80 STA $8000
( ~" o @$ g( m: j, n4 y( l! l" c: bFB31:68 PLA0 }% Y9 A( ^8 B& n1 X
FB32:8C 01 80 STY $8001
7 d& @5 i! h+ j2 Z3 Q' v* wFB35:60 RTS, m5 B2 z( ]. Q4 g: D
0 H1 L ?- k+ |FB36:48 PHA
" V' ]; `! Y5 w: {; t8 h$ k4 MFB37:A9 07 LDA #$07: }/ w# }( y7 E0 A* }. @& N) h
FB39:8D 00 80 STA $8000 = #$143 }( O# s& S K* h* J
FB3C:68 PLA9 W9 q+ e2 d; X, |) n/ ?+ U+ P8 N
FB3D:8C 01 80 STY $8001 = #$1D
9 ]$ x, f3 A4 m7 h5 O& XFB40:60 RTS/ } O& h6 Y( b0 c: C- c* P
7 v( c4 s6 R5 E G; J* {# ~+ E# C: B/ P$ t
还要把原ROM的对$8000和$A000进行写入操作的程序修改一下:/ t* K9 E( r! }, t1 O4 p
F989:AD 00 80 LDA $8000 ?" C9 ^2 y+ U8 E7 |6 N
F98C:8D EC 07 STA $07EC8 S: Y$ w1 Q! ]- D
F98F:20 2B FB JSR $FB2B
5 w1 I5 G! X7 J8 l! BF992:C8 INY
. D. T) c2 W j* a" i& [1 i( rF993:20 36 FB JSR FB36& B* @, ^6 j1 t" M6 W
F996:60 RTS
$ I! s% d; \0 S( B
9 e$ z) S6 u, a! C# u再修改切VRAM程序:
: V% H. b* L9 {4 T; B- R) {FACE:A9 00 LDA #$00
' l/ L. O& \& KFAD0:8D 00 80 STA $8000
% A# m1 N' {& g s1 g" f r0 @FAD3:AD F0 07 LDA $07F00 I5 ?) Q4 V% o/ ~2 H
FAD6:C9 01 CMP #$01
% Q* {+ v1 R! UFAD8:D0 11 BNE $FAEB9 E9 R+ R. ^4 K& i3 h7 O9 \' b
FADA:AD F1 07 LDA $07F19 r( M; b' h* c$ |
FADD:C9 04 CMP #$04
# A0 y4 z. y" Q7 F- L1 c! b% XFADF:D0 04 BNE $FAE5
& R: P- ?& I5 o5 l1 b TFAE1:A9 80 LDA #$80. B" r) B/ n# v5 `
FAE3:D0 06 BNE $FAEB
X3 d3 e- M& xFAE5:C9 05 CMP #$05
+ m3 l- j( f' x1 ?FAE7:D0 02 BNE $FAEB% o( d8 ~ N5 Y/ g8 S- t3 N) ^
FAE9:A9 82 LDA #$82- h% ]4 j: g. `" \. l: M A! E2 J. e
FAEB:8D 01 80 STA $8001
+ s' t! `( C: [- m+ { m6 E8 AFAEE:A9 01 LDA #$01
! T A- X3 Y7 O, hFAF0:8D 00 80 STA $80003 D& h3 T S; v4 M4 q7 U# ~8 G1 h- v1 C
FAF3:AD F2 07 LDA $07F22 S* Q: M4 o. k3 i/ `+ n, H
FAF6:8D 01 80 STA $8001
9 v; ~* q+ @6 K6 o6 Y$ Q, EFAF9:A9 02 LDA #$02( \9 {5 W; \) C( x- [8 ]
FAFB:8D 00 80 STA $8000
. y8 J2 B% V! [' Q. U- c/ S6 [FAFE:AD F4 07 LDA $07F4
" D1 |( i1 j, c) a. |FB01:8D 01 80 STA $8001
2 a6 Y* @! J6 t; c! i$ ~FB04:A9 03 LDA #$039 W0 } |6 J" n0 ~
FB06:8D 00 80 STA $8000 }* {+ y4 m3 ^9 M& N
FB09:AD F5 07 LDA $07F5 H+ W) U0 \) f' h C8 V+ F& B
FB0C:8D 01 80 STA $80011 W0 ]& T g/ w1 J/ A* i& d9 Z
FB0F:A9 04 LDA #$04
6 {, P; E' `1 D& h6 PFB11:8D 00 80 STA $8000
5 [% a' r3 p+ k/ X5 IFB14:AD F6 07 LDA $07F6
% W6 l0 j& |! y" ~0 n& A( w5 ]FB17:8D 01 80 STA $8001 S, R# x, J9 {8 |3 X! D
FB1A:A9 05 LDA #$05* Q- b& q7 |' ^6 E! u% h8 @* g
FB1C:8D 00 80 STA $8000* ]# f% X9 h H: ]) t
FB1F:AD F7 07 LDA $07F7, [4 h \( m3 y& I6 ]0 J
FB22:8D 01 80 STA $8001
* t7 r4 [* q) dFB25:A9 00 LDA #$00
* K2 t. Y/ q L* e. P8 v* S# bFB27:8D 00 A0 STA $A0000 K0 ` ^ s- n
FB2A:60 RTS
+ b/ g3 H7 b0 @$ [% z
, {) W& q4 n' |7 Y3 _' F0 V% |然后保存文件。
, n. M+ }& l4 R/ p使用HXD修改文件头:
" {& g- t% O0 M) p% z4 y将Mapper 236 a8 }0 {6 V- v3 ]7 x
06字节的高4位是Mapper号的低4位
$ @+ P3 ~7 T+ D y4 _6 u, X07字节的高4位是Mapper号的高4位
) z# R; r. }9 k8 z组合起来就是0x17=1*16+7=23
0 M$ {& g; g% a) N4 \+ k V" V9 \. D% c; s
修改成 Mapper 4" e3 k- A, ^0 z0 I6 Q/ x
% ^& z0 @% L( B' H
- ~1 j4 k4 _4 ]3 t) X
; ~8 |. J3 S; E, L8 O0 j: |再次打开文件:
/ c0 M- @) @; N- K# h) |* W5 ~7 H
. J1 R5 H) J1 p7 u可以正常运行- \$ A% d1 ~3 W) n/ b% H9 j- |5 l, X
通过全面测试,发现出现精灵错乱:+ e, q) z$ r& P0 e8 s) K# m
第1关:
' r) M( @, m5 ^6 f
8 c7 ~. w! b: w; U& E! Z/ d
* S$ d5 a5 U6 U% B, g; ?2 q' p第2关:$ N8 p$ I1 |$ l4 _* O7 R: n
/ o, a1 p. _/ @任务失败后:% v1 q, y- }. S
* w8 V) _6 ^) ~! `
通关后上飞机画面:4 D, F. O0 t$ x N
5 r9 p+ ]. W. A! b, P这是为何呢?
3 ?) y' T6 H" T- {. Y这是因为Mapper 23 中精灵VRAM切bank是一次切1KB( J: `" l- f6 h5 e7 p! y& e
但是在Mapper 4中精灵VRAM切换却是一次切2KB,而且忽略bank号的D0位
) T0 ]" X9 {$ K8 ?1 g F5 ? _ T比方bank 0和bank 1是同一个bank,同理bank 2和bank 3是同一个bank( [" g7 [/ D; T2 U1 n6 n
也就是说. V! e! L2 `& @
Mapper 23中的VRAM的
- e6 ~* I# m: x3 u+ ?6 `' lbank 0,bank 1,bank 2,bank 3. L5 t3 i7 o! k. Z* \
在Mapper 4中对应的是0 t0 X- H$ {$ M n M4 F3 O
Bank 0,bank 0,bank 2, bank2: b" Z: I6 t* D3 W; P& E
然后查找原来的ROM的切VRAM的程序:6 i8 V" I# M" z8 F/ d. o
知道是从07F0-07F3切到精灵VRAM的:
& w, [5 l7 o/ m) S2 Y9 \8 {, j/ L# P7 ^& E' o如图所示:
9 A/ x! V" k' S
' D. V$ R0 k n% j' k" e# D
A$ I) p" B# u: E( `作为对比,左边是原版,右边是修改。6 S8 \! _) O! y8 u6 J* [
接下来是完善VRAM切换带来的问题,因为Mapper 4只能切2KB的bank,所以我们不能通过切bank程序解决问题。/ {8 r$ ?& R! P* [
通过测试知道1,3,5,6,7,8关的精灵VRAM排序如下(07F0-07F3):
! d" Q! @ G( j, C: U1 a01 04 06 070 J7 J! N" I$ F$ g
第2,4关如下:
! q, |! C: G9 {! V+ M1 l+ h0 o01 05 08 09
8 T* Y9 H# m' Z2 J6 ?任务失败时如下:, Z, S5 W) F) J6 J, h3 R
32 00 00 1B
$ [* y/ q; `, y, B/ j* Q其中任务失败时对应的VRAM是07F3的1B,只要让07F2为1A或1B即可:+ W% U* d* x$ `: r
通过调试找到对07F2写入数据#$00时程序如下,于是修改C7E5的值为1A即可:
% ?+ w% |2 B' S% o; i' @9 @( k: V0 z, l2 W
转到ROM地址:6 _: Y8 o& I9 O2 W
; t L Z$ X4 E8 _修改数据:. b* J2 k" s6 G# Q; }5 n$ J) U
/ _& f1 |" c) N! G$ c _7 M
重新失败后可以看到修复成功:; I& h5 [' |, D2 q( b
3 I- v8 z5 ~5 X0 h
接下来是修复正常进行任务时的精灵错乱问题。
9 T5 c" ]9 O7 U首先运行Mapper 23版本,在1,3,5,6,7,8关任意一关的时候,将PPU导出来0 G- G0 K; l8 w j
! U: y' _$ @ O4 l1 _+ ?5 |+ e- _3 T4 X' x; }6 @% N8 Z
2 W1 Q# y m* a1 s- ~9 j' [+ w) f
# x w& w% v# m) ^
然后用Hxd打开修改的Mapper 4的ROM和刚刚保存的PPU的数据文件:
( K4 S J, {( j( @: e/ M$ N( l; H; g* a
在ROM文件头第05字节改为0x20:$ J& j' l9 T' @: B! C# d1 l
4 s4 _* ?" |, l1 o0 ?! Z然后转到文件末尾,插入0x20000字节空字节:6 \# c4 g9 y, K$ k1 y( e
0 h0 ]# i. Q* k4 l( ^
3 I: V% i8 ^. I* e) v& H" k6 @
! e$ n1 o$ R' R G) M7 n' g; H5 {+ w# u% t% B) E
然后将第1关的PPU数据的前面2KB数据选定:
3 {& Z3 I: }7 s$ `+ k; i ~7 @$ V9 g+ `* |) `$ H. N" G
9 y, V" ~% ]/ K e: ?( }# L+ U0 T @- _, p6 I- l
复制之后以覆盖方式粘贴到ROM的40010,同样把第2关的PPU数据的前面2KB以覆盖方式粘贴到ROM的40810
7 Y9 A, [0 w% S* x- _! g R; N" Y+ A
然后保存文件:
1 C0 Q& ~' L9 S o8 O: V% ~, y% N( e [3 E" J, ], e/ n0 I
最后用FCEUX打开文件,添加07F0-07F3的写入断点0 p% I! Y4 ]: Q% o& t
3 a, U5 O2 i' {" A3 m
地图预览后即将进入第一关画面时程序暂停了,可以知道此时准备将C793的数据写到07F0:
# F Z; r) O, x a* Y$ \/ L
% W6 m. V' F G$ r V4 y3 j2 ?测试后知道将C793-0796写入到了07F0-07F3:" T1 u; U' {/ f/ B; o3 b. Q$ U( c
同理,经测试每4个字节一组,一共17组,其中01 04对应普通关卡精灵以及其BOSS关的精灵VRAM的bank号,01 05对应2,4关卡精灵以及其BOSS关的精灵VRAM的bank号,再加上一个通关后跳上飞机那段动画的精灵VRAM的bank号。2 q& p9 s. X5 g
( L/ B& H% G' u( Q0 a' D C+ [8 U
- l+ [: w- A }: e然后将文件中标记的01 04修改为 80 04,将01 05 修改为82 04即可:. L1 p8 o$ p! f& T$ T
5 w7 B8 h' J( H# C% Z0 P
保存之后重新运行后效果如下:3 [5 K+ c4 L/ X6 f- E% g
6 `; j2 J% c8 g2 G L7 X- T) P m/ d) [+ a# o6 v
( w" U6 l+ u4 \8 ]! k4 {当前使用的是FCEUX模拟器,如果用NEStopia玩的话一开始就死机了,这是因为这个ROM有文件保护吧,它会往$6000里写入数据:# D, k* |) P- y6 T0 N
/ r& E# c8 {+ D. c' Y
F863:A0 03 LDY #$03+ `. e) I) k- M2 p# ~2 K
F865:98 TYA" o0 c; A0 L& G
F866:29 01 AND #$014 b+ S) R1 E4 @0 v8 c& J1 q; f
F868:8D E9 07 STA $07E9
+ J d$ F! e9 s P6 C+ F RF86B:8D 00 60 STA $6000
' \$ \# ]8 e1 MF86E:AD 00 60 LDA $6000
# I9 [7 ~9 j/ y: g! b9 uF871:29 01 AND #$018 l( s5 @* {( ?. l x- k, y* }
F873:CD E9 07 CMP $07E9
: g# q0 r2 T4 D! o" }" c' `F876:D0 05 BNE $F87D
7 f. N3 d4 |( F) I# Y" _# s; {6 X* QF878:88 DEY! ^ e E7 Y* L0 w
F879:10 EA BPL $F865/ ], a5 V' G% G
F87B:30 03 BMI $F8806 o$ s0 ]/ g4 t' K q
F87D:4C 00 00 JMP $0000
/ d' M, V2 Z- s6 V/ b! b, mF880:A5 1A LDA $001A
1 c2 H9 w% f" [! M, _# q' vF882:65 34 ADC $00340 J% J7 @+ B0 _8 z5 C, o$ u
F884:85 34 STA $0034
0 i7 S% B' t; `, D! G! ZF886:4C 80 F8 JMP $F880
$ z6 [4 N' Y9 S% d先取Y值=#$03! N, G' _& k3 A7 U) }
与#$01相与后得到#$01
' \' B& v! s2 h z4 k# @写入到$07E9
1 g' ?3 d: ^; Q/ U/ z$ n写入到$60002 K+ K- v. N$ X6 y4 h
再读取$6000的数据和#$01相与后和$07E9的数据比较+ C$ T: _9 i0 c' i! C; w8 B5 N
不同的话跳过5字节, Y( @! o* v' I' S. F! U9 ~+ V, O
否则Y递减; f- i. I/ v" K' X; P, i- {
为正数就跳回0x100-0xEA=16字节
* |. R2 B; A4 t' z9 f, c为负数就跳过0x3字节
2 V) l2 S0 {2 k6 d跳转到$0000(简直没有人性了,跳到这里死机,真想得出来)
; O- v: r3 t- b- `
- j3 J% {2 T$ G8 U6 S7 I* i$ g# H正是因为这样,NEStopia运行FC时,6000-7FFF默认是不可写的,必须在ROM文件头第6字节的D1位置1设置ROM有SRAM,对于Mapper 4,还需要向$A001写入#$80来启用SRAM。
) ~1 ]2 n- q! x7 P4 w$ h由于$6000不可写,因此想$6000写入#$01后$6000还是#$00,之后读取$07E9的#$01与之相比当然不同了,于是直接跳转到死机程序了。* N) R7 X. P: E4 i' ^. p9 m% `# ~
解决方法是把ROM中的所有的AD 00 60 29 01 CD E9 07 D0 05 88 10 EA 30 03 4C 00 00
! J4 v N+ \! o; ?4 ?% y: |中的D0 05改为D0 00,然后保存即可。
3 F+ ]2 Q% L+ u) r9 D测试完美运行。
9 j6 {$ ]* Z3 \/ U! h( R' R1 u' S: V& v9 {8 L9 o7 F
+ t& } y6 n4 s
教程到此结束。
2 V9 e2 D. z9 L& S( K% F1 u+ ^9 R! z7 X' k: B/ D4 V
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|