|
本帖最后由 yandagui 于 2017-4-16 19:06 编辑 ) W A- o. [, d9 v( b# B9 _/ u+ s
, g. Z& } c7 X) J! I! u
Mapper23转Mapper4实例教程
- U" g. v% L2 B! M# [' D. [
+ Z. U) y& T2 |# H; J' ~FlameCyclone 2017.4.14 U8 ]; j d( `6 P2 z
, p) s9 T* Y* l( v8 Q Y先看看Mapper23文档:
, G+ Q* C1 Q; Q. N/ H' i# G, i# \1 ~1 b; s0 F
Mapper 23% b* I7 ^/ n! P# R/ e0 e! [1 Q% H4 T
3 j: h0 W$ E& x/ |. z( j
$8000: 选择8KB的ROM存储体映射到$8000# K0 F4 e7 y* I F& n) _- J
& c" ~, ^. Q* r5 X1 G
$9000: 0:垂直镜像
- a7 q8 t1 D: I 1:水平镜像+ ]- g3 x2 g( O" h% h
2:$2400镜像
4 B& n e# @; Y) Q5 c* P1 J2 ^ 3:$2000镜像 O4 k6 U1 Z4 y! b0 T7 l- ?- d
; e, K4 }0 N/ ^: s( n; k
$A000: 选择8KB的ROM存储体映射到$A0003 u) q* g! q# K& q* k; v& E
* [: s! c. D" a7 A+ p5 {
$B000: 选择1KB的VROM存储体映射到PPU的$0000(低4位)) L7 e/ e% v6 n. _- _8 q
$B001: 选择1KB的VROM存储体映射到PPU的$0000(高4位)8 v9 _% m6 Z+ _4 `! b, r$ R) Z
$B002: 选择1KB的VROM存储体映射到PPU的$0400(低4位)1 m9 e4 s; x, V8 Y( ^( M* `
$B003: 选择1KB的VROM存储体映射到PPU的$0400(高4位)
% l7 E4 Z4 J$ f1 T+ S, E0 w. C1 e; F" y6 l" h
$C000: 选择1KB的VROM存储体映射到PPU的$0800(低4位)
4 }( r; F6 P" n9 C1 m$C001: 选择1KB的VROM存储体映射到PPU的$0800(高4位)
2 @% u t' p( x% d1 @$ y. w6 u$C002: 选择1KB的VROM存储体映射到PPU的$0C00(低4位)
/ j2 u- {) ^6 D# ]. l0 ~& {$C003: 选择1KB的VROM存储体映射到PPU的$0C00(高4位)3 P2 }% r# h6 r
6 K0 ]1 p. w& m, b: w$D000: 选择1KB的VROM存储体映射到PPU的$1000(低4位)% \$ ~! w0 H( V9 u
$D001: 选择1KB的VROM存储体映射到PPU的$1000(高4位)4 F1 M( U0 A! P& e
$D002: 选择1KB的VROM存储体映射到PPU的$1400(低4位)8 l6 |2 y5 q4 H9 T1 } L5 B
$D003: 选择1KB的VROM存储体映射到PPU的$1400(高4位)
% Z b8 M# u5 G1 A! H6 A, X+ y* O. ` m8 {! n. P
$E000: 选择1KB的VROM存储体映射到PPU的$1800(低4位)# i% O( `8 g7 Z- T5 S
$E001: 选择1KB的VROM存储体映射到PPU的$1800(高4位)# @1 o k9 I" |+ r5 ?
$E002: 选择1KB的VROM存储体映射到PPU的$1C00(低4位)
1 w& [4 |1 O! ?$E003: 选择1KB的VROM存储体映射到PPU的$1C00(高4位), K$ O5 q6 F5 o
4 E' F6 l* S5 ?0 D再看看Mapper 4文档: c! G3 W x. v
3 n, e. r5 Z0 i7 W( `" o: _8 MMapper 4
% x+ a; `4 q4 a% N7 P. M8 P! e. ` ?1 z; v
$8000: 模式号
9 e. r: W7 U7 q4 v: T& w 位D0-D2:
3 z9 p d, l! \ 0:选择2KB的VROM存储体映射到PPU的$0000
. ~8 Z- u" v+ S$ o* ~) r 1:选择2KB的VROM存储体映射到PPU的$0800
! i& z! z- s6 V' A 2:选择1KB的VROM存储体映射到PPU的$1000
3 ?3 c; X0 k/ k3 a5 | 3:选择1KB的VROM存储体映射到PPU的$1400: \# F! D" G7 J0 v6 L* f! r4 ~- f% Z
4:选择1KB的VROM存储体映射到PPU的$1800
7 n3 A/ c5 X( ]" o3 {& B3 l4 Q 5:选择1KB的VROM存储体映射到PPU的$1C00
2 O( V5 y1 B1 X! g! F 6:选择8KB的ROM存储体映射到$8000
7 W" q3 Z4 ], Z* N; c5 Z3 U 7:选择8KB的ROM存储体映射到$A0009 Z+ l1 ?- r8 S* S
位D6:3 a1 \$ ?8 {* n
0:允许擦写$8000和$A000
! Z! `) p+ P3 Q, T 1:允许擦写$A000和$C0001 Q7 A! u# U7 i% X- O
位D7:
; j7 @. G4 P: Y. X1 P/ p/ U' C3 V 0:模式号D0-D2使用普通地址
6 d: i0 M/ i- i' b6 `8 V 1:模式号D0-D2地址异或$1000; f" C: E- z, H" I5 O
( e9 i2 N& t7 l( a2 X$8001: 模式页面号 R, O6 N* \- x2 F
写入一个数(00-07),切换存储体到对应地址
7 b5 U3 C( R' t( x" K3 [2 c' v6 }( c$ U6 C# `& H* W- T
$A000: 镜像选择
. w5 t! K& y9 P, f4 t 0:垂直镜像
4 f8 Q( L& ~5 G) ?4 V! W 1:水平镜像
+ S& d4 o$ k) P. u6 Y+ @3 @# D/ d! Y
$A001: SaveRAM 切换0 n4 t" }' K$ T- D9 {5 [
0:禁用$6000-$7FFF
4 R( n0 Z! j" r& r$ b5 H* J5 A 1:启用$6000-$7FFF( r: ~! w) h; v& k5 \1 }1 y
1 a/ y/ a) x2 F0 L3 G
$C000: IRQ计数器; a, z$ G$ ]* c C! h2 @# I
IRQ计数器的值存储在此处- P' ?' W; `8 Z3 l* i
1 J$ I9 q; J+ ]7 ]$C001: IRQ暂存器
0 }# j$ a) L4 s$ O. R IRQ暂存器的值存储在此处
: B" b' f9 W; H, F6 N' |: P. ~9 w. n" z% Z/ ^
$E000: IRQ控制计数器0
: e- u+ G3 s1 i' @9 S4 j 向这里写入任何数来关闭IRQ,并从暂存器中拷贝数据开始计数,进入IRQ
) e+ i) I, l% [0 J, b# S
+ ]+ a8 g/ \8 u2 F4 D- k+ u$E001: IRQ控制计数器1# S5 t( b: B" ~- p
向这里写入任何数,允许IRQ(退出IRQ,允许下一个IRQ进来)
0 A5 j Q8 v/ `2 f j' ]" H8 d* W7 U6 e* h& f6 z
0 |: N8 u8 S. S: y
转换思路:
/ ]9 j) |: ^; O8 O( A将Mapper 23 的切bank 方式和切VRAM的方式修改成Mapper 4 的方式。
! B1 L4 a+ C* L; Z! Z; |5 ~7 C( W* C7 V5 B9 U
修改实例:
: r$ O0 s, {. r; r, {Contra (J) 256KB Mapper 23
; G, s+ }0 i! }$ S工具:! x: s6 @ X Q1 E% u5 D7 j! y
1.FCEUX 2。2。3, | U; c; [! B, z' [+ L6 y
2.HXD1 k7 [1 a7 J5 ^, t2 Q! Q6 q. v
先来看看这ROM的切bank方式:
% \# K. @! V% n- O* j7 C1 a2 |# zF989:AD 00 80 LDA $8000
( I% T2 Y4 y6 z3 x6 K; \7 l* U: mF98C:8D EC 07 STA $07EC) y- K+ A: _0 [) Z+ x& ?! Q0 j2 u) G
F98F:8C 00 80 STY $8000
$ Q7 ^( P9 `3 F( [F992:C8 INY5 r: E4 } S$ Y7 @! _ N# s
F993:8C 00 A0 STY $A000
6 K& q6 o! D& G6 v: x9 j5 h( HF996:60 RTS
`9 }! Q9 S1 o, L4 k; b1 G8 Z$ M
2 q' D5 @- P0 J0 G再看看它的切VRAM方式:5 r( m6 e9 V2 G, K, f: F3 c9 \
FACE:AD F0 07 LDA $07F0
- k5 q! ~4 [( a N6 g: D0 }FAD1:8D 00 B0 STA $B000
- A1 f2 @) n2 q* d' |( h/ eFAD4:4A LSR+ F. T8 z% n' ?4 I2 Y& |6 u
FAD5:4A LSR
2 O, i1 x6 ~6 D6 v1 u9 F6 n% X1 F3 jFAD6:4A LSR
& f: [; c4 ^! Q" Y0 v8 A, g9 }FAD7:4A LSR# W7 A6 x: o2 H
FAD8:8D 01 B0 STA $B001
! w2 N, f- ^/ n/ V( B4 V. gFADB:AD F1 07 LDA $07F1
" w/ ]4 U7 \" `FADE:8D 02 B0 STA $B002
+ C: m( a, j$ T7 hFAE1:4A LSR8 H0 K& o$ @5 `- m5 ?; m3 Y
FAE2:4A LSR
+ { ~0 L9 [ W8 l" ` p' DFAE3:4A LSR
5 M4 T8 ?" I, `$ Q* oFAE4:4A LSR; C) M' d! l D2 a* i, y
FAE5:8D 03 B0 STA $B003" X) `4 q, J# ?( E0 U
FAE8:AD F2 07 LDA $07F2
. x2 ^! {3 h- A9 R( f$ E- UFAEB:8D 00 C0 STA $C000* _8 X2 ?- P- ?# r' l# h
FAEE:4A LSR p+ G) k" i* g4 t1 p# J! R
FAEF:4A LSR6 g+ V+ E3 n4 y) A [2 L
FAF0:4A LSR
% K. j' K) x3 [0 e Z( ~FAF1:4A LSR# Z: a* M4 x* ?* L
FAF2:8D 01 C0 STA $C0014 G0 M6 J/ P1 K' G
FAF5:AD F3 07 LDA $07F3
! b$ n8 U# d9 g7 m8 t5 JFAF8:8D 02 C0 STA $C002* |# |) D/ f$ l( |1 X
FAFB:4A LSR
2 K7 A* ~2 j, u0 l8 p' {: x# M# ?8 EFAFC:4A LSR
" T3 u E8 f3 @1 \) c+ EFAFD:4A LSR
0 P' ~; u# J1 x) u6 oFAFE:4A LSR
) D/ o; n% z3 i# W5 XFAFF:8D 03 C0 STA $C003: T3 j& \8 o6 V
FB02:AD F4 07 LDA $07F4
, E% i5 y2 d- u; UFB05:8D 00 D0 STA $D000
4 k) s' n9 |& n2 [2 oFB08:4A LSR( J4 Z! R: ~6 @: s: k
FB09:4A LSR
: h; S4 b( G9 d, q3 kFB0A:4A LSR5 ^+ Y; j* Z% r7 Q
FB0B:4A LSR% T& x. j- g w5 ^
FB0C:8D 01 D0 STA $D001! Z. R1 Q$ n# z! ^/ I7 U
FB0F:AD F5 07 LDA $07F5
$ B6 d5 h" u$ O4 w7 l# `0 YFB12:8D 02 D0 STA $D002- z% W/ k; j& t7 s6 e0 r6 Q% n6 F
FB15:4A LSR
) \/ t" V+ f3 N& b2 _1 j. TFB16:4A LSR* Y Q' X$ e; v% [* _7 r; p
FB17:4A LSR0 y3 e. C! p& S3 ^' n4 O9 B- P
FB18:4A LSR
* h# `# @+ c6 ` |9 `FB19:8D 03 D0 STA $D003. A* n4 @( R5 b5 K) k* n3 m
FB1C:AD F6 07 LDA $07F6* I' j8 m: Z5 a j1 U9 l
FB1F:8D 00 E0 STA $E000
- l# B( e A* l" y' uFB22:4A LSR( [* }1 [7 o- [+ d6 m% t- d+ o, f) D
FB23:4A LSR
5 Z% A: m- ]0 E2 x' v! P5 }FB24:4A LSR: E! U& {9 Y X" t( J" J2 n) w
FB25:4A LSR3 f6 E, r+ N; ]: V1 T4 @4 u
FB26:8D 01 E0 STA $E001* V! x) ^& z; A& s
FB29:AD F7 07 LDA $07F7, P! d2 o( x2 D: H7 D/ c
FB2C:8D 02 E0 STA $E002. b# S) ?8 t, \
FB2F:4A LSR( |' I+ I' h9 N) D
FB30:4A LSR
5 R" [. }4 P* b% r$ Y! pFB31:4A LSR
5 q# s6 I" Y7 p) ^4 i" QFB32:4A LSR
. H9 k+ O- @: @7 J0 A* ZFB33:8D 03 E0 STA $E003
* Z4 u" n6 n, t5 FFB36:A9 00 LDA #$00 F, y" y& a# U* W
FB38:8D 00 90 STA $9000
. O* Y( M+ h7 O$ FFB3B:60 RTS; {. X3 S" |( t6 z: T9 |+ I3 W
. N3 a1 B% e \2 H$ A接下来修改切bank方式:, B2 F* x4 v: z. K; s
FB2B:48 PHA7 Y p# y& i9 H+ t9 a$ C" l8 b8 }
FB2C:A9 06 LDA #$06
& Y! ?4 g! N' M* WFB2E:8D 00 80 STA $8000
7 D0 U( ~; m, n2 h% C% RFB31:68 PLA. i; K6 M, N, t) o5 a
FB32:8C 01 80 STY $8001% D) D, i" w% w6 D& l
FB35:60 RTS
2 l5 J( k: S* Z1 P5 r% [, g
& ?* m! Y- E; V$ ~7 VFB36:48 PHA* ]$ _) \1 [- G6 \& m) O7 u
FB37:A9 07 LDA #$07: s: R. \9 }" a7 |
FB39:8D 00 80 STA $8000 = #$14 _& \& L3 n! ~. R; e! `
FB3C:68 PLA2 o' @- ~- i2 S% n# k
FB3D:8C 01 80 STY $8001 = #$1D
* A6 R# c1 ?' B8 e+ X7 YFB40:60 RTS3 ]1 k* f( c# F' N' p! j
/ D8 F9 U( ~" W; I3 B- B8 V还要把原ROM的对$8000和$A000进行写入操作的程序修改一下:
% L+ H0 ~7 M( l4 I, ?F989:AD 00 80 LDA $8000
. j0 R. n+ X" E, O& u! YF98C:8D EC 07 STA $07EC
( V7 j/ o2 g: _" xF98F:20 2B FB JSR $FB2B0 P+ Z- X2 d0 d
F992:C8 INY8 t; h+ U7 Y, i1 [8 a U3 d
F993:20 36 FB JSR FB36
/ _* V! d6 b; B& | w9 fF996:60 RTS$ C( o1 U1 E( c/ N; n/ j
$ Y+ W/ o6 _$ P: J. F再修改切VRAM程序:5 ~# k i, }8 G. D; F7 J8 V" A
FACE:A9 00 LDA #$00
1 m# G; O+ \& G: A4 R6 WFAD0:8D 00 80 STA $8000
. \ k, y! H. dFAD3:AD F0 07 LDA $07F06 }# x" L; ~4 e8 V0 Z. E
FAD6:C9 01 CMP #$01
8 o4 A5 S7 |* w) LFAD8:D0 11 BNE $FAEB
# X: \+ J6 _/ H) @) b' l8 X& f- RFADA:AD F1 07 LDA $07F1
# }9 i# P% y% ZFADD:C9 04 CMP #$04
2 ^# B' x6 y6 h( s, wFADF:D0 04 BNE $FAE5& ], g+ U3 \# ~! K3 h6 f& o+ i
FAE1:A9 80 LDA #$80
) B5 C# w3 P% R* {2 oFAE3:D0 06 BNE $FAEB! l! C8 K+ c7 ^7 Y1 _6 ^
FAE5:C9 05 CMP #$05$ c1 y3 F' s# u+ c' f4 D0 W1 {, l7 x
FAE7:D0 02 BNE $FAEB x6 ]/ A* v5 x/ Q$ P* @" \2 X# k
FAE9:A9 82 LDA #$82
) w F! v2 W; u0 _# S0 N+ N6 ^FAEB:8D 01 80 STA $8001
; C) G& h* H7 p" [FAEE:A9 01 LDA #$01' o' k$ h* w2 \" |
FAF0:8D 00 80 STA $8000
; \( R! m; Y& A# g& _' A$ ^4 R9 bFAF3:AD F2 07 LDA $07F2/ z$ }& U5 k1 X, R, t6 v1 |6 o% P
FAF6:8D 01 80 STA $80011 T& }7 w( J) Y5 w. C X4 q' I
FAF9:A9 02 LDA #$02
% ^# V } I. f/ x$ NFAFB:8D 00 80 STA $8000% P6 T: x" D% B3 g( l( p$ @
FAFE:AD F4 07 LDA $07F4
& X6 B; V) m. X6 \7 C! V# M$ iFB01:8D 01 80 STA $8001% ?% l0 v* b4 d+ l [9 t8 J
FB04:A9 03 LDA #$03
( i2 \& } [ r. ?6 }/ SFB06:8D 00 80 STA $8000( u" x+ A' C' s
FB09:AD F5 07 LDA $07F54 z' g' s' N, m1 H+ Q1 g4 J
FB0C:8D 01 80 STA $8001( m0 H2 \" d4 ~
FB0F:A9 04 LDA #$04* S% O& I, \2 ^8 @
FB11:8D 00 80 STA $8000) _+ d" I0 i5 }5 f& H, ~. P) C4 u
FB14:AD F6 07 LDA $07F65 H% E- ^4 }: x0 J
FB17:8D 01 80 STA $80015 h7 z) g* _6 G" e$ s' Q$ b
FB1A:A9 05 LDA #$05
7 ]) W( K! g4 oFB1C:8D 00 80 STA $8000
: r* ~3 @, I# e3 z9 t1 }, cFB1F:AD F7 07 LDA $07F7
7 K' @! t8 x4 R" k+ OFB22:8D 01 80 STA $8001; n7 M- G$ K! W
FB25:A9 00 LDA #$00/ c1 w' J; X: @' X+ A& }$ ^. L
FB27:8D 00 A0 STA $A000. K2 T0 S5 a$ ?
FB2A:60 RTS
) W/ I# `1 I& H9 h$ J( P, o. V R6 R1 S/ e2 E, K
然后保存文件。! V' E; N8 ?: }. E
使用HXD修改文件头:
* B4 l/ O; B% d- f将Mapper 236 L: w( U4 Y( _# _6 Q) ]
06字节的高4位是Mapper号的低4位
1 B6 r# Q+ q5 }, x5 v3 r/ x6 d3 a07字节的高4位是Mapper号的高4位6 m4 D$ N5 e5 \# }# ^: I B
组合起来就是0x17=1*16+7=23
$ ^# \4 J& U: [ k & M2 m8 W" w$ V- h
修改成 Mapper 4
5 Q8 ~' { l9 y! A' L& ] o) F# S% T }. g$ ]
& Y% i2 |' {( f0 c! Y, }2 w
% e: [9 E" T4 g5 i" c
再次打开文件:
a; b" }2 }5 Z) A" s
@& K A0 h0 A$ r4 Q: N5 f可以正常运行, v; B# H& {; J! ^ |+ [% h
通过全面测试,发现出现精灵错乱:
7 t. }# P) E6 x2 n' c第1关:
" h7 m/ s! z7 M* y # l# n: j. Z# d' F7 V9 q
2 ~# s7 {: T, \! E, ^
第2关:
: g$ X Z: h# D( g A. a
' N+ X! p7 _- G( U( L# M K任务失败后:
" Z/ z2 ~. n2 S8 ] p& h. v
& P9 D/ u$ z; W* e, X, H通关后上飞机画面:
) N; h! R ^8 ~/ d" N " J$ U! m, @1 p8 D
这是为何呢?
, H9 l! x$ a$ H这是因为Mapper 23 中精灵VRAM切bank是一次切1KB
, L7 A1 T* P1 J) {* A但是在Mapper 4中精灵VRAM切换却是一次切2KB,而且忽略bank号的D0位
5 _9 `4 ?& [5 b9 E比方bank 0和bank 1是同一个bank,同理bank 2和bank 3是同一个bank
4 q) u9 H9 p% L- p也就是说
1 B9 ^) C/ Z' m/ PMapper 23中的VRAM的
5 G: J- ^0 K/ M- v3 G; P" k/ c+ Bbank 0,bank 1,bank 2,bank 3" d2 S, g0 D! s b. Y
在Mapper 4中对应的是
( `) u9 ?; t; l2 BBank 0,bank 0,bank 2, bank2
5 {2 K$ z& _, \然后查找原来的ROM的切VRAM的程序:
( E! Y6 o1 d; \* \知道是从07F0-07F3切到精灵VRAM的:
3 I- u7 H$ n6 k0 _& g2 K5 e如图所示:) P: f" g. ]- X
& Q4 {! d, M6 W! E* f F
 
4 B$ l& q& j& g+ l作为对比,左边是原版,右边是修改。& a* ^" P' n7 h" @ C4 {2 u
接下来是完善VRAM切换带来的问题,因为Mapper 4只能切2KB的bank,所以我们不能通过切bank程序解决问题。# A# u8 p- W! |. A% W
通过测试知道1,3,5,6,7,8关的精灵VRAM排序如下(07F0-07F3):
; _% U5 p% [) c" [, E01 04 06 074 x5 K# j6 Q6 k5 ?( L
第2,4关如下:
) p6 h/ Y+ X. G; d% ?2 R! e01 05 08 093 F; b4 t9 ?, d+ T% H; l/ ~
任务失败时如下:* |0 W3 U9 {$ `( _
32 00 00 1B
8 |9 e. v3 N; _( T0 \其中任务失败时对应的VRAM是07F3的1B,只要让07F2为1A或1B即可:, Y# C6 M5 g1 L0 G& p1 z
通过调试找到对07F2写入数据#$00时程序如下,于是修改C7E5的值为1A即可:% P' q5 ]& n& D ]" o( J
) @7 l: v5 R7 E, t2 m4 ~3 ^
转到ROM地址:. W$ ]4 U( _" f+ k

- D- D2 A1 _9 m, b: ^! |! d& j修改数据:8 o" ]3 F+ ~4 c( `, g
" Y1 B; J) G9 o C2 I
重新失败后可以看到修复成功:
* Y3 S* b; E& W: ^ 9 s2 ?0 D' P0 o; ~; F
接下来是修复正常进行任务时的精灵错乱问题。
+ [" d- n# w) Q: g首先运行Mapper 23版本,在1,3,5,6,7,8关任意一关的时候,将PPU导出来# }6 ^; P! q, Q0 I' ~, W

( D5 m" D6 l9 w* w1 J. _
) L$ ?) Y0 q6 E1 q: e% ? C* A- U6 G4 \3 L
) x, K1 C0 @) Y" |* k5 A" x d
然后用Hxd打开修改的Mapper 4的ROM和刚刚保存的PPU的数据文件:! ]. u5 h: G) l' Y

1 g+ B" |" N, q5 j在ROM文件头第05字节改为0x20:7 y. i" O+ H0 G+ f& O( x
3 b9 K8 L. V# c. K' P
然后转到文件末尾,插入0x20000字节空字节:
9 ?8 e# j) w! C3 D% Z/ R6 Z
' C- b0 h4 O w G( A
0 w) M8 l( \! }+ G ) A) h e' A A
2 x& V$ ~9 a6 P+ \% r( h, V
然后将第1关的PPU数据的前面2KB数据选定:( l; M$ e. C0 v2 G* S

! C( A4 s" W6 r
0 m P6 y: F' O/ ^* }9 ?9 _
8 _3 _# D( T( T' @0 n; j复制之后以覆盖方式粘贴到ROM的40010,同样把第2关的PPU数据的前面2KB以覆盖方式粘贴到ROM的40810
& H' k1 w' m# h
; H' o6 R' c' ]& G% N3 p然后保存文件:7 X+ g! B! V2 P! }0 Z
7 C) C3 ]* S8 X9 D) u6 t. ~; L' x5 M
最后用FCEUX打开文件,添加07F0-07F3的写入断点, B+ A- L/ }. g; g& N8 d# }

" t) N8 _7 w: a地图预览后即将进入第一关画面时程序暂停了,可以知道此时准备将C793的数据写到07F0:
' ]; b G$ u) ~8 q+ m, i5 Y
y4 S# X- p h* u9 Q测试后知道将C793-0796写入到了07F0-07F3:& f$ Q- h4 x6 ~, ]
同理,经测试每4个字节一组,一共17组,其中01 04对应普通关卡精灵以及其BOSS关的精灵VRAM的bank号,01 05对应2,4关卡精灵以及其BOSS关的精灵VRAM的bank号,再加上一个通关后跳上飞机那段动画的精灵VRAM的bank号。, I! a2 s% A7 X1 F5 b$ m, Q5 J
6 m4 O E; E* T( b) J3 a
6 b8 l2 C) g$ t6 |+ J然后将文件中标记的01 04修改为 80 04,将01 05 修改为82 04即可:$ ?4 J& M3 S5 W; p
& }3 Q& A+ [" @9 T
保存之后重新运行后效果如下:$ i* |* c' @) ^/ q5 {

$ B, c; M( i8 T3 z8 s - A; F* Z! Z) K) n) Q3 x6 b4 @

7 v, D* a# _. {" E( u当前使用的是FCEUX模拟器,如果用NEStopia玩的话一开始就死机了,这是因为这个ROM有文件保护吧,它会往$6000里写入数据:' Q, Y5 H: X& N% K
+ E% k4 f1 u# U
F863:A0 03 LDY #$03
0 p3 }( K; Z/ { g$ B5 oF865:98 TYA
3 U( v( I3 M5 f* FF866:29 01 AND #$01$ I1 A9 q) G9 y
F868:8D E9 07 STA $07E9
7 w% y4 H! Q% a6 RF86B:8D 00 60 STA $6000
4 q9 B `. O3 \$ q" n# G' uF86E:AD 00 60 LDA $60006 k$ W/ C) ^5 O) b% k5 I
F871:29 01 AND #$01
0 P/ V6 n- e9 @5 T/ o) i: qF873:CD E9 07 CMP $07E9
5 l8 L7 h4 P0 v8 G+ I! k+ sF876:D0 05 BNE $F87D
- j* s2 F+ O& H0 N. k; mF878:88 DEY" H8 v0 N# Y* R( T
F879:10 EA BPL $F865& [- p! b( |. d' ~& y
F87B:30 03 BMI $F8805 j/ N. D# \0 F1 i# v4 C
F87D:4C 00 00 JMP $0000% ~! w+ F; `9 m, V% g2 O$ _7 h
F880:A5 1A LDA $001A
* a/ x+ k' `& ^9 s" A; Y" qF882:65 34 ADC $0034+ O3 L* y. O' G/ s* f
F884:85 34 STA $0034
. ~5 r4 N! T1 G( a6 J1 V i* y: WF886:4C 80 F8 JMP $F880% t. @+ Z0 i* a4 ~ V
先取Y值=#$03) f( y: v- s+ @) L2 H
与#$01相与后得到#$016 y& N- k) l# V# p" y
写入到$07E9
8 F1 }6 Q) m1 i c- T7 o# e4 o! ~写入到$60009 h- v% W8 O$ f0 M; ?& W9 d) J) o
再读取$6000的数据和#$01相与后和$07E9的数据比较
- w' j9 s/ J3 n8 x- l! H+ h5 S不同的话跳过5字节+ J3 f. {& V8 r9 t4 e
否则Y递减
3 \) O, f% u0 \9 \( L为正数就跳回0x100-0xEA=16字节' A$ D7 ~# Z: a- ^& g/ H
为负数就跳过0x3字节# ]+ I. _1 Z' u9 O
跳转到$0000(简直没有人性了,跳到这里死机,真想得出来)0 B! J+ ~3 n: L0 Q7 m8 h
* B* o, M4 ]4 ~( f! A正是因为这样,NEStopia运行FC时,6000-7FFF默认是不可写的,必须在ROM文件头第6字节的D1位置1设置ROM有SRAM,对于Mapper 4,还需要向$A001写入#$80来启用SRAM。
: W7 z2 m/ a8 t1 X8 _0 J9 R3 [3 N由于$6000不可写,因此想$6000写入#$01后$6000还是#$00,之后读取$07E9的#$01与之相比当然不同了,于是直接跳转到死机程序了。" ^* S& U% Q: G( h# U/ x+ f; r
解决方法是把ROM中的所有的AD 00 60 29 01 CD E9 07 D0 05 88 10 EA 30 03 4C 00 00( f1 R3 o3 k9 x
中的D0 05改为D0 00,然后保存即可。* R9 V R# z$ t' b6 x
测试完美运行。4 `! o! e9 T# S% U# x/ V
! E* i: G" C' y/ @ t* I
8 c" J Z. t; O/ e& v
教程到此结束。
6 i* T: t" U' p- S* [$ }
/ T0 G% k; E3 u3 _8 `- m8 H |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|