EMU618社区

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

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

[复制链接]

签到天数: 39 天

[LV.5]常住居民I

发表于 2017-4-14 19:43:10 | 显示全部楼层 |阅读模式
本帖最后由 yandagui 于 2017-4-16 19:06 编辑
. u: Q; \5 G+ F; ?0 I+ B1 D' |% m6 Q% i
Mapper23转Mapper4实例教程( Z6 l7 o' h) `. j( r
7 {0 U! {. e0 G# _6 s, Y* L
FlameCyclone 2017.4.14
' i/ v( u3 Q" c8 o  f# w- R9 _% F' z; Z1 C* s7 Q, N) u+ a
先看看Mapper23文档:
4 h9 o! G8 ?4 G1 w% j5 Z, T
0 a5 H; h% C0 m; n. RMapper 234 P& q% H) U/ [0 Q! p9 P% _
# G- i* I: O$ X4 z# H
$8000:  选择8KB的ROM存储体映射到$8000
4 h) v: D% @( t# c6 a/ o9 q7 s8 f: y" f0 A, |% o4 X. }* @! T3 g
$9000:  0:垂直镜像% S# l" f& w6 b8 `) U
        1:水平镜像. {+ ?# ~: ]9 l; \7 j* x4 N
        2:$2400镜像$ N+ X: w9 D' k. G% b8 z+ f2 G3 y
        3:$2000镜像$ M% R8 }- ]9 V; b

4 }2 x" R0 M; s4 {' V$A000:  选择8KB的ROM存储体映射到$A000
9 m- i* z5 t; ?" j
( }1 f4 K4 m. E) f$B000:  选择1KB的VROM存储体映射到PPU的$0000(低4位)
( e8 J& [1 l4 U8 B  o$B001:  选择1KB的VROM存储体映射到PPU的$0000(高4位)0 `) j8 {; ]/ Z! f) ^1 D
$B002:  选择1KB的VROM存储体映射到PPU的$0400(低4位)
' V6 I0 V# G. b& O5 T  `6 y2 I$B003:  选择1KB的VROM存储体映射到PPU的$0400(高4位)
# k/ q7 M6 b4 k- C) `+ `( ^" q
' O& f6 e* J5 ^1 N1 Q- P$C000:  选择1KB的VROM存储体映射到PPU的$0800(低4位)
# a" e3 ~6 Q) P5 d# s& q2 v% }+ [$C001:  选择1KB的VROM存储体映射到PPU的$0800(高4位)
9 ^) ^: J! G  g- @3 k$C002:  选择1KB的VROM存储体映射到PPU的$0C00(低4位)
1 z8 a" N* h. O/ i$ d$C003:  选择1KB的VROM存储体映射到PPU的$0C00(高4位)
2 N3 ~: I3 ~) F% s* L$ F
4 Z% Z% ^. L" U8 Q4 W0 k9 H# n$D000:  选择1KB的VROM存储体映射到PPU的$1000(低4位)* o3 `7 {5 c* X
$D001:  选择1KB的VROM存储体映射到PPU的$1000(高4位)
3 S$ T$ p( I4 k# R! V* S$D002:  选择1KB的VROM存储体映射到PPU的$1400(低4位)
" A) }, T0 i" G/ `+ D$D003:  选择1KB的VROM存储体映射到PPU的$1400(高4位)# T% e+ y4 O0 c" q  D
8 N" X4 k* I7 g1 w$ [5 l3 S( G
$E000:  选择1KB的VROM存储体映射到PPU的$1800(低4位)
: {% ~/ C5 B, [" \" w( K$E001:  选择1KB的VROM存储体映射到PPU的$1800(高4位)2 K3 w( {; @+ y& Q) I: B* x
$E002:  选择1KB的VROM存储体映射到PPU的$1C00(低4位)9 e, b( v% C1 y0 M
$E003:  选择1KB的VROM存储体映射到PPU的$1C00(高4位)2 y) K/ j4 R, H
: d' T% k% A% z: @! r
再看看Mapper 4文档:& q4 t" D" L# E+ @

) \. _& i! R/ {Mapper 41 S7 }( u1 m: j2 K1 e
: z* ^5 k7 Z# |2 l  m& _- V
$8000:  模式号
' e+ J( D$ r- D7 `        位D0-D2:  a' K. r/ f8 q+ G% m: `
        0:选择2KB的VROM存储体映射到PPU的$00005 g5 q7 q5 k5 L) b2 p# Y( B
        1:选择2KB的VROM存储体映射到PPU的$0800
9 ^; z% B$ [4 {- |4 Z% W4 U! h        2:选择1KB的VROM存储体映射到PPU的$1000! G) d( M6 F+ V  m7 Q# }
        3:选择1KB的VROM存储体映射到PPU的$1400$ G  y5 N+ S% j! B% R7 U
        4:选择1KB的VROM存储体映射到PPU的$18000 K+ D( v- X; Z5 z. t" y
        5:选择1KB的VROM存储体映射到PPU的$1C00) ?  y7 [( o' U
        6:选择8KB的ROM存储体映射到$8000
* [& x( U8 v) Q! K1 N( J/ B& I        7:选择8KB的ROM存储体映射到$A000
4 i: ?* y& `* ~! ~& J  T4 [. V7 C        位D6:
+ S) R& }9 s: k3 r5 r        0:允许擦写$8000和$A0008 K/ P7 p0 }! p3 I' S6 @2 X
        1:允许擦写$A000和$C000
6 @# M1 d# P7 p2 P        位D7:- u7 Z/ B! v' P2 G
        0:模式号D0-D2使用普通地址* T0 ^# X1 x, Z9 M
        1:模式号D0-D2地址异或$1000
3 f# S" [  t0 ]4 Y- n6 B- N3 Z: S& l* N9 K
$8001:  模式页面号; c1 m/ d- `: \; m+ Q
        写入一个数(00-07),切换存储体到对应地址; R; |: C& q* o! G

- |) z" `3 V2 B/ V9 F; N$A000:  镜像选择
& r2 R& m" r' t0 K- P        0:垂直镜像; a+ v$ h5 D, o
        1:水平镜像
) s9 {- `4 s' z  C8 Y# q
5 A3 P' }  G' o: I9 }$ s$A001:  SaveRAM 切换3 Z. ~; V( q! C1 R+ }1 n7 Q
        0:禁用$6000-$7FFF% p" Y! ?- L  S& G
        1:启用$6000-$7FFF' d/ K# J& ?3 `4 L
9 C) [2 ?3 _" n' C* ^9 h; m
$C000:  IRQ计数器9 V7 J! X% k9 X! w2 I
        IRQ计数器的值存储在此处
- N" N& s9 m$ \% ]
; g0 p, o1 J7 b& M$C001:  IRQ暂存器9 V9 F, C. w4 m. y, v0 K
        IRQ暂存器的值存储在此处% [: j3 o3 B- f6 e7 w% ?% s

: w( [4 ?) H1 E$ {9 Z$E000:  IRQ控制计数器07 d. e" T7 e7 ?4 X9 {& x6 O3 F
        向这里写入任何数来关闭IRQ,并从暂存器中拷贝数据开始计数,进入IRQ+ N/ I7 ~. s+ o1 |2 x% ^3 Z4 s
* T. P' @! ]; A! a" X$ J
$E001:  IRQ控制计数器1# _/ G( k2 s+ Q; e2 b7 c
        向这里写入任何数,允许IRQ(退出IRQ,允许下一个IRQ进来)
% ~6 O+ k0 G7 u2 a9 A0 U0 `1 i$ o& j+ X
' t. W0 I9 L6 \- W& b( T
转换思路:+ p* J; f' c- c+ @1 K
将Mapper 23 的切bank 方式和切VRAM的方式修改成Mapper 4 的方式。  A. C! T& c9 l4 D
1 U6 Z. K( ^3 `$ v9 y5 i6 h
修改实例:" C+ K9 _. M3 a) c! a3 X
Contra (J) 256KB Mapper 23
0 A! ~& c9 [4 E: m  M工具:) c# _8 R3 R5 m7 H
1.FCEUX 2。2。3
; t# X$ M: O5 e/ t7 s  C* X/ A2.HXD
# v( ]/ _4 P( \* N/ N" {先来看看这ROM的切bank方式:
4 h& x; d; [0 @9 m6 H3 r" }( SF989:AD 00 80  LDA $8000
1 U% X. }8 T3 i3 IF98C:8D EC 07  STA $07EC
9 K4 @) K5 ?% G7 l  \1 ]% rF98F:8C 00 80  STY $80009 v6 {* |' p) b! N+ ?! U
F992:C8        INY
( Q: p+ ]4 c4 @1 MF993:8C 00 A0  STY $A000) N! ?4 c% n6 R; K( O3 O
F996:60        RTS
( X& Y" y! @6 C- n% o+ L* v1 b  O7 r* R
再看看它的切VRAM方式:0 W2 g2 `2 j6 d& ^& B
FACE:AD F0 07  LDA $07F0
$ J( r4 B# R4 n6 I2 ~+ X1 Q9 y( yFAD1:8D 00 B0  STA $B000+ ?# x2 ?6 A1 q) ]( W1 |5 _  @: {/ l
FAD4:4A        LSR
2 f; ^% s1 U/ i5 WFAD5:4A        LSR
" M. R+ ^, f# Z' H7 W; eFAD6:4A        LSR" {* G! A7 `( @! x
FAD7:4A        LSR
, ~/ e8 e8 P  V8 U; K) gFAD8:8D 01 B0  STA $B0013 [$ l* k6 P9 D- ~4 x6 C- C
FADB:AD F1 07  LDA $07F1) w7 q/ u, ]  w. q
FADE:8D 02 B0  STA $B002
6 w+ M1 W6 T# N' TFAE1:4A        LSR% \4 o# M) @# r: N
FAE2:4A        LSR
$ J9 Q- e! E$ u7 S# J3 Y5 uFAE3:4A        LSR
3 R: A4 p) P! k- J6 A6 CFAE4:4A        LSR
: d& K8 i3 i: {- \8 t% W. DFAE5:8D 03 B0  STA $B0036 g% B: _3 u4 ?" P
FAE8:AD F2 07  LDA $07F2  D9 s5 M8 O6 Q. R; j+ x' B- o
FAEB:8D 00 C0  STA $C000) Z( Z% H" G1 G1 x. ^- u
FAEE:4A        LSR5 L. j7 {/ i4 h$ F; g* V! @
FAEF:4A        LSR
# N; z" _# P/ h5 v) rFAF0:4A        LSR! D6 k$ r, B) D7 j- x+ H+ _" O4 C
FAF1:4A        LSR. n8 y) O! E8 D& |2 o
FAF2:8D 01 C0  STA $C001) C. g2 X/ u  b8 ~0 E( \
FAF5:AD F3 07  LDA $07F3
( V9 s9 z6 Z( K6 C* J: rFAF8:8D 02 C0  STA $C002
$ O; O+ c6 ]' b4 r* dFAFB:4A        LSR+ {7 [( X7 N1 M2 R) b) N% O
FAFC:4A        LSR% w' O4 g+ C( v, `( ]
FAFD:4A        LSR
$ J0 n0 j/ q0 \% I5 `0 fFAFE:4A        LSR
$ M/ ]  i& E7 |4 `: Y  e" UFAFF:8D 03 C0  STA $C003% ?7 R6 ^9 U. D
FB02:AD F4 07  LDA $07F44 z+ U6 k6 R: Y, N) M8 C, p
FB05:8D 00 D0  STA $D000; C  n- \* i6 F, L# b- k% w
FB08:4A        LSR& _( U- `" k2 M& |" U) ], ^
FB09:4A        LSR! ^% K/ M/ N8 i' x0 L) E
FB0A:4A        LSR0 g( H4 u4 G* A# ?+ P: R
FB0B:4A        LSR
3 X3 @5 x! d4 m8 g- L! v3 X* fFB0C:8D 01 D0  STA $D001$ o5 D( q5 B/ Q' V% Z& x$ U9 g
FB0F:AD F5 07  LDA $07F5& r% y% o9 F4 K9 D
FB12:8D 02 D0  STA $D002
) f/ Z5 |/ a) p- D8 `* s# }FB15:4A        LSR% y3 a3 I( D! N: a& ]
FB16:4A        LSR
7 Y. Y3 r" B7 q6 S) ?! _FB17:4A        LSR& _* h# |" p1 p  z
FB18:4A        LSR
+ _+ V( C; A( S9 R6 ~' f4 j8 B1 jFB19:8D 03 D0  STA $D003
3 P  E& _$ ]. P1 bFB1C:AD F6 07  LDA $07F6
. S/ V6 I' e# w* q* g7 ]) F6 cFB1F:8D 00 E0  STA $E0008 g% J$ }0 Q% j
FB22:4A        LSR
+ U6 C/ c; L6 N1 Y- Z' ZFB23:4A        LSR8 l+ {7 h9 E$ f3 M5 |
FB24:4A        LSR# g0 |! p" F* _" j6 i
FB25:4A        LSR
. M3 L% Z& r0 J! O& x# Q3 WFB26:8D 01 E0  STA $E001$ B1 V- b9 F+ f" M3 I3 m
FB29:AD F7 07  LDA $07F7
) Y8 f2 K3 }% x% J# m3 R% \FB2C:8D 02 E0  STA $E002$ J8 g; L* t, P  v; s% d
FB2F:4A        LSR
  b' c3 @, v8 L' Y0 [FB30:4A        LSR
0 a' f2 W! ?9 R  Y+ hFB31:4A        LSR
7 R$ _" Z/ _# m9 EFB32:4A        LSR, _; E9 J0 R$ s
FB33:8D 03 E0  STA $E003
  c. `# v4 b9 g9 b( _: e& IFB36:A9 00     LDA #$00
2 F% B; y& }) H% v3 V& z+ |FB38:8D 00 90  STA $9000/ C4 J4 j  X6 H* F
FB3B:60        RTS
8 U! }' ~& ~( U/ b6 P
+ t5 I9 P( ]3 ^' G4 q* k0 T+ Z, @接下来修改切bank方式:
* Z9 Z8 z! x, R! x/ fFB2B:48        PHA
1 N: O, j; {/ ]; e* I  aFB2C:A9 06     LDA #$063 s: N7 Q6 X) r8 F+ c6 k& \0 _/ T; ]
FB2E:8D 00 80  STA $80009 ?4 W! }# A# u6 ?  a" P
FB31:68        PLA# g; g; T3 |, ^- b2 v6 n
FB32:8C 01 80  STY $8001
+ H- I; C  X1 B$ E% u% iFB35:60        RTS
; Y- g% k" M1 k- x- P2 u$ {* M, i, r% U
FB36:48        PHA
2 \4 D& L: d# TFB37:A9 07     LDA #$072 e( A, ?, |0 r: q* y3 b5 L4 C9 a- l9 O
FB39:8D 00 80  STA $8000 = #$146 C' t. Q0 S) Z2 e/ G& ]% X
FB3C:68        PLA7 M6 c8 c; n+ i' T3 ]
FB3D:8C 01 80  STY $8001 = #$1D: J1 j' ~4 X$ Z; V6 i9 M
FB40:60        RTS* G* s! H  l! _: |# u# S  Q" H
: B0 k2 s, h8 W! I! H7 }! z
还要把原ROM的对$8000和$A000进行写入操作的程序修改一下:
( i2 g7 w- N! e& \' {( EF989:AD 00 80  LDA $8000 ( U- R' U0 h! w0 \. ^$ u- Z
F98C:8D EC 07  STA $07EC
. w; O6 t4 k& x1 \1 ?$ c5 B+ PF98F:20 2B FB  JSR $FB2B0 k8 N7 p& P# \" ~8 {; _
F992:C8        INY
3 _& b" m" X; N5 R3 Y4 g1 LF993:20 36 FB  JSR FB365 L; X! D9 ?+ t$ [2 g3 E/ g1 u
F996:60        RTS
1 g- I; U. t% g: c3 \1 J9 n' y5 W; `3 y
再修改切VRAM程序:! L# R, }7 {0 i  D
FACE:A9 00     LDA #$00
! \) P! }2 ~: E- Q: m% X+ VFAD0:8D 00 80  STA $8000
3 S0 t) o- O# k; VFAD3:AD F0 07  LDA $07F05 b2 p9 H% L" S
FAD6:C9 01     CMP #$01
0 w1 r4 Y& E8 ~8 Q! AFAD8:D0 11     BNE $FAEB9 A; W0 g/ ]7 J! k. s- }& @. D1 @/ G
FADA:AD F1 07  LDA $07F1% g2 ]  g( Q8 n
FADD:C9 04     CMP #$04
. P- ^% K. l" RFADF:D0 04     BNE $FAE55 Q  V4 G6 {: D/ J( M
FAE1:A9 80     LDA #$80
0 ?$ V2 p2 j( G' f+ mFAE3:D0 06     BNE $FAEB
5 r, s( g+ [# g6 P# y# bFAE5:C9 05     CMP #$05+ @! L" `& k2 L' S# Q
FAE7:D0 02     BNE $FAEB
' C, y4 H- p5 ~, c, W* UFAE9:A9 82     LDA #$82
2 f# A/ g9 \4 w+ _" s& mFAEB:8D 01 80  STA $80019 h' r* r% X9 F- q  i3 D
FAEE:A9 01     LDA #$012 W2 `& E/ h& W' A0 q) D
FAF0:8D 00 80  STA $8000
1 N  z7 l5 b$ ?FAF3:AD F2 07  LDA $07F2
3 P. `# m, Q0 A0 R' L: q5 ?4 bFAF6:8D 01 80  STA $8001& y# T8 T3 i' p
FAF9:A9 02     LDA #$02
. P! E7 @5 S' h$ }FAFB:8D 00 80  STA $8000
0 Z; b( m( ]5 f4 Q) Q1 x: sFAFE:AD F4 07  LDA $07F4
: i3 x4 Q; Z5 i2 l7 kFB01:8D 01 80  STA $8001
) R, P! t2 j4 ~9 f& \FB04:A9 03     LDA #$03
* B: \8 j& T$ _' d  g. jFB06:8D 00 80  STA $8000; z, o' j1 x& C" U7 [" f7 r& x
FB09:AD F5 07  LDA $07F5( i/ v4 j& G8 E0 }
FB0C:8D 01 80  STA $8001
! i' r7 g- Q0 r& B# H3 LFB0F:A9 04     LDA #$043 e2 _* o0 W: _6 R/ g! |
FB11:8D 00 80  STA $80003 K/ P4 b8 ^7 i1 p
FB14:AD F6 07  LDA $07F6  q4 ^& R5 d) ~
FB17:8D 01 80  STA $8001& o9 C7 p2 `3 B. C! x2 h4 D/ |
FB1A:A9 05     LDA #$05
1 Q' V0 N! Z% k$ c0 {* WFB1C:8D 00 80  STA $8000. D6 W2 @4 B: H5 V5 N
FB1F:AD F7 07  LDA $07F7/ j4 u1 ^, L2 B- \0 l  y1 ]
FB22:8D 01 80  STA $8001. Q8 ]: x+ Q$ V4 ]- m( o; k
FB25:A9 00     LDA #$00
7 g8 y/ F- `3 j5 y* QFB27:8D 00 A0  STA $A000
7 ]1 e- W$ v) X# a* SFB2A:60        RTS8 O! y: g8 E) Y9 ~
4 ?& i. }5 g- n' z& i( X
然后保存文件。
5 Y) K( r4 j+ O7 @4 z使用HXD修改文件头:
4 s8 F. r$ L: ]) U9 k( j将Mapper  23
: ^3 K) f  U$ P4 a# g0 u. N06字节的高4位是Mapper号的低4位+ S# H- x- F% L5 O- f5 R
07字节的高4位是Mapper号的高4位
4 S7 v! X; \7 `  c( T! J: w0 [3 k组合起来就是0x17=1*16+7=23, g- C- I0 }. m! d" _

% D7 n) ]" a# p修改成 Mapper 4
" u; {3 O/ X$ L( x9 P
; a, S% M* p2 J' ?6 m. M& C/ x% e- n+ K' R

: Z; H! _% m0 P再次打开文件:7 Q1 ^9 ~& Z  S  W
: k! P' C) p, [/ x6 f9 l
可以正常运行; q: k; I, a# Y8 `* X# E
通过全面测试,发现出现精灵错乱:
3 W4 j. @" \- \2 g3 x5 l0 F! b( A第1关:+ n+ o  ~0 t2 ^8 z0 R9 R7 L, S
1 R2 E) Y( C: P$ l# ^
& k1 e1 F( ^: I3 A( M& U4 Z9 Y
第2关:
# \9 {5 Y' Y. H/ f! X
# g+ v, W. J. O8 O" L% v) }任务失败后:
5 E+ ~3 ?' {; r6 P$ x
/ Q6 y5 n9 ?! b% i( g通关后上飞机画面:
! J  k# b4 N2 x& a/ m+ i6 F
+ N2 ~2 x9 j8 ?这是为何呢?% z9 R& W) n" M9 A2 y! D& t+ d( Z
这是因为Mapper 23 中精灵VRAM切bank是一次切1KB9 _# Z6 j- _6 b/ u; t4 j# q: T
但是在Mapper 4中精灵VRAM切换却是一次切2KB,而且忽略bank号的D0位
, Z: p5 w8 a, v* z! M+ f( \比方bank 0和bank 1是同一个bank,同理bank 2和bank 3是同一个bank) M4 {# N+ m  U8 m
也就是说
" \& v4 W6 R; k2 CMapper 23中的VRAM的
* T$ v$ m+ s4 F" v% I) A, obank 0,bank 1,bank 2,bank 3% b* Z. ^% m9 ]
在Mapper 4中对应的是
. W+ l) F! y& M# \, p0 BBank 0,bank 0,bank 2, bank2( u) u9 I" C5 r
然后查找原来的ROM的切VRAM的程序:
) p/ @, x- K: V# I知道是从07F0-07F3切到精灵VRAM的:
0 i! N) O7 U0 n* Y1 A如图所示:
% J2 b1 h/ p  ?( d& _# s/ k3 Q1 }; Y2 A" J

' V- r, B6 S$ T' g5 [. `" T: \作为对比,左边是原版,右边是修改。: M; n5 A9 V" E! ?0 D: i5 m
接下来是完善VRAM切换带来的问题,因为Mapper 4只能切2KB的bank,所以我们不能通过切bank程序解决问题。
/ J$ F4 i5 L0 u5 E2 Z1 r( U' @& p通过测试知道1,3,5,6,7,8关的精灵VRAM排序如下(07F0-07F3):
% B5 E- \5 o. s+ U6 P01 04 06 07
5 C  o7 X8 R% i4 ~- u+ m6 |第2,4关如下:
/ T( k& l2 W% T  d5 [; X  o+ Z+ ?& {; U01 05 08 09
" r" c7 H" }0 v6 o任务失败时如下:/ V* d* i3 V) A/ O5 J' @4 o1 m# A
32 00 00 1B
9 t; M( V( u4 L3 L4 }其中任务失败时对应的VRAM是07F3的1B,只要让07F2为1A或1B即可:
, n) S# |4 l& M6 m通过调试找到对07F2写入数据#$00时程序如下,于是修改C7E5的值为1A即可:
& I+ H9 m* k% J6 P- \1 M+ ~, C1 s. `# H1 N, X+ u/ E7 V- s
转到ROM地址:
& X, {7 D: E+ O2 U
7 z% D7 p( k& Q# S: r" S修改数据:
, M5 ?' a% y, D0 T0 {! z2 W( _- a8 N# W+ b" e9 C3 |8 h
重新失败后可以看到修复成功:6 L% u! R: q4 V% T# F3 O. t- |

7 J/ [8 G- X/ h接下来是修复正常进行任务时的精灵错乱问题。
  N1 B5 F  ]5 P1 Q首先运行Mapper 23版本,在1,3,5,6,7,8关任意一关的时候,将PPU导出来# S$ b. h" V2 j. B7 V( g) E
+ c; a7 d. {4 |% v

  ~" T+ l8 ?3 m5 o- H: V* R, L1 v2 f

. G1 U5 b" ]$ N8 w然后用Hxd打开修改的Mapper 4的ROM和刚刚保存的PPU的数据文件:
( j; S# V0 Z- Q" x* b/ ~4 I$ c( W3 U' o4 x6 h
在ROM文件头第05字节改为0x20:
7 N1 M: U# b0 B% Q3 y% W8 F5 B
然后转到文件末尾,插入0x20000字节空字节:7 }0 k) t' ]) t1 G8 `8 `3 s

0 y% l! w8 v$ B8 N9 Y
7 q. h8 P- G7 e& M- a8 E2 \( E
; C, n, t9 ]* y/ h% g, q9 r6 u$ v0 A
然后将第1关的PPU数据的前面2KB数据选定:
- k1 r( U6 o! o7 h9 a5 ]% |0 E+ ?  ], K+ i) p
! B) j; ^& @& T! X! }7 o+ x' ~  J
) q0 X! k6 H" c  h/ N6 `8 s: @- S
复制之后以覆盖方式粘贴到ROM的40010,同样把第2关的PPU数据的前面2KB以覆盖方式粘贴到ROM的40810
% ?0 a1 g4 K4 P
! K2 M9 x, M: Q' [  i7 Z8 w然后保存文件:
: K1 M3 }: N% Z
3 ^; T' T1 l$ z# F最后用FCEUX打开文件,添加07F0-07F3的写入断点" K8 ^% Z/ S8 i' O6 Z! f

0 N% d: e( L3 I+ ?9 ?6 m. b地图预览后即将进入第一关画面时程序暂停了,可以知道此时准备将C793的数据写到07F0:5 b9 M9 E# L: \( P) c/ Z$ q

9 D; W4 p* x( Q8 h0 a8 C测试后知道将C793-0796写入到了07F0-07F3:3 t' R1 `$ a( j1 ~
同理,经测试每4个字节一组,一共17组,其中01 04对应普通关卡精灵以及其BOSS关的精灵VRAM的bank号,01 05对应2,4关卡精灵以及其BOSS关的精灵VRAM的bank号,再加上一个通关后跳上飞机那段动画的精灵VRAM的bank号。
, B7 }3 _1 h4 a7 F
- X- }6 q6 H+ s) J" R$ `% W8 A( U) F* A6 h# o- ?2 l- k9 c0 z  ~
然后将文件中标记的01 04修改为 80 04,将01 05 修改为82 04即可:
1 l# S8 J, w4 O8 Z) j- m5 Y$ x+ n+ A0 [. D- h6 i3 A( }5 G
保存之后重新运行后效果如下:
) K: m. g8 y, E7 ^9 B
+ s. n  ^3 I0 Q0 n( i
3 b" b: y* a6 Y. ~1 S9 c1 ?2 d8 P6 M$ z) B+ n
当前使用的是FCEUX模拟器,如果用NEStopia玩的话一开始就死机了,这是因为这个ROM有文件保护吧,它会往$6000里写入数据:
  `; J9 N3 o! C1 q$ o/ X2 V: p' h1 s
F863:A0 03     LDY #$03
" M7 V8 u7 y: l2 h! ?) SF865:98        TYA+ Q, F0 |7 H* m& ~
F866:29 01     AND #$01$ m, s# E% t6 E8 R/ ]% O/ h9 r0 j
F868:8D E9 07  STA $07E9" I2 W3 N: ^% h% A, }! ]0 K2 m3 x6 G
F86B:8D 00 60  STA $6000
0 k6 @3 e' w9 d8 j/ D( WF86E:AD 00 60  LDA $6000
0 @+ @0 d/ [  a! x2 N7 d1 cF871:29 01     AND #$01
+ e/ j# E" V) K+ v) p6 UF873:CD E9 07  CMP $07E9+ n: q/ E# b- M$ h
F876:D0 05     BNE $F87D+ O( F! \7 F: W9 I; p0 S
F878:88        DEY
3 }* p- e: P, b# F9 B( oF879:10 EA     BPL $F865$ F6 p5 V! O. r- {
F87B:30 03     BMI $F880
' R$ `% U/ u3 c, z1 y+ dF87D:4C 00 00  JMP $0000
7 ^; s; e* x' [6 xF880:A5 1A     LDA $001A
8 O1 Z  ]8 n* @. |3 oF882:65 34     ADC $0034  u. k: D$ u% g8 X" J
F884:85 34     STA $0034' p) B* `/ l7 ?& T) ~( r
F886:4C 80 F8  JMP $F880
6 q3 G& W0 {  y/ A3 U3 d" S+ b1 G- @先取Y值=#$03/ R+ V: e2 {: ?
与#$01相与后得到#$01
6 C' [. c$ K5 u) ?$ N% v. }写入到$07E9
( k2 P* x1 k$ h( P写入到$6000
7 J! |8 S& L* H* j) z再读取$6000的数据和#$01相与后和$07E9的数据比较  `  f  l5 d) I# L: J
不同的话跳过5字节5 p& R" M0 p+ ]6 Q
否则Y递减
2 r3 r& i. V1 e0 s) q3 `3 I9 F为正数就跳回0x100-0xEA=16字节* q, i" Z( L, B$ ~6 f
为负数就跳过0x3字节
6 J( e& o. n0 N9 a跳转到$0000(简直没有人性了,跳到这里死机,真想得出来)
  T5 \5 w4 B% M# h, t
9 x* F" E$ N5 {" [正是因为这样,NEStopia运行FC时,6000-7FFF默认是不可写的,必须在ROM文件头第6字节的D1位置1设置ROM有SRAM,对于Mapper 4,还需要向$A001写入#$80来启用SRAM。1 D9 f1 e% E% L; L
由于$6000不可写,因此想$6000写入#$01后$6000还是#$00,之后读取$07E9的#$01与之相比当然不同了,于是直接跳转到死机程序了。* d- G$ Y- O- r, R8 N' h' q; M% A1 p
解决方法是把ROM中的所有的AD 00 60 29 01 CD E9 07 D0 05 88 10 EA 30 03 4C 00 00
' w. h' }/ ^# ]- K+ @9 O" R' N中的D0 05改为D0 00,然后保存即可。
7 c" U$ P4 }& r' H% w* R9 H测试完美运行。
" U  L% v* y& r& N7 J4 D
7 ^0 `& S. |7 _2 m
0 N0 h; [1 ]' \& H7 h教程到此结束。1 y5 V# C* z3 D
/ j- U+ T, ?" q; q
游客,如果您要查看本帖隐藏内容请回复

本帖子中包含更多资源

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

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

签到天数: 71 天

[LV.6]常住居民II

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

签到天数: 49 天

[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:}

签到天数: 3283 天

[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-12-27 06:07 , Processed in 1.090820 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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