EMU618社区

 找回密码
 立即注册
搜索
查看: 758|回复: 7

[原创HACK教程] [FC][Mapper23转Mapper4实例教程]

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2017-4-14 19:43:10 | 显示全部楼层 |阅读模式
本帖最后由 yandagui 于 2017-4-16 19:06 编辑
2 ^! D. I. l4 G( H6 z5 z: X
, h) F3 ^, W' e6 n2 AMapper23转Mapper4实例教程
, E% x+ ~, P4 G
$ f2 g; l) X/ W8 DFlameCyclone 2017.4.14/ z' W6 v  F: A3 {+ R

) k, U/ x. s1 R! h先看看Mapper23文档:5 g! A9 c. T, }0 {- `

& ]4 m# e% X2 `8 AMapper 23
) D' w. l2 K/ m. h  X( @  X) _; ?. S( z7 j
$8000:  选择8KB的ROM存储体映射到$8000
1 s. V, l) u5 h" x. _* G" x% @3 V8 c, C2 x' w% l) g
$9000:  0:垂直镜像
' h5 u1 ?/ t5 e$ n        1:水平镜像+ d+ N/ H1 J( z% r1 E) Q
        2:$2400镜像
' Z' C  V5 s7 d6 P0 n: C3 H        3:$2000镜像
; R  p% U: x  r+ Y! i! N$ v
; t0 u2 V' z% W) g: q' ~$A000:  选择8KB的ROM存储体映射到$A000
- x4 g5 @! B/ m4 G% p( O- y9 g* B2 o+ p
$B000:  选择1KB的VROM存储体映射到PPU的$0000(低4位)- R$ b0 m( Q7 F2 E; \
$B001:  选择1KB的VROM存储体映射到PPU的$0000(高4位)) E+ |6 g2 i9 g% i, Q. c
$B002:  选择1KB的VROM存储体映射到PPU的$0400(低4位)
2 D, r+ n, S( I% R2 E$B003:  选择1KB的VROM存储体映射到PPU的$0400(高4位)$ U# o$ z7 n- I! f* v# t! j: i
4 ^0 I" y" a0 M  f3 d
$C000:  选择1KB的VROM存储体映射到PPU的$0800(低4位)
: S' s* O5 j) o7 U8 c4 X: e% v$C001:  选择1KB的VROM存储体映射到PPU的$0800(高4位)
) a  {( G" D  {7 ~$C002:  选择1KB的VROM存储体映射到PPU的$0C00(低4位)
5 H) [. C% c1 S. H) q4 f* r; ~$C003:  选择1KB的VROM存储体映射到PPU的$0C00(高4位)
3 A! b( ^" g0 D2 S, \; x% ~9 J" J( S# q+ U$ `  ~
$D000:  选择1KB的VROM存储体映射到PPU的$1000(低4位)# L! J+ W6 t( \. s
$D001:  选择1KB的VROM存储体映射到PPU的$1000(高4位)
. Y0 g& I4 e; g7 J/ r+ M$D002:  选择1KB的VROM存储体映射到PPU的$1400(低4位)
2 u" ^& v# K- s: Y1 z$D003:  选择1KB的VROM存储体映射到PPU的$1400(高4位)
/ _% O# {' f& R+ Z% [3 Z8 E7 M: N5 H
$E000:  选择1KB的VROM存储体映射到PPU的$1800(低4位): z: ]$ t$ g, O8 Q8 I
$E001:  选择1KB的VROM存储体映射到PPU的$1800(高4位)
6 r1 _- q* s5 Q8 R$E002:  选择1KB的VROM存储体映射到PPU的$1C00(低4位), A7 `- ]6 y$ b* t; O3 A
$E003:  选择1KB的VROM存储体映射到PPU的$1C00(高4位)$ g# B- }4 @  Y! H0 @' \

& h8 E4 j' n0 J8 u- w8 D再看看Mapper 4文档:: O) g- z7 c! T0 V
8 g5 b# F0 z+ q' Q1 v# M: _
Mapper 4
% p1 w" u, w/ k3 f2 w7 D  j) M2 o1 }; E8 }
$8000:  模式号% |7 p. U5 T  G$ ]- N9 d2 t
        位D0-D2:1 b+ W$ P4 g3 s  c$ V. n7 Y
        0:选择2KB的VROM存储体映射到PPU的$0000$ }0 T! @2 D6 a' Z
        1:选择2KB的VROM存储体映射到PPU的$08001 N/ \1 c: C- @9 }7 W' C6 @
        2:选择1KB的VROM存储体映射到PPU的$1000
+ ]  |. S' T/ [) ~/ Z) a        3:选择1KB的VROM存储体映射到PPU的$1400
7 `& @" L) t& K: Z        4:选择1KB的VROM存储体映射到PPU的$1800
/ [# @- U& K7 x) e, B# c( f        5:选择1KB的VROM存储体映射到PPU的$1C00. Y$ ?; ]9 F3 j# d' z+ _
        6:选择8KB的ROM存储体映射到$8000
2 U+ i. u! n3 P) |        7:选择8KB的ROM存储体映射到$A0005 z2 ]4 Q$ n* H: I
        位D6:
/ Y1 J. R/ M) Q# ^        0:允许擦写$8000和$A000
3 p, s3 S3 P1 Y( l2 j        1:允许擦写$A000和$C000/ J/ S% [# \7 @" E) [# n
        位D7:
. w& h" O7 a6 Y! Q" P$ B        0:模式号D0-D2使用普通地址6 {' P' O, o  {+ j: c9 \7 H5 C
        1:模式号D0-D2地址异或$1000
* @( A& m8 O4 U* x% c$ I- Y) b/ a* l% G
$8001:  模式页面号
% G: l$ j1 W1 H- [5 y: W        写入一个数(00-07),切换存储体到对应地址& B4 M  m5 ]8 O7 v
: }9 H; a( E4 r+ B0 I
$A000:  镜像选择
0 z. P: F, @% ?/ r  J        0:垂直镜像; `( q) a& @( m" i
        1:水平镜像
; e, |7 I% m& ]6 p' u3 n8 E' ]! y. \5 c
$A001:  SaveRAM 切换
* n) f' _" X1 Z) d# g; v* G! {        0:禁用$6000-$7FFF; C$ \& e5 y+ B$ \5 X7 \
        1:启用$6000-$7FFF+ w* N8 Y- `5 S8 A0 r; D/ y

$ W7 g  E8 B" {% s, e2 q% R$C000:  IRQ计数器
; Y: ?. T% X; M( o% ?        IRQ计数器的值存储在此处
7 Q  v  V, L" l/ W( I  t
* |) A2 R& Q! X$ I' d7 F$C001:  IRQ暂存器2 S( [8 K% s* q9 J7 v5 v3 U
        IRQ暂存器的值存储在此处
) j# e, V, W" w5 x: D2 |! v, ~$ Z0 _# a5 _) F* O
$E000:  IRQ控制计数器0
5 x0 |" h; x: {: s/ h        向这里写入任何数来关闭IRQ,并从暂存器中拷贝数据开始计数,进入IRQ
. n0 h* V& g$ p& [% o3 I4 g' z% l" b3 p5 @; {5 z  Q
$E001:  IRQ控制计数器1
  b$ O/ V, d$ ]/ B7 N3 v) z) |        向这里写入任何数,允许IRQ(退出IRQ,允许下一个IRQ进来)8 _' U6 R1 Q' k! ]1 H0 l

& b9 L/ N) L3 t3 I5 y. q% A6 z& E# |, ?
转换思路:& r6 i* o6 X- h
将Mapper 23 的切bank 方式和切VRAM的方式修改成Mapper 4 的方式。
8 |) Z4 x! `+ X* B8 D( V! _
' P8 J2 S3 y2 a修改实例:
- U9 |% m5 |. L- X# {, QContra (J) 256KB Mapper 23
. Z8 p, k2 l7 X3 {3 m6 U4 W工具:. p* t) m; L  [
1.FCEUX 2。2。34 c, a' y& ]! e  Z3 ~5 z
2.HXD& h" }0 J( Y. s. t5 J& w
先来看看这ROM的切bank方式:
6 |) r" }' A0 J: i  k6 q3 G2 {F989:AD 00 80  LDA $8000
- u; Q; k, w& O* _1 D  I) BF98C:8D EC 07  STA $07EC& W7 w4 x2 u4 I2 o
F98F:8C 00 80  STY $8000% Z/ F7 V$ j1 D5 B, A: l5 O
F992:C8        INY/ G3 P" {3 t( y% f) l7 U( }5 H
F993:8C 00 A0  STY $A0000 G' n7 y9 |# k. `
F996:60        RTS
5 q, j: U" M3 W7 A! Y! ^% v* C
8 [5 K: X; u$ Z$ _! m  o- K! \再看看它的切VRAM方式:( Z5 K$ h7 O! {5 [, S
FACE:AD F0 07  LDA $07F0: q; D5 n1 u, t) Y/ y; s
FAD1:8D 00 B0  STA $B000
- V, `) r. O  J# ~7 V% @FAD4:4A        LSR9 D# k7 k( b; g0 M
FAD5:4A        LSR4 A4 h; }6 O, s+ k1 N
FAD6:4A        LSR0 k4 {/ T* [" W
FAD7:4A        LSR
. `; `$ b: H$ Y2 fFAD8:8D 01 B0  STA $B001" [; G: f( _! C* L! C
FADB:AD F1 07  LDA $07F1
# u$ X9 [# n+ G. T0 T3 B- ^& EFADE:8D 02 B0  STA $B002
, Z. \# x# ^' a' tFAE1:4A        LSR
7 D9 I5 e0 q+ A# y7 u; p& C4 oFAE2:4A        LSR8 B9 s+ {/ z0 [; U. G
FAE3:4A        LSR: Q& P" T6 G! j
FAE4:4A        LSR
1 p$ F. C2 A2 ^) SFAE5:8D 03 B0  STA $B0036 y! T5 C7 B& }7 D3 }1 n
FAE8:AD F2 07  LDA $07F2
6 J# [3 P9 A4 U' tFAEB:8D 00 C0  STA $C000
( Q7 T# P+ l, hFAEE:4A        LSR; p1 M* H3 g% d' W3 `
FAEF:4A        LSR4 O1 b: C% h+ R: C
FAF0:4A        LSR
& [1 m# ^0 s* y: U0 FFAF1:4A        LSR  v% \0 D$ F3 g- S
FAF2:8D 01 C0  STA $C001# n- F& e: \7 c
FAF5:AD F3 07  LDA $07F39 n7 j' \! r& P
FAF8:8D 02 C0  STA $C002
+ Y  U# @' r3 {4 b- K4 _FAFB:4A        LSR# ]$ e! |2 F2 a( a
FAFC:4A        LSR
# Q2 A3 X5 X1 \. G( R/ B* \$ yFAFD:4A        LSR
5 E- N5 e; O# p9 x3 a% bFAFE:4A        LSR- u2 J( C5 ^: L
FAFF:8D 03 C0  STA $C003( }: H8 t) J. G1 [7 p, ^7 z2 f  h
FB02:AD F4 07  LDA $07F4
1 a- q7 t( Y( X( O6 ]8 h) iFB05:8D 00 D0  STA $D000/ h0 F4 F/ N, m. b- o" V
FB08:4A        LSR  Q& p5 \3 T* Y, a& m
FB09:4A        LSR
! L- ~8 n* L/ U& ?FB0A:4A        LSR
; d' ~. @; B) g; Q; n: dFB0B:4A        LSR; R& j) \" Y1 ^. E  w) N
FB0C:8D 01 D0  STA $D0016 W' {& ^! h$ [7 U3 s! j# o, c
FB0F:AD F5 07  LDA $07F5
, z& u+ n, Z3 JFB12:8D 02 D0  STA $D002
) ?% x: s) r. |8 @; v; }6 _! |: rFB15:4A        LSR
6 h: v- r# ^3 Q) _! KFB16:4A        LSR
+ ^* d5 r7 ]- Y' T: @, ?( U% bFB17:4A        LSR
' C' o# z9 c" G; [; Y; ~2 _FB18:4A        LSR4 i) K! M8 ?6 _) B. [4 W6 M. G
FB19:8D 03 D0  STA $D003$ _$ e: R8 S! P0 u) h
FB1C:AD F6 07  LDA $07F6
- E3 r  A5 h" |5 ]% @FB1F:8D 00 E0  STA $E000
0 y5 o1 W- k6 |2 MFB22:4A        LSR$ O* b' ?* L$ |6 ?1 R
FB23:4A        LSR% z  N" Q3 o) U
FB24:4A        LSR
1 \4 f, q  M; n" p) K' {FB25:4A        LSR
5 S1 M* T* T, M, [: y( Z: sFB26:8D 01 E0  STA $E001& P! x- v3 I: T3 p6 v$ P
FB29:AD F7 07  LDA $07F7
, m) k, ?2 r/ v' [2 iFB2C:8D 02 E0  STA $E002
5 B3 O! m! h+ {+ EFB2F:4A        LSR
3 x9 z. y% N0 i' b; g+ g, M0 tFB30:4A        LSR: t/ Y8 y1 a0 R2 H: M
FB31:4A        LSR
; I3 \6 f9 j. e2 r7 ]: IFB32:4A        LSR& O+ N& R' {" Z( E# b
FB33:8D 03 E0  STA $E003/ h$ p( O. p' ]! I
FB36:A9 00     LDA #$00
! _4 C" A7 p! o# u2 I2 R! m/ ~: B$ WFB38:8D 00 90  STA $90002 t; k9 j1 l# j. r/ a4 P+ m
FB3B:60        RTS
; A# d) X7 k* |
: o' ~6 U* f: K; P# t# F( H接下来修改切bank方式:; L' z8 s2 {, R( k0 F( D) v2 `- I
FB2B:48        PHA
) u# k; i; m: D2 o* dFB2C:A9 06     LDA #$06# v  T2 L, J# M) v& U0 W% Q
FB2E:8D 00 80  STA $8000
& F5 o1 N  e2 x1 u) W6 hFB31:68        PLA- H8 ]1 N  E1 H8 _. \, ]
FB32:8C 01 80  STY $80018 r% G& E' g- B8 {
FB35:60        RTS2 a1 S- K3 M" y4 S; B( L
/ a; v( r& k" E  {  U' P& }& f) B
FB36:48        PHA
. F! H7 J: O' D! tFB37:A9 07     LDA #$07
) d9 E: L/ Q6 j2 c$ b$ I" PFB39:8D 00 80  STA $8000 = #$142 |$ n! ~0 n1 @
FB3C:68        PLA4 L2 G) [: I$ C- L
FB3D:8C 01 80  STY $8001 = #$1D
& m; x: P, D5 v& Q0 CFB40:60        RTS
- m+ i/ ?3 K: P8 {9 a- F) Z0 Y  u9 s9 I+ p5 \7 R) J4 E
还要把原ROM的对$8000和$A000进行写入操作的程序修改一下:
1 T3 p+ d. j( j% J) Q% e/ tF989:AD 00 80  LDA $8000 2 {9 n' s3 j6 J- p  g
F98C:8D EC 07  STA $07EC( S2 y1 K4 k; M, q0 l- m: z
F98F:20 2B FB  JSR $FB2B4 f, \" s) ]  ?! |' L- R
F992:C8        INY
: L9 `# k  G" I' c- v4 kF993:20 36 FB  JSR FB36
( M. P% k/ U4 A# @* L: O: xF996:60        RTS
/ r# Y+ ?9 I: P
* t, q. F& y5 |7 F7 y/ K5 L再修改切VRAM程序:+ O+ l4 N3 \. V
FACE:A9 00     LDA #$00' \( z9 l2 ]! U+ C
FAD0:8D 00 80  STA $80001 _! T4 o$ `) a* _! E" D% {
FAD3:AD F0 07  LDA $07F0
2 A9 X  F% R; |( |- Z5 N/ hFAD6:C9 01     CMP #$01
! M; I8 J. S4 u, {% _FAD8:D0 11     BNE $FAEB4 Y0 n! l! q' j! e$ Y+ Y$ j0 f" X6 ~
FADA:AD F1 07  LDA $07F1
% O2 H8 ]/ g# h3 DFADD:C9 04     CMP #$049 A) i( \3 e  }- A0 j7 h. H
FADF:D0 04     BNE $FAE5
  M5 f9 D4 M! P' |. C) O" @FAE1:A9 80     LDA #$80+ C/ e% j1 ]$ `7 b
FAE3:D0 06     BNE $FAEB. C- r' k3 m7 h
FAE5:C9 05     CMP #$053 U, s# t; d5 f9 {
FAE7:D0 02     BNE $FAEB4 [6 T" F% e& Z
FAE9:A9 82     LDA #$82
$ ?& n) y1 }6 \9 sFAEB:8D 01 80  STA $80011 Q+ E- g6 ]8 k- n
FAEE:A9 01     LDA #$01
. k* o2 a* |) a8 h% I) mFAF0:8D 00 80  STA $80003 Q3 J  A( V+ ]/ P# l
FAF3:AD F2 07  LDA $07F2
! i: D9 p0 u3 o: Q8 k1 ]5 o5 oFAF6:8D 01 80  STA $8001+ @' x8 x) J  L- @; X: h
FAF9:A9 02     LDA #$02+ w6 m# Q6 z6 K- E
FAFB:8D 00 80  STA $80002 e# Q, o; x0 I3 r% Q- ~( f7 K
FAFE:AD F4 07  LDA $07F4' e2 |& C* `% C8 ^
FB01:8D 01 80  STA $8001
% o% n- E# s* U% zFB04:A9 03     LDA #$03
) N, U  X; v8 w2 [4 D1 A6 ]: D3 nFB06:8D 00 80  STA $8000
; M6 U# Q' r! {) |5 n3 _% x5 F+ sFB09:AD F5 07  LDA $07F5( K) X- `( i2 x' U3 O
FB0C:8D 01 80  STA $80013 p( i, ?& i' o: C/ m% k3 ?
FB0F:A9 04     LDA #$043 |  [9 Q% v7 l7 L( v8 W' g
FB11:8D 00 80  STA $8000" g/ |, M0 v/ ^- V
FB14:AD F6 07  LDA $07F6! o5 a% C0 g2 W5 v4 ]
FB17:8D 01 80  STA $8001
* D! k. s% W; ^! X: Z  fFB1A:A9 05     LDA #$05: g; S8 p- e5 {, m5 ?! P
FB1C:8D 00 80  STA $80002 K3 a: B! |2 Q5 k
FB1F:AD F7 07  LDA $07F7
0 v5 A, Z* Q, Z: n2 |( G. l, @FB22:8D 01 80  STA $8001: ^( E$ \9 d+ H9 W7 {
FB25:A9 00     LDA #$00
$ ?# l5 R6 ]6 ~; S% G- t' }FB27:8D 00 A0  STA $A0004 G$ `8 y% f. |( g" V0 H
FB2A:60        RTS1 `' J$ i1 |1 P# x, P
, C& E4 S: @& y  H3 f: t8 F# v
然后保存文件。+ t) z$ U. t: M1 c0 ?
使用HXD修改文件头:
1 l, \, X4 t3 Q( Z5 z6 ]0 e" A: _将Mapper  235 C+ ]( d4 W6 c6 z4 B9 F  J2 T+ d3 F
06字节的高4位是Mapper号的低4位
/ b9 d' }& v! \, `, i+ c07字节的高4位是Mapper号的高4位  b* m4 G: z: ~. ?
组合起来就是0x17=1*16+7=23
2 E' @; [, Z. o/ |. r- p! F/ O/ ^7 _, `9 F
修改成 Mapper 4$ p! ^: W( b* B
2 w! m2 \% \: ^0 G
- R8 i9 L* v( G/ s! b# ^- U& r
! v0 f6 a7 v( M7 ?
再次打开文件:* F$ ]7 u9 X' A( \: r3 A6 k( ~
" n5 [! z( B6 S
可以正常运行" y0 _  X, m# p: l" f, o
通过全面测试,发现出现精灵错乱:
3 B/ ?6 Q1 D* D; a" }/ |8 C第1关:
% L) X+ P7 S+ W3 ^# a! @4 |6 `  x7 u# K$ @5 ~* P' q& ~
& y+ [9 C5 Q/ b6 ?2 U3 \* p" j
第2关:
1 G3 ?6 i) L! {+ C+ x4 u
1 J  ]  Z2 N1 v" p任务失败后:5 S/ z. J4 @% J

* G! _* H9 y2 Y' T通关后上飞机画面:
+ [1 _5 ?: a. [: w$ l' F" n+ Z. H: \  W% k, F- m
这是为何呢?
- K  Q8 ~& n/ X& N3 x* {这是因为Mapper 23 中精灵VRAM切bank是一次切1KB8 o3 |# z  z' |. M
但是在Mapper 4中精灵VRAM切换却是一次切2KB,而且忽略bank号的D0位
0 t2 g2 ?8 v& @5 F0 N比方bank 0和bank 1是同一个bank,同理bank 2和bank 3是同一个bank8 Y: _2 x/ ~% L$ b: @, A
也就是说
5 i8 K  U" Z! o* bMapper 23中的VRAM的7 A$ [4 K" M3 F0 [0 L9 ~
bank 0,bank 1,bank 2,bank 3
* ^! K$ Y- k6 \+ X在Mapper 4中对应的是4 R: ]$ M( d' B& d5 ]6 l' [& R
Bank 0,bank 0,bank 2, bank2
7 P+ F" f% |8 P/ N8 Z8 n8 t然后查找原来的ROM的切VRAM的程序:
' M2 A9 _- S" V4 v4 b1 e1 n  _' P; R知道是从07F0-07F3切到精灵VRAM的:, q) A# ?' s0 |# Q9 p+ j7 g
如图所示:! L4 V, R+ Y& U! K

1 h. S/ ^% f, q) Q6 o
. s9 j  I* _! p4 l作为对比,左边是原版,右边是修改。
, s+ [0 s* [. ]! Q3 w6 u+ Q- Y接下来是完善VRAM切换带来的问题,因为Mapper 4只能切2KB的bank,所以我们不能通过切bank程序解决问题。
6 Z4 k  g# w/ F: u2 h3 H1 u通过测试知道1,3,5,6,7,8关的精灵VRAM排序如下(07F0-07F3):
# N: b" \. a: L! S8 Y! b01 04 06 076 y9 ?( S2 S$ j. Q
第2,4关如下:, N5 w# n: `* G8 j
01 05 08 09
/ g9 J( g8 y. A$ ?; ]% I, Z3 d任务失败时如下:! r( A2 @. a; ^  t0 s
32 00 00 1B
% _9 O6 b  f6 m; P9 d0 }- k$ ?其中任务失败时对应的VRAM是07F3的1B,只要让07F2为1A或1B即可:
* m  s. L/ k1 N- l8 c: T4 d通过调试找到对07F2写入数据#$00时程序如下,于是修改C7E5的值为1A即可:
; A$ M( U' D1 [2 s9 W  l6 E
. H3 h* ?- H" y8 p) q转到ROM地址:
# O+ B' y* _6 z9 V/ P$ j0 U; d7 i# ^0 W! {
修改数据:* o. r; N0 z" O

2 A  E. i6 R$ @$ U+ ?6 |重新失败后可以看到修复成功:+ [: z5 o' d/ q2 T6 c9 C: Q$ P

7 k1 s0 i0 a8 u+ a3 T- ]' P接下来是修复正常进行任务时的精灵错乱问题。# M( Q# z/ j- h( O2 n7 o
首先运行Mapper 23版本,在1,3,5,6,7,8关任意一关的时候,将PPU导出来1 q6 N! ^( N' q  l- z1 Y

7 z' Z! x* h# Y  D) i; m3 ^
: y0 \7 W. T/ O# i; d( O/ k* _- L; F6 {0 E' s( ^

: R! A4 o' a- P/ B! @+ j- i: Y+ ^然后用Hxd打开修改的Mapper 4的ROM和刚刚保存的PPU的数据文件:( a( F( ~# A2 s6 H8 Z) G
9 z- Q7 [+ h+ A" j  R9 T& g
在ROM文件头第05字节改为0x20:
& ]; @; I7 u) `( L8 [/ |7 q' S8 |2 B& Z- Z: S5 [: ?$ X; m: L/ T
然后转到文件末尾,插入0x20000字节空字节:  Z3 ?1 E1 {% c( B! l  G- @, n
- ]4 t& N* E" Z. P

7 n( ]# L# `5 J; x  B4 l6 H% T0 T) b7 N0 u# \% h) R
' {+ ]6 r6 b3 R# b5 {) V
然后将第1关的PPU数据的前面2KB数据选定:
3 I5 _' P  `2 b* P4 c- {3 `( u) d: b) Q7 E( G, {1 Q' }& f

* B/ p/ L" @" g0 _  ^, \) B  e# s4 n/ K9 p# |8 w: s
复制之后以覆盖方式粘贴到ROM的40010,同样把第2关的PPU数据的前面2KB以覆盖方式粘贴到ROM的40810' P+ k! i5 ?/ _7 A3 z
' S) J. j+ ]9 |- ?+ c
然后保存文件:, Q! y& X4 m# X% N
. a% ~  b+ u) ?: S' j# S6 b- F
最后用FCEUX打开文件,添加07F0-07F3的写入断点4 B. t' Q/ q, x! v- f
. F7 R: l, q( i4 }9 A) `6 U* a8 n
地图预览后即将进入第一关画面时程序暂停了,可以知道此时准备将C793的数据写到07F0:9 l9 j* g" W! ~- H% w

, r1 ]; W3 U8 U, u测试后知道将C793-0796写入到了07F0-07F3:% x" ^) Y' b5 A( a
同理,经测试每4个字节一组,一共17组,其中01 04对应普通关卡精灵以及其BOSS关的精灵VRAM的bank号,01 05对应2,4关卡精灵以及其BOSS关的精灵VRAM的bank号,再加上一个通关后跳上飞机那段动画的精灵VRAM的bank号。
# {+ b& A/ Q& `$ U* J
, ]  T5 h' ?1 P' y* \: \
7 u( q" |6 Y" c+ ~3 k. w然后将文件中标记的01 04修改为 80 04,将01 05 修改为82 04即可:$ ~$ p6 Z; V$ a$ G- N! @6 y2 m

7 k: `, w. g9 @! i- p# n' X保存之后重新运行后效果如下:$ a" {5 h0 h6 R' P0 `! h# K
* @$ z; k' g1 Z1 a- U8 s' J
, b6 z) [7 f+ [

8 D6 h7 ~. s- U/ `, Z当前使用的是FCEUX模拟器,如果用NEStopia玩的话一开始就死机了,这是因为这个ROM有文件保护吧,它会往$6000里写入数据:
0 c6 L" d% v2 l7 v! s3 x& F  B$ Y4 C0 M3 U+ P* j0 T& B
F863:A0 03     LDY #$03
% p7 ^+ T+ h# H( ]( _. j6 Q  c, M% NF865:98        TYA
3 i* i' `) c5 d, j1 OF866:29 01     AND #$01
- E) d1 ]9 B+ j6 U, v' jF868:8D E9 07  STA $07E9
; l1 F% P8 E  t- M) oF86B:8D 00 60  STA $6000; O0 Q! ?9 h7 l4 l, Z& q! Q
F86E:AD 00 60  LDA $6000( D5 R) z3 W0 d
F871:29 01     AND #$01' n) w' }9 x. q' u
F873:CD E9 07  CMP $07E9) {5 {; k' i/ @3 P8 ]7 ^' {
F876:D0 05     BNE $F87D
8 W3 b* {3 s  R6 f. v2 a% V6 LF878:88        DEY
+ z- W( [% n1 k1 Y* {( k- bF879:10 EA     BPL $F865
2 c2 A/ W" o7 M% j2 @7 R$ v  BF87B:30 03     BMI $F8804 }. h0 E; o  j6 t
F87D:4C 00 00  JMP $0000
6 e3 ?9 S3 _2 H* O$ \F880:A5 1A     LDA $001A0 M$ u' d) M+ n& P# J2 I
F882:65 34     ADC $00346 O, i- }: j$ L7 P3 r; E
F884:85 34     STA $0034- B3 H* z: ^' S+ K% T. e
F886:4C 80 F8  JMP $F880
' @- a2 \9 m  u: `先取Y值=#$03) ~( s# e+ w4 ~( K4 c$ ~. o
与#$01相与后得到#$01
- U" ~% T# f" W! m4 ~: k% V$ s8 c写入到$07E9
0 A# e' F7 Y9 Z" M: {写入到$6000; u# }7 ]9 _+ N$ i& B- p
再读取$6000的数据和#$01相与后和$07E9的数据比较8 A  N4 f) [4 t! s" R
不同的话跳过5字节
: n+ E" J, ]- m- P( ~" z否则Y递减
- C! n, A8 V( @4 }& Q) Q3 B) x! \3 w为正数就跳回0x100-0xEA=16字节" ?6 _+ i! t0 }" `& I( h: W
为负数就跳过0x3字节
0 W% ~* C' y6 K跳转到$0000(简直没有人性了,跳到这里死机,真想得出来)
- @! I' o) k- E, ^) u
4 T) k! j. m; p2 P/ q" o正是因为这样,NEStopia运行FC时,6000-7FFF默认是不可写的,必须在ROM文件头第6字节的D1位置1设置ROM有SRAM,对于Mapper 4,还需要向$A001写入#$80来启用SRAM。
* U0 O' n7 G& L  i+ _7 R7 A由于$6000不可写,因此想$6000写入#$01后$6000还是#$00,之后读取$07E9的#$01与之相比当然不同了,于是直接跳转到死机程序了。
5 o; X; j1 r3 E0 T  A解决方法是把ROM中的所有的AD 00 60 29 01 CD E9 07 D0 05 88 10 EA 30 03 4C 00 00% z3 A- d) o( a' P* Z
中的D0 05改为D0 00,然后保存即可。
' Q. ~7 U7 k6 B9 U5 s测试完美运行。; o( l9 m$ |, L! }: z: k% M+ U
/ P& F$ g) v2 s$ ^' P" f' ]
1 c+ Y0 Q( Y, M. D
教程到此结束。) ^. a0 [( B! x0 q8 M
7 d9 Y: i( n2 c0 w, x
游客,如果您要查看本帖隐藏内容请回复

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
[发帖际遇]: yandagui踩坏了花花草草,被罚款9 个 柠檬. 幸运榜 / 衰神榜

签到天数: 71 天

[LV.6]常住居民II

发表于 2017-4-14 21:37:22 | 显示全部楼层
虽然看不懂,但还是进来支持一下楼主发的修改游戏的教程,楼主辛苦了。{:4_137:}
[发帖际遇]: 街机爱好者 打扫环境卫生,被奖励 1 个 柠檬. 幸运榜 / 衰神榜

签到天数: 48 天

[LV.5]常住居民I

发表于 2017-4-15 07:40:42 | 显示全部楼层
巨巨威武,不但分享作品,还分享技术。目前只能纯支持了。希望有一天能看懂。{:4_118:}
[发帖际遇]: 一个袋子砸在了 cococo8858 头上,cococo8858 赚了 5 个 柠檬. 幸运榜 / 衰神榜

签到天数: 1418 天

[LV.10]以坛为家III

发表于 2017-4-15 08:18:51 | 显示全部楼层
长文一般不看{:4_112:}

签到天数: 3185 天

[LV.Master]伴坛终老

发表于 2017-4-15 09:07:05 | 显示全部楼层
感谢发布实例教程!
[发帖际遇]: afti辛苦发帖,赚了 2 个 柠檬. 幸运榜 / 衰神榜

签到天数: 1296 天

[LV.10]以坛为家III

发表于 2017-4-15 10:18:45 | 显示全部楼层
很好的实例教程,学习了。
[发帖际遇]: qqture2005 打扫环境卫生,被奖励 4 个 柠檬. 幸运榜 / 衰神榜

签到天数: 20 天

[LV.4]偶尔看看III

发表于 2017-6-23 09:40:56 | 显示全部楼层
学校谢谢。。。。。。。。。。。。。。。。。。。。。
回复 支持 反对

使用道具 举报

签到天数: 30 天

[LV.5]常住居民I

发表于 2017-8-15 17:17:13 | 显示全部楼层
感谢分享,看一下楼主的修改方法
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|国治模拟精品屋 ( 沪ICP备15012945号-1 )

GMT+8, 2025-9-16 17:00 , Processed in 1.145508 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表