|
|
本帖最后由 yandagui 于 2017-4-16 19:06 编辑
/ _- K8 e. U) ?* J0 i# {" d: k# q5 o0 I8 r. ?
Mapper23转Mapper4实例教程3 D' |7 U& o. ]8 N6 r# S
7 S( k: m! V [9 x- X) v6 M
FlameCyclone 2017.4.140 ~4 z# A2 L* y9 w
7 n* c' y2 F, F5 ^/ N# R
先看看Mapper23文档:
0 Y# G0 k( ^0 N, [* w" `& x; o B4 B: S! {( h. @
Mapper 23, |- H% F0 e+ D! i; A, s' b
) L) p7 v0 I9 a& ?' f
$8000: 选择8KB的ROM存储体映射到$8000
( v! m4 B; C0 G* V) r; x
) ~5 X1 w- O# F$9000: 0:垂直镜像
" {' }6 L4 Z5 D; K3 t2 Q 1:水平镜像
% a( p" M, b5 ]" M3 T* r4 E 2:$2400镜像6 H* I2 Z# S1 z
3:$2000镜像
6 X& a y, E0 k; ?9 ?8 J4 |2 N$ t4 n/ [3 B) Y: @( N& e0 M
$A000: 选择8KB的ROM存储体映射到$A000
5 x: `4 ?8 g ]7 t. o5 U3 x) k
. L$ I! n! f5 X1 v% a7 n5 N$B000: 选择1KB的VROM存储体映射到PPU的$0000(低4位)
3 S* A* n n+ @* |" Z& U$B001: 选择1KB的VROM存储体映射到PPU的$0000(高4位)
+ U4 }, p% M! B2 T( Z$B002: 选择1KB的VROM存储体映射到PPU的$0400(低4位)
" a) b$ e9 l: p$ {. O m, @! `$B003: 选择1KB的VROM存储体映射到PPU的$0400(高4位)
; [4 {' X( k6 s( m" R' t$ f3 h8 V) X: A
$C000: 选择1KB的VROM存储体映射到PPU的$0800(低4位)8 `% f; N0 {" s3 I- c
$C001: 选择1KB的VROM存储体映射到PPU的$0800(高4位)
2 l! r4 x: m5 e" O2 U1 b$C002: 选择1KB的VROM存储体映射到PPU的$0C00(低4位): A6 }9 U! p" ?
$C003: 选择1KB的VROM存储体映射到PPU的$0C00(高4位)
) ]' U+ t6 U3 T9 }1 _" b* B: l
7 D* H, }2 d% q, ?$ d3 j6 m5 N3 ?$D000: 选择1KB的VROM存储体映射到PPU的$1000(低4位)) U8 P. K3 U) k9 r# T- E y; z
$D001: 选择1KB的VROM存储体映射到PPU的$1000(高4位) k7 a3 Y9 s; B' S- h i9 J
$D002: 选择1KB的VROM存储体映射到PPU的$1400(低4位)
$ G, L" l: Y1 N; D/ p; z \$D003: 选择1KB的VROM存储体映射到PPU的$1400(高4位)
+ w/ `% A" r4 z% n$ t6 M. {# A! V3 A& T5 S
$E000: 选择1KB的VROM存储体映射到PPU的$1800(低4位); ?$ K: Q' t+ \# d( j# o
$E001: 选择1KB的VROM存储体映射到PPU的$1800(高4位)- w5 S$ L7 }: n$ O0 l7 Q5 E
$E002: 选择1KB的VROM存储体映射到PPU的$1C00(低4位)
1 D( _4 |; G# e/ p$E003: 选择1KB的VROM存储体映射到PPU的$1C00(高4位)9 _ a3 a; }4 \6 [7 ^5 u- Q" ?
0 r0 j' s- b& ]: T2 Z# @$ l再看看Mapper 4文档:+ z' t7 [" v$ E2 H' O2 C
3 m! c! ~" h8 G4 S9 V. _
Mapper 4
. d( r1 L4 U2 i
9 f# Q7 d* ^/ v# `$ p l$8000: 模式号
! V* u6 P( E. C3 \) H7 _; U' o& q 位D0-D2:
; ^: ~+ g0 d# v* d. Z7 o+ l 0:选择2KB的VROM存储体映射到PPU的$0000
8 L1 _0 h l7 i& R6 a 1:选择2KB的VROM存储体映射到PPU的$08005 c# U5 F. T. p
2:选择1KB的VROM存储体映射到PPU的$1000
# \) e$ B) R+ q9 f: O* R 3:选择1KB的VROM存储体映射到PPU的$1400
/ ?( z/ V) p: R U0 u. ?% n; l 4:选择1KB的VROM存储体映射到PPU的$1800
+ o7 C! f; ^* A% u 5:选择1KB的VROM存储体映射到PPU的$1C00
( f1 d7 M" d# W 6:选择8KB的ROM存储体映射到$8000
0 [( ]$ d4 h3 Q7 Z+ g8 Z9 U+ y8 m 7:选择8KB的ROM存储体映射到$A000& j/ N/ ~" m2 C' L2 w
位D6:
! I6 ?7 B; ?8 Y$ @* A 0:允许擦写$8000和$A000* ?4 A9 c% Z& ]% K% v ?
1:允许擦写$A000和$C000
. F* x& n4 \* A% Z 位D7:2 {5 h0 g) r% N# [" {9 A. P- l
0:模式号D0-D2使用普通地址- `9 R* [9 P; X" E7 G1 k8 k
1:模式号D0-D2地址异或$10000 O& l, V' v8 D7 z. r# |* O4 z/ p
# f( e/ V' j$ Z& K# i
$8001: 模式页面号
! i3 P+ } P9 _3 l6 m. p" V 写入一个数(00-07),切换存储体到对应地址
2 Q( L- p5 c& ]; ?. k8 X! [: y# Z% w. T4 M0 v
$A000: 镜像选择
3 b0 D1 v, Y3 q 0:垂直镜像% T+ {* P4 c' s1 s
1:水平镜像9 d% e: P7 Q Z% f Y) l
8 s1 u6 E% U! c9 g7 H$A001: SaveRAM 切换9 o( E& l' k3 G! z
0:禁用$6000-$7FFF
- n$ @' v6 ? q' R 1:启用$6000-$7FFF
, U1 P1 [1 t/ r( U- y2 g
# {; k2 m# c4 J' l/ {2 O% z7 F/ l$C000: IRQ计数器, ^: M. g' u* X2 E" f
IRQ计数器的值存储在此处. A/ A9 G& i- E3 |; J9 m1 `
0 Y2 H; d+ g# ?# R. F$ q; R7 x$C001: IRQ暂存器
8 z$ H5 o! s+ g) r* G IRQ暂存器的值存储在此处+ T* z( h: ^4 w& X7 |
, v( l$ e2 K% U* M; z$E000: IRQ控制计数器0' ^; h% n% X4 O k* `6 H3 J1 M
向这里写入任何数来关闭IRQ,并从暂存器中拷贝数据开始计数,进入IRQ7 Y8 `4 H- b$ ~. D* r1 \
9 Y5 t: j9 O5 w. I8 {9 ~3 \$E001: IRQ控制计数器1) `2 T, P- {& b8 v. U/ X
向这里写入任何数,允许IRQ(退出IRQ,允许下一个IRQ进来)8 [) M5 ^3 q; X9 ^* W
( @' D" m2 a/ x+ D) a* ~6 {4 L% ^
" D, j. p/ }0 G- i9 o' |5 B转换思路:: o6 Y- a- s4 J; G! H+ L r
将Mapper 23 的切bank 方式和切VRAM的方式修改成Mapper 4 的方式。
8 a! G8 U$ U5 S$ ^" H* z* p7 V% ]: N/ ~( _
修改实例:
9 {' c& B3 O* ~/ d9 ^: oContra (J) 256KB Mapper 230 ?! @# z: J$ u! c# \ p) L3 V1 h
工具:
/ ^6 k5 } {/ f. i* S1.FCEUX 2。2。3& o5 y9 s) D! D% `+ n( w' o
2.HXD
' c) y: k% M N4 ~, Y先来看看这ROM的切bank方式:
* K+ R- U) I qF989:AD 00 80 LDA $8000 " R7 ? z" D! a. V: p
F98C:8D EC 07 STA $07EC3 l X6 T! F6 ~8 Q9 A2 w' t+ }
F98F:8C 00 80 STY $8000
9 w: S- D" W8 Y, a/ q6 O d* Q. ]F992:C8 INY5 ^* Y$ I& u+ b& q* i
F993:8C 00 A0 STY $A0003 _9 S% N. q" a/ b+ R# N; Q
F996:60 RTS8 C. Z: H. r0 b
! l) B7 y- D6 R0 K
再看看它的切VRAM方式:$ f" s! }# I" R5 ^3 i$ B- H* ]
FACE:AD F0 07 LDA $07F0
k5 n8 I1 P, q9 \& {7 o+ {FAD1:8D 00 B0 STA $B000
& Y; E8 \) |, A! s& l; j) A# i' lFAD4:4A LSR
9 J) y% J2 Y% |3 E6 B+ A9 qFAD5:4A LSR
# z$ @! w- k* `FAD6:4A LSR) E9 |3 s! D1 a# }4 M9 q
FAD7:4A LSR6 t8 @6 G# u7 w9 Y; m& G: S
FAD8:8D 01 B0 STA $B0013 v; ]! N) g( H6 u: S. G# ~
FADB:AD F1 07 LDA $07F1' P6 R: @! ?( q& D) F8 h; C
FADE:8D 02 B0 STA $B002
7 H' T" @* j$ p1 wFAE1:4A LSR+ j8 f3 `: T. N) _ q
FAE2:4A LSR0 ]! {4 \* h6 }
FAE3:4A LSR
& _: m5 m6 y% `! d+ V# a4 o4 X* _& `FAE4:4A LSR
4 F. A3 [6 L& HFAE5:8D 03 B0 STA $B003* \4 }. X9 G4 K- {' Q
FAE8:AD F2 07 LDA $07F2
Q3 N6 W e) B9 t' C. L `FAEB:8D 00 C0 STA $C000
4 F- E7 `% i# k% T5 X& o: u- l+ bFAEE:4A LSR7 ~5 d' s# x. C% K* F. c
FAEF:4A LSR) e3 e0 _7 Q1 R8 X3 A
FAF0:4A LSR. t Y1 o1 j5 q7 h
FAF1:4A LSR, f, C/ o% |9 j2 O! F* F% `# U
FAF2:8D 01 C0 STA $C001
0 j3 D: }5 t/ n, U" Y4 oFAF5:AD F3 07 LDA $07F3
7 j2 z' C# F( ?, ZFAF8:8D 02 C0 STA $C002
2 ?, R: ~* Z: ~7 V5 o' pFAFB:4A LSR
: n% { o7 r, [( wFAFC:4A LSR
- b3 B& M: @1 u2 Y. z! l& ]FAFD:4A LSR
2 q# z( l* G! z; UFAFE:4A LSR
: k6 h H6 B* U- DFAFF:8D 03 C0 STA $C003
1 q/ h/ B8 ]8 P2 e! dFB02:AD F4 07 LDA $07F43 |! n3 ]9 n# j% {' V w& b: O/ z
FB05:8D 00 D0 STA $D000
9 Q# @/ O2 u7 Q3 u& H( XFB08:4A LSR
; H9 w2 U0 v/ l! ]) \) l; `FB09:4A LSR
9 p0 h# @ h. U( C4 F' H9 MFB0A:4A LSR
& z f r2 ^5 n3 cFB0B:4A LSR
1 E# f& p' o& R# b' t* t# h( ZFB0C:8D 01 D0 STA $D001
" X. U q* f4 |9 j. l* ~FB0F:AD F5 07 LDA $07F5
0 m, [& I- ^- _FB12:8D 02 D0 STA $D002
" w% M7 R: a! l* h( tFB15:4A LSR8 Z( r$ @" z, P1 K4 `2 ?
FB16:4A LSR/ w. a- N; G3 N' Y
FB17:4A LSR6 m8 b. H; r! s8 A. u
FB18:4A LSR
% J- y6 K* i+ {9 C3 pFB19:8D 03 D0 STA $D0031 g0 ~0 T3 E% D* S$ v/ q* T& P
FB1C:AD F6 07 LDA $07F6& z9 ]% n, W9 C5 q
FB1F:8D 00 E0 STA $E000
( S6 z; `- v( s6 f$ U QFB22:4A LSR' c2 m1 n0 S% k b) f+ K8 f
FB23:4A LSR
% Y6 g1 B9 _# `8 oFB24:4A LSR
: S+ `) c7 W$ T/ ~) @FB25:4A LSR7 @/ n7 ?4 r- \* C! z% |5 C
FB26:8D 01 E0 STA $E001' @$ P3 }% s: m Z j9 _' f
FB29:AD F7 07 LDA $07F7
; f( Z3 d4 o7 {. Y& mFB2C:8D 02 E0 STA $E0020 j2 Y) d: v9 d) u3 \+ N4 w
FB2F:4A LSR
. x0 o/ t- a7 XFB30:4A LSR' \0 G2 ~+ o: @9 `, Y* `
FB31:4A LSR
: C8 w4 y3 T2 z' c0 S- \' s/ TFB32:4A LSR
0 F4 s/ I& _, k( G* o% D" ]FB33:8D 03 E0 STA $E003
, J4 G5 W3 D x$ S5 w" GFB36:A9 00 LDA #$005 I: ~4 o- v9 h" V9 a; V: s( T
FB38:8D 00 90 STA $9000: \% t# I _1 d
FB3B:60 RTS) j1 Z; k- q( @1 G; a
9 c* s6 X J g% g n; s. ]( l
接下来修改切bank方式:
1 Z) V, o$ Y. v& z1 [, RFB2B:48 PHA# b6 H1 l5 h8 }$ y3 {! }! S9 A
FB2C:A9 06 LDA #$06/ c3 @7 f) O+ h
FB2E:8D 00 80 STA $8000. [: E$ b8 H7 L; r9 K
FB31:68 PLA3 X) w1 G# [) D( e7 O( T
FB32:8C 01 80 STY $8001
0 g+ s5 `5 i3 cFB35:60 RTS7 D/ Z: a* ?5 b2 ^; D- a# H
! B; k: K+ W3 u) _FB36:48 PHA
5 Y" j" p7 F0 r f1 P9 u# qFB37:A9 07 LDA #$07
7 D; W4 ?) a0 x x! i4 u0 LFB39:8D 00 80 STA $8000 = #$14+ O |1 ^* f4 [4 A
FB3C:68 PLA
7 ]7 p6 a. [- v- n% k. Q1 @FB3D:8C 01 80 STY $8001 = #$1D
, D0 k% O/ A2 }) M( I* OFB40:60 RTS
0 s$ K$ p8 R7 t2 o
" m7 ^) x1 Y5 {- m$ X( L' ~还要把原ROM的对$8000和$A000进行写入操作的程序修改一下:
) L, M$ c# p9 Q6 E% i$ [F989:AD 00 80 LDA $8000 5 }9 |- y8 X) ]2 c3 Z- o/ x4 ?
F98C:8D EC 07 STA $07EC
& [' `% p) ^& a+ l6 mF98F:20 2B FB JSR $FB2B
( K4 d8 ]: ?! E! e2 @5 m5 T) pF992:C8 INY* J1 z( D* K: g& h7 {6 l
F993:20 36 FB JSR FB36
! [" J. f- g8 T% \: lF996:60 RTS
0 W l2 e! a$ f1 U1 ~ m6 e. d9 z4 A ]" C, G- b
再修改切VRAM程序:
$ v Q' P$ o; v1 ZFACE:A9 00 LDA #$00: `( f0 O5 D( K- x7 s& a7 d
FAD0:8D 00 80 STA $80005 a' [* I1 ?$ N0 A3 K5 k
FAD3:AD F0 07 LDA $07F0
- P& i: @1 _& X8 J/ YFAD6:C9 01 CMP #$01
! K& G& ~4 e% q* d7 mFAD8:D0 11 BNE $FAEB& L6 n& Z1 T, S1 |0 N
FADA:AD F1 07 LDA $07F14 D! g$ U: I6 ]" T5 P8 w @* T
FADD:C9 04 CMP #$04+ F$ v9 ]6 @1 v( [
FADF:D0 04 BNE $FAE5$ R7 n8 V; F9 j% w
FAE1:A9 80 LDA #$809 L- s0 A0 q3 r6 F1 K7 h
FAE3:D0 06 BNE $FAEB
0 @$ x c) n- H8 k3 hFAE5:C9 05 CMP #$05& q& o" ]+ }- C; E7 ` P* O' ]
FAE7:D0 02 BNE $FAEB' Y0 |4 K; T9 ~7 Z; f
FAE9:A9 82 LDA #$82! \+ p7 V- b& e6 k% y% v" E' I) |
FAEB:8D 01 80 STA $8001' l, V4 X( Z, |, r. q
FAEE:A9 01 LDA #$01
5 ]# o+ n) a$ qFAF0:8D 00 80 STA $8000& ?$ R H& j; C' A
FAF3:AD F2 07 LDA $07F25 _7 F: Q5 Y; H
FAF6:8D 01 80 STA $8001, l9 F" r% m; f
FAF9:A9 02 LDA #$02
+ v( o7 T5 o6 I$ J$ H0 l# p: Q. kFAFB:8D 00 80 STA $8000
7 V1 R" _5 X) N/ J2 d5 w4 uFAFE:AD F4 07 LDA $07F4
! l( V# u2 k& \. a+ T% u0 HFB01:8D 01 80 STA $8001
" C3 o4 k0 o6 W& c4 LFB04:A9 03 LDA #$03& a: k* T2 {. A. T# l* Q* u
FB06:8D 00 80 STA $8000
; K/ a& ]& B4 D/ M7 X) OFB09:AD F5 07 LDA $07F5) @, y! @! H6 T, J; w( T/ J8 k
FB0C:8D 01 80 STA $8001! M$ J6 l& m1 }* a. W
FB0F:A9 04 LDA #$04
$ m/ Z# Z1 W: X3 K! w) S/ K7 g5 HFB11:8D 00 80 STA $8000
5 P. i t8 K3 z0 w8 B; ?FB14:AD F6 07 LDA $07F60 S" l2 X9 D7 J. e# u+ R
FB17:8D 01 80 STA $8001
3 a- F6 M6 f, ]+ u, J6 LFB1A:A9 05 LDA #$058 f* s6 h6 S9 |
FB1C:8D 00 80 STA $8000
) k( ?# T, p) ?) v- w- QFB1F:AD F7 07 LDA $07F7" q) R+ d2 ~) B1 _
FB22:8D 01 80 STA $8001' H6 ?6 A9 n" d6 ^: ^) c
FB25:A9 00 LDA #$00. u* L3 y/ J+ N3 R- A2 w( ^6 k
FB27:8D 00 A0 STA $A000: Z: z. E. b) p& H# W! ~! f7 d1 E
FB2A:60 RTS9 [% T {( {5 f% g" D2 Z' u
( E2 d5 I- Q6 w" ]! s$ u4 v
然后保存文件。
; x$ d7 ]/ R- p% J' `& ^使用HXD修改文件头:- u0 x' J3 u/ k, t. c6 P
将Mapper 23
" j& X. K* S3 j# k( i06字节的高4位是Mapper号的低4位
4 S2 t/ [$ C4 O% T07字节的高4位是Mapper号的高4位
5 h0 c; S7 W2 g) w4 F4 S* w组合起来就是0x17=1*16+7=23
, a* T8 i5 Z% J 5 T9 q2 H; Z6 d- F' t
修改成 Mapper 4/ g1 N. |8 _* [

# _! e4 E% t" r7 a1 ?2 W: H- z" o5 U* x$ k: ]
8 f! E0 V- E! K1 {" L1 K" k
再次打开文件:# f4 ^# R. R9 m; @# H/ u2 y
% E( \8 O- a: Z
可以正常运行+ O# l) v8 K; _( [1 S. X* y
通过全面测试,发现出现精灵错乱:
; P3 @0 r+ \& H4 S+ k/ B; ?. }第1关:+ h8 u' I3 ?. G1 U" ]
4 I9 g$ E, o( Y$ {' ]" Y! S
) o; Z. d) o' H
第2关:
' J. x6 u7 W2 h( N$ z# m : ?3 Q$ q( y# a+ u3 o/ \* U/ E
任务失败后:
5 ?: z4 C/ N O' P) @ P - c' a* ]. s# ^% b
通关后上飞机画面:
& o3 C& i) l3 y) L
4 U4 V- E$ [3 |5 [) H. `, E& }4 u$ Y. `这是为何呢?9 f! n; E0 `6 P; v) _9 ?8 m
这是因为Mapper 23 中精灵VRAM切bank是一次切1KB4 o3 N" T. V% \; m3 c8 c, c
但是在Mapper 4中精灵VRAM切换却是一次切2KB,而且忽略bank号的D0位% R' f7 } P& W* V
比方bank 0和bank 1是同一个bank,同理bank 2和bank 3是同一个bank
. n( e$ t7 x% M也就是说
@: R( T9 M9 Q( P8 kMapper 23中的VRAM的
6 u# Y( I% W" f5 N- p# R, H8 Abank 0,bank 1,bank 2,bank 3! r; J6 L0 q6 K4 I. S n6 j) e
在Mapper 4中对应的是3 q0 t) k3 p4 J/ C
Bank 0,bank 0,bank 2, bank26 R- Y4 M. S& z) a' r* x7 D
然后查找原来的ROM的切VRAM的程序:
S" v/ g4 W. E% c2 U知道是从07F0-07F3切到精灵VRAM的:
4 p+ q; T. v0 ], Q `3 \, s2 w如图所示:
" t' N7 F N G/ A
* G6 X/ R* \( K2 M6 U4 W0 @ ' o7 O1 D4 L. l3 {
作为对比,左边是原版,右边是修改。3 g1 v- _9 W. T) \
接下来是完善VRAM切换带来的问题,因为Mapper 4只能切2KB的bank,所以我们不能通过切bank程序解决问题。
+ C( @' i9 @9 X# U$ d+ I通过测试知道1,3,5,6,7,8关的精灵VRAM排序如下(07F0-07F3):' v+ w4 C7 x. l: I7 H7 N& b$ o* e
01 04 06 07
2 d1 x7 S' z* w第2,4关如下:* `+ B% q7 M: _' V5 d3 |
01 05 08 093 E/ u J% i2 W9 h; T
任务失败时如下:) y. u, o& T8 g2 `0 c' G+ O+ |
32 00 00 1B
7 [) {$ h& ?2 N其中任务失败时对应的VRAM是07F3的1B,只要让07F2为1A或1B即可:
) s8 q! X6 [0 k通过调试找到对07F2写入数据#$00时程序如下,于是修改C7E5的值为1A即可:
. e0 y' A! U* A' Z7 f: f
, \ Y! Y3 ~' f) A% W; p+ f/ u转到ROM地址:
3 M9 }% U+ |( z3 B8 i, q
$ U; h7 w+ V9 m6 [% U: C修改数据:5 L. P0 {4 H: @

& W6 }9 s, ^5 C _4 E重新失败后可以看到修复成功:9 O0 i* m( @9 T5 M: d" f
7 e& _& e5 j7 E. k' ?9 x& P2 O9 y
接下来是修复正常进行任务时的精灵错乱问题。
8 l0 T! b4 a4 |4 Z1 `4 Y' e9 q, P: A首先运行Mapper 23版本,在1,3,5,6,7,8关任意一关的时候,将PPU导出来
. q: r4 I @/ b
~& g; p ?4 f* ~! L; r4 P4 G / o4 R- k2 L2 M: I3 @# k. v! c
* _. l& e& w0 `

/ X( H( x9 B5 y2 ^0 A; w5 I然后用Hxd打开修改的Mapper 4的ROM和刚刚保存的PPU的数据文件:
4 R. p) l2 g+ m0 F0 z5 `3 u4 C
! H2 b, ~& h0 a0 u) e- e在ROM文件头第05字节改为0x20:. B: `1 T( h: e4 y0 H+ [( N

& g; c9 q8 m" B2 f6 S# }% D然后转到文件末尾,插入0x20000字节空字节:
( o7 S1 I3 p$ t) [0 s# A$ ]" n
x2 }! N1 \6 R J1 l ( J( _1 ]- b# X* z3 P5 P8 H
) G- ]6 K. P6 B- V; k7 e
$ [. @( d C4 V! \
然后将第1关的PPU数据的前面2KB数据选定:
* T" n8 x E! V9 n- y 8 N i1 O5 [8 r2 z( T6 q* q+ V
! p3 T; ~3 D% q( Z0 X" g
# h. I" ?# H2 m8 T- m: i$ W7 s
复制之后以覆盖方式粘贴到ROM的40010,同样把第2关的PPU数据的前面2KB以覆盖方式粘贴到ROM的40810" V2 r. f8 g4 _* _) e& S ^, Q* _- e

0 k( Q, C& z/ t& f+ b R然后保存文件:* G- S6 `- B; l5 u! ^: K
! L! Z# [" L8 n4 l) w
最后用FCEUX打开文件,添加07F0-07F3的写入断点3 F [9 p! Q, M

, ^2 G9 f+ L C. o地图预览后即将进入第一关画面时程序暂停了,可以知道此时准备将C793的数据写到07F0:) q C+ ~; Y7 ^

* N& K' Y( ^" n8 t( ~测试后知道将C793-0796写入到了07F0-07F3:
& `1 \ Q: L: { A0 u5 N同理,经测试每4个字节一组,一共17组,其中01 04对应普通关卡精灵以及其BOSS关的精灵VRAM的bank号,01 05对应2,4关卡精灵以及其BOSS关的精灵VRAM的bank号,再加上一个通关后跳上飞机那段动画的精灵VRAM的bank号。, _7 D2 S, A$ w; f: n
7 }5 j4 ]& u- _: z/ \ 7 K: x7 l. q8 S4 \3 P
然后将文件中标记的01 04修改为 80 04,将01 05 修改为82 04即可:3 J* X7 U9 i( ]) s. w
8 T2 _) t- {2 P3 f0 I# c
保存之后重新运行后效果如下:. l9 Z! s3 a9 V5 V3 I

; }8 m. D' @$ L 3 A# F$ g! x) g4 \, E, }
0 ?0 Z2 ]8 e4 c( t
当前使用的是FCEUX模拟器,如果用NEStopia玩的话一开始就死机了,这是因为这个ROM有文件保护吧,它会往$6000里写入数据: m; I1 p# I# x9 M# U" x1 D# v9 h4 U
: C5 J2 N0 H5 P6 i. T: C4 B
F863:A0 03 LDY #$038 }# v5 h- @! G# G$ d
F865:98 TYA2 K$ G: k% v+ s5 t* T6 M8 ]8 }
F866:29 01 AND #$01
7 R$ ^5 y. ?7 W+ M/ H* P% [" `7 {F868:8D E9 07 STA $07E9
+ ]7 P5 g: H" U# Y# |# e# IF86B:8D 00 60 STA $6000' x& Y8 k) M( A8 D1 L
F86E:AD 00 60 LDA $6000
$ E8 i/ b4 ?6 F( d+ n) U( ]0 t0 ZF871:29 01 AND #$01% C9 o/ r' R) p
F873:CD E9 07 CMP $07E9 R. i% x a( ]. X6 Z3 J7 v
F876:D0 05 BNE $F87D/ K: i( W7 i- B/ H; `# \2 S
F878:88 DEY9 A$ u2 h4 J( M8 {* R' s }
F879:10 EA BPL $F865
( \0 i) r% q* A9 E9 d: V: RF87B:30 03 BMI $F880% A5 P3 H, N3 I" h
F87D:4C 00 00 JMP $0000
5 x6 m( \! g8 ]' ~1 qF880:A5 1A LDA $001A
/ G, }, f" m8 {( ^' b% d4 D4 `F882:65 34 ADC $0034( ] d1 x2 ], t/ |. b
F884:85 34 STA $0034 Y$ P9 ?: W3 I3 B( ~+ _
F886:4C 80 F8 JMP $F8804 g5 ^ u3 q; |3 F( \
先取Y值=#$037 }( d C4 u E A3 e( s7 N
与#$01相与后得到#$01! \4 [4 s: O+ h, q; i5 R& x
写入到$07E9* l2 R8 @% k. ~2 M
写入到$6000
# s. i, P1 [( H; ?* ]; j' O# |8 H再读取$6000的数据和#$01相与后和$07E9的数据比较
( ]7 Z0 u) e* u, C& I( K1 S不同的话跳过5字节
% j% S7 E) e- Q: Z+ R7 \$ S否则Y递减7 T9 o4 W& S& ^
为正数就跳回0x100-0xEA=16字节4 o' W/ h2 v# b3 G% P) r) G
为负数就跳过0x3字节
5 U. q$ I! p) ^ n1 ]+ d' @跳转到$0000(简直没有人性了,跳到这里死机,真想得出来); n/ m$ r. ^' n2 E9 c; m; L
/ a- c* h1 n& g4 Z: k" c7 g
正是因为这样,NEStopia运行FC时,6000-7FFF默认是不可写的,必须在ROM文件头第6字节的D1位置1设置ROM有SRAM,对于Mapper 4,还需要向$A001写入#$80来启用SRAM。
( e5 ?/ L7 ?! t$ e: d, g) }- ^由于$6000不可写,因此想$6000写入#$01后$6000还是#$00,之后读取$07E9的#$01与之相比当然不同了,于是直接跳转到死机程序了。
0 m4 H0 O! |9 E! \9 g3 l- |9 f9 H) ]$ B解决方法是把ROM中的所有的AD 00 60 29 01 CD E9 07 D0 05 88 10 EA 30 03 4C 00 00
7 r* z4 {1 n% n: D: _中的D0 05改为D0 00,然后保存即可。
, k3 b4 Q S$ l" E) {测试完美运行。! u7 D! b( N! ~, m; x
1 b) t# t. K5 [5 i' [, N; q
/ w( W B2 H3 C: {
教程到此结束。8 A( z. B/ W+ P0 I3 ?3 G
6 F- \" X8 d- ^% V7 ?
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|