|
|
本帖最后由 yandagui 于 2017-4-16 19:06 编辑
1 H( \/ Z% ]% d. S& ]( i
- O; f) M7 V: e4 z" xMapper23转Mapper4实例教程
4 K- A& T% ?- @- B
6 D; e/ \# F& H/ e& y% BFlameCyclone 2017.4.14
6 Z2 u. [- v7 i3 W1 m. U* D3 O2 t3 |7 I, |
先看看Mapper23文档:
: [9 F, k2 @8 s$ b' J- ^, @$ B9 i1 e5 @1 R7 v8 m0 P
Mapper 237 a3 j9 J' N! j) _, Z2 A
+ K) c; U5 a% \% \$8000: 选择8KB的ROM存储体映射到$8000
: g' Z0 G" D0 U+ t7 }) w, T/ N! v5 ]+ D# G6 L
$9000: 0:垂直镜像% h, v y; B/ r9 ~1 K) j
1:水平镜像: ?, P* m5 f. L2 q* P' V# v# n3 K
2:$2400镜像
4 Q, z6 t) s: l D: F 3:$2000镜像
" c( ]7 H6 q$ g+ T |
+ h3 \: p3 U. E6 J$A000: 选择8KB的ROM存储体映射到$A000
. w. l+ T/ U1 d. X
% ` m7 C* X9 T" j7 ?- e! N$B000: 选择1KB的VROM存储体映射到PPU的$0000(低4位)
2 p$ c' V6 I& e4 s0 ]# b$B001: 选择1KB的VROM存储体映射到PPU的$0000(高4位)
( A+ e3 U! w$ e$B002: 选择1KB的VROM存储体映射到PPU的$0400(低4位)8 G- D+ x" [/ j/ n& t
$B003: 选择1KB的VROM存储体映射到PPU的$0400(高4位)
; V& E7 O7 ^2 X: h' x4 {- k, w. u% K+ u8 x t$ @+ \0 J
$C000: 选择1KB的VROM存储体映射到PPU的$0800(低4位)
- o! U7 @3 [: B+ v$C001: 选择1KB的VROM存储体映射到PPU的$0800(高4位)
4 a' c7 F) X0 i3 s. j. {9 k! c$C002: 选择1KB的VROM存储体映射到PPU的$0C00(低4位)7 m c) u' M9 [! Q. N# c) ^, s2 x- u
$C003: 选择1KB的VROM存储体映射到PPU的$0C00(高4位)
( `' v/ H2 i4 u# G# D9 }- _- p1 v) i+ {
$D000: 选择1KB的VROM存储体映射到PPU的$1000(低4位), d4 a# b% a2 [
$D001: 选择1KB的VROM存储体映射到PPU的$1000(高4位)
0 f& ]0 f; ]: Y! ~6 s- n$D002: 选择1KB的VROM存储体映射到PPU的$1400(低4位)& {. T' b7 q1 l- `
$D003: 选择1KB的VROM存储体映射到PPU的$1400(高4位)0 n- w7 i+ l. O8 N$ E/ v& h
+ ]( Y$ z1 r# v$ d5 Q& E2 f
$E000: 选择1KB的VROM存储体映射到PPU的$1800(低4位)
+ x6 ~- K; h; B% E7 L0 T' I8 q2 i$E001: 选择1KB的VROM存储体映射到PPU的$1800(高4位)
, Y) b. Z ~" b6 E( e q" q$E002: 选择1KB的VROM存储体映射到PPU的$1C00(低4位)
! z) o; f% m7 _7 o& }$E003: 选择1KB的VROM存储体映射到PPU的$1C00(高4位)6 y4 u. r1 ~6 W" O* q- ~
# J- e& e* {: R ?; k+ k再看看Mapper 4文档:8 R9 K% f& [. ` Z1 V
v+ p; F7 S: R: ~8 WMapper 4) b1 s2 d ? b+ H4 Y
# P5 s1 ] D0 f! C: R3 i E$8000: 模式号
6 v3 S4 D5 k% p$ S+ L: T/ \$ ?" r- i 位D0-D2:: v( i3 R- Q9 ~4 @3 z4 X- y
0:选择2KB的VROM存储体映射到PPU的$0000
! _; O* g3 A/ h; j) d 1:选择2KB的VROM存储体映射到PPU的$08000 Z3 y1 |2 ]0 N$ X; R9 z. a
2:选择1KB的VROM存储体映射到PPU的$10007 d3 Z' Y: c+ _
3:选择1KB的VROM存储体映射到PPU的$1400
& z, z' Y7 c, x( b+ V+ |$ M. m 4:选择1KB的VROM存储体映射到PPU的$1800" i& Y8 {1 C+ o( K
5:选择1KB的VROM存储体映射到PPU的$1C00
3 g) S0 |6 j0 B4 v$ a6 f( |5 u 6:选择8KB的ROM存储体映射到$8000
" |# D3 t) E( r+ h2 j 7:选择8KB的ROM存储体映射到$A000
/ e: U5 U2 S6 v1 D0 Q2 S X' Y8 q% y$ X 位D6:
/ Q) E l; Y- T! { 0:允许擦写$8000和$A000
2 A$ g: G5 N1 N9 J0 B0 H! w3 w 1:允许擦写$A000和$C000' a) x! ]( C5 X9 W) P- W
位D7:
3 y& G8 i, {# n+ U, U* t- @ 0:模式号D0-D2使用普通地址" {8 U0 w x- A6 _1 o/ E
1:模式号D0-D2地址异或$1000
, t0 k3 c: {9 t* {* Q K8 W
1 h" `3 i; ]- H% Y+ Z; P/ `) u$8001: 模式页面号
# v6 h" \3 r# F 写入一个数(00-07),切换存储体到对应地址2 m0 y3 i8 s8 D( A8 F
# ~3 \7 X( ^2 l0 G# I5 c
$A000: 镜像选择% C7 d8 y! O6 f* N, k- t
0:垂直镜像
6 O7 z' K+ B: V3 y4 }$ H 1:水平镜像% B/ d7 ~! l$ @. U9 h4 G
. e v- Z9 X+ k' ~5 u" A" w
$A001: SaveRAM 切换- q) V9 x( a+ n4 p$ ?/ Q; S
0:禁用$6000-$7FFF
B" b2 w9 b+ z9 H7 e/ R 1:启用$6000-$7FFF
! G0 ~7 f4 z3 \) w; ^6 q
1 w: \2 k9 ~+ n$C000: IRQ计数器
( o; a( n6 S( Q; K6 a IRQ计数器的值存储在此处
' @7 G# e$ r2 N* D, d6 V" F$ C4 h( I' Z# Y
$C001: IRQ暂存器
. k N' U0 `# f6 }% L IRQ暂存器的值存储在此处
6 I6 h* _' t3 j3 i, T! S7 e6 B4 @4 q
5 F6 z9 k' i, {! G3 \$E000: IRQ控制计数器0
( H T; p; h/ C# \) p5 v) h 向这里写入任何数来关闭IRQ,并从暂存器中拷贝数据开始计数,进入IRQ
2 c1 q3 g% v: R; F9 X
Z$ G" f, D$ c& @6 r' n$E001: IRQ控制计数器17 Q/ u& e7 v. E, ~
向这里写入任何数,允许IRQ(退出IRQ,允许下一个IRQ进来)9 e% s$ E; B* T9 t9 p" Q
6 A# I2 n3 w) s- {/ \: y# z3 L" X- a* w5 o+ a
转换思路:
3 I+ [! F4 A1 N# K将Mapper 23 的切bank 方式和切VRAM的方式修改成Mapper 4 的方式。
; p( k2 ^# {$ j- g- [" k( p6 a
' B! X5 q0 I4 `. j, b$ J+ y( \修改实例:
D( Y/ ]- K d4 C5 Y4 _1 P& t8 UContra (J) 256KB Mapper 23
" a8 E2 p _9 X工具:9 D+ L* e( |; c
1.FCEUX 2。2。39 E R, E0 L6 D9 L
2.HXD- {4 t& h# W% v4 [6 J6 ^/ Z. w
先来看看这ROM的切bank方式:7 l0 b8 ?2 ]) |/ U! I
F989:AD 00 80 LDA $8000
4 y8 n; @4 k. Q# P) ]% y" [F98C:8D EC 07 STA $07EC" E/ L% X- U ?
F98F:8C 00 80 STY $8000
1 `: p0 q* [' H1 Y. lF992:C8 INY7 ~/ @% v, t$ q: |7 m- ?
F993:8C 00 A0 STY $A000
* \9 @' D" V( QF996:60 RTS
* A' J* y) S w# s! |& q: |. _
$ K: t+ j d" ~. \& k% Y( p" }再看看它的切VRAM方式:
, M* `; V1 Z% D y UFACE:AD F0 07 LDA $07F0
" ] d) j5 i& a+ m: y6 `% y( L9 W7 ?FAD1:8D 00 B0 STA $B000
5 V6 Y2 G {* N( q( G; \7 xFAD4:4A LSR
' C$ p+ M, T6 c1 y w1 zFAD5:4A LSR
1 V& q2 d* S- G2 CFAD6:4A LSR
0 W7 A2 x. O4 o% h- s; c9 |7 ]FAD7:4A LSR# P; m: W7 Y8 s1 _6 G8 U2 `7 w/ N
FAD8:8D 01 B0 STA $B001" a' ~; F7 F) Z! \
FADB:AD F1 07 LDA $07F1
$ g( g6 T& e" QFADE:8D 02 B0 STA $B002
5 A7 j, S8 X/ R: p& mFAE1:4A LSR
5 g, N% C- P" N2 FFAE2:4A LSR+ W4 \5 c2 E3 i& Z% f! C/ F8 S
FAE3:4A LSR
2 \) x; h! P7 q; x% OFAE4:4A LSR$ V/ a' N7 N' L, w
FAE5:8D 03 B0 STA $B003; e/ T: b- l4 I6 l
FAE8:AD F2 07 LDA $07F2, j8 r1 W$ w) R. v& A8 ~
FAEB:8D 00 C0 STA $C000
: ~5 c( r: d% l0 wFAEE:4A LSR
6 P e7 q1 |& {FAEF:4A LSR
: J4 O2 h) h/ P9 DFAF0:4A LSR
3 H/ o0 g' I! |FAF1:4A LSR
% ?7 K* n7 _" k* \FAF2:8D 01 C0 STA $C001) X' ?- }) j+ _% E0 _' p
FAF5:AD F3 07 LDA $07F3" y0 c, Q" q4 A' h' Q' Y$ v
FAF8:8D 02 C0 STA $C002( \1 S2 V2 J2 S' K. i( e
FAFB:4A LSR/ m- _5 V+ t" Z: q0 K# J) d
FAFC:4A LSR& Q; Y* |1 u. k4 S0 v9 F$ u) U. `
FAFD:4A LSR
: k9 q5 a7 I& P9 P4 VFAFE:4A LSR
$ u7 w9 o8 N- ?& ^6 a% T! [4 BFAFF:8D 03 C0 STA $C003
+ l* A% T2 Z8 Z7 CFB02:AD F4 07 LDA $07F4' X: {# b" P- _1 z: l: D2 ]
FB05:8D 00 D0 STA $D000 p, h/ d E0 v$ T+ l
FB08:4A LSR
6 s' u. n( ~+ Y1 mFB09:4A LSR# \) n6 B6 b3 u% ~# {
FB0A:4A LSR+ Z' S# S+ J Q7 F) [2 H& {
FB0B:4A LSR7 l; ?) i" K5 B% i$ X3 ?8 c$ F
FB0C:8D 01 D0 STA $D0019 _3 x3 e, K: d4 d' z* l& y0 t) z
FB0F:AD F5 07 LDA $07F5
2 Z1 x, S- ~3 o2 O! Y! ^% JFB12:8D 02 D0 STA $D002$ k6 S, h2 S4 P E/ s, p
FB15:4A LSR" ?5 a% i4 b8 t" F0 g
FB16:4A LSR0 N; b& q3 W7 P T p$ t$ Y
FB17:4A LSR5 C% P% b( q9 \/ k: g" n
FB18:4A LSR
- c* m# N( r" `FB19:8D 03 D0 STA $D003
/ K% f2 T0 F4 b- v' l: X G) l9 BFB1C:AD F6 07 LDA $07F6
! T* _- d( C; W5 L) J0 VFB1F:8D 00 E0 STA $E000
2 @2 ~6 ]: b G9 i5 S Y+ cFB22:4A LSR
" I7 H. H- m2 U7 P8 Q/ J* QFB23:4A LSR
- u8 j( Z* A1 P) E3 k2 I! z. T$ jFB24:4A LSR, r# X; f9 W& d! V
FB25:4A LSR8 M6 s% t, `; z. U r/ @! ?
FB26:8D 01 E0 STA $E001
( ]$ v5 Z: C4 c. R3 iFB29:AD F7 07 LDA $07F74 e# M6 }% @0 n
FB2C:8D 02 E0 STA $E0027 G7 z" S* f( t+ K) {& o
FB2F:4A LSR
. P# ?9 p( c7 D) jFB30:4A LSR+ h( J% g; I0 M9 J9 u' p
FB31:4A LSR' O. h( D7 t0 W. k
FB32:4A LSR
, u6 Y( i# Z' WFB33:8D 03 E0 STA $E003: n1 Y+ v* y& D/ n' x# u
FB36:A9 00 LDA #$00- b. \9 ?& B2 y1 A3 N
FB38:8D 00 90 STA $90007 Y: o% K9 g! K2 V9 y
FB3B:60 RTS# n2 z' J7 Q# D* w, m4 B
9 F' I' b& A7 I3 }: H( ]
接下来修改切bank方式:: i& s1 |1 h, F4 W# \# u" q. x
FB2B:48 PHA# A2 Y/ c1 u- |
FB2C:A9 06 LDA #$06
" ~2 g- T8 G" M: rFB2E:8D 00 80 STA $8000
9 o2 n6 n, o* hFB31:68 PLA. t. l0 h6 r) H
FB32:8C 01 80 STY $8001! U& \2 u) e. {0 c- E2 Y
FB35:60 RTS
4 \% Z5 {" n" s
6 F2 V( i/ O# {! i+ Z9 GFB36:48 PHA
! G. T) P' T+ {7 q& HFB37:A9 07 LDA #$07
0 _# N9 C0 z9 c6 ?* DFB39:8D 00 80 STA $8000 = #$146 v4 u2 @- ]. ^- w$ p( d
FB3C:68 PLA4 ? g- w+ E! J, U* ~
FB3D:8C 01 80 STY $8001 = #$1D- c/ T: M- J/ d9 J1 G
FB40:60 RTS
" ^! a! i7 k0 i$ x! E* V
% H: m/ C! t8 t7 t" B! `还要把原ROM的对$8000和$A000进行写入操作的程序修改一下:
) x9 S2 S3 z- j9 @9 e: X+ OF989:AD 00 80 LDA $8000 5 `) ^% G2 J0 e% z* U6 u
F98C:8D EC 07 STA $07EC0 R$ J+ Z5 N1 d+ g: H
F98F:20 2B FB JSR $FB2B" P n4 m. l) d- X& m$ R" r+ O9 @8 o
F992:C8 INY: N* m* M) l$ Y6 O% `0 R
F993:20 36 FB JSR FB36
& ]/ G' }- H( L4 l, B' H! MF996:60 RTS
3 b' ]& x( M5 G* f5 J( m9 L
8 r) N' i) d# I* o4 d' e8 R再修改切VRAM程序:
( U7 I3 l! [0 u% e$ j+ GFACE:A9 00 LDA #$00
! g- o) q4 s H- I, [9 p$ F( @+ X' RFAD0:8D 00 80 STA $8000, n9 O- R5 C1 E$ Q# b4 Q+ A
FAD3:AD F0 07 LDA $07F0
) F3 p% q7 A' C# ~0 t7 n) lFAD6:C9 01 CMP #$01
- W& N1 ^) E/ J% `FAD8:D0 11 BNE $FAEB
0 J) `) E4 Q$ g2 N$ gFADA:AD F1 07 LDA $07F1
" ^: s, v+ P" M2 r( o# ^: FFADD:C9 04 CMP #$04, W! |8 n4 N1 h# V- d' ~
FADF:D0 04 BNE $FAE55 R- A1 Y+ @5 y ~; I ^$ E
FAE1:A9 80 LDA #$80$ X4 D+ V3 h% v8 D
FAE3:D0 06 BNE $FAEB
8 @$ I: n+ W( e0 n+ b8 H n5 M7 W' RFAE5:C9 05 CMP #$05+ O5 z0 g6 j4 z5 r4 @
FAE7:D0 02 BNE $FAEB
& ^9 r. C: h; r8 G* ]( }4 |* g1 `FAE9:A9 82 LDA #$82
; C* I( j7 b) H9 }" D" oFAEB:8D 01 80 STA $8001& Q4 d; E. O+ Y
FAEE:A9 01 LDA #$01
* H1 a- P+ V" }( JFAF0:8D 00 80 STA $8000 s w3 N' S3 i+ D
FAF3:AD F2 07 LDA $07F28 \/ [# e/ }- n
FAF6:8D 01 80 STA $8001# _# z# _9 Y+ W; i- d, i0 n" L
FAF9:A9 02 LDA #$02) B( o, n5 h P. x
FAFB:8D 00 80 STA $8000
$ @2 E, z, G& X% a3 WFAFE:AD F4 07 LDA $07F4
: W: c2 i# E6 a& s5 ?3 RFB01:8D 01 80 STA $8001& S+ ~7 b2 V6 n; N, Q2 Y; x! b
FB04:A9 03 LDA #$03) {# \. y2 C) u# k; M/ Q
FB06:8D 00 80 STA $8000
5 g% H' _2 W# d) T& c O x& q3 oFB09:AD F5 07 LDA $07F5
* r* d, u" A3 ^FB0C:8D 01 80 STA $8001' N3 b1 W7 I# w+ T
FB0F:A9 04 LDA #$04
5 g8 X* {( S7 L( w5 u ~FB11:8D 00 80 STA $8000" s1 `1 i3 Z- [! C: {, X$ ?$ _3 r
FB14:AD F6 07 LDA $07F6
; h/ w# U1 w& sFB17:8D 01 80 STA $8001
' |' Y# ^, ?. ?+ [FB1A:A9 05 LDA #$05* w$ Y s' H0 l. G6 R
FB1C:8D 00 80 STA $8000
) \5 E& {* g$ p5 \5 O9 B! uFB1F:AD F7 07 LDA $07F7
: I6 I" A1 H, w9 [6 v, pFB22:8D 01 80 STA $80012 M/ D6 _8 U% t$ s
FB25:A9 00 LDA #$00$ q6 _% w* F& o/ C- {
FB27:8D 00 A0 STA $A000, u3 @+ c" C- [# J0 u6 ~) y: c3 W+ g8 q
FB2A:60 RTS$ |0 a7 `' ?0 f& v, `/ e
& `- U: E4 _. _0 H
然后保存文件。4 L+ r2 x! F8 G1 |+ e
使用HXD修改文件头:
8 E0 r' c6 {3 ?% q4 B! T将Mapper 23. F% O& |& P" V/ E/ S$ ~- J
06字节的高4位是Mapper号的低4位$ Q7 z9 b% d4 e4 X1 }: q) n
07字节的高4位是Mapper号的高4位" P9 h8 ~8 Z( l& ?9 z5 o! V
组合起来就是0x17=1*16+7=23
0 R1 @8 T# _* Q' Q" X0 u : {9 Q4 u- a( P% q/ s" ]7 d" V
修改成 Mapper 4
4 N% C0 J3 [: W$ z2 u8 P , a0 N" D8 b" [% m. n
9 @: b0 T2 u& t" d
5 E& J% ~2 D( c q# c再次打开文件:. x5 C; z! T j7 o* A
- @; \' K$ m5 Y0 L1 D
可以正常运行$ y$ I. @' [& \+ Z9 `
通过全面测试,发现出现精灵错乱:( y1 Y5 m+ W, Z1 f7 k
第1关:& l& W R' k2 _, H' E
( l; U. s& i# @6 B+ d6 I
1 P) J8 E( y: X' U" l2 Z第2关:4 B+ E: {+ ~: q8 R8 d, C" U6 h
1 ^& T7 \) J: J4 x3 |- T) s k" |" l
任务失败后:
T3 |' H& q( H : e9 ?6 }4 b6 a5 j
通关后上飞机画面: ?3 R( P/ L- L+ ?/ l1 P( s" [+ w

/ @9 J) H7 i* w* ]4 C4 \7 _这是为何呢?( J' w" i9 W7 l% N
这是因为Mapper 23 中精灵VRAM切bank是一次切1KB4 s; M8 M! j# S" R( f& P- D3 w/ ]
但是在Mapper 4中精灵VRAM切换却是一次切2KB,而且忽略bank号的D0位
1 I$ C9 M* q$ ^2 F3 S$ F7 p比方bank 0和bank 1是同一个bank,同理bank 2和bank 3是同一个bank
6 i5 _ Y, c3 s4 t7 L也就是说% B" X) Z# J- \
Mapper 23中的VRAM的* ]+ D* S, N7 _) c0 g+ e4 ?
bank 0,bank 1,bank 2,bank 3
0 q* Q) h$ L9 H# g" Z6 s在Mapper 4中对应的是2 v- T$ w/ B* j C: V
Bank 0,bank 0,bank 2, bank2
" w2 }: t8 O+ A然后查找原来的ROM的切VRAM的程序:& X( S. s; f% j1 O
知道是从07F0-07F3切到精灵VRAM的:6 n) G7 N# K+ w4 v d
如图所示:/ \0 h. V" {# l
; P. T/ i! i( s) Y6 c8 W8 i+ K
 ! s; w8 e o2 F( @8 O
作为对比,左边是原版,右边是修改。! q; F4 q% j3 w2 M9 B4 }: O) Z, \
接下来是完善VRAM切换带来的问题,因为Mapper 4只能切2KB的bank,所以我们不能通过切bank程序解决问题。+ g& Y8 J0 y9 m7 q# k+ i T# k3 Y
通过测试知道1,3,5,6,7,8关的精灵VRAM排序如下(07F0-07F3):( E1 [. U1 T. ]6 Y" W4 c
01 04 06 078 |, E+ W% L! M' W) P- ]
第2,4关如下:% v k9 h9 A5 p
01 05 08 09
8 K! t0 }1 m' E2 Q( t任务失败时如下:
8 f6 }5 O" ]8 f5 ^ J32 00 00 1B
- `9 M' }& F2 i! D" ~$ S$ D其中任务失败时对应的VRAM是07F3的1B,只要让07F2为1A或1B即可:
1 Q& q- Q' H* j3 e% ?; n通过调试找到对07F2写入数据#$00时程序如下,于是修改C7E5的值为1A即可:. m, w! ?- Y5 D$ T. `( Z

. x! a [; T, N E" ~转到ROM地址:
* S$ G( j. ^, P$ S2 L
% G7 { L/ _) R V& |修改数据:
3 r# {! n+ x9 ^7 E# h/ [. L" V
2 c3 s# ?# T/ Y. s) z# e重新失败后可以看到修复成功:
+ }) `7 e, T# M0 V6 o! u. o ! G4 [5 }5 \7 y- ^8 d! a
接下来是修复正常进行任务时的精灵错乱问题。
6 P4 v* R* U# P, j) M首先运行Mapper 23版本,在1,3,5,6,7,8关任意一关的时候,将PPU导出来
8 Z$ S. d1 c5 ^8 ~9 ]% }1 S " m3 c$ p; q0 z6 j# s

8 u. U& W" @) w4 B( ` i . j- o/ _; b8 A" s( q# _3 I0 |

# }7 ], t$ C8 b1 {( Z S4 R然后用Hxd打开修改的Mapper 4的ROM和刚刚保存的PPU的数据文件:+ W" J: H, g8 b6 _
# s' v1 ]6 L, b" w v' U, T
在ROM文件头第05字节改为0x20:
) B4 r: }5 F" {+ j& r
5 G+ x7 Z, v K* I, ]% H' d/ P) q ]然后转到文件末尾,插入0x20000字节空字节:! L. ~( V2 C* e% Y7 g" b" _

1 J, O; N9 ]# W( } ! p6 k$ n1 |) g! Z+ i0 H9 U X
. m- l- _2 h+ K1 P* o7 v" t( U

- A2 V, r2 b& S; f4 d然后将第1关的PPU数据的前面2KB数据选定:% v( U" f, \+ O" e/ b2 |9 W) n
3 ?' |/ S# s5 M8 ?+ V
& q& |, B$ J; N5 z5 J2 U

4 N9 L. `1 ^. h( z1 \复制之后以覆盖方式粘贴到ROM的40010,同样把第2关的PPU数据的前面2KB以覆盖方式粘贴到ROM的40810% _0 u2 w5 l4 `% X

: U- G5 B6 }2 J3 t2 E然后保存文件:7 \, O) M" r9 O4 h4 o' y6 h

. F4 k F3 a0 B最后用FCEUX打开文件,添加07F0-07F3的写入断点
, [, `" u7 B( U$ K* G $ [, @ B9 X) w: y- w
地图预览后即将进入第一关画面时程序暂停了,可以知道此时准备将C793的数据写到07F0:% ]; L1 M, s* J% C- A6 i
: f- @8 j4 C* l" a2 y
测试后知道将C793-0796写入到了07F0-07F3:
- p. N! T1 }1 C7 U8 \6 X; U同理,经测试每4个字节一组,一共17组,其中01 04对应普通关卡精灵以及其BOSS关的精灵VRAM的bank号,01 05对应2,4关卡精灵以及其BOSS关的精灵VRAM的bank号,再加上一个通关后跳上飞机那段动画的精灵VRAM的bank号。
$ o. c) s0 V& {0 t4 G0 u; i: _( G
$ Y/ D# L% ?+ }: D: C
. D: \7 O& ~" @" U# k然后将文件中标记的01 04修改为 80 04,将01 05 修改为82 04即可:, J- {: y) O% M3 k2 E# @
. p' T" b, {, H0 n" D
保存之后重新运行后效果如下:
+ b' F5 t/ Y6 g( N! d / M1 U2 q$ i3 S$ r
/ a2 X4 |& e; E/ U) ?
) F! W" |; j- X5 a9 v/ g/ t' i3 O
当前使用的是FCEUX模拟器,如果用NEStopia玩的话一开始就死机了,这是因为这个ROM有文件保护吧,它会往$6000里写入数据:! U, e' l" W$ s7 S; Z
! ~" y% V5 d5 r J( ]
F863:A0 03 LDY #$03, U% V. B) F ~& t1 Y# k
F865:98 TYA2 x5 y) ~5 q# X" m1 x" i/ c8 t& n
F866:29 01 AND #$012 R$ S6 \% a8 h6 y$ r" h
F868:8D E9 07 STA $07E9- D3 L- H- _ p5 Q. i5 K- o
F86B:8D 00 60 STA $6000
1 \4 ^# I9 z. D% k s0 nF86E:AD 00 60 LDA $6000
4 Q" q) g2 r6 o5 o& F3 {8 zF871:29 01 AND #$01
0 Y, T5 r4 z) p+ B: wF873:CD E9 07 CMP $07E9. R) n m) j# L0 J9 b" T
F876:D0 05 BNE $F87D
: W" h$ W- r) R- N& c, P/ yF878:88 DEY) k: {9 F* ?$ M5 X
F879:10 EA BPL $F865
* L# ?3 T: E9 I* D6 D7 ?F87B:30 03 BMI $F880$ e$ S6 Q! A/ \8 e/ X* \
F87D:4C 00 00 JMP $0000
0 P+ T% M. d, r( W9 \% P$ ^0 Z) dF880:A5 1A LDA $001A% Z4 }8 d7 T7 ^( x
F882:65 34 ADC $0034
) o/ y3 \' M5 |6 Q, p# WF884:85 34 STA $0034
) x9 S/ g; h$ \( CF886:4C 80 F8 JMP $F880. P# y; p* F7 |0 {" R
先取Y值=#$03
* ^/ M9 }4 }- d& w与#$01相与后得到#$01
0 B* `; h5 a( ]) g4 R2 W) j0 a写入到$07E9: i/ O% @& z+ w; ]% }: O k; i
写入到$6000
( H* v3 b1 J+ r, g! A$ r8 D2 W4 Y再读取$6000的数据和#$01相与后和$07E9的数据比较( [! g+ T O' C
不同的话跳过5字节
: D: h ~/ I7 i否则Y递减, L' W+ X2 G" f3 ]" q
为正数就跳回0x100-0xEA=16字节. a! J# X2 f' P5 b$ l
为负数就跳过0x3字节
$ D: q' L$ z2 I& }1 I L2 W跳转到$0000(简直没有人性了,跳到这里死机,真想得出来)
& N+ B2 d0 a; r, W z$ x. z8 S) ]. n4 U+ C1 G" f b. P
正是因为这样,NEStopia运行FC时,6000-7FFF默认是不可写的,必须在ROM文件头第6字节的D1位置1设置ROM有SRAM,对于Mapper 4,还需要向$A001写入#$80来启用SRAM。. [2 F/ Y0 E8 A+ D, S r3 {) T
由于$6000不可写,因此想$6000写入#$01后$6000还是#$00,之后读取$07E9的#$01与之相比当然不同了,于是直接跳转到死机程序了。6 X" L8 f7 @2 U# S6 |5 |
解决方法是把ROM中的所有的AD 00 60 29 01 CD E9 07 D0 05 88 10 EA 30 03 4C 00 00
$ U, F; D$ w- z( }3 a/ a, E' S: X4 D中的D0 05改为D0 00,然后保存即可。3 p# W) z8 {) n4 _
测试完美运行。6 {; l4 {8 D5 k' X5 ^# X$ P, S
+ }" [) E, B# @2 [6 ~8 v! l
4 |) Q" d7 u# j" N9 \3 O2 h0 w6 t
教程到此结束。
" y) O/ G3 v8 ^0 {
7 x/ A& T7 p: a) e! ], f2 W( z2 j |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|