|
本帖最后由 yandagui 于 2017-4-16 19:06 编辑 * ^: `% {5 L9 h6 f$ r# x8 p7 z
4 W s- I7 {$ d) }) E/ ^Mapper23转Mapper4实例教程
n, G/ \) x" ^" g6 c" C- U7 x3 f2 V3 M( n1 [# `$ C
FlameCyclone 2017.4.144 U! n. H! G8 I( N& s6 ]/ C
1 x' i% A- L- N
先看看Mapper23文档:6 I" m: I' D1 ?- t4 S
, e( N2 M5 Q. i( e" r
Mapper 23
2 X1 h; v1 J; Q$ H8 z! P4 V8 y& E+ R- q$ J# h/ S
$8000: 选择8KB的ROM存储体映射到$80008 \9 f1 d, C" f% B* z; j
) Q$ K9 \4 _( i5 B1 E* K2 O0 M3 I
$9000: 0:垂直镜像
7 r3 a; I' e1 `/ T' B 1:水平镜像8 |. ^ |# v6 _" s8 ~. n( I3 s5 d
2:$2400镜像
Y! ]/ @- l; u& y: g* {& f 3:$2000镜像
9 F2 N3 i1 h: b9 ]1 B& S
" P+ F" s' I# r, W$ `7 `, E4 a1 v$A000: 选择8KB的ROM存储体映射到$A000
" G: k6 x, _3 `' n# |, j$ n5 }, E1 o' P# u1 t8 d7 D l
$B000: 选择1KB的VROM存储体映射到PPU的$0000(低4位)
$ Q0 F" |' j# K- `$B001: 选择1KB的VROM存储体映射到PPU的$0000(高4位)' ?; M7 u+ b5 h" d4 {; ]4 \
$B002: 选择1KB的VROM存储体映射到PPU的$0400(低4位)
4 H/ C. ~: Y1 N" L$B003: 选择1KB的VROM存储体映射到PPU的$0400(高4位). w& b, V# ^! ^3 L3 n
/ O5 T3 P- O; U- K, d% a
$C000: 选择1KB的VROM存储体映射到PPU的$0800(低4位)
4 R1 _: T+ q2 f1 d$C001: 选择1KB的VROM存储体映射到PPU的$0800(高4位)
; Y$ }7 R" D& ~. }- v- o) H1 }$C002: 选择1KB的VROM存储体映射到PPU的$0C00(低4位)
4 ?2 X) w: F$ v' n! Q W0 a$C003: 选择1KB的VROM存储体映射到PPU的$0C00(高4位)# x5 n4 g! K. h% ~
: B" C. M+ d( @2 r6 g5 A2 d( ]: E
$D000: 选择1KB的VROM存储体映射到PPU的$1000(低4位)
6 L8 m! D+ ?) u, V$D001: 选择1KB的VROM存储体映射到PPU的$1000(高4位)
' X# w6 b) E6 a3 k0 a$D002: 选择1KB的VROM存储体映射到PPU的$1400(低4位)! N: v0 A, t' h; g1 X+ I/ m
$D003: 选择1KB的VROM存储体映射到PPU的$1400(高4位), B# [0 t, H, b3 d0 ^4 d
4 `3 c" {- S! C* p( y2 _- Q$E000: 选择1KB的VROM存储体映射到PPU的$1800(低4位)
k2 K0 L' a+ {7 K9 n+ q$E001: 选择1KB的VROM存储体映射到PPU的$1800(高4位)
% Y$ F, U5 G4 y+ O' o# U$E002: 选择1KB的VROM存储体映射到PPU的$1C00(低4位)
( s: g& A: C1 }* ~1 g! e6 j$E003: 选择1KB的VROM存储体映射到PPU的$1C00(高4位)
7 r" A/ D+ @! n0 d' K1 s
; q5 E9 Z0 L* E5 u, P$ \8 A再看看Mapper 4文档:& L! ^" h, F+ n5 }$ [7 @, V
- n/ K1 @, H4 d: n
Mapper 4
/ w/ R5 {. M1 n9 {3 j5 J+ Y$ J9 h+ X! J( K' Q: n! G% r; v
$8000: 模式号
: x- x) U8 Y9 c( w3 P$ ?, i" Y 位D0-D2:
Q7 y! w, n- V. V 0:选择2KB的VROM存储体映射到PPU的$0000
( o5 }0 ]0 m# @3 g2 A; u7 N! y 1:选择2KB的VROM存储体映射到PPU的$0800
/ M! y8 e: B2 n; B, F 2:选择1KB的VROM存储体映射到PPU的$1000' c/ z2 Q& R6 ]8 m1 m
3:选择1KB的VROM存储体映射到PPU的$14009 n( w1 W h+ O, k1 t5 Y& M" x
4:选择1KB的VROM存储体映射到PPU的$1800- r' V. R% V( H8 [, c# k a+ V2 |
5:选择1KB的VROM存储体映射到PPU的$1C00( o. S8 ?" ?% I e
6:选择8KB的ROM存储体映射到$8000
) y+ A; ]& I7 e( Z. A 7:选择8KB的ROM存储体映射到$A0008 M' W& s4 y K
位D6:
' H7 r4 W7 G% b: Z# W7 b/ h5 k5 ? 0:允许擦写$8000和$A000
; Z' f! G* H# u. ~9 R 1:允许擦写$A000和$C0005 M! o7 E! Z' s! e) c
位D7:4 N2 j: P( o+ I
0:模式号D0-D2使用普通地址$ u4 y& T' X& R! r
1:模式号D0-D2地址异或$1000" X$ O; Y3 G4 h/ B
( f6 e8 u3 X5 y: ^2 }$8001: 模式页面号
( Q% Z8 h$ b7 ?( L# V8 d9 x 写入一个数(00-07),切换存储体到对应地址+ k5 o2 x* r' E8 D9 \ v
S$ k; b7 q$ l& |- E$A000: 镜像选择
1 Y" U3 c) U I 0:垂直镜像6 ^0 r! m& s4 I0 _& ]6 b3 A* I
1:水平镜像
0 m& A" c/ `! O5 z7 Z1 C3 @1 L1 C7 f. P7 o
$A001: SaveRAM 切换
. p+ g, y& y% j X8 C% D4 l$ n 0:禁用$6000-$7FFF
) [2 z A/ u; p. e8 a( i 1:启用$6000-$7FFF
! b# ]9 {4 M4 {5 E/ N
8 D x( g$ B! z$C000: IRQ计数器 m/ Z% c% O$ v9 e+ g
IRQ计数器的值存储在此处- t7 B# l* x/ Z! x8 i! G2 p
- E" h+ c( W& b( A; Z# b+ L7 f1 Q) d
$C001: IRQ暂存器. }7 w; a O* h% X, Q L
IRQ暂存器的值存储在此处) C' b2 M# J8 u7 T+ G
. s9 W% |, O' |0 {8 N2 R4 A
$E000: IRQ控制计数器09 ]8 v N9 w, o/ T) Y Z) C( {0 _
向这里写入任何数来关闭IRQ,并从暂存器中拷贝数据开始计数,进入IRQ3 ~4 |2 U9 [$ u# B/ N- S
]: Q' O9 R5 }4 A9 O: b$E001: IRQ控制计数器11 A( r. m. v! f8 u. |
向这里写入任何数,允许IRQ(退出IRQ,允许下一个IRQ进来)
3 R U+ a/ g/ [9 \! Y( f: e4 n T# e4 }. }1 N# l# T1 C2 Q
2 C$ b" a# M' `5 o2 I5 T转换思路:! j1 u# a+ K5 E8 M8 I2 y
将Mapper 23 的切bank 方式和切VRAM的方式修改成Mapper 4 的方式。2 M( b) k6 h1 J N8 W
* }+ G5 ]- ~% w( q9 r
修改实例:% C. _4 T/ P' v, ]
Contra (J) 256KB Mapper 23
. w) \7 R7 b' m5 `+ r0 F- c工具:: M* F; ?& M- W. ~
1.FCEUX 2。2。3
$ J% V$ \9 Q, n D9 A2.HXD
2 _- j. T! q% O R: e. }: f先来看看这ROM的切bank方式:
# s0 Y( p7 c& }# W9 bF989:AD 00 80 LDA $8000 , q, K! t2 P" Z; L- v7 h* z/ Y
F98C:8D EC 07 STA $07EC
3 ^' j' L9 Y2 P) }3 ^" Y+ c P1 HF98F:8C 00 80 STY $8000
- D0 j [! r0 @F992:C8 INY
: W% h; _3 V2 v6 F' L; {F993:8C 00 A0 STY $A0008 n ^$ z1 S+ Y5 c2 _* s
F996:60 RTS9 I6 ]1 e0 [1 [' ?$ V
t q) J" u" r! @再看看它的切VRAM方式:
5 ]1 _+ s2 E. A6 B5 `FACE:AD F0 07 LDA $07F05 [' @5 Y) I+ H
FAD1:8D 00 B0 STA $B000
. P+ t" g$ E5 h$ j% `' I, T! b! |FAD4:4A LSR
5 H" V/ Q4 r& a8 pFAD5:4A LSR3 a$ ~* l8 j& ~. @* e
FAD6:4A LSR
5 D6 l+ j6 O# hFAD7:4A LSR
. x$ `' n- M9 D/ p( n+ }% H, Z2 \FAD8:8D 01 B0 STA $B0016 B; _+ e9 v- N
FADB:AD F1 07 LDA $07F1$ u- e2 G& y) m/ q8 d( D
FADE:8D 02 B0 STA $B002. P5 N: W" x+ R" h3 C: m
FAE1:4A LSR5 k+ [( e9 M4 z v
FAE2:4A LSR
* g% Q' [5 q- N) c& z) kFAE3:4A LSR
! [$ K; [: Q/ tFAE4:4A LSR5 ~' R) R9 x+ R( j f" {; B
FAE5:8D 03 B0 STA $B003. `) @' T0 I1 n2 U2 \
FAE8:AD F2 07 LDA $07F27 L) m: e& c, B& o H+ P# N
FAEB:8D 00 C0 STA $C000
, N: v# ^; I' @" ? P2 UFAEE:4A LSR. Y$ ~3 R& H! b
FAEF:4A LSR$ O4 l5 T$ @! L+ [+ t7 s. z6 [
FAF0:4A LSR: I3 ]4 g, ~. Y, @- b
FAF1:4A LSR8 x% c1 l1 @7 e
FAF2:8D 01 C0 STA $C001( o4 A- r ]- S# D: \
FAF5:AD F3 07 LDA $07F35 k2 H7 I8 N: J* i
FAF8:8D 02 C0 STA $C002
" M. j( a* z8 i+ v2 C2 l3 VFAFB:4A LSR
. C$ ~: Z) \3 _+ X& F6 M- C S& t8 o( _FAFC:4A LSR
J7 X0 [9 t) x$ I2 A7 O2 NFAFD:4A LSR2 l& H- e5 r0 h% n' w! k2 ?4 y U! F1 b
FAFE:4A LSR- K$ [5 ^ d8 j& Z7 E* X3 }
FAFF:8D 03 C0 STA $C003
8 S' Q* g# c6 d* `& lFB02:AD F4 07 LDA $07F46 }* a/ B) i0 p, I) b0 @
FB05:8D 00 D0 STA $D000$ ?6 Q- X- C# _( i5 Z3 i
FB08:4A LSR
8 L! p+ L& b/ B7 ~. RFB09:4A LSR
* N4 O/ {' l+ f) p; Q7 wFB0A:4A LSR
, L" t" L9 l5 g! u# DFB0B:4A LSR& h/ B6 g" w! D# K8 B& b0 q7 d* }- ~
FB0C:8D 01 D0 STA $D001
! u! J$ g4 ]: c8 M: G1 p1 Z0 T$ J" TFB0F:AD F5 07 LDA $07F5
6 G# p1 J! H$ ~4 y7 AFB12:8D 02 D0 STA $D0027 k ^: q! s, v
FB15:4A LSR
) R+ }3 S& M9 e% |# x$ Q' sFB16:4A LSR0 M9 d$ S* V6 j
FB17:4A LSR
' c+ T7 Z' P" {2 p7 [ lFB18:4A LSR
! H+ R( {7 t/ Z7 [FB19:8D 03 D0 STA $D003
+ F" S5 s( L( e7 V' CFB1C:AD F6 07 LDA $07F6
2 ^ f( [4 C+ y# G% x4 G# YFB1F:8D 00 E0 STA $E000
5 s/ Y9 c( n4 n3 Y: e7 k xFB22:4A LSR
. _& H j& F5 E. sFB23:4A LSR
6 H! @, W% T E: C. tFB24:4A LSR) \3 f, X; H* R1 \' j
FB25:4A LSR
" ^2 c, n- \$ VFB26:8D 01 E0 STA $E001
, L; [2 k- \% n$ U- R( PFB29:AD F7 07 LDA $07F7
- x0 x" M; Z# kFB2C:8D 02 E0 STA $E002
% u6 @+ j% W6 D0 x3 h/ ZFB2F:4A LSR8 N/ G& o. T* f- i/ W, ?- t
FB30:4A LSR
. h# p- v: O" E5 ZFB31:4A LSR3 s+ ?, q3 ^1 n; O6 I3 l
FB32:4A LSR
" c5 C9 N( f+ N: A Q0 CFB33:8D 03 E0 STA $E003( o" X3 K5 }1 h) ?
FB36:A9 00 LDA #$00& N; Y& T1 [. {6 }" w" R2 K
FB38:8D 00 90 STA $9000
( e5 H6 r$ @6 M* R: M2 {FB3B:60 RTS
' S/ Y/ C$ @! ~8 Z& X# S J$ T( r8 R1 d- ~2 M
接下来修改切bank方式:
' O% S' F7 z, S2 s L P. mFB2B:48 PHA
+ R0 p& [6 l# h0 H1 sFB2C:A9 06 LDA #$068 L$ m3 V+ F5 g
FB2E:8D 00 80 STA $8000
! a4 K* L) e/ G' BFB31:68 PLA/ V' r( M* O5 ~+ F, D
FB32:8C 01 80 STY $80013 D( ^' ]2 @6 l5 o# b- c
FB35:60 RTS. [" X5 V) B# v; t: W/ V
2 D+ v0 R: L' m) g, q
FB36:48 PHA
( e, M8 L" I; yFB37:A9 07 LDA #$07
' b$ J+ {' o0 u: @# T7 UFB39:8D 00 80 STA $8000 = #$14
; {& x/ c1 m Y% NFB3C:68 PLA
6 v# x6 Y( k* |! X3 ^3 Z* v6 ?FB3D:8C 01 80 STY $8001 = #$1D
9 p" o* C x' h" AFB40:60 RTS3 G7 r5 d4 I2 f6 l: K/ r* e" s/ w
' j% ^4 X5 Y5 b' U1 T* V+ e还要把原ROM的对$8000和$A000进行写入操作的程序修改一下:
* }/ `9 Z: k; u+ V- v; S1 v* ]F989:AD 00 80 LDA $8000
]% u( n. E+ M: VF98C:8D EC 07 STA $07EC. c9 h& _! w- J& X% z* U& H( r
F98F:20 2B FB JSR $FB2B6 n( E; m, D2 F5 ~- D4 h
F992:C8 INY3 f/ z6 T. J8 }5 ^5 W3 i2 u
F993:20 36 FB JSR FB36
W0 i' ^, x8 I! r9 Y, Z! j QF996:60 RTS2 m! R, K O0 d+ y5 |0 C' o( D
2 q7 h$ @3 B7 E6 {0 H* L6 p# _再修改切VRAM程序:
$ \, s% u& Z4 _- a2 ]FACE:A9 00 LDA #$00
+ L, z e: o8 d7 k% r- QFAD0:8D 00 80 STA $8000, N4 f5 l7 ?; Q" P3 g" d5 ~
FAD3:AD F0 07 LDA $07F0! L' Y a1 F" k# U, n
FAD6:C9 01 CMP #$01- ~- F, g" e& b8 I* h
FAD8:D0 11 BNE $FAEB8 k7 g: A* W( V; F7 R/ `
FADA:AD F1 07 LDA $07F1) h F2 T1 F: F1 {2 b; [6 Q
FADD:C9 04 CMP #$04
; ~- O6 p/ B- z cFADF:D0 04 BNE $FAE5# f# w8 Y8 m$ W. [0 b: B: D
FAE1:A9 80 LDA #$80
% Q E& d0 ?: b& H3 K0 R7 uFAE3:D0 06 BNE $FAEB
' H% k; Z7 ]5 v* B% oFAE5:C9 05 CMP #$053 T- j4 T7 @' {/ e) x% r/ Z
FAE7:D0 02 BNE $FAEB/ U. t- r* `0 s y1 `1 u
FAE9:A9 82 LDA #$824 S+ e' e$ v/ ]
FAEB:8D 01 80 STA $80013 }9 |$ p( X/ K. h, y" M
FAEE:A9 01 LDA #$01- z- q- k* E( G. o
FAF0:8D 00 80 STA $8000
- t( D: [3 X: g9 k# vFAF3:AD F2 07 LDA $07F2
; W3 G) N3 f5 Q# X: RFAF6:8D 01 80 STA $8001+ n) x# E' z$ I: V8 b. e! z
FAF9:A9 02 LDA #$02
2 Y; I+ `/ w- q, N- \2 A. C6 ` TFAFB:8D 00 80 STA $8000& X# X3 b: o% {$ `8 N
FAFE:AD F4 07 LDA $07F4* M( H' a. V) J, e/ e! r" C# v2 d, t
FB01:8D 01 80 STA $8001
' R3 \1 @1 }- |9 O) `# t$ I1 T9 wFB04:A9 03 LDA #$03; }- [2 K4 E h# T
FB06:8D 00 80 STA $8000 C& ^1 P( z8 b& v" d5 z
FB09:AD F5 07 LDA $07F5% t! X' J% w0 \) M0 |7 `3 {9 z0 H. m
FB0C:8D 01 80 STA $80012 M V6 Z0 P w3 i5 m1 \1 C- ]
FB0F:A9 04 LDA #$04
; t% t o, D7 m# m U6 c4 W& JFB11:8D 00 80 STA $8000
i/ P8 `" n% x+ [6 C2 F4 R% q- S9 pFB14:AD F6 07 LDA $07F6. p! v" X7 \& h7 `: [# I. ?6 B" B
FB17:8D 01 80 STA $8001
/ \, r# }/ K6 H/ F$ u0 NFB1A:A9 05 LDA #$05
$ B! d( S7 h; r) X' CFB1C:8D 00 80 STA $8000! s- P7 r6 x/ n- P! i. J: A* f
FB1F:AD F7 07 LDA $07F76 w& ?6 |" c" O- P, M$ R" ~; m
FB22:8D 01 80 STA $8001
1 q7 W: S/ E) J+ v, x, o" f* CFB25:A9 00 LDA #$00
% k' e8 i- |" x, n8 g8 S2 o, Q; b6 S# K7 YFB27:8D 00 A0 STA $A000, X! I3 ^: r1 ^; ?, B
FB2A:60 RTS
% {7 v' u& v: _3 H" R3 N' R. s* k6 M0 Z" n4 _
然后保存文件。- [$ d. m6 x D2 a7 j i2 i
使用HXD修改文件头:
7 Y0 ]" u r) G3 M- q5 \8 I3 T将Mapper 230 U6 a9 _* z. R0 k* ^/ d
06字节的高4位是Mapper号的低4位4 j4 _- |6 y0 g4 D
07字节的高4位是Mapper号的高4位
) f, N6 T: }! v$ ^3 b* R* j5 C组合起来就是0x17=1*16+7=237 s2 x: S. e/ c) j) d5 @
) ~" E4 s/ _! M/ Z
修改成 Mapper 4
( B; m0 V q! |1 S$ p1 _$ Z 3 Y+ k, }0 i9 S' |7 e0 b
) i) q% ~ @ |/ |6 c$ f, p# N( ]& ]$ L) ^: n8 s
再次打开文件:2 A8 N8 t" p0 P$ S- D
: [) v7 H' }6 B0 B2 N2 `
可以正常运行
& q8 y/ {: y. S( b3 n4 N. [; t通过全面测试,发现出现精灵错乱:( {9 V% W+ {4 O* j
第1关:- v. M3 @! ~2 t, l5 t7 D) y& n1 o

% V. H3 b$ S& s k" q X: M. E# g$ N
第2关:
: f2 H; W6 T/ t# \ 9 V" O1 t% H6 J
任务失败后:/ N% t$ P+ x7 \) Y' Q1 M

8 h* J, f! A( q8 i; n通关后上飞机画面:
$ N8 ^, d% m+ ^$ u% |% d
2 W& @9 d9 G: }4 I5 A$ M这是为何呢?
$ a, D! o4 `+ W! J) G/ o1 B" w" {这是因为Mapper 23 中精灵VRAM切bank是一次切1KB
8 K7 e: ?5 d c- u3 {, N) E5 C但是在Mapper 4中精灵VRAM切换却是一次切2KB,而且忽略bank号的D0位
6 i4 ~4 m. p6 k A比方bank 0和bank 1是同一个bank,同理bank 2和bank 3是同一个bank
- ?, K' i: ~5 a' k( o- l也就是说, I' \" C4 }* H) I$ h% d
Mapper 23中的VRAM的
3 c# Y) ~( G1 s# T" p, }bank 0,bank 1,bank 2,bank 3
/ Y( I+ @' v6 r9 h9 s& t& i8 r在Mapper 4中对应的是1 q2 n/ J9 A5 ^) {4 ?- t
Bank 0,bank 0,bank 2, bank2% w1 W- R0 E' @7 S0 o, I
然后查找原来的ROM的切VRAM的程序:
o' S4 q" s8 W: V% l0 x知道是从07F0-07F3切到精灵VRAM的:
2 _" G& [/ F" K如图所示:5 m' @) X5 x1 h( P4 C/ J! W

7 h. M$ f3 F3 P6 c+ j4 {- E, Y. k * c& X0 b" A/ S8 d* e
作为对比,左边是原版,右边是修改。
' b3 {/ b! d. N& z* l8 E& X接下来是完善VRAM切换带来的问题,因为Mapper 4只能切2KB的bank,所以我们不能通过切bank程序解决问题。7 H! \ |0 e4 s3 b
通过测试知道1,3,5,6,7,8关的精灵VRAM排序如下(07F0-07F3):
2 V/ d! Z; ?. P+ `01 04 06 07
% k- t; [7 }3 u9 m' P4 l第2,4关如下:
, J, s8 V6 o, ]. }9 d! k9 K01 05 08 097 U# x* h# e7 u) a+ U% l
任务失败时如下:8 _- H$ l( ~# p( B. y1 l
32 00 00 1B
2 p6 C ~$ M# f2 H- {% Y/ Z其中任务失败时对应的VRAM是07F3的1B,只要让07F2为1A或1B即可:2 Y' \( N' W) w. m2 M) R* N: H
通过调试找到对07F2写入数据#$00时程序如下,于是修改C7E5的值为1A即可:
) E+ G8 a) t* @3 n3 m# ^# w
& G# Q* {# T- \! [" x转到ROM地址:( n& @0 g( m9 G
1 [+ S& ^4 ?' c1 i% S
修改数据:
! v1 Z, k( z0 ]4 {$ x h 1 k) K0 I( {6 o8 n
重新失败后可以看到修复成功:2 o7 z5 l1 j2 w/ a+ ~' w9 g2 f$ |
# A4 u3 I8 X- `. X! p$ F! p7 s+ C+ `
接下来是修复正常进行任务时的精灵错乱问题。
; ~+ o" x# k0 X首先运行Mapper 23版本,在1,3,5,6,7,8关任意一关的时候,将PPU导出来 B( A# ]8 I/ \- G' Z1 X+ X
0 }1 ]+ ~5 ~3 b. e2 l, b

; h* a& [' ~9 { & m: _/ a: p. {
- F9 R5 y' H0 r4 z% I
然后用Hxd打开修改的Mapper 4的ROM和刚刚保存的PPU的数据文件:
- f% F- n2 e2 L1 H5 }' e$ P; o
& D# l$ l' `5 W1 p$ ?, ^在ROM文件头第05字节改为0x20:
& l+ [8 [: ^: t
/ K8 M: K$ W5 D# B; P7 {; D然后转到文件末尾,插入0x20000字节空字节:
V) c' J$ C2 O6 z 1 o) l6 |9 p" \/ A: [' e

4 ~) \: l* Q0 {5 C ]# f
! V+ K1 }5 g* W' U2 q
* ], A5 d9 D7 x" u0 K$ g" f然后将第1关的PPU数据的前面2KB数据选定:1 I1 S2 z8 \2 c7 K% X: v* [
* L; M4 @( a' [: @ |
4 [- o; a/ ?( j% X* d6 x ~

/ q' g P" z8 n7 [7 V0 n8 n复制之后以覆盖方式粘贴到ROM的40010,同样把第2关的PPU数据的前面2KB以覆盖方式粘贴到ROM的40810
( [ l! ^0 z- L1 l" q5 p
8 H( D8 F2 f7 r8 m8 x然后保存文件: R, @, D C, _- M
9 n; ~8 c- }) Y9 M
最后用FCEUX打开文件,添加07F0-07F3的写入断点
' c( h! z' a+ \9 O3 S8 q
$ d/ u4 a6 L, T$ m$ }; Z, P" c地图预览后即将进入第一关画面时程序暂停了,可以知道此时准备将C793的数据写到07F0:% ]& z' K# ^8 B4 x& Z

, `6 ]! l& U2 W; k! y9 @3 z测试后知道将C793-0796写入到了07F0-07F3:3 t/ [% ^& h" Q; U q0 S: }
同理,经测试每4个字节一组,一共17组,其中01 04对应普通关卡精灵以及其BOSS关的精灵VRAM的bank号,01 05对应2,4关卡精灵以及其BOSS关的精灵VRAM的bank号,再加上一个通关后跳上飞机那段动画的精灵VRAM的bank号。/ l9 C; ], O' j) ]6 k& m- v
) [# a0 I, A" h$ [9 I5 m4 S7 U6 W1 X
" c C, z4 A! n$ }; j1 R& L% n5 L) u( v
然后将文件中标记的01 04修改为 80 04,将01 05 修改为82 04即可:
: |4 a9 c6 S/ E' i$ ?' n
& \4 }/ R# ]6 ^6 W* R保存之后重新运行后效果如下:8 ?) @% E- x5 }& K( k

1 A' q& u1 D8 C# S' _ 3 z3 N7 J4 |5 j, D y

+ r+ T! e/ m# w7 h9 F* e- @当前使用的是FCEUX模拟器,如果用NEStopia玩的话一开始就死机了,这是因为这个ROM有文件保护吧,它会往$6000里写入数据:8 T2 g4 h) m! w, h/ O* k$ u( R8 Z& d+ C1 [
1 [8 S4 `0 o7 q7 v' o* }, J$ a
F863:A0 03 LDY #$03
* R7 `. [ x, [- MF865:98 TYA( s! X4 @$ a* W+ L/ z
F866:29 01 AND #$01
" I) ?6 d% O5 b0 [! |4 h9 e! q- nF868:8D E9 07 STA $07E9
8 _' |, f4 o9 ^( s2 F% N. C, yF86B:8D 00 60 STA $6000
% z8 v1 q( F' l1 `, w5 B3 DF86E:AD 00 60 LDA $6000# m" s/ T0 d) }" E- q) V/ Q1 L/ k
F871:29 01 AND #$01
. c' W5 r, p( W/ GF873:CD E9 07 CMP $07E9 V/ S7 |) e- @7 l2 V
F876:D0 05 BNE $F87D! w7 d( |' B9 P- w1 r7 b
F878:88 DEY/ E& t2 g# Y% n
F879:10 EA BPL $F865
1 q) R1 ] s) q: k) S% ^# bF87B:30 03 BMI $F880- M6 P: `+ I4 Y& \" e" S
F87D:4C 00 00 JMP $0000
( C1 N: h J( p" cF880:A5 1A LDA $001A
, o! I* e9 l% a' }) vF882:65 34 ADC $00344 i7 Q5 r( [+ \$ ?, d- j
F884:85 34 STA $0034* Q @3 f, i" N; F9 V
F886:4C 80 F8 JMP $F8801 c+ ?' f* [' t, [0 d# W4 P& E
先取Y值=#$03
/ B: c. d } `. X. c与#$01相与后得到#$014 d+ x' n W3 [9 P8 ?% r( S! ]. F
写入到$07E9" Z; m: {$ Z: d8 `, T1 h: f( b0 U
写入到$60003 ~' F8 Q$ Z3 y$ F4 T; ^
再读取$6000的数据和#$01相与后和$07E9的数据比较& B; w0 O" a- K* V0 ^ r
不同的话跳过5字节0 d6 o. Y, r- E
否则Y递减& l: x& @/ v: j! p# e& B& V: v
为正数就跳回0x100-0xEA=16字节
# z y1 ?/ g# K( f5 Q0 Z) l" W为负数就跳过0x3字节# Y+ \$ L& J5 }3 b1 w* X# O
跳转到$0000(简直没有人性了,跳到这里死机,真想得出来)
0 b) H( W; [& | S8 G9 Q( t2 T' G( ~. Z* {
正是因为这样,NEStopia运行FC时,6000-7FFF默认是不可写的,必须在ROM文件头第6字节的D1位置1设置ROM有SRAM,对于Mapper 4,还需要向$A001写入#$80来启用SRAM。
. r9 k* N+ d, A0 `' E/ u. j由于$6000不可写,因此想$6000写入#$01后$6000还是#$00,之后读取$07E9的#$01与之相比当然不同了,于是直接跳转到死机程序了。+ p- H6 v/ R/ z4 o; l9 I
解决方法是把ROM中的所有的AD 00 60 29 01 CD E9 07 D0 05 88 10 EA 30 03 4C 00 00$ X2 A3 c+ [9 \4 Y8 @, s% n
中的D0 05改为D0 00,然后保存即可。3 u: v1 {* {" m) V H4 C1 C0 ]
测试完美运行。
* v/ q, L! h) \$ b! z2 o! k; ?
0 ?0 v- V9 c7 e( d3 N/ C+ D9 c1 E$ k& n" w( P: \5 Y- H
教程到此结束。6 W6 t+ K" a- U# l; X
3 l) ]. ~ d9 h% y& e3 y0 I |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|