|
|
本帖最后由 yandagui 于 2017-4-16 19:06 编辑 0 X$ |( i2 H1 o3 L# z8 j; ]2 m
0 n; z% P6 G+ U, N
Mapper23转Mapper4实例教程
( d% v$ y5 x4 q- T/ Z) y! s
/ i) j8 V' v4 g3 l& p. JFlameCyclone 2017.4.146 y; G& @/ t+ E" i5 T/ Z4 H
3 Q% e- l/ r& q
先看看Mapper23文档:+ u4 ~: L8 V0 z* c
) C6 {0 K: G8 d, `, I5 l" h
Mapper 233 ^7 ^; l' i; p+ a1 I2 h
, l* @# r* T! q* Q- ^
$8000: 选择8KB的ROM存储体映射到$8000
2 E) q! u" t: }1 p# o: ^; z0 ^0 g7 t- I! @" x& V# _
$9000: 0:垂直镜像
1 M6 n; n* t/ [0 u7 ]7 @7 h 1:水平镜像
# @; K; \# A0 G2 r. q& M) b9 S0 { 2:$2400镜像
6 @% E, M1 q- k7 S 3:$2000镜像. U, b) V7 g1 |; i
- Z9 d2 }2 S$ J/ p# d: @$A000: 选择8KB的ROM存储体映射到$A0001 l( e3 C7 b4 k' W8 f" N6 U
* P2 J7 _/ t7 y! N$B000: 选择1KB的VROM存储体映射到PPU的$0000(低4位)- n) i# C6 X3 K) V# C
$B001: 选择1KB的VROM存储体映射到PPU的$0000(高4位)) X ]. M4 t7 ?; A
$B002: 选择1KB的VROM存储体映射到PPU的$0400(低4位)
( e* N$ k6 ^6 \3 Q* ]$B003: 选择1KB的VROM存储体映射到PPU的$0400(高4位)+ i/ {$ Q' D8 I* w! \0 m
7 i) w6 _1 z( A9 { T9 F8 ]$C000: 选择1KB的VROM存储体映射到PPU的$0800(低4位)% M4 m3 \' D U3 L
$C001: 选择1KB的VROM存储体映射到PPU的$0800(高4位)9 M( W4 [/ R' m
$C002: 选择1KB的VROM存储体映射到PPU的$0C00(低4位)
8 V' ^% d! s& H2 z$C003: 选择1KB的VROM存储体映射到PPU的$0C00(高4位)% X* N) L3 p* x9 ]# g9 u+ a) n
* L5 a# Z' M3 q9 V$ T- q$D000: 选择1KB的VROM存储体映射到PPU的$1000(低4位)6 r3 `6 n( G8 L2 K
$D001: 选择1KB的VROM存储体映射到PPU的$1000(高4位)
& j" d M) I. ^7 `3 X$D002: 选择1KB的VROM存储体映射到PPU的$1400(低4位)
$ d% c9 B0 H) N* A8 z$D003: 选择1KB的VROM存储体映射到PPU的$1400(高4位)1 h5 J; l- t0 i3 j
5 G% W" j# ?* T
$E000: 选择1KB的VROM存储体映射到PPU的$1800(低4位)
$ x+ F( Q' {; C0 @- {# W. L% A$E001: 选择1KB的VROM存储体映射到PPU的$1800(高4位)5 Y! Z3 @1 o* Q: I1 c5 K% E3 v
$E002: 选择1KB的VROM存储体映射到PPU的$1C00(低4位)
: @. j+ m/ M: k" W3 a2 n* h: ^5 N$E003: 选择1KB的VROM存储体映射到PPU的$1C00(高4位)
6 S/ m$ q6 ?0 A6 Q. `* _+ x! B3 c! a& p* g4 }; H5 y* M) h
再看看Mapper 4文档:
8 J% d; W8 n0 {( m5 q/ c- @- d3 s/ p: W2 `
Mapper 4
' ?+ D; W$ J/ N. H) d7 ^' N, v+ ]8 S( ]/ w* w( R2 n
$8000: 模式号. Z* e$ N/ y0 l7 U3 D
位D0-D2:# U" [5 y* }: _/ i7 Z4 w
0:选择2KB的VROM存储体映射到PPU的$0000
0 M+ ^$ W; T- R; H. N 1:选择2KB的VROM存储体映射到PPU的$0800
. G" z& X3 r! \# Y/ O) ? 2:选择1KB的VROM存储体映射到PPU的$1000' P* w* @' l1 g- `( n) @& |
3:选择1KB的VROM存储体映射到PPU的$1400# m: v- d: r: p
4:选择1KB的VROM存储体映射到PPU的$1800& L& r/ z/ l4 N$ w7 A7 \
5:选择1KB的VROM存储体映射到PPU的$1C00
% B2 P# E3 ]3 s: |7 H t6 h5 ]# l3 I 6:选择8KB的ROM存储体映射到$80004 U' {7 z5 i k1 u$ V9 Y
7:选择8KB的ROM存储体映射到$A000- |/ N$ g/ A8 S% m
位D6:
) B+ Q: ^9 g+ g, e# n2 V6 U 0:允许擦写$8000和$A000# }" @0 |* i' m1 `0 m$ W. A
1:允许擦写$A000和$C0005 E8 W% Q7 A' W- |' I/ d
位D7:/ x* N) c' Z7 d
0:模式号D0-D2使用普通地址8 Y& M- q" {# H' x& q0 N8 }
1:模式号D0-D2地址异或$10004 o6 H- u; d# D0 i. l
6 @+ E- X! K$ I4 L
$8001: 模式页面号
2 H# z) H- f! {, n 写入一个数(00-07),切换存储体到对应地址1 U3 k( h- ?! ^/ [( J8 h) W- f: d" Y: z
- Z+ M- `/ y" }
$A000: 镜像选择
V7 F7 D( r# z# r$ j3 Y 0:垂直镜像) `% E" P0 {, v2 b- \
1:水平镜像5 V# x2 b W, v' e* J& F6 S; C% F9 z
2 Q' i4 a5 A) o4 T" T$A001: SaveRAM 切换
. n0 }: s/ ?3 c3 O1 }2 W' `4 x2 n 0:禁用$6000-$7FFF' u+ u1 N/ w# b7 y( v. f- u
1:启用$6000-$7FFF
2 D2 H4 a* {2 W& j0 I0 S
7 V8 {$ P% K# e* Z) m8 L$C000: IRQ计数器! N# T& K3 i/ k* M5 f
IRQ计数器的值存储在此处9 Z% |' D: n% U. Q! f" I1 C
2 j$ X! R/ J- a$ G$C001: IRQ暂存器) p$ U, S5 v! z) k2 o
IRQ暂存器的值存储在此处
7 {0 H! I" }9 d6 u$ F! c& D, n; r P1 V8 o% ~' O; r
$E000: IRQ控制计数器0* Q4 Y! `2 [3 K6 b
向这里写入任何数来关闭IRQ,并从暂存器中拷贝数据开始计数,进入IRQ. @) f `0 r6 @% H
! ~9 V9 R" k" n5 r' A! x; Y0 _
$E001: IRQ控制计数器1
0 T9 H4 X1 |/ u! ~8 ^+ Y' x/ e e 向这里写入任何数,允许IRQ(退出IRQ,允许下一个IRQ进来)# x% s7 x+ B, U! p! e8 T( c( }
6 r0 F% q `$ e2 m7 W) d2 C6 V3 L0 d9 s# Q, m1 X
转换思路:7 {' G4 {) P/ C3 y2 ~$ [
将Mapper 23 的切bank 方式和切VRAM的方式修改成Mapper 4 的方式。, v& S1 w4 X) X% M" [# Y
1 e4 g# Q" ^) v修改实例:+ k1 r5 F6 j) \2 N* `
Contra (J) 256KB Mapper 23
" j9 f* I p. Q/ |工具:
* t% Z+ c' s# \$ d1 f1.FCEUX 2。2。3
( X+ r. p0 C1 @/ h3 g2.HXD7 \9 A& Z- D: S4 E; y. }
先来看看这ROM的切bank方式:+ w0 w+ I" g7 t. b8 V
F989:AD 00 80 LDA $8000 + |& t1 H; ]* U: u j8 d5 v- t9 |
F98C:8D EC 07 STA $07EC
' B9 c4 [) M* N8 o6 J6 w1 mF98F:8C 00 80 STY $80007 R* c4 Q4 T; Q# o' R8 @. b
F992:C8 INY
/ Q! C# F; L- b9 }% O7 v% vF993:8C 00 A0 STY $A000
9 X) `! y7 E gF996:60 RTS
( Y2 O* I# U+ \$ f/ j
3 i9 Y. d5 X/ u- Z" ]再看看它的切VRAM方式:: Z9 `: E6 F+ h- S* r% r
FACE:AD F0 07 LDA $07F0" y' c- V, R+ D# N: `
FAD1:8D 00 B0 STA $B000
3 H. O/ {+ [" G$ |) R0 ~FAD4:4A LSR
% s5 F8 W$ q4 A8 \ d3 }6 KFAD5:4A LSR
' ?0 F4 S- k- G# w; {* iFAD6:4A LSR, u0 e$ T& Q: h9 x# u' M
FAD7:4A LSR0 X, `( B2 M u0 l% P" S2 y4 J. y
FAD8:8D 01 B0 STA $B0017 s3 l* d6 n3 y2 T2 _
FADB:AD F1 07 LDA $07F1
( n7 Q: j0 D! Z3 R5 u# ^, F1 \, K0 KFADE:8D 02 B0 STA $B002$ N# V! D# U5 k. \% }
FAE1:4A LSR$ S) W2 n; A P2 O, l+ S* \1 M
FAE2:4A LSR
2 p a" i; J+ j, eFAE3:4A LSR
8 @9 ^: E6 O' i/ a9 }1 `FAE4:4A LSR
3 K+ j, B3 C! C( X! d" }; ZFAE5:8D 03 B0 STA $B003
' {4 U$ N! w) h5 L$ M2 r; C& cFAE8:AD F2 07 LDA $07F2, f5 v, o2 m( ~6 M
FAEB:8D 00 C0 STA $C0001 r+ `3 H8 W( B2 m! {1 _
FAEE:4A LSR7 P8 t* H3 m2 o' n
FAEF:4A LSR
+ G# G3 q9 ]# i/ K2 xFAF0:4A LSR0 b" w0 C$ a# \3 M
FAF1:4A LSR' S7 }9 L& S9 A1 @
FAF2:8D 01 C0 STA $C001
2 Q" x# [& x$ l8 N, s- lFAF5:AD F3 07 LDA $07F3
0 N% {; @" l* T* d- t; zFAF8:8D 02 C0 STA $C002
4 f w5 J3 Y$ c3 F* |; eFAFB:4A LSR
" w. J" V R& t4 v) x; s mFAFC:4A LSR
1 l& j! l$ b, sFAFD:4A LSR! \5 M9 K7 i0 ~ f, G$ l
FAFE:4A LSR; ]" s4 w: Y) z( ~% e
FAFF:8D 03 C0 STA $C003* C0 | Z# Z5 C! g
FB02:AD F4 07 LDA $07F4& p6 i6 U& [' }1 s5 w* X( \9 P+ C
FB05:8D 00 D0 STA $D0008 V. h( x+ O8 g- B
FB08:4A LSR9 a) N, i0 t8 P. }* P8 Z
FB09:4A LSR
9 K% H4 [5 v% h' A8 r0 O! D/ GFB0A:4A LSR
& L. G Y3 {! [* t( c; TFB0B:4A LSR
1 P( N' H, j- {: BFB0C:8D 01 D0 STA $D001
" T7 G: t' p& i# j( p: s8 [FB0F:AD F5 07 LDA $07F5& t* k5 B: p9 z! s8 X* E1 V
FB12:8D 02 D0 STA $D002; N0 K" x$ ~2 Y' h5 m5 a1 C2 p
FB15:4A LSR
" d z0 k2 U- T9 a- mFB16:4A LSR6 P# H; I1 N% ^ [ S; T
FB17:4A LSR2 Y! y: N- i2 I( A' K
FB18:4A LSR1 q. @3 r2 E8 K6 Y6 [: `
FB19:8D 03 D0 STA $D003
) {" Z7 h2 X- J, x7 IFB1C:AD F6 07 LDA $07F6
/ \. L. A! l+ Z1 X* [! T) uFB1F:8D 00 E0 STA $E000
' f0 x0 e" v3 v) Q3 o% NFB22:4A LSR6 E6 O5 t: L8 K* r8 X6 t
FB23:4A LSR
1 l% D2 H- u3 ?0 P5 pFB24:4A LSR5 Z I$ b% Z! L* w0 d6 i# A/ p5 Q
FB25:4A LSR* U% u: X2 v; m
FB26:8D 01 E0 STA $E001
S" ]; P" C5 s8 ?+ rFB29:AD F7 07 LDA $07F75 }2 u! {+ T7 O) c& n
FB2C:8D 02 E0 STA $E002
! K* s5 b8 n) B% |6 [: a, F8 A u2 IFB2F:4A LSR9 ~; A0 r9 C+ j0 E; q/ L
FB30:4A LSR
/ H' w( ^" C0 z8 h8 ~) R3 q+ N GFB31:4A LSR
" T8 v5 l! y0 m' QFB32:4A LSR
# z/ ~1 B" Z4 c6 Y" h1 BFB33:8D 03 E0 STA $E003/ ^2 m7 v5 H3 x- Z) z! w$ N, m
FB36:A9 00 LDA #$007 t i, M7 ^1 v) S1 A. ]* {
FB38:8D 00 90 STA $9000
2 j! U9 K( C' P3 t5 fFB3B:60 RTS* H9 t9 B* I8 q! j1 s
7 o: Y' }+ f, O) m) B: V2 [0 e接下来修改切bank方式:; b" l* {5 l7 h8 g( e6 E! O3 H
FB2B:48 PHA8 o9 c+ R6 n: Y t' a+ A; a$ p% y
FB2C:A9 06 LDA #$06( Y% }' Z' k; d% Q2 r$ J, J
FB2E:8D 00 80 STA $8000
* B7 i* ~' g- X# F% S" nFB31:68 PLA# n) t0 h2 ?; b* T
FB32:8C 01 80 STY $8001 `/ T2 p+ j+ U5 T, a
FB35:60 RTS- u7 G9 Z# A+ p' ~' P/ j4 r
. z- q; l: p2 n0 H4 D% h
FB36:48 PHA
. H, z/ c% ~5 c( pFB37:A9 07 LDA #$07
; A% ~4 ^& y2 S. [0 ~FB39:8D 00 80 STA $8000 = #$14
6 W6 Y( b' O2 E5 x9 bFB3C:68 PLA
& x, j; E5 K' ~& P) {/ oFB3D:8C 01 80 STY $8001 = #$1D j. J. g+ J+ t" z& ?5 P
FB40:60 RTS: ^4 W: S. V) O T
; f% p" }7 Z* U& a% l0 V* H还要把原ROM的对$8000和$A000进行写入操作的程序修改一下:+ L% R/ E% f# x% j
F989:AD 00 80 LDA $8000 + \8 ~1 b/ a: S0 S4 ~- E8 i
F98C:8D EC 07 STA $07EC3 J% B7 h8 O7 `1 n4 B. I
F98F:20 2B FB JSR $FB2B
4 q8 d: I4 r) \F992:C8 INY
2 D$ \9 P, J. j# _9 QF993:20 36 FB JSR FB36
. o1 i1 z& s @. w" R$ AF996:60 RTS& w c2 c- F8 s- G
: j4 V# e0 l" R9 `" {: a再修改切VRAM程序:
! ]& s* R# z/ b' f9 `FACE:A9 00 LDA #$00
7 c8 F! ]: I) f) T; g Y. s! w6 X! ~FAD0:8D 00 80 STA $8000! k, V; d6 w" |' z4 d
FAD3:AD F0 07 LDA $07F0
, ~, o3 R" ~" @. K6 _FAD6:C9 01 CMP #$017 b e9 R. q% h7 J
FAD8:D0 11 BNE $FAEB
$ A$ t3 x5 g+ F, wFADA:AD F1 07 LDA $07F1
$ M2 X$ @4 x' Y* ]. f( c; v1 r8 e4 gFADD:C9 04 CMP #$04
8 v# C7 d' d8 q6 j' p" tFADF:D0 04 BNE $FAE52 V, ]- g( [+ c
FAE1:A9 80 LDA #$807 w. a9 f3 s4 Q5 v. B7 \4 j$ N8 ?
FAE3:D0 06 BNE $FAEB
( u, L- \0 G; v B2 SFAE5:C9 05 CMP #$05
% }' l$ m/ b. W" G9 s0 aFAE7:D0 02 BNE $FAEB- ?7 P9 u, n: y8 |) b
FAE9:A9 82 LDA #$825 Y, T7 T& Z& k, U2 \
FAEB:8D 01 80 STA $8001
$ m! t j* v* G7 j/ v) r, YFAEE:A9 01 LDA #$01! C7 l* {3 g9 A
FAF0:8D 00 80 STA $8000" Z0 T$ R* @- Z' Q
FAF3:AD F2 07 LDA $07F28 H9 H- B5 [$ X
FAF6:8D 01 80 STA $8001
, M2 Y8 o @- Z7 J: ?9 L' {* ?FAF9:A9 02 LDA #$02
1 F+ B# Z. j7 N+ y* c2 t! rFAFB:8D 00 80 STA $8000
y7 W' u! i8 @+ Q9 l2 o+ SFAFE:AD F4 07 LDA $07F4
- v* _/ |* q, }+ wFB01:8D 01 80 STA $80010 c6 Q3 U" P( b$ Z& x( s9 b+ c0 o3 @
FB04:A9 03 LDA #$03- y$ R7 `9 e9 ]2 F& n& c7 Z+ p. ?9 p
FB06:8D 00 80 STA $8000. N; i1 ?. P9 a. D
FB09:AD F5 07 LDA $07F5
- r7 Y- W4 ]+ i4 j! tFB0C:8D 01 80 STA $8001
D; z+ T0 T9 _/ \$ nFB0F:A9 04 LDA #$04
: J: E" E" c4 k0 k, r2 dFB11:8D 00 80 STA $8000
8 N/ {. F" p$ k4 t/ x- s5 n% IFB14:AD F6 07 LDA $07F6) i F o! P" M3 \
FB17:8D 01 80 STA $8001
+ [* ?1 p% G) J) L' @8 BFB1A:A9 05 LDA #$056 K2 I+ B, J! h0 d. |& C
FB1C:8D 00 80 STA $8000
# X* l1 h$ p; F6 { E1 L/ MFB1F:AD F7 07 LDA $07F7& A$ ~( Z7 V4 g9 d. W6 |
FB22:8D 01 80 STA $8001
# I' m8 R8 \6 w* v' EFB25:A9 00 LDA #$009 ^: J: p M- X: I
FB27:8D 00 A0 STA $A0002 K; b2 H- I: S% o. l
FB2A:60 RTS
& B- ], Z7 K9 H/ ]) Q0 c9 m7 }
" W, Y7 ]4 C2 E& B# ~然后保存文件。
1 w) L P+ m+ b. J; t- }0 u使用HXD修改文件头:
1 r7 s0 {8 A1 g3 M; `7 O3 D将Mapper 23
! m4 C2 Q7 ?3 ^- L+ _: `' D4 K06字节的高4位是Mapper号的低4位
# _4 _6 U5 v# L0 C3 R. _8 Q- h07字节的高4位是Mapper号的高4位
/ Z: X6 u6 V& c* o组合起来就是0x17=1*16+7=23# {! _6 x- ?; y( d1 B3 g6 E/ r/ S/ J

* b7 ^1 l' g8 q4 T修改成 Mapper 4
0 U9 u+ `, T6 T# n/ ]' h
1 {- t# E1 J: H- t& A6 Q
0 i* {3 l: `& D! m- Y
- D" ^# X* B1 D- [; o& V再次打开文件:* F) X/ _7 t( K+ i0 r* G! q; o3 ~

8 _( [: y$ X" U/ s可以正常运行! p$ S( @7 |: l% H# g9 \( V
通过全面测试,发现出现精灵错乱:
" E2 Q, K2 P: G& p第1关:
% d" X4 m" K2 z3 t: m9 Z / i9 c9 ?& M* d- X3 `) S
8 {8 l2 \3 \& A0 i7 {$ J0 |
第2关:
( c; C! v- E% o# }* B
* D9 ~( c9 ^' c6 [) ]/ b; N任务失败后: _; n: A# P$ C- T7 m! U/ \
7 K0 v. e* @1 w: |* a, j
通关后上飞机画面:
9 E4 M' Y/ K& } `! i4 Z4 x+ w$ E 9 Q9 H' @; Y# U- {
这是为何呢?' n5 k" g* B' `* [9 R* c
这是因为Mapper 23 中精灵VRAM切bank是一次切1KB
; {& E. `% P/ O7 v/ A0 v; K1 }; d但是在Mapper 4中精灵VRAM切换却是一次切2KB,而且忽略bank号的D0位
# `# x0 z& @ v6 w( `7 B比方bank 0和bank 1是同一个bank,同理bank 2和bank 3是同一个bank
: R* e6 t* O/ ]# m也就是说
! I7 b$ k9 n; L/ p, ~) LMapper 23中的VRAM的8 a8 z* R2 N4 x% X' U+ }
bank 0,bank 1,bank 2,bank 39 q" {5 ]: c$ }
在Mapper 4中对应的是' ]% e8 l) ~3 p1 r2 F9 a! v Y
Bank 0,bank 0,bank 2, bank2
' f4 J! u" _! \( C' x8 z然后查找原来的ROM的切VRAM的程序:
* {8 s! p- U1 O! ]知道是从07F0-07F3切到精灵VRAM的:( J" ?) k7 B- Y" @
如图所示:
& e1 ~# z) Q) `5 P5 `4 F( W
, M. M1 X( G' U 5 z: D2 _4 w% y5 n4 x t
作为对比,左边是原版,右边是修改。% E, k1 K- S& b3 Z7 Q+ H
接下来是完善VRAM切换带来的问题,因为Mapper 4只能切2KB的bank,所以我们不能通过切bank程序解决问题。# U, V# ]9 y3 o T4 K
通过测试知道1,3,5,6,7,8关的精灵VRAM排序如下(07F0-07F3):
- ^4 v% c( Z. u8 [, g8 ~# d01 04 06 07
. `2 y/ s2 k& Q: P x3 G. {8 a第2,4关如下:2 K% h; K5 ^+ b8 m& P
01 05 08 098 ]+ y7 G) m# U0 {
任务失败时如下:
4 ` z/ w# [, {' t. u* ^( F5 G1 w% Q32 00 00 1B
+ _* v" Q8 ]0 B, c% ]0 d其中任务失败时对应的VRAM是07F3的1B,只要让07F2为1A或1B即可:
7 P0 V- @% N6 y& J通过调试找到对07F2写入数据#$00时程序如下,于是修改C7E5的值为1A即可:7 @- W) M) U) {- E+ N7 c5 T- d1 A' z

E5 `/ Z- D8 G, Z" E' b1 a转到ROM地址:% a/ H2 e9 v; ~1 x/ |/ d. m
4 g3 L0 a0 K' ?1 O. Z+ D# G! b
修改数据:7 T r# V6 h, V2 t+ ?. L e* q
0 j3 N& `0 B. @% d4 |- S
重新失败后可以看到修复成功:
2 [ n3 K' O. u$ ~. E 9 i- v- A: V, @9 B" i( A4 B# X
接下来是修复正常进行任务时的精灵错乱问题。2 H5 j/ Y3 m2 b# P. ~- Y, F( m
首先运行Mapper 23版本,在1,3,5,6,7,8关任意一关的时候,将PPU导出来
9 k$ z) S) y% s; n) }- \
1 t c% H4 Q B5 S8 }) n( S" z
1 c A9 f/ c q* q7 e! w / q: `/ `8 F* M6 S! h

/ n5 E2 z5 h9 m% O# x6 r; ]然后用Hxd打开修改的Mapper 4的ROM和刚刚保存的PPU的数据文件:
. |. ~3 j7 c% R$ Q$ l ( L9 B1 z; @$ g5 A |
在ROM文件头第05字节改为0x20:5 [7 Z. j! F. D" e* Z0 L
# z8 N- I7 D2 r" @ n, v/ f
然后转到文件末尾,插入0x20000字节空字节:! W+ Q7 H2 b. o D, c) k. _2 O B9 l8 P
3 N( j; S/ p! k/ O+ |% Q
3 D. E! h7 S5 C' D

. d M* [+ ` p) G8 w " O. L1 i8 @5 K# U
然后将第1关的PPU数据的前面2KB数据选定:, b) h& m0 t+ D6 j( V
! V* b3 t6 f* V q0 N8 N- M8 s7 e

/ v( P0 S' }3 v& h& P8 m- O* H
3 W$ f s+ d2 a* ?; Z# ?7 ~ |0 i" i. ]复制之后以覆盖方式粘贴到ROM的40010,同样把第2关的PPU数据的前面2KB以覆盖方式粘贴到ROM的408103 k2 Z3 d7 C l- p I5 ?

! R7 j {2 {+ f) g! G$ F3 U/ n然后保存文件:2 D+ k- S2 O# y9 k7 H) U6 [

$ G, V6 o& @5 i. ?3 {( y2 i5 A8 h最后用FCEUX打开文件,添加07F0-07F3的写入断点
" W' P4 V' b5 s: o! N8 p
( X6 e! p+ U, s* z: w7 J地图预览后即将进入第一关画面时程序暂停了,可以知道此时准备将C793的数据写到07F0:
1 r' \9 c( q+ p, u1 \0 f5 X$ d% a* F6 O
@. \# [+ Z2 b$ a测试后知道将C793-0796写入到了07F0-07F3:. ]4 r7 l% o. t9 O) |* ^
同理,经测试每4个字节一组,一共17组,其中01 04对应普通关卡精灵以及其BOSS关的精灵VRAM的bank号,01 05对应2,4关卡精灵以及其BOSS关的精灵VRAM的bank号,再加上一个通关后跳上飞机那段动画的精灵VRAM的bank号。. H0 V' h* @/ K! l9 X
: G6 S d' d, g8 z

e9 t; i" j) e" r7 c) K4 C然后将文件中标记的01 04修改为 80 04,将01 05 修改为82 04即可:. u6 o( P2 S8 f( ^! l

3 u/ Y1 `5 j6 ?4 j$ w保存之后重新运行后效果如下:
( L9 z% l6 a" M# M1 l
3 E. d* n+ z, l$ r, f+ L* N 2 v, K) D$ H: y% v6 G. \5 `
) g P1 f. k; U0 M* M
当前使用的是FCEUX模拟器,如果用NEStopia玩的话一开始就死机了,这是因为这个ROM有文件保护吧,它会往$6000里写入数据:
1 m! B9 s% `, Z1 A( Z% ^3 Q
\! E3 I4 O7 ~) oF863:A0 03 LDY #$03
) K" N7 g& T- u. \% tF865:98 TYA
; F7 U0 {5 v* g; x6 VF866:29 01 AND #$01
; ^+ ]% Y4 i2 _0 z' E4 A" UF868:8D E9 07 STA $07E9
6 k1 ]) ~1 s! w) ~, n7 R8 v7 l. \F86B:8D 00 60 STA $6000. K" S1 |; Z3 a+ Q) D
F86E:AD 00 60 LDA $60004 _/ E' w/ o* [ T# |- L x
F871:29 01 AND #$01
. J7 ]0 v% w( Y |* b! \& ^F873:CD E9 07 CMP $07E91 q. B# i' `: @
F876:D0 05 BNE $F87D
9 \# [8 ?( B5 h- B( \F878:88 DEY6 u3 @$ m) B: s% w- Q; K
F879:10 EA BPL $F865" [& V8 b$ G3 T8 d8 _. M, V+ C
F87B:30 03 BMI $F880
/ k3 s- C. T9 [' r. v8 kF87D:4C 00 00 JMP $0000& q6 A+ K6 H; ~% l
F880:A5 1A LDA $001A; f* `1 u/ T1 W. U" E7 H- r
F882:65 34 ADC $0034
2 c2 \6 i" V5 B# qF884:85 34 STA $00349 R) F4 x+ v, ?+ |7 n+ J
F886:4C 80 F8 JMP $F880 \+ o: O- Z @3 l
先取Y值=#$03' |/ w( h8 J4 \& w5 O+ J
与#$01相与后得到#$01
. e8 O' N4 }: z0 y写入到$07E9
p& F& }( {: c) ?$ W: a* c0 Y写入到$6000! w1 w0 z0 g9 R- I$ O
再读取$6000的数据和#$01相与后和$07E9的数据比较4 z2 O9 z- J8 T$ L7 d
不同的话跳过5字节
' T! D' W7 p6 K& ]; B否则Y递减
& t; {& s v& U i6 M: P( R为正数就跳回0x100-0xEA=16字节( P5 X$ p2 E+ T
为负数就跳过0x3字节
; G7 h5 j) X s j% ?跳转到$0000(简直没有人性了,跳到这里死机,真想得出来)
' ]; V+ W3 _6 p/ O
" X! o/ z$ y& |; j8 {正是因为这样,NEStopia运行FC时,6000-7FFF默认是不可写的,必须在ROM文件头第6字节的D1位置1设置ROM有SRAM,对于Mapper 4,还需要向$A001写入#$80来启用SRAM。
6 \1 d" C- O* M S$ f由于$6000不可写,因此想$6000写入#$01后$6000还是#$00,之后读取$07E9的#$01与之相比当然不同了,于是直接跳转到死机程序了。1 N/ _3 q% W. g. Y) \
解决方法是把ROM中的所有的AD 00 60 29 01 CD E9 07 D0 05 88 10 EA 30 03 4C 00 00
- I; f, S. `* x2 B% D中的D0 05改为D0 00,然后保存即可。$ P; y8 s) E* X1 j% v
测试完美运行。. m+ \) n2 _' p7 ]

8 F7 z5 q# x( Z, m! a' y: i' j. k
8 b0 U6 W; `& _) g \" J" S教程到此结束。* h) r$ |( W! H' L7 D/ L0 g
) J9 _3 [/ {8 H: S2 Y8 V2 l2 _ |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|