|
本帖最后由 yandagui 于 2017-4-16 19:06 编辑 7 {4 H L, ]' i/ `6 @
; q C; }8 J# C0 p W" cMapper23转Mapper4实例教程
* @( ?7 R# E/ N9 k) K
/ W% b% v a8 I8 l& B( z. nFlameCyclone 2017.4.14
s/ e7 e) `& L& Z; g# S5 Z/ p
- U2 K4 `$ V0 F0 V先看看Mapper23文档:6 h5 C5 X1 u; r# b
9 U# ~* |. e/ z$ PMapper 23" T/ Z/ j' c+ R9 q3 F$ n3 ~1 n
1 S* K% V2 \9 a+ s& \6 D" B) ?
$8000: 选择8KB的ROM存储体映射到$8000
* Z8 P8 m- n8 K1 I1 ?0 i
/ t& {6 g$ t9 A; i$ q" _2 F9 p$9000: 0:垂直镜像
, W" T) D* w2 h1 | 1:水平镜像
m. v/ a. _; P$ C& s/ k 2:$2400镜像
! R' ], s$ z! u2 g6 t1 k 3:$2000镜像
1 R) q4 a6 e9 t' x# g( N5 J2 Q9 v6 B9 L
$A000: 选择8KB的ROM存储体映射到$A000
: N& P4 h' J+ u4 B5 ?5 M% I8 {% S X1 c3 R k
$B000: 选择1KB的VROM存储体映射到PPU的$0000(低4位)
7 r4 j. s+ T) m% V# o$B001: 选择1KB的VROM存储体映射到PPU的$0000(高4位)
' I$ t- b5 y3 d$B002: 选择1KB的VROM存储体映射到PPU的$0400(低4位)
: G5 ]6 y0 D3 P: e. W* W$B003: 选择1KB的VROM存储体映射到PPU的$0400(高4位)
$ Q+ q" Q+ V! p! h
" `- f! x, A% I ~; [' R4 x" d$C000: 选择1KB的VROM存储体映射到PPU的$0800(低4位)
' F* V! S$ w9 R/ _$C001: 选择1KB的VROM存储体映射到PPU的$0800(高4位)
0 s. c( W+ ~- A( I9 Q$C002: 选择1KB的VROM存储体映射到PPU的$0C00(低4位)
8 ~, O2 ^+ P6 w! P+ M. h/ S$C003: 选择1KB的VROM存储体映射到PPU的$0C00(高4位)
0 J- ?& M9 c- J x6 p e( ~# P8 _- `) T/ k! a C
$D000: 选择1KB的VROM存储体映射到PPU的$1000(低4位)& ~; b: {) f* f+ w2 s% E8 Q
$D001: 选择1KB的VROM存储体映射到PPU的$1000(高4位)7 I' H5 d, h; l; `- f- V3 t% y
$D002: 选择1KB的VROM存储体映射到PPU的$1400(低4位)
1 N/ i. N: z2 Q5 q8 a' w$D003: 选择1KB的VROM存储体映射到PPU的$1400(高4位)$ S) o) N- F1 X
/ S% P+ J; } o/ t0 G4 i4 J$E000: 选择1KB的VROM存储体映射到PPU的$1800(低4位)
" `8 i6 v, z/ v* F; [, [$E001: 选择1KB的VROM存储体映射到PPU的$1800(高4位)6 P' H7 w3 x- U8 V& y( D* \6 b a
$E002: 选择1KB的VROM存储体映射到PPU的$1C00(低4位)
. _7 H7 X( D+ g# ~+ B$E003: 选择1KB的VROM存储体映射到PPU的$1C00(高4位)
8 K, _. f. q- }+ N9 }+ C; o- I! O1 a
再看看Mapper 4文档:
) {# L* Z& ?) x6 D/ }
4 O; D8 ~# G2 w% B% o- g0 f& }Mapper 4! `# ]3 i* f8 b- E" L( i$ D8 \9 D+ j
3 y% ~- ?6 f, m; q0 T/ @4 g) c
$8000: 模式号
5 I% _7 u3 z7 f8 z- ?: j9 d 位D0-D2:
0 E4 J: a( {+ N7 ~1 ~9 p 0:选择2KB的VROM存储体映射到PPU的$0000
" u) Z+ q1 K6 k# P 1:选择2KB的VROM存储体映射到PPU的$0800
3 O* Z4 ~4 J. Z' x 2:选择1KB的VROM存储体映射到PPU的$1000: {+ w" M8 D$ _' i! X" ^* N
3:选择1KB的VROM存储体映射到PPU的$1400% a/ H: a7 G7 ?0 B( d
4:选择1KB的VROM存储体映射到PPU的$18001 q9 N% J8 u$ a) u8 E5 _+ e% d
5:选择1KB的VROM存储体映射到PPU的$1C00' Z" N M3 c0 M% D/ q
6:选择8KB的ROM存储体映射到$8000
8 V! c I4 G l2 C* e 7:选择8KB的ROM存储体映射到$A000
7 Y' E3 v8 w. {; { 位D6:$ R2 H; D8 l7 P& Z) I4 B1 Q: A
0:允许擦写$8000和$A000
: i3 P7 {/ i1 V0 a- G1 t 1:允许擦写$A000和$C000
4 R4 Y( m( Y$ E7 Y! I3 }3 x( q3 q 位D7:
; W, a r: B2 L! l9 |6 w- y 0:模式号D0-D2使用普通地址6 N6 \3 u8 p. d* v9 Y
1:模式号D0-D2地址异或$1000
: k# b# ^* P3 z4 w1 T4 p! O' s/ v. [4 o# I& p' n6 F
$8001: 模式页面号
& H! [2 y$ P" O 写入一个数(00-07),切换存储体到对应地址( b1 Y3 H6 G- E$ v+ d1 j8 `* X
' ?" o( ~- @4 B6 y) ?" M- Y- g4 W$A000: 镜像选择
8 F/ f% O4 ^$ m9 |1 i/ c$ Z8 n: p 0:垂直镜像
" `: @9 V9 l8 z" G 1:水平镜像: u3 D) U0 I2 T! A
$ X9 ]( u/ k2 }7 G" {
$A001: SaveRAM 切换
6 q; ^& `) o& Y3 x) V 0:禁用$6000-$7FFF
5 O' V7 E" u0 |! c 1:启用$6000-$7FFF* T. `/ }( Q5 h/ u4 o
. m2 X) B0 s6 a) Z6 G3 I
$C000: IRQ计数器
j3 a9 M# X! a0 j) E9 n IRQ计数器的值存储在此处
. q( W1 P/ F; @ [6 B1 i# m6 t* y* _2 r: I( h1 M9 y
$C001: IRQ暂存器7 I4 H W+ S( s. k0 a+ ]; r
IRQ暂存器的值存储在此处
# z# Y3 u2 `/ a5 H% {1 e7 d1 c$ D* O. S; H
$E000: IRQ控制计数器0
4 Y7 _% y8 f; n, A8 w8 c& w* U* | 向这里写入任何数来关闭IRQ,并从暂存器中拷贝数据开始计数,进入IRQ
4 x' B# W" b8 V" C y' W6 I! {0 N* I& l; j5 t% o( L7 U5 J* l
$E001: IRQ控制计数器1: F0 }2 K7 b4 g
向这里写入任何数,允许IRQ(退出IRQ,允许下一个IRQ进来)2 z6 r, ~2 c2 L1 v2 K j3 x4 O. f
6 g' d9 w2 s* M# K( f2 S2 }$ i: |, {; ?4 F# a% S
转换思路:3 G' T8 p' J! Y* X: Y3 X
将Mapper 23 的切bank 方式和切VRAM的方式修改成Mapper 4 的方式。, |7 X5 i# f; D$ p1 i
) d4 V3 i% }* Q7 A, U
修改实例:: S3 d/ H% D# A! C
Contra (J) 256KB Mapper 23
3 O& y7 i( e6 ?" M+ q: S# d工具:: x% M+ I" \! J! }
1.FCEUX 2。2。38 q+ ?1 I! \/ A( n+ q4 R) b) y
2.HXD
# n/ \& d9 U1 s& w先来看看这ROM的切bank方式:
# |6 l: I2 v" y& ~F989:AD 00 80 LDA $8000 3 T- L2 V4 d% \+ M) M; l7 v( X- o
F98C:8D EC 07 STA $07EC5 r) A# V$ V" |, ?
F98F:8C 00 80 STY $8000
/ Y" \. d3 r" Q4 ~4 h& F4 vF992:C8 INY+ |/ S3 W8 H1 h( \8 q; g8 E
F993:8C 00 A0 STY $A000# ?# N d* }7 p
F996:60 RTS, ^, y; U# [! e# p8 ^( L2 B
}9 a# e0 A( x" X
再看看它的切VRAM方式:; _; Z$ _$ D8 D- R
FACE:AD F0 07 LDA $07F0) }" v% U3 f% @! H
FAD1:8D 00 B0 STA $B000) X9 C. ~8 D6 v1 P9 d
FAD4:4A LSR' i2 @: k( R- K+ P, ^
FAD5:4A LSR
" V) j. y+ R5 h) M0 H: o9 jFAD6:4A LSR/ m% Z Z! m# Q) z" P% M
FAD7:4A LSR+ H) K u- P) L, r2 O8 a- `% ?
FAD8:8D 01 B0 STA $B001
( Q, E9 `5 Z; G; i7 w: l; \4 E( UFADB:AD F1 07 LDA $07F1
^: i. p4 W% C# zFADE:8D 02 B0 STA $B002
+ W8 J7 s D) O, Y3 ZFAE1:4A LSR, U0 ~9 L5 G! L# Z
FAE2:4A LSR7 I# f4 F4 n- I! A. |
FAE3:4A LSR
; `* P9 d5 v# ^; c! E7 Z! H% v H9 kFAE4:4A LSR
. G, w/ ^* a: ~3 P+ U+ RFAE5:8D 03 B0 STA $B003
, x/ @) ^$ y O. X8 IFAE8:AD F2 07 LDA $07F23 [9 r/ |& k* ] F# I5 q+ S
FAEB:8D 00 C0 STA $C000, V/ Y6 M# S6 N2 p
FAEE:4A LSR* N9 t. s+ H# a( ]0 n
FAEF:4A LSR9 k% P l/ c2 N6 J( I
FAF0:4A LSR
/ f. p V7 V3 I( o0 N9 r( Z; wFAF1:4A LSR
' B7 f! @ B3 z* }; n5 o: \FAF2:8D 01 C0 STA $C001
* N% t# p& X t% A- pFAF5:AD F3 07 LDA $07F35 B6 U7 ~1 b5 l8 e# F) P
FAF8:8D 02 C0 STA $C002
* B5 b% m1 m& j. H' yFAFB:4A LSR
* I( @6 w% X, B7 V! `) G3 p( W1 ^FAFC:4A LSR4 s" {; X7 [; v8 P: R
FAFD:4A LSR
9 F9 H( I) t. m* o( B2 F# GFAFE:4A LSR
3 ]. a! O% t: X' M6 VFAFF:8D 03 C0 STA $C003
, V% ^- { z4 E1 P; G, sFB02:AD F4 07 LDA $07F49 U/ l9 o c2 f9 I4 I+ u
FB05:8D 00 D0 STA $D0004 p: w# {0 W+ ]
FB08:4A LSR
6 h" O: H9 G2 KFB09:4A LSR8 N: u& ?9 G5 u% K6 W7 b, q* V
FB0A:4A LSR
) L) e. a, W4 a; fFB0B:4A LSR v5 R' ~& q/ O3 V! K L
FB0C:8D 01 D0 STA $D001# v8 n/ u. X0 ]
FB0F:AD F5 07 LDA $07F5
, S, z0 y; A3 G5 A1 X8 g9 P6 O: MFB12:8D 02 D0 STA $D002
$ N2 t; o; ]1 i- iFB15:4A LSR
" L3 A/ P& H+ jFB16:4A LSR' w, A: o4 H& i8 _7 j; ]' Q
FB17:4A LSR+ g+ q6 t1 }3 [( S3 O y% Z2 l
FB18:4A LSR8 l3 `! _5 V4 A1 Q# ^: |
FB19:8D 03 D0 STA $D003& o- J5 ^/ U" k0 {6 K3 k
FB1C:AD F6 07 LDA $07F6
% \* X/ S) P0 ^8 r9 U5 I uFB1F:8D 00 E0 STA $E000
" L. u* `' E6 |+ U: KFB22:4A LSR% c( j- I3 h, C& c% p4 k% F% y# N
FB23:4A LSR
# ~( E" l3 ^, uFB24:4A LSR
+ j/ n7 l6 H4 {FB25:4A LSR& {$ v$ `' g0 i7 C9 r/ Q N8 b. g
FB26:8D 01 E0 STA $E001
+ `- S/ @1 H l6 x, a8 N( fFB29:AD F7 07 LDA $07F77 y: V8 n6 X- S4 F
FB2C:8D 02 E0 STA $E002- V' [' y9 I9 W
FB2F:4A LSR! y0 f. N. c$ s, y
FB30:4A LSR1 _. v. u2 K- o1 B
FB31:4A LSR
) K, [* D) Y5 C9 ~- tFB32:4A LSR& P0 G4 @5 V7 B% ]) v! C2 t9 d
FB33:8D 03 E0 STA $E003* t) T3 U: d: g4 E
FB36:A9 00 LDA #$004 H5 C% e4 a% t& d
FB38:8D 00 90 STA $90001 e* z1 R# u+ G
FB3B:60 RTS$ Y8 E' [6 `/ J6 z, |. F) p
5 s( J4 m* s: }* ~+ O接下来修改切bank方式:
6 @! x! X" q5 U/ ]/ vFB2B:48 PHA# C9 `0 @9 _) k, w$ D/ y8 l
FB2C:A9 06 LDA #$06- t8 [6 r9 Q. w. N1 R, \8 H
FB2E:8D 00 80 STA $8000
- C2 ~0 U d! _+ `0 K8 A6 e2 lFB31:68 PLA
6 |! Z4 a5 F$ T F+ ]: q0 ]FB32:8C 01 80 STY $8001' y7 ~& e* C9 l' n* N1 B" X0 ]
FB35:60 RTS9 g A) N ]* e, _) Q, {, s0 Y
0 i* B. c# J8 z# u3 a4 g, t$ IFB36:48 PHA$ O4 x$ w, i. T- o% ], T1 I
FB37:A9 07 LDA #$07
. ]3 ]6 j% u2 z; _FB39:8D 00 80 STA $8000 = #$14
/ A D1 o! A0 ?$ Z, i. M7 ~( _5 @FB3C:68 PLA
% A8 [. k. Q( h" m2 _% g0 qFB3D:8C 01 80 STY $8001 = #$1D7 j# t3 R1 a* Z" N6 b/ W9 t) x; _) A
FB40:60 RTS
* J6 J7 X: U: h* J& ?
( I9 R% g1 k' L还要把原ROM的对$8000和$A000进行写入操作的程序修改一下:
, O# x- |5 O9 f0 e( S$ X, GF989:AD 00 80 LDA $8000 % x$ e" c5 E5 _
F98C:8D EC 07 STA $07EC% L) f; F8 Y3 G# |! v8 j! \" e
F98F:20 2B FB JSR $FB2B1 U: {" `4 p6 s
F992:C8 INY1 x" n5 S$ j# ~( n2 `
F993:20 36 FB JSR FB361 ~3 C/ R/ R* X& ^6 m
F996:60 RTS, j+ h( ?5 `/ Y1 \3 [+ b; s
5 z/ H2 m: S' J/ S
再修改切VRAM程序:
0 v, i) p) j' L% pFACE:A9 00 LDA #$00
9 }1 H' `. }8 {1 w) n6 VFAD0:8D 00 80 STA $8000# j" h5 S- \1 a1 g4 a/ m
FAD3:AD F0 07 LDA $07F0
- f/ V6 n9 D1 [! H; R0 oFAD6:C9 01 CMP #$01/ ^9 F I. n# Q/ S' S
FAD8:D0 11 BNE $FAEB
, q& S& f' g- f& m0 d% S8 S) zFADA:AD F1 07 LDA $07F18 P& I# f; }4 W' k U l
FADD:C9 04 CMP #$040 J5 ?, V0 G% t5 t; S
FADF:D0 04 BNE $FAE59 j1 N5 s7 u; t9 T. L& `7 R' X# ]
FAE1:A9 80 LDA #$800 h0 s- \3 p- v" g& y/ K1 j7 |0 F7 W
FAE3:D0 06 BNE $FAEB
A6 f. |, |, P+ l' I7 }/ iFAE5:C9 05 CMP #$05
9 A) }8 [7 U' x h& ~FAE7:D0 02 BNE $FAEB% a, E7 m$ z2 ~) m! K. n, F
FAE9:A9 82 LDA #$82
m5 |7 `9 v; j2 x( mFAEB:8D 01 80 STA $8001
( Q* p% D2 w2 i! G6 YFAEE:A9 01 LDA #$01+ J, v5 O6 @! Y
FAF0:8D 00 80 STA $8000* V6 a2 p2 \# z1 }" s
FAF3:AD F2 07 LDA $07F21 w% D3 a7 R" S- ?4 x
FAF6:8D 01 80 STA $80018 m c' S7 D. d O" j T) J
FAF9:A9 02 LDA #$02
5 r8 R E0 K" |- l3 a& rFAFB:8D 00 80 STA $80004 N; U. |: l/ P7 {5 z2 \5 ?) ^
FAFE:AD F4 07 LDA $07F4: S7 x: h) V( T) e7 V- e# L# o
FB01:8D 01 80 STA $8001
7 E" C8 ]' G7 CFB04:A9 03 LDA #$03$ z" T; s# m4 {; w! ?
FB06:8D 00 80 STA $8000) K( W/ E, V1 O
FB09:AD F5 07 LDA $07F5
- F3 L* j5 \ |* pFB0C:8D 01 80 STA $8001! a1 K! F6 m( g5 v* n! F
FB0F:A9 04 LDA #$04
% S; [4 t8 S7 fFB11:8D 00 80 STA $8000
9 J Z, Y" g: R# m6 |FB14:AD F6 07 LDA $07F6
9 N( m2 Y8 A% k& }/ }6 j& cFB17:8D 01 80 STA $8001# w% s" C% Z9 C/ W: F1 U" W: _
FB1A:A9 05 LDA #$05$ @/ Y- H% }+ K3 S, a; R
FB1C:8D 00 80 STA $8000
& h5 S+ L L3 fFB1F:AD F7 07 LDA $07F7- U0 ^; r9 k' c, W, {/ k1 l3 G
FB22:8D 01 80 STA $80014 `0 v- e# K7 `
FB25:A9 00 LDA #$00
! F! |+ W C! `( D; w' V! yFB27:8D 00 A0 STA $A000
( j# ~* h7 o9 `& H# d5 DFB2A:60 RTS, O; ^5 g" W/ V7 R. D
% ~4 z! d1 m2 f8 X0 o8 k( o6 c然后保存文件。
9 u* R/ c) p8 c7 A: {2 V% U使用HXD修改文件头: U5 t* W3 n% F" t: x' V. p5 r
将Mapper 234 h$ v/ B5 Z9 `$ W5 _( h4 j( R
06字节的高4位是Mapper号的低4位
6 R& ^7 j' a0 B/ g6 L% c07字节的高4位是Mapper号的高4位. Z2 Q/ q3 i' a: b, P
组合起来就是0x17=1*16+7=23) w& J4 j0 \1 i+ l4 `
" P! k$ b% U; K* D4 s4 N$ H3 q6 }8 L
修改成 Mapper 4
2 n! u' n. J/ r5 z; K3 S - d3 b3 v( m! h, ~
6 t( ?% F# I i7 k4 B
2 M$ a* t# x/ c) ~
再次打开文件:
5 m8 ~, M/ B: \. n 1 I8 ? Z: e; K0 ]8 k% _% Y
可以正常运行
1 j; ?0 K) O& r- K) m" P通过全面测试,发现出现精灵错乱:
! F( L8 h6 h H! n: g, v( r/ \第1关:
( G. H$ f' T. G3 R; Q![](http://www.emu618.org/data/attachment/album/201704/14/194124m9j9eyv92e8l9d2t.png)
) y" H7 I$ N4 j/ b+ k8 `6 C; U0 ?/ {8 d0 ~( a) F
第2关:
8 j, n! c2 D- D, h' c" x0 l # a6 b! A( g8 f" R+ F% |
任务失败后:
$ r7 Y, T" O& O8 \, i e 2 Z$ s3 s$ E1 H/ @
通关后上飞机画面:
5 G% R: \7 Q5 T" G4 R- h q: h: V7 @/ I- r+ p
这是为何呢?
$ e7 [& ]$ ?: V% O% l8 a/ h+ C这是因为Mapper 23 中精灵VRAM切bank是一次切1KB
5 `* d6 k& K s$ z& |- p l! X8 @" t但是在Mapper 4中精灵VRAM切换却是一次切2KB,而且忽略bank号的D0位& P& k z2 U5 R
比方bank 0和bank 1是同一个bank,同理bank 2和bank 3是同一个bank
- z# \. Q# J3 P ^4 q2 I) E也就是说
+ @5 V2 g7 i! ~, AMapper 23中的VRAM的
5 x) W5 c' T& N# ibank 0,bank 1,bank 2,bank 36 ~/ D& b2 L& [. F9 }
在Mapper 4中对应的是
7 H( K: k7 d8 DBank 0,bank 0,bank 2, bank2, F. v- P& V: n& |* R& d$ J2 |
然后查找原来的ROM的切VRAM的程序:9 G# {. a8 s+ S) k; h4 k+ g
知道是从07F0-07F3切到精灵VRAM的:
d% t% J, o! B# f: v7 X( P. T% W如图所示:
( C% z Y: J* w / Q- D9 c' [2 L- U+ c, ]
![](http://www.emu618.org/data/attachment/album/201704/14/194135nn2wswsyhpz697yc.png) ![](http://www.emu618.org/data/attachment/album/201704/14/194137vgoi1ow2oi5gicoi.png)
6 q) q" V: W$ ]1 _8 n' o( n作为对比,左边是原版,右边是修改。# b' ?4 Z7 c* B
接下来是完善VRAM切换带来的问题,因为Mapper 4只能切2KB的bank,所以我们不能通过切bank程序解决问题。( z8 K+ J2 a% j+ ?
通过测试知道1,3,5,6,7,8关的精灵VRAM排序如下(07F0-07F3):7 ]+ z+ q1 }8 K5 G: L# d7 Q
01 04 06 07+ k% j$ \- d* e& b8 a; P h6 ~. ^
第2,4关如下:6 J9 v- b' j1 C, j$ r, c
01 05 08 09
0 K+ K% Y) i+ \* R任务失败时如下:$ C# \2 O. n s2 R. t
32 00 00 1B r) v/ L- r8 ^: S) R3 y2 D3 A1 w
其中任务失败时对应的VRAM是07F3的1B,只要让07F2为1A或1B即可:+ }1 w, i/ E1 G/ g
通过调试找到对07F2写入数据#$00时程序如下,于是修改C7E5的值为1A即可:9 V# \3 x+ |, o
![](http://www.emu618.org/data/attachment/album/201704/14/194140wrbap8a8ulaz5nr8.png)
" K" m( Q- i6 v9 Q6 N& X) t转到ROM地址:
' i9 J7 ^$ @* u; H& |, F - N/ d" x! M2 P/ k" u0 S% A
修改数据:
_+ Y' ^) q' K4 ] & e6 e3 z+ j* i" }: U: k. f
重新失败后可以看到修复成功:3 f* Y% V% O5 L# y/ T$ `
![](http://www.emu618.org/data/attachment/album/201704/14/194146jztpp4nj11dr76fa.png)
! V. W1 [- F& V' M- n8 T接下来是修复正常进行任务时的精灵错乱问题。
; U" |3 Z( m& V$ v首先运行Mapper 23版本,在1,3,5,6,7,8关任意一关的时候,将PPU导出来& D/ U) d. m/ V3 }$ i* |/ J
![](http://www.emu618.org/data/attachment/album/201704/14/194148od800dyk24y4555r.png)
5 \. t7 l1 D" L; ? T/ b![](http://www.emu618.org/data/attachment/album/201704/14/194150sbjbbwdjd0hw3dj4.png)
* f2 R3 y) {( r; V5 Y& B , L9 m& K" P8 u& \) N
![](http://www.emu618.org/data/attachment/album/201704/14/194154cxbx8ia6v10qjijo.png)
# g# ~0 K4 A, c. E0 {4 H然后用Hxd打开修改的Mapper 4的ROM和刚刚保存的PPU的数据文件:# ~ i2 ]/ y* W
4 ~. J# \% S! d/ N7 c8 }+ M- {5 F
在ROM文件头第05字节改为0x20:& l8 K, c! |. N) f
+ T: s" J" U/ H- S9 ^
然后转到文件末尾,插入0x20000字节空字节:: [: F3 F0 \& t* U2 o+ k# V
![](http://www.emu618.org/data/attachment/album/201704/14/194159jrtpxj0r7qt185pw.png)
2 }' W3 Q4 w( o![](http://www.emu618.org/data/attachment/album/201704/14/194200i9y62qkyikr5ys5y.png)
. k( T* m0 R/ z+ Y3 w8 l1 }/ G 1 R, |4 P) |2 v2 Z
6 E3 ]5 j* Y" c, T* B
然后将第1关的PPU数据的前面2KB数据选定:4 D- p7 c! d8 D, j9 v' T+ S
8 X5 `1 J# S) A
7 L+ ]1 f q+ [
![](http://www.emu618.org/data/attachment/album/201704/14/194207np44po1544r59o6j.png)
. y7 }) c2 _; f; ^9 x9 H, C复制之后以覆盖方式粘贴到ROM的40010,同样把第2关的PPU数据的前面2KB以覆盖方式粘贴到ROM的40810
0 W2 l- b8 x/ s3 B$ k8 {![](http://www.emu618.org/data/attachment/album/201704/14/194209v3buwrb3fjwvm4vm.png)
7 q1 k3 N& z8 @然后保存文件:; Q/ Y% o2 A; P& q) H m0 H6 a
, G& |7 q, B3 r2 {
最后用FCEUX打开文件,添加07F0-07F3的写入断点
2 j& l, e: H- v, K ' |7 H" |* q6 D) B: i
地图预览后即将进入第一关画面时程序暂停了,可以知道此时准备将C793的数据写到07F0:- u" U8 q ^3 j& j
![](http://www.emu618.org/data/attachment/album/201704/14/194217iuu3u3uvuu3rtll2.png)
2 d9 _- _* l h0 ^- `测试后知道将C793-0796写入到了07F0-07F3:! o6 ^) |# F6 H% R5 \
同理,经测试每4个字节一组,一共17组,其中01 04对应普通关卡精灵以及其BOSS关的精灵VRAM的bank号,01 05对应2,4关卡精灵以及其BOSS关的精灵VRAM的bank号,再加上一个通关后跳上飞机那段动画的精灵VRAM的bank号。* }+ K* R1 ]" `8 s4 R
0 h) h8 H, w l; ^3 M: s/ A0 J![](http://www.emu618.org/data/attachment/album/201704/14/194219gusvrtbn2utc2vz3.png)
5 s; I/ V& g$ q# i# }7 n" S然后将文件中标记的01 04修改为 80 04,将01 05 修改为82 04即可:
6 o1 A) h% W" Y/ U0 U l![](http://www.emu618.org/data/attachment/album/201704/14/194221bltohlzdkjkxfcxo.png)
& ?& h: v8 y: J! S: a# K保存之后重新运行后效果如下:2 [) \1 N* L) f6 W1 ~2 q
! ~3 ~" g$ r* v2 E. G1 Q. |
9 K8 _2 }7 q$ {
9 M7 i( P! B2 z0 R; A+ J
当前使用的是FCEUX模拟器,如果用NEStopia玩的话一开始就死机了,这是因为这个ROM有文件保护吧,它会往$6000里写入数据:3 N g+ S+ |$ u8 ]9 q; ~
/ I7 M% \( [2 E' z4 m
F863:A0 03 LDY #$03# r2 G% Z8 Q& J, `% v
F865:98 TYA G& v, C: l- N6 N" o
F866:29 01 AND #$01
4 y4 X: x2 }9 z5 H5 AF868:8D E9 07 STA $07E9
+ Q* K% R: f" R. R6 e7 [0 iF86B:8D 00 60 STA $6000# O- v T& U) a$ C
F86E:AD 00 60 LDA $6000
1 L J1 W! e0 \5 h$ zF871:29 01 AND #$01
8 r% x# y3 Z) K6 \' [+ s3 h& iF873:CD E9 07 CMP $07E9
. L7 x6 W# D8 @( O% V: vF876:D0 05 BNE $F87D
/ A; `1 p+ D+ g. ]/ sF878:88 DEY1 z+ i! o* T1 C1 x v( @
F879:10 EA BPL $F865$ b- u l4 a+ z: U
F87B:30 03 BMI $F8803 s0 Z( r% M) K1 I! h
F87D:4C 00 00 JMP $00008 n# w- _8 t' I- R3 y, \
F880:A5 1A LDA $001A
; G: j3 v& _ X$ {5 l2 J' eF882:65 34 ADC $00341 V+ u5 ?% C+ p2 u+ u
F884:85 34 STA $0034) f% U2 j8 O6 Z4 M, f+ H, _4 \
F886:4C 80 F8 JMP $F880
1 A; u, k# n# P, l+ t: s1 |; U先取Y值=#$03' R }! y* j' V& e; p% B- d
与#$01相与后得到#$01
) p* o) e* I# o; t# V写入到$07E9" A; _9 F- w0 e. K$ I0 k: c' L
写入到$6000
" G0 @/ U6 P2 p. W& l* J再读取$6000的数据和#$01相与后和$07E9的数据比较& O( V' x; i7 T1 S3 V3 y0 Y6 x9 X
不同的话跳过5字节
9 k* m1 d# ]1 O! D否则Y递减% v1 R, @/ A( @9 h6 X9 C% h
为正数就跳回0x100-0xEA=16字节8 h, w% T0 }- o" v$ P9 b4 b. ?
为负数就跳过0x3字节
" \ B" [! ?* d# G跳转到$0000(简直没有人性了,跳到这里死机,真想得出来)
' i) A d3 O! l# e: M# x |0 G0 U# j; [" b! X. k* h! r
正是因为这样,NEStopia运行FC时,6000-7FFF默认是不可写的,必须在ROM文件头第6字节的D1位置1设置ROM有SRAM,对于Mapper 4,还需要向$A001写入#$80来启用SRAM。8 B2 ]+ U0 `# [$ M! U1 L& [7 O
由于$6000不可写,因此想$6000写入#$01后$6000还是#$00,之后读取$07E9的#$01与之相比当然不同了,于是直接跳转到死机程序了。! G/ e5 l) Q3 F1 p) j* @, q ?9 }5 \
解决方法是把ROM中的所有的AD 00 60 29 01 CD E9 07 D0 05 88 10 EA 30 03 4C 00 00- r D* M# c7 e
中的D0 05改为D0 00,然后保存即可。
! J" ~* R, g( s, h+ B" @' @' @测试完美运行。
' {8 g6 i3 Y+ Y, u$ j, _# P![](http://www.emu618.org/data/attachment/album/201704/14/200424y1nggy1yf1mmyf11.png)
, }. F4 u# y$ Y/ C! K- U4 M
) @1 t, i* E: ?& T教程到此结束。/ D* R5 v) w* ]! d; i
: w3 H! [ I5 x: f. w$ p
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|