|
本帖最后由 yandagui 于 2017-4-16 19:06 编辑
1 @" {4 D' i6 A& [: U/ q
2 ^; q' Q& [: h% m$ H eMapper23转Mapper4实例教程7 h0 j6 A9 B( P/ J5 y
7 [, p+ P4 e% |8 J# Y9 d
FlameCyclone 2017.4.14% H. Z) i! ~2 o9 V8 x
9 @5 y# r( B+ Y/ T先看看Mapper23文档:
/ A! C* O, O1 T% O: t6 M* u% U
# L8 Z2 g8 r$ }6 j/ C/ z2 QMapper 23! J4 \& M3 _2 P" K' n! }
; j8 O! u. e+ h ]& a/ e$8000: 选择8KB的ROM存储体映射到$8000
9 `: e: }+ L: R; U% h/ }0 R9 u0 f7 ]
$9000: 0:垂直镜像
$ r( P; O+ D' W% Y; l6 s4 K- | 1:水平镜像$ T9 s( S- L5 f8 N5 P
2:$2400镜像% q7 A" ~4 C3 i% o* v3 r- l; \
3:$2000镜像
3 a) O3 m( @$ n0 u, p3 Q/ G. r2 b, e" l6 a4 _3 p
$A000: 选择8KB的ROM存储体映射到$A000
% Z) ]5 o% W( F* | e0 O
' b2 m: d* j! M$B000: 选择1KB的VROM存储体映射到PPU的$0000(低4位)) T6 }2 j0 b8 Y5 m
$B001: 选择1KB的VROM存储体映射到PPU的$0000(高4位)! C$ T. v1 V; ]9 G* K
$B002: 选择1KB的VROM存储体映射到PPU的$0400(低4位)
O" h* |" \1 d3 R0 v& E. r$B003: 选择1KB的VROM存储体映射到PPU的$0400(高4位)7 m0 U# M+ ]; U* @/ X O, Q
# c, x# s1 z! r; K& @9 l
$C000: 选择1KB的VROM存储体映射到PPU的$0800(低4位)9 d8 u5 p$ t9 m) P& D* |! I$ Q
$C001: 选择1KB的VROM存储体映射到PPU的$0800(高4位)
7 e' p# I; O1 z$C002: 选择1KB的VROM存储体映射到PPU的$0C00(低4位): ?# q. e% t# u; V' C" S# G2 B
$C003: 选择1KB的VROM存储体映射到PPU的$0C00(高4位)0 e& K: p$ i0 x, T
7 t9 E5 T& e- d' m# L. ?0 L$D000: 选择1KB的VROM存储体映射到PPU的$1000(低4位)
/ b: x9 m' y0 u$D001: 选择1KB的VROM存储体映射到PPU的$1000(高4位)& a3 j3 r8 _' I+ v% i6 d
$D002: 选择1KB的VROM存储体映射到PPU的$1400(低4位)
' W7 B4 D& L4 Z) @, E% }0 B8 K$D003: 选择1KB的VROM存储体映射到PPU的$1400(高4位)
( D! g6 {+ l# _1 d1 C9 T
9 q( r: `' W c- d6 ^$E000: 选择1KB的VROM存储体映射到PPU的$1800(低4位)( N X" Z( F& R+ }: u- z
$E001: 选择1KB的VROM存储体映射到PPU的$1800(高4位)
& T6 H9 p6 m5 e ?$E002: 选择1KB的VROM存储体映射到PPU的$1C00(低4位)
% H8 B3 z v) ^$E003: 选择1KB的VROM存储体映射到PPU的$1C00(高4位)9 X9 |8 Y+ N) Y3 s) M2 o
6 _0 f' o+ h5 d/ |) a9 L
再看看Mapper 4文档:
1 x/ Q3 {$ a1 ~% Q+ z" h6 i4 x
: W9 u* t/ h7 U- G7 A: pMapper 4) U/ [8 M* N. T
9 w3 F5 p% _) T$8000: 模式号* w$ j) w- W: z: _
位D0-D2:1 D% ?, D! l+ l; N3 a0 j
0:选择2KB的VROM存储体映射到PPU的$0000
& x0 M. N9 @+ Y) n5 n5 `# ]+ R 1:选择2KB的VROM存储体映射到PPU的$0800
! Y- w3 `% @5 m( C @- t 2:选择1KB的VROM存储体映射到PPU的$1000% w; v' N$ \- @9 f
3:选择1KB的VROM存储体映射到PPU的$1400. n8 l' n. w% Q6 S
4:选择1KB的VROM存储体映射到PPU的$1800
* B$ J0 I+ j1 {* s6 V 5:选择1KB的VROM存储体映射到PPU的$1C00
8 s; u* a0 \! B; Z+ a7 ], y# F 6:选择8KB的ROM存储体映射到$8000
6 |/ c) R V: x5 m 7:选择8KB的ROM存储体映射到$A0001 Z' `! L& v- _ m; ]; V- ]% s2 ]
位D6:+ n3 ^: v5 ^1 K4 n- T4 r% o( s
0:允许擦写$8000和$A0008 V8 @6 Z( V5 \
1:允许擦写$A000和$C0002 G Q4 ~+ d+ X+ _/ L
位D7:
! a) k0 F0 Q( g& ? 0:模式号D0-D2使用普通地址
* y |5 p& _! [1 K 1:模式号D0-D2地址异或$1000
4 o6 l3 a6 h3 N+ A; _
; B" t- A4 f5 b. g( Q' G$8001: 模式页面号5 Y6 F+ o6 e1 o8 T1 T
写入一个数(00-07),切换存储体到对应地址* U1 p! z! d* j( }9 N
& ?; X' B& \; a2 w: [9 _1 ?6 U; e$A000: 镜像选择) a+ l* q" W. B: e0 F+ `* b
0:垂直镜像7 I4 f+ J% G' O, d7 x5 q/ d3 g
1:水平镜像1 \- t6 U% W5 R- K7 a# Y
9 R- i: U& k( R0 Q' M$A001: SaveRAM 切换3 m( r [' |5 K7 Z* {3 q
0:禁用$6000-$7FFF
0 c: S4 c5 u1 j3 d, ]+ b 1:启用$6000-$7FFF* W9 W5 ?/ x, W# y! G
* `- L9 m/ D! Y: p8 F3 C2 D5 c$C000: IRQ计数器
1 Z; ^7 P* j! x( {1 t IRQ计数器的值存储在此处6 V4 w& g# O; Z' h% u
) I8 h: ? F {* f# l$ Q
$C001: IRQ暂存器* G0 O( c6 p6 ], t9 C( U+ Y
IRQ暂存器的值存储在此处
2 W* k* U" k% K! P( i& y0 r l6 H2 [7 ]/ y5 J, S$ J1 O
$E000: IRQ控制计数器0: Y" W( O" v1 |" K% M2 c
向这里写入任何数来关闭IRQ,并从暂存器中拷贝数据开始计数,进入IRQ
3 x# l0 w/ L: W* o9 y3 ^/ `) E# K) l% z5 c
$E001: IRQ控制计数器1. I- }4 W# g/ Q/ C& A( d
向这里写入任何数,允许IRQ(退出IRQ,允许下一个IRQ进来)$ U1 O+ B8 ?0 v0 a! E
x& A8 z$ R; L
) n1 s8 i s1 i; C" I) s: [
转换思路:1 T, n C9 @8 Z+ d5 J& M
将Mapper 23 的切bank 方式和切VRAM的方式修改成Mapper 4 的方式。+ J7 |- d5 i- O' V0 H
+ U, K/ n4 u5 i( x0 n9 P7 r3 d修改实例:6 I, Z- l o" a
Contra (J) 256KB Mapper 23: u b) n7 z: T/ s
工具:
* l$ s+ r0 M5 F4 Z9 M* Y7 W1.FCEUX 2。2。3' u7 J' A# A, K: M. [/ p' X6 B
2.HXD0 u" O5 l% [+ M& K
先来看看这ROM的切bank方式:+ R& f! g4 S$ ?/ x: n3 D
F989:AD 00 80 LDA $8000 : p) T1 v& ]0 e4 ^" V
F98C:8D EC 07 STA $07EC* ?! p6 ~: T5 h# f/ a7 i4 ~
F98F:8C 00 80 STY $8000
- P' F- X+ R; d* Q, n4 g O+ f% IF992:C8 INY
3 q9 d0 I# u* K" N) tF993:8C 00 A0 STY $A000
: E! e: ^ N! DF996:60 RTS2 @# _ Q8 I7 _ N6 V1 S% F
: K7 K. ~+ ^5 x/ O
再看看它的切VRAM方式:! S- W9 s% `* u2 L; N3 V# w
FACE:AD F0 07 LDA $07F0+ b3 {# m7 q! ]+ w8 R- k8 w3 \5 {
FAD1:8D 00 B0 STA $B000
% T% @4 S5 `% W2 X. h( GFAD4:4A LSR
3 G2 ?' z1 U# e6 o: g& }7 r1 [FAD5:4A LSR
( }( L0 f+ K1 xFAD6:4A LSR
5 [/ k3 E1 e, K" cFAD7:4A LSR5 D* i/ Q3 S+ [0 H" V
FAD8:8D 01 B0 STA $B001. G- u9 N( l1 S) a6 {2 m! s
FADB:AD F1 07 LDA $07F1
* z4 X) Y: K8 h$ A2 {# s" fFADE:8D 02 B0 STA $B002
) [% k% ?* j* C- Z$ SFAE1:4A LSR
1 o1 f0 X" i; vFAE2:4A LSR' c+ n6 y! M p8 J
FAE3:4A LSR
7 p/ f+ R/ b" u( w) D1 U& K5 yFAE4:4A LSR
0 r. x* `* ^3 H. u/ ^( G, U. p8 p4 T: }FAE5:8D 03 B0 STA $B003
- B! C2 w9 h- Q6 d2 [' A2 RFAE8:AD F2 07 LDA $07F2
# n' `6 T" c4 LFAEB:8D 00 C0 STA $C0001 a" V5 l' ~; o- I
FAEE:4A LSR
6 }) |6 k4 I- `) M7 {FAEF:4A LSR% D5 S! O( N Y4 N1 B" A
FAF0:4A LSR
: E8 Z* s h' q9 e: O" f8 T& zFAF1:4A LSR, l+ _$ h! D+ \6 O9 _" b8 M0 _# ~% w
FAF2:8D 01 C0 STA $C001% D* v# c. |# X$ b) h" L
FAF5:AD F3 07 LDA $07F3. m, C0 Q+ \% |, v. ~0 R+ ?
FAF8:8D 02 C0 STA $C002
+ w3 A, ?; k: U' z+ mFAFB:4A LSR
# t) m9 x5 K0 K- CFAFC:4A LSR
: q* M$ d& m4 v# LFAFD:4A LSR: l1 d' o8 S' ^" \, ~1 c2 U- G
FAFE:4A LSR9 J, m& i$ b5 P1 M' ?. b
FAFF:8D 03 C0 STA $C003
2 [7 x; F" A: P" ~FB02:AD F4 07 LDA $07F41 E! L( x/ H; y; \3 G
FB05:8D 00 D0 STA $D000* m0 i+ B5 n* x
FB08:4A LSR6 Y5 Q& b+ o, i1 R8 v
FB09:4A LSR
. r1 i7 e2 j7 tFB0A:4A LSR+ h* o" W! G* F! C" e, v4 {. H
FB0B:4A LSR
" S4 }% |1 _' Z7 V/ m" nFB0C:8D 01 D0 STA $D001
( x9 O- g( U: o! y' j4 L9 s7 }FB0F:AD F5 07 LDA $07F5
3 e' I& Y5 w7 P5 p' c mFB12:8D 02 D0 STA $D002
, H6 `8 i8 [& P7 rFB15:4A LSR
; R+ b) z7 S1 x4 C" L) FFB16:4A LSR
' E6 T2 Y- m8 d/ p) o. eFB17:4A LSR
" f- I. ~$ W. N/ p# W" z) W7 k6 SFB18:4A LSR
* c9 B1 {/ s) }7 p7 {) |5 jFB19:8D 03 D0 STA $D003$ \2 t% z1 t1 k4 l8 n
FB1C:AD F6 07 LDA $07F6
! b& B7 `" Q& P( _& d+ Z7 Z& fFB1F:8D 00 E0 STA $E000 D4 D, a% I' E# R. l
FB22:4A LSR8 V; V- ^7 M5 U# q$ [
FB23:4A LSR
1 j# ]/ b9 T: Y% v+ k; k, hFB24:4A LSR% q4 c4 [) B9 p9 M5 v
FB25:4A LSR
; k" l' x- z2 e# o# h2 E- \+ \FB26:8D 01 E0 STA $E001+ ~8 x) j2 S2 ?# E! [
FB29:AD F7 07 LDA $07F7* m& ~; c8 X) \8 S- B+ q+ A4 u
FB2C:8D 02 E0 STA $E002
2 C. l& D5 s& E8 b5 ~. P. X. s, TFB2F:4A LSR
. b) m! D B: `$ m2 ~) u% QFB30:4A LSR1 o$ Z3 X0 U& u V/ r) x# W
FB31:4A LSR
4 K" p) C; @3 m! n8 WFB32:4A LSR
6 A) Q+ Q2 j7 H/ C, L, |# Y, n5 hFB33:8D 03 E0 STA $E0038 r2 L0 T p' a9 ]
FB36:A9 00 LDA #$00
: w9 B o; v& r0 P; b% f+ g5 _4 tFB38:8D 00 90 STA $9000
8 F6 V3 o# S9 r! Q+ w6 \FB3B:60 RTS
4 J7 C Q' c2 b) F$ f0 h- _% c+ X" G% [% E
接下来修改切bank方式:
1 O1 z a" d$ i" z7 ~2 @- ?" x8 SFB2B:48 PHA
% ]2 v* ?8 q) i4 dFB2C:A9 06 LDA #$06. p2 B/ U; o m6 H
FB2E:8D 00 80 STA $8000
# C# y. G' a- n |3 M4 W4 FFB31:68 PLA0 e8 L0 u# Y8 z3 ~) O# x& m# I, F
FB32:8C 01 80 STY $8001
6 i- }& y" e! KFB35:60 RTS
/ j# P9 J/ F4 T. g5 X
, e7 _: u2 ^# q7 |! NFB36:48 PHA3 m( S1 t. g6 {. ~
FB37:A9 07 LDA #$07
2 a& A3 X: l$ }8 u3 g' ^0 qFB39:8D 00 80 STA $8000 = #$14
% k/ ]- M; |( UFB3C:68 PLA
+ y+ Z. @# q- f5 nFB3D:8C 01 80 STY $8001 = #$1D3 y5 M, F" V) n% @
FB40:60 RTS
0 B" U5 B8 F2 g2 y
# s) E2 w: Y4 [6 S, l" [1 {' n' g! S5 c还要把原ROM的对$8000和$A000进行写入操作的程序修改一下:6 l/ O5 _- r( m
F989:AD 00 80 LDA $8000 ! v1 ^8 V% R& Y; F
F98C:8D EC 07 STA $07EC
& w5 P1 `' l3 U3 j; {6 T9 ^F98F:20 2B FB JSR $FB2B; L( o& a4 u; H' r
F992:C8 INY! V5 r- F6 G/ @2 g' L g
F993:20 36 FB JSR FB361 J# c9 O! d2 Y0 M' p
F996:60 RTS; y6 {" n% A( |" l* {2 K
! {/ O# ]3 e# ]5 F9 X
再修改切VRAM程序:& M4 k+ P6 j* G+ x
FACE:A9 00 LDA #$00
1 L2 g9 U3 S# ~+ F8 C- I9 o: WFAD0:8D 00 80 STA $8000% E, c! D: q7 J, ^
FAD3:AD F0 07 LDA $07F08 ?4 Y; \1 R) i- W6 \& K
FAD6:C9 01 CMP #$01+ t3 C" w, P- B; ?# q
FAD8:D0 11 BNE $FAEB6 |) Z- }% ]+ v1 b9 V7 i& G
FADA:AD F1 07 LDA $07F1
+ n! r; s4 c" `. F2 E7 aFADD:C9 04 CMP #$04
2 R1 C3 u& w. [0 C( p( wFADF:D0 04 BNE $FAE55 Q& Z: h5 ~/ f* G3 ~$ G
FAE1:A9 80 LDA #$80
0 m( G. A% M! Y3 W9 _" S! K+ W- {FAE3:D0 06 BNE $FAEB6 F8 g; m7 N% l% b6 t
FAE5:C9 05 CMP #$05
% W0 ^1 [- q6 ZFAE7:D0 02 BNE $FAEB3 A/ F- |9 i5 L2 J
FAE9:A9 82 LDA #$822 P5 x0 I4 A3 b& o
FAEB:8D 01 80 STA $8001( T* h, s8 C% F) [ Q
FAEE:A9 01 LDA #$01$ }) X# ]- y/ J: i+ ^% \
FAF0:8D 00 80 STA $8000
$ w, ^; D1 z* \2 HFAF3:AD F2 07 LDA $07F2
3 w# E7 e7 U5 Z5 \: ZFAF6:8D 01 80 STA $8001
# M P+ V- y& G& I9 v, yFAF9:A9 02 LDA #$02
; f. k* g9 m5 p( V5 GFAFB:8D 00 80 STA $8000
' x) g. f1 A, `2 t3 @FAFE:AD F4 07 LDA $07F4
, U6 L5 |) C% `$ uFB01:8D 01 80 STA $8001+ y3 L2 B. r. B2 d2 x
FB04:A9 03 LDA #$031 ] s# ^/ I# f- E% k# x* T8 Z% {
FB06:8D 00 80 STA $8000$ r3 O0 n8 q* C$ R8 G
FB09:AD F5 07 LDA $07F5
: [) p8 F# Q* t) d0 o/ N# dFB0C:8D 01 80 STA $80017 f4 [$ G% j' Y/ T; {9 K
FB0F:A9 04 LDA #$04
" w, h' Z) E4 D" B7 tFB11:8D 00 80 STA $8000
! C) C, ^$ S6 ~FB14:AD F6 07 LDA $07F6, @& A7 Q+ Q8 K) Z% t( Z
FB17:8D 01 80 STA $8001/ e3 n1 u5 Q4 d. K' G" b) q
FB1A:A9 05 LDA #$05( B: `7 V0 U+ w% U
FB1C:8D 00 80 STA $8000- N$ K% n$ q9 a4 R0 N
FB1F:AD F7 07 LDA $07F7
& s& e; u: `3 |) `8 iFB22:8D 01 80 STA $8001& T) o* H" J) M
FB25:A9 00 LDA #$00( @; A7 y# \- }/ D
FB27:8D 00 A0 STA $A0007 d- t3 E2 j* b. H0 R
FB2A:60 RTS
5 ~+ ~4 D/ Q& i$ j& c5 c* W/ s3 m6 Z
然后保存文件。) W1 d0 i( z; y4 r2 ~
使用HXD修改文件头:
) x% C7 k8 U1 O& X0 a将Mapper 23: p* [; m" c1 k6 d
06字节的高4位是Mapper号的低4位0 p2 F4 S+ ~3 O& B1 H1 \( r
07字节的高4位是Mapper号的高4位7 {; `4 b- i2 n5 V5 r% f3 X. s/ S; ?& p
组合起来就是0x17=1*16+7=23- J$ ^) U/ v6 G5 \

& i0 f4 B& w+ o$ F3 d+ H修改成 Mapper 4
% K3 i7 m* [* p: ^9 |! g4 K . u* y: P" [4 o7 e2 z; j" x
7 e2 V1 n' y6 n( |
' A6 Y% i( z% R3 [8 \
再次打开文件:
: O2 L- Q& V* U$ U+ o
+ R4 W' v* ]1 k2 S; c% }可以正常运行
0 m- u: b# T7 ~ Z0 ?通过全面测试,发现出现精灵错乱:
2 f' U6 u9 j1 q# }( k9 ]第1关:# k& p6 b, i, ?! r7 _4 B- ~( Z5 g
5 P4 I9 k! T! n, q" P K
B$ U* o9 J- l( z+ R
第2关:
/ _: G+ t" K& K) ?8 C, |
! W$ T' d/ U4 M7 C" U" i1 A任务失败后:
) P, W) s" I. ?$ E4 E$ ^ , [" v& i; u; Y0 K5 s
通关后上飞机画面:- _# F/ a# p3 X9 h6 S) i3 ]0 @
' G+ g* ^3 w- P/ w0 r! ]* U6 u
这是为何呢?
6 v8 Q4 u! Z. p5 x9 J# @这是因为Mapper 23 中精灵VRAM切bank是一次切1KB
$ U9 G+ }' [& f. u. u但是在Mapper 4中精灵VRAM切换却是一次切2KB,而且忽略bank号的D0位
& |5 C a- Z! V1 I6 e比方bank 0和bank 1是同一个bank,同理bank 2和bank 3是同一个bank/ i; e) S J; V! z6 [2 `- I
也就是说
9 O3 ^3 p/ J& I1 jMapper 23中的VRAM的 E2 Z7 Q4 \- u$ s8 a
bank 0,bank 1,bank 2,bank 3
* U8 h. a! y% ~' n在Mapper 4中对应的是
! ?7 P1 [, c K0 Y7 ?# H+ i3 jBank 0,bank 0,bank 2, bank2
4 w3 x s( y$ J- U, F; t- x" F然后查找原来的ROM的切VRAM的程序:- H' z& {, Y; M O
知道是从07F0-07F3切到精灵VRAM的:1 W5 S9 E% y# F+ b( B n
如图所示:
' r8 z3 ~5 s! s( B# V7 g0 U
2 x9 [/ f( `0 V/ I0 f ' q; m% {& X! ] ~: c" \
作为对比,左边是原版,右边是修改。: ]$ b7 }' M3 P3 b" X3 `
接下来是完善VRAM切换带来的问题,因为Mapper 4只能切2KB的bank,所以我们不能通过切bank程序解决问题。4 a( V4 H6 A7 O% t
通过测试知道1,3,5,6,7,8关的精灵VRAM排序如下(07F0-07F3):
* h! R3 m( j& [: ?01 04 06 07, H1 J. D& H9 p& ^) ^5 r
第2,4关如下:6 H9 t3 [: ~" j
01 05 08 094 ]$ }' v9 {+ o- {2 O+ s) r
任务失败时如下:$ x% Z" i/ C- ` w
32 00 00 1B1 @& W M" U- S& g2 o- W
其中任务失败时对应的VRAM是07F3的1B,只要让07F2为1A或1B即可:) T3 Z2 E9 P; H3 ^2 U& g8 t) T" u! K4 g
通过调试找到对07F2写入数据#$00时程序如下,于是修改C7E5的值为1A即可:7 ~2 E* z7 {0 f; |8 }

7 A8 U; K' ~+ f$ U转到ROM地址:
0 N+ I' N0 L1 g7 r0 k; X$ i4 U % f8 Q$ A- r- s" o
修改数据:
) K* A: R9 g8 S% ]1 Y% w ; H- b' |) l6 b' i
重新失败后可以看到修复成功:
3 }# ~& A! i0 a! ^
& ?: g+ f% ?/ L接下来是修复正常进行任务时的精灵错乱问题。+ t# N _* j4 d9 a9 n9 }3 b- `
首先运行Mapper 23版本,在1,3,5,6,7,8关任意一关的时候,将PPU导出来* S1 f5 _" Q$ B5 x" W

0 D) n+ [( ]5 g
! o/ E- O o4 `9 Y
y4 G1 o, ? \4 d1 M0 q/ N6 V" P
1 b$ {* }' f) j, k然后用Hxd打开修改的Mapper 4的ROM和刚刚保存的PPU的数据文件:
, C$ |' u* q7 d, ?3 R
8 g- M. n+ `+ _/ x8 b; \" M, }. p& e在ROM文件头第05字节改为0x20:2 q6 A2 S* V! t0 w f

6 N% ?, e' N: s8 X然后转到文件末尾,插入0x20000字节空字节:
9 M# h6 Z3 g9 e* f4 [9 c - k7 L- V( q$ V
0 s) T* D! V: o1 H
' \2 e9 b$ A- D- m% K4 T
3 D7 G. _5 y% C* K x+ z! I5 T
然后将第1关的PPU数据的前面2KB数据选定:* X1 G2 O# n, K7 [* v
8 Q- ~) j' r6 v$ w, S6 y# ]
3 [' } U- Q2 r. z+ B

. d8 c. {8 r+ y# x* Z复制之后以覆盖方式粘贴到ROM的40010,同样把第2关的PPU数据的前面2KB以覆盖方式粘贴到ROM的40810
6 ]2 K. H! T f: P9 H
! N# s f% B9 f |2 i然后保存文件:7 z0 ~; p' ^- I) A! [+ q
4 K* b4 J. {) t4 {
最后用FCEUX打开文件,添加07F0-07F3的写入断点* h' S* A) l8 s4 `' e: B/ e! W

( C( P" o$ S3 F" w. k0 e地图预览后即将进入第一关画面时程序暂停了,可以知道此时准备将C793的数据写到07F0:
' T' |3 \* V0 ~9 H% C ( ]' i. J+ H$ R# h1 x# |7 O, V4 `
测试后知道将C793-0796写入到了07F0-07F3:
9 ^6 j) l& m0 r J+ I1 X- |" `7 N同理,经测试每4个字节一组,一共17组,其中01 04对应普通关卡精灵以及其BOSS关的精灵VRAM的bank号,01 05对应2,4关卡精灵以及其BOSS关的精灵VRAM的bank号,再加上一个通关后跳上飞机那段动画的精灵VRAM的bank号。- u2 ]; |- |% G4 G% ^2 P
2 V; U' J: p" x

& ^) L3 c* j' M3 {. s" e* M然后将文件中标记的01 04修改为 80 04,将01 05 修改为82 04即可:: Z; k& i) E2 Z% E# z# y

" _1 d$ G8 n( M L保存之后重新运行后效果如下:
' P+ t; g- O; T7 q& w8 g0 w
/ y3 Q d0 o- Q, j4 F. Y , l U: W, V+ K

: T% {' q* N$ ^: ?当前使用的是FCEUX模拟器,如果用NEStopia玩的话一开始就死机了,这是因为这个ROM有文件保护吧,它会往$6000里写入数据:% L2 J3 C# i" T" F3 ~4 z

D- R) O7 s0 o1 HF863:A0 03 LDY #$03$ c* X8 @! g4 r7 o5 B) J: C
F865:98 TYA' |# c- ] T1 f, h) s6 A
F866:29 01 AND #$01
$ i5 q% O5 S% ^1 W; }5 K! b" sF868:8D E9 07 STA $07E9 Y0 J2 P5 i( c f7 P- A
F86B:8D 00 60 STA $6000, s Y' x+ n$ E
F86E:AD 00 60 LDA $6000
( `( C% z% U. Q- m% t9 U7 lF871:29 01 AND #$01
0 Q) G6 n0 k; _9 MF873:CD E9 07 CMP $07E9
, w0 m" B, ^$ j p6 `# VF876:D0 05 BNE $F87D, G. G! m0 K1 H3 K6 M& Y
F878:88 DEY) A+ W5 E& v/ a9 f% n
F879:10 EA BPL $F865
* b. W; F# y# P. y7 `F87B:30 03 BMI $F880* n8 p8 i* O7 ~: ?/ A
F87D:4C 00 00 JMP $0000
" R9 k; j; i4 V. c' H% q( { `F880:A5 1A LDA $001A# W! W2 E+ ` d- v
F882:65 34 ADC $0034
7 i2 @! k0 S% J0 I( y% P$ h: yF884:85 34 STA $0034
, I! }/ {0 d" `/ P9 mF886:4C 80 F8 JMP $F880
- Y$ `/ ?, d" Y9 ~. c先取Y值=#$033 u/ R# [ ^( s( m% i) c
与#$01相与后得到#$01& z3 x, {( \. P
写入到$07E9
- B4 G U9 B. q6 j! |& `# y) P( I写入到$6000
8 M6 q* a4 N) F4 U1 K8 L9 |, ^$ ~再读取$6000的数据和#$01相与后和$07E9的数据比较
7 W/ u9 Y- P2 _" W0 b2 X/ T; R! r不同的话跳过5字节, }" M0 ]4 S$ i8 ?- K3 n" R
否则Y递减4 J! d; q. h( ^5 L$ W s% ^& T9 ^
为正数就跳回0x100-0xEA=16字节4 k9 d4 U0 H0 Z: y3 b% i2 a
为负数就跳过0x3字节3 {6 l2 N" S0 O; s5 B, ^
跳转到$0000(简直没有人性了,跳到这里死机,真想得出来)
& \+ A0 T& i2 B! O# E: w6 M6 D( \# b
正是因为这样,NEStopia运行FC时,6000-7FFF默认是不可写的,必须在ROM文件头第6字节的D1位置1设置ROM有SRAM,对于Mapper 4,还需要向$A001写入#$80来启用SRAM。1 Z# K4 Q( R- d( o9 N& b
由于$6000不可写,因此想$6000写入#$01后$6000还是#$00,之后读取$07E9的#$01与之相比当然不同了,于是直接跳转到死机程序了。
8 ?- \5 [1 r8 K3 b$ q2 m7 a1 ^ d解决方法是把ROM中的所有的AD 00 60 29 01 CD E9 07 D0 05 88 10 EA 30 03 4C 00 00
q1 S7 b# q7 k" n$ k3 C/ f中的D0 05改为D0 00,然后保存即可。
5 b! I& V" x* {! `9 n测试完美运行。' ~$ ?2 q# K7 @: c, P/ K5 P

1 S/ n/ J- u1 m$ y& j' S1 G0 T* |; c+ K1 j( A4 t
教程到此结束。% B+ ^- X5 x1 [& t. G% f9 B
9 e9 q0 ^, G, Q2 r& K9 a. ^
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|