|
本帖最后由 yandagui 于 2017-4-16 19:06 编辑
! V/ f, x5 a) _/ Z' s0 G3 u) C. a* _, ~1 w& y q0 p# ]
Mapper23转Mapper4实例教程
# Z( L! x- a* o* c" {5 }+ f0 }
! [. F9 w: D3 aFlameCyclone 2017.4.14* r: A' h" a$ z# t& @
7 J9 y. y C7 f7 C
先看看Mapper23文档:
' R$ n' H4 R* g1 O3 v- t" q5 D1 @1 p7 f+ x4 v$ t& O1 q) s* t
Mapper 23
# ~( l& E5 B" W, L7 `; x& G' L0 L% K8 D8 I: g. p
$8000: 选择8KB的ROM存储体映射到$8000, \5 d* q7 T' J4 B1 B. w: {
7 ]- h8 o c( `" `' W
$9000: 0:垂直镜像
/ m' j# |" t& X/ e) f 1:水平镜像 Y. l' w1 q9 R. R8 W' ^) W
2:$2400镜像
; Y& w$ I$ U4 w% s* l" _/ g) ? 3:$2000镜像2 x9 ~# M4 [. k% ~: y; @
& U8 Z# W+ `# J) F' D7 t( {, i- ?$A000: 选择8KB的ROM存储体映射到$A000 Y. Y Q' o0 k5 i" y
/ X; H) R( G3 e
$B000: 选择1KB的VROM存储体映射到PPU的$0000(低4位)7 J, c! \# l9 K& ^2 z6 Y
$B001: 选择1KB的VROM存储体映射到PPU的$0000(高4位)
# _! t, L! ~+ a3 v$B002: 选择1KB的VROM存储体映射到PPU的$0400(低4位)! {/ E; @4 O6 a( Q; V
$B003: 选择1KB的VROM存储体映射到PPU的$0400(高4位)
, E, D* \. V8 C, s- ~: L! X# |0 M5 D6 |& K( s2 U; f2 N
$C000: 选择1KB的VROM存储体映射到PPU的$0800(低4位)
3 O" W* C# K# u' v$C001: 选择1KB的VROM存储体映射到PPU的$0800(高4位)7 ~6 j+ c* l1 `+ H; B
$C002: 选择1KB的VROM存储体映射到PPU的$0C00(低4位)
' ]/ Y) j, D% A. T4 B$C003: 选择1KB的VROM存储体映射到PPU的$0C00(高4位)" T# H6 N: g# U& n* k
9 f2 `4 i* F0 A3 J
$D000: 选择1KB的VROM存储体映射到PPU的$1000(低4位)
+ d. W, C# T) }# z, A5 k$D001: 选择1KB的VROM存储体映射到PPU的$1000(高4位)# |: u, ?$ f: g' y/ | R, `+ j2 R( [
$D002: 选择1KB的VROM存储体映射到PPU的$1400(低4位)
/ u+ |, d5 l4 y+ D, }: k# Z+ K; n$D003: 选择1KB的VROM存储体映射到PPU的$1400(高4位)7 \( S( U. H! C3 D8 E3 e* z" a
/ E; Z6 c T8 v0 v0 W
$E000: 选择1KB的VROM存储体映射到PPU的$1800(低4位)
% G, a) f7 `! f" U" P0 S$E001: 选择1KB的VROM存储体映射到PPU的$1800(高4位)
- m- B0 Y: s) U( P: s, W$E002: 选择1KB的VROM存储体映射到PPU的$1C00(低4位)+ h# {* g) L3 O; K! ^
$E003: 选择1KB的VROM存储体映射到PPU的$1C00(高4位)
8 `1 ?5 ~- Y5 d4 Q6 y B/ A) f! h! a
再看看Mapper 4文档:
& S2 y5 r; I/ a/ G, G' l7 P' o: s) s! ^7 d
Mapper 4
) s( k C* Y t& p# D" _) @7 Q _
[1 p8 J( I8 {' t2 Q* W7 w) ]$8000: 模式号
+ h7 I! }* r3 N U8 I, n 位D0-D2:$ {- B: Y) T9 I' S+ I$ o* d
0:选择2KB的VROM存储体映射到PPU的$00003 ?# ?- E4 @9 b9 h. Y" a: f5 U4 s6 Z
1:选择2KB的VROM存储体映射到PPU的$0800( Y: l/ S$ x) C$ G# j) a$ o; S
2:选择1KB的VROM存储体映射到PPU的$1000
6 \9 d" P0 h1 I) d6 Q0 U# i 3:选择1KB的VROM存储体映射到PPU的$14002 k/ _' E, Y% [- i
4:选择1KB的VROM存储体映射到PPU的$1800; G7 u/ I- u$ o
5:选择1KB的VROM存储体映射到PPU的$1C00
* V8 }' s6 b# j% h! x- C. C 6:选择8KB的ROM存储体映射到$8000
/ A* L% W6 z+ P" q7 f+ e' T- E 7:选择8KB的ROM存储体映射到$A000
( d6 Z: r% N, o% ]- w7 |4 d' m 位D6:
% C- w. N' F1 {" a2 G 0:允许擦写$8000和$A0004 N! U) X# ]1 X8 I
1:允许擦写$A000和$C000) m; R3 _4 U/ m
位D7:
6 K2 }( O) f( b% l9 Q% g2 m3 F 0:模式号D0-D2使用普通地址
7 D& e9 V3 n) g- O0 H6 G& Y) ^( N 1:模式号D0-D2地址异或$1000
- m4 r7 o& W; v# b8 I
: r0 K+ S1 i/ `+ j$8001: 模式页面号& W* e/ x' v# X% i
写入一个数(00-07),切换存储体到对应地址9 q, S0 e* b4 i4 W$ @' Z: P* b5 b
" L" F5 z) B9 p7 j# H9 k( o- }2 G$A000: 镜像选择 J* S" ?0 r! m! E$ g
0:垂直镜像
7 {$ n. [0 }0 A4 c- _9 q2 z 1:水平镜像
) U) _$ n8 E+ a& v) u( O! J5 m' W1 F5 w
$A001: SaveRAM 切换% Y2 i" j0 B' e) O; F' J
0:禁用$6000-$7FFF. J& E, i, ~4 A4 O9 H w
1:启用$6000-$7FFF$ s1 O Q) f S4 l
* p& D7 v! G7 T+ v7 g$C000: IRQ计数器
! t; y9 e: U0 S! u9 r; n9 X! u IRQ计数器的值存储在此处7 z" z- a4 S, Y I5 p
: V- s$ Y$ i' X, l& D* B& Q$C001: IRQ暂存器
7 v$ Z8 o Z' `& x2 D IRQ暂存器的值存储在此处
3 G5 k5 n* ^1 y5 [! i+ d. |
k' K. k( f4 [. g$E000: IRQ控制计数器0
5 V% q+ L' t$ @! p 向这里写入任何数来关闭IRQ,并从暂存器中拷贝数据开始计数,进入IRQ
4 c6 [+ D; D5 a7 b
7 y9 C" [: d: A$E001: IRQ控制计数器18 ?- l# x& B0 Q$ A% c0 s: |
向这里写入任何数,允许IRQ(退出IRQ,允许下一个IRQ进来)
, L0 O2 a- O6 P3 h! Y2 d, \5 f5 M |. A* T
5 U% B: v4 k$ {转换思路:4 D; E- `: \/ d& m; B2 g, n: J6 M
将Mapper 23 的切bank 方式和切VRAM的方式修改成Mapper 4 的方式。- Z: G' l+ R( s3 a6 m
9 q. [0 X" N) c1 y' q9 A o% w" |6 Z修改实例:
! X) R& \4 y% w+ c" u8 MContra (J) 256KB Mapper 23
) ], c. F" [" l6 b- K0 B3 e工具:' m ~! f/ o4 s
1.FCEUX 2。2。3) v- s" l8 J8 Y& p
2.HXD5 x( \( s" N( p7 }0 S
先来看看这ROM的切bank方式:/ `! [& ]! l( {& p2 Y
F989:AD 00 80 LDA $8000
- T, j% e1 ^3 R/ \ X% m- wF98C:8D EC 07 STA $07EC% v& Q$ j5 D- @' ^
F98F:8C 00 80 STY $8000
, O7 T% O5 q& D# J* t" ~F992:C8 INY
7 _2 H1 |. W& K, yF993:8C 00 A0 STY $A000
% u4 a O; P0 {( N X9 o+ `F996:60 RTS% j; I+ F* h1 T0 W
) H, {! t2 P$ S) e: I: {8 h
再看看它的切VRAM方式:
/ ?: U7 I# m1 Z' j1 V+ ?/ O3 IFACE:AD F0 07 LDA $07F0/ J, S' J( p1 A8 Y) l
FAD1:8D 00 B0 STA $B000
) s, r$ v; T. J* G3 sFAD4:4A LSR( f4 I, S* M/ R) V* @8 @( _
FAD5:4A LSR
: f4 k, m4 |3 |7 }1 g6 rFAD6:4A LSR
; ~, o, t7 I" Z3 c& B7 Z X6 E8 z3 gFAD7:4A LSR
6 T7 [2 J. V+ I( [6 s9 zFAD8:8D 01 B0 STA $B001/ W, w! V9 i! _% X. W
FADB:AD F1 07 LDA $07F1
M4 U* z d! u. _+ i; W7 r# b5 ^FADE:8D 02 B0 STA $B002* r, V& {) y2 M( [ \/ D1 I- [6 r6 J
FAE1:4A LSR
7 ]5 H2 K" s( k, h6 a* }FAE2:4A LSR
: t- L' b- L0 _; T# [# GFAE3:4A LSR$ I: ]6 Z5 w! F. Y! N8 L
FAE4:4A LSR
2 [' B- { ?" n* d, B% sFAE5:8D 03 B0 STA $B003
, I+ Y5 @* w6 \" `FAE8:AD F2 07 LDA $07F2
0 Z$ Q V+ u7 m" [7 ^# pFAEB:8D 00 C0 STA $C000
3 {3 W& E( ^. X" zFAEE:4A LSR! |$ o& j1 j3 C/ H
FAEF:4A LSR
) I* E; U! O2 J. \7 ^* cFAF0:4A LSR q/ a. [$ g# r/ g
FAF1:4A LSR
. o$ @9 \1 V; YFAF2:8D 01 C0 STA $C001) p9 l0 X6 j8 J
FAF5:AD F3 07 LDA $07F32 t) u# g5 b+ J) ]. E" F8 j5 x4 g2 \
FAF8:8D 02 C0 STA $C002: k( O8 f+ g0 X7 |& N" }3 N7 n
FAFB:4A LSR
5 @' J& Q: E+ q6 i6 H8 x( dFAFC:4A LSR
# R- D( l9 x B% x1 C/ QFAFD:4A LSR
1 J* V% Q1 ]! A3 R, m0 g FFAFE:4A LSR# F2 p, y9 i/ s, ~
FAFF:8D 03 C0 STA $C003) W, s) J5 U @
FB02:AD F4 07 LDA $07F43 {0 a) r. R" g+ m% O; |
FB05:8D 00 D0 STA $D000* ~- R, [6 ^ ~- F- X$ W! A6 i
FB08:4A LSR; q; N- f# M! }) d; j5 x8 d2 d
FB09:4A LSR7 G; ?6 {! c/ J. c& G8 s& b& @0 T
FB0A:4A LSR
- t1 J* x0 Z* T' S9 ]) o6 f$ GFB0B:4A LSR+ R# C0 A4 c, o9 ]0 t4 ]& I
FB0C:8D 01 D0 STA $D001
; U( E2 V4 t: a8 O* EFB0F:AD F5 07 LDA $07F5
/ E" h7 r2 W2 S+ j. e( }FB12:8D 02 D0 STA $D002
0 F, @. g& K8 g2 ~2 wFB15:4A LSR; q4 j$ h3 T( I+ a& m; A% M
FB16:4A LSR
0 E% S% Y7 O J3 o1 [ yFB17:4A LSR: o4 n7 f! l4 ] o5 a; g' ~! L" P
FB18:4A LSR7 j' d: \% a7 S8 U
FB19:8D 03 D0 STA $D003
- Y% Y S$ Q/ j/ [0 p2 PFB1C:AD F6 07 LDA $07F6* E- b) {% {+ F3 B; F( f8 ?
FB1F:8D 00 E0 STA $E000' P. U, e/ j+ Y4 [* R
FB22:4A LSR2 C, L3 [( R: c+ R0 }
FB23:4A LSR
5 Y& D. A) Z! s7 q" K4 ~FB24:4A LSR
9 d0 _8 k% N+ rFB25:4A LSR
E" u7 ]! j. f; b- d! Y- u, [5 CFB26:8D 01 E0 STA $E001 N6 K g/ h1 A2 x6 [& e
FB29:AD F7 07 LDA $07F7" X, l, R& U p$ H' W
FB2C:8D 02 E0 STA $E002
5 a0 @$ F7 |- m$ X& ?; MFB2F:4A LSR
`) o0 ?# }" f* ` wFB30:4A LSR
}' Z* l0 S' P6 K+ s/ cFB31:4A LSR
8 O8 h b" x3 w: J- [ DFB32:4A LSR
8 V- Y8 e1 M V* c9 wFB33:8D 03 E0 STA $E003) ?' ~3 S: f; I" _
FB36:A9 00 LDA #$00# e9 O J1 |5 |4 ]' s- C& }( h8 v; a
FB38:8D 00 90 STA $9000
& [/ M6 ^/ w' h3 DFB3B:60 RTS
! ?" u( M4 R( h) f& d
2 x- X0 ~3 ^( j1 r' {接下来修改切bank方式:
8 \) H8 S1 ]) _3 b% tFB2B:48 PHA. D- z4 @( W2 V! V
FB2C:A9 06 LDA #$06
: c; e$ }/ t4 f) eFB2E:8D 00 80 STA $8000# o" P" ~% k, p. A, u( T
FB31:68 PLA
, S0 I, Y6 @6 c( oFB32:8C 01 80 STY $8001- D( o- c8 T e: U2 q5 p+ b! ~
FB35:60 RTS2 V% `7 S8 K; O+ A7 |' K; H9 S
* }! n" Z3 D9 |- v6 |6 ~! bFB36:48 PHA6 L, r7 S4 o% f/ @8 n$ _5 ~
FB37:A9 07 LDA #$071 ?$ u2 I* ~9 l3 `2 d
FB39:8D 00 80 STA $8000 = #$14
) g2 z' z) h6 R1 ?FB3C:68 PLA2 D! Z1 w8 |; G f3 x
FB3D:8C 01 80 STY $8001 = #$1D
: g; v+ F# ~) SFB40:60 RTS
) f/ l" ]! m3 b* K$ N/ ?) j6 T& M( `% k: U+ G
还要把原ROM的对$8000和$A000进行写入操作的程序修改一下:/ P8 |7 l2 c3 c2 O! @. Z& c* W4 g
F989:AD 00 80 LDA $8000
+ C" P- L( `# f: `F98C:8D EC 07 STA $07EC8 j$ c) [! E1 |, y2 Q. M6 Y
F98F:20 2B FB JSR $FB2B5 l- N! X% u, i: |) }
F992:C8 INY
k8 \- ~' T, E6 ^' nF993:20 36 FB JSR FB36
2 `5 B6 p, @% xF996:60 RTS
+ n+ h L* {9 k* g% A3 _. M" Q$ M+ K% ~; R2 q8 N0 M" T, m; k
再修改切VRAM程序:
; O+ u0 K9 e" DFACE:A9 00 LDA #$00/ b5 e, h# B4 @/ ?- N6 Z( z
FAD0:8D 00 80 STA $8000
4 Q& y' ^$ t1 E3 \- c. E* N1 fFAD3:AD F0 07 LDA $07F0
# @% t. L* p, h! s8 iFAD6:C9 01 CMP #$01
: d( e1 N- W j5 TFAD8:D0 11 BNE $FAEB) S f3 Q& U5 ~7 n3 m$ ~8 S
FADA:AD F1 07 LDA $07F1) L7 D; G4 f* R- u
FADD:C9 04 CMP #$04
( c, b* ^0 x6 [& e: h+ w5 h% @FADF:D0 04 BNE $FAE5 }9 H# @) `7 q, |: ^- ?- A
FAE1:A9 80 LDA #$80& S. k3 B( g6 r! }9 Y) u% B- J
FAE3:D0 06 BNE $FAEB% p5 G+ S9 p1 S0 o+ i
FAE5:C9 05 CMP #$05
& O0 a+ @0 X) u! i7 q# {FAE7:D0 02 BNE $FAEB# j4 d D0 w* G1 @- h6 |
FAE9:A9 82 LDA #$82
* b9 W1 q9 Q; ]+ x& K! _' oFAEB:8D 01 80 STA $8001
( l& R6 G+ r( t; ~ a% l7 EFAEE:A9 01 LDA #$018 r2 N% S: b5 d- f" Q- t% ]* M
FAF0:8D 00 80 STA $8000
# q2 ~+ L8 o$ tFAF3:AD F2 07 LDA $07F2 L3 p9 [9 e2 t8 h& |
FAF6:8D 01 80 STA $80017 g* G/ @& p/ S# |3 O7 Q8 x
FAF9:A9 02 LDA #$02
" j1 S1 v# T/ j9 Z% C4 X& AFAFB:8D 00 80 STA $8000/ W3 S! @7 L6 G- n
FAFE:AD F4 07 LDA $07F47 T* O, w1 e9 b' C
FB01:8D 01 80 STA $80014 z% q8 O, |6 G" q# p
FB04:A9 03 LDA #$036 h8 m) _! v4 u2 }+ Z2 p0 H
FB06:8D 00 80 STA $8000
* G2 }: c: ^: x! v7 f% wFB09:AD F5 07 LDA $07F51 R8 w) k& N8 c! x# ~$ o' o
FB0C:8D 01 80 STA $8001) ?& y& J0 m5 @" W) Q, g' B
FB0F:A9 04 LDA #$04
7 F$ b- O7 l2 ~0 Z, j5 cFB11:8D 00 80 STA $8000' B: Y$ i9 @/ Y5 W# w$ Z9 o' Q
FB14:AD F6 07 LDA $07F6' U; }6 h! q0 t8 T
FB17:8D 01 80 STA $80014 j/ G8 I' |: U( \
FB1A:A9 05 LDA #$05
4 A- s7 l! |+ m* C% b& f) MFB1C:8D 00 80 STA $8000
8 W1 J @4 `1 H+ ?FB1F:AD F7 07 LDA $07F7 J1 y8 L- G5 p& [6 i) M
FB22:8D 01 80 STA $8001
( S1 E9 z/ X N/ m$ f$ B3 YFB25:A9 00 LDA #$00
4 \# O$ f5 k6 g. KFB27:8D 00 A0 STA $A000 Y# S) B! t6 }5 J/ b
FB2A:60 RTS* n2 D' V& y* u6 j; m" P3 k# C
# @ u; J4 G, x! n+ [( p然后保存文件。; o+ N' c+ p. A
使用HXD修改文件头:
* f' m7 E+ x( w) @8 f3 h将Mapper 239 U% [- B* Z: g; g8 S G7 X
06字节的高4位是Mapper号的低4位2 P* v8 t) c X9 I7 O
07字节的高4位是Mapper号的高4位
1 M- j7 i" U l7 ?7 m% s组合起来就是0x17=1*16+7=23
: F6 a# g: V( H! E( j9 |0 o/ z! G- G- Z* k9 L* ^
修改成 Mapper 4
1 ]6 [% d+ L3 i* W4 ?, b
5 v1 V. `, L2 F2 _& l$ U# o* k8 B5 @, r8 T8 l) K( F" o
Z, F: q4 Z! \+ q8 n2 J1 s
再次打开文件:$ Q6 {8 u5 K: }- o
9 _& Y& K2 u: x) W& n可以正常运行
$ A7 o2 a( r, Q6 L2 u通过全面测试,发现出现精灵错乱:
Q2 P+ U+ L: P& E v- R第1关:
9 G' [8 [9 G4 w, Q
% i7 h7 h; J& Z
f: P- S- `8 B# |% i第2关:
* _" F; [9 V+ ]! V, c
$ {- J7 q% U5 L6 z4 O6 ]" Q/ z2 f任务失败后:( H C) r& C1 x1 L, {
A: n" W8 C0 m9 \
通关后上飞机画面:
# t* x- ^; b: A2 R
& E* r& B& l$ J" ~* G这是为何呢?
8 X9 K1 ]( A+ I. y6 j2 G% ~这是因为Mapper 23 中精灵VRAM切bank是一次切1KB
a$ B# L) T- ]但是在Mapper 4中精灵VRAM切换却是一次切2KB,而且忽略bank号的D0位. j0 |- v. B0 g J' k
比方bank 0和bank 1是同一个bank,同理bank 2和bank 3是同一个bank
- S' k2 b. P7 w8 { {也就是说+ a& U& t' b: l' }
Mapper 23中的VRAM的8 p; w6 V% m) ?6 C/ j
bank 0,bank 1,bank 2,bank 31 W2 w! }- y1 w; [2 E- I; |
在Mapper 4中对应的是2 c& D" k7 E7 g/ H
Bank 0,bank 0,bank 2, bank2% ~8 U+ z# t8 o7 ?
然后查找原来的ROM的切VRAM的程序:2 @7 Z$ z: M& f/ s
知道是从07F0-07F3切到精灵VRAM的:# c; S& {2 e' L
如图所示:- b! u- v; G) {# X- S/ }* ?; b
& E' H# V6 @# w5 g ]
4 Q% v" H3 r. r作为对比,左边是原版,右边是修改。
5 l z0 J1 `" l接下来是完善VRAM切换带来的问题,因为Mapper 4只能切2KB的bank,所以我们不能通过切bank程序解决问题。$ f0 X* `% O% m' }( R
通过测试知道1,3,5,6,7,8关的精灵VRAM排序如下(07F0-07F3):1 F8 L) S( K% s4 v2 Y
01 04 06 07. S1 Q# G. B+ s% i# u' C5 M
第2,4关如下:
, x2 D& m# p( |& w( S01 05 08 092 \* y5 P" j& j
任务失败时如下:
& [0 I4 F P6 m/ B& Z _/ p32 00 00 1B
* c7 }& i+ b6 Q# A& \其中任务失败时对应的VRAM是07F3的1B,只要让07F2为1A或1B即可:
$ l7 x# n1 p9 c8 Q+ f; F s# ~通过调试找到对07F2写入数据#$00时程序如下,于是修改C7E5的值为1A即可:
' t5 J8 c7 X' k
4 l' B" d" P/ W: o% {, P& Y- Z转到ROM地址:( b U, o- ?5 N/ F% E
1 C X( J. y* g5 S9 c修改数据:6 ^' j% i% A* R
1 e( S9 Z2 q0 n( `
重新失败后可以看到修复成功:
U8 {# C V, }) l
/ [2 w7 P; Z' @1 `接下来是修复正常进行任务时的精灵错乱问题。) d" a. {+ J, E, G& W9 L" _
首先运行Mapper 23版本,在1,3,5,6,7,8关任意一关的时候,将PPU导出来
$ B6 D% k/ Y+ E0 Z9 g
1 i* x) t3 r! L3 }) O
0 \9 [& e: J: c# d+ V- x0 S/ j5 |: J0 B
2 M! d( [' H7 [, f3 O8 P8 F5 Z然后用Hxd打开修改的Mapper 4的ROM和刚刚保存的PPU的数据文件:% \& L. `( n6 H7 L) z8 N/ _
9 ^: P! M$ w# `. S* `! s
在ROM文件头第05字节改为0x20:! y- [1 B9 x% e3 i! ]( P3 t
, b. W* H6 g8 J
然后转到文件末尾,插入0x20000字节空字节:' l$ k, n& [" ]# W! Y
Q! }0 {4 A( D3 F3 f2 o& Z0 S) V9 B1 P, q/ @0 e% R. {/ x
1 H; }% k5 {# ~7 A% i; A
) P" t L% H' E& l M; j( V然后将第1关的PPU数据的前面2KB数据选定:' b7 n a0 o7 \! h* s, A/ c
# [& W. H6 F; ?7 K( o( E
" C7 f" ~. c" x
& ~3 S" D* L, P( G0 ^: o$ S( ^' Y
复制之后以覆盖方式粘贴到ROM的40010,同样把第2关的PPU数据的前面2KB以覆盖方式粘贴到ROM的408107 m- p$ ]/ z! g* W/ U& ]" F j
z' b5 D2 G' s然后保存文件:
G, D+ t5 u3 D ]$ ]! Z2 s. w; s! U/ K. {1 P; ^! B% z) v
最后用FCEUX打开文件,添加07F0-07F3的写入断点2 E7 D) T: ?+ R7 `
7 n, `, R+ d- d: Y- k$ m地图预览后即将进入第一关画面时程序暂停了,可以知道此时准备将C793的数据写到07F0:/ o$ L' l/ H1 P6 t' w6 \/ I$ C
% `& ^# d* b9 k; o; f4 ?
测试后知道将C793-0796写入到了07F0-07F3:
! D! p- y- c# ~3 B同理,经测试每4个字节一组,一共17组,其中01 04对应普通关卡精灵以及其BOSS关的精灵VRAM的bank号,01 05对应2,4关卡精灵以及其BOSS关的精灵VRAM的bank号,再加上一个通关后跳上飞机那段动画的精灵VRAM的bank号。
4 a+ t( P. b& S# Y1 N! |
& W- M; a, A: R" v' \6 e
' L' ]+ C; `( l- n! ]) f1 ^/ K然后将文件中标记的01 04修改为 80 04,将01 05 修改为82 04即可:: t2 N/ ]% ^, y* \9 y! i+ L) ]
! l( t7 h7 ~+ t& d W# T$ G
保存之后重新运行后效果如下:
( f% Y( N4 R) l0 ]7 d$ Q+ z8 u' K" Y0 ~8 f0 G" ^
0 q' ]" @" e# c7 o( [
7 q9 Q4 K' R# F) N2 F- ?" E
当前使用的是FCEUX模拟器,如果用NEStopia玩的话一开始就死机了,这是因为这个ROM有文件保护吧,它会往$6000里写入数据:" g; Z' K/ e* m/ r( Y% U/ @
7 G3 h/ G. U' w, ]/ y0 zF863:A0 03 LDY #$03* g; U: M- B) A) b% P0 V" _/ }
F865:98 TYA! L" g# ~3 o N/ N/ x
F866:29 01 AND #$01
+ I, m: E. |# ? ?F868:8D E9 07 STA $07E9
$ u4 M8 O" g5 f: [- ], i% S$ h. \F86B:8D 00 60 STA $6000; A' E+ [1 R: T; n4 l5 i
F86E:AD 00 60 LDA $6000; \8 U& H8 @7 r* R
F871:29 01 AND #$01
4 Q4 d% E i9 r R/ n. j0 sF873:CD E9 07 CMP $07E9( ~- U. P, R9 |# J) P
F876:D0 05 BNE $F87D4 X5 k: v, D! U
F878:88 DEY* H8 V6 {# J5 F
F879:10 EA BPL $F865/ O: A, c! ?' ~9 f, o6 l
F87B:30 03 BMI $F880
# X8 `3 D/ e% P: w8 P" Q; d& cF87D:4C 00 00 JMP $0000" m+ _7 n) Z# v% t- n
F880:A5 1A LDA $001A- Y( V* e; j, k- h: b4 t
F882:65 34 ADC $00344 i. w* \2 [: e. X9 o
F884:85 34 STA $0034$ Y8 c/ {8 S9 r& B4 Z' R
F886:4C 80 F8 JMP $F8804 M4 T5 }. y% B% S& q
先取Y值=#$03: f' L7 r1 ?* I
与#$01相与后得到#$01
7 k0 A4 k+ }: i6 j- f; N( L% k写入到$07E9( v; i; k8 S: V/ O; e
写入到$6000! |* J4 {, Y8 E4 c0 w1 r3 o
再读取$6000的数据和#$01相与后和$07E9的数据比较
5 ?8 W) }/ z4 K, R; L不同的话跳过5字节
, ^, R: b# o7 q' W否则Y递减
: Z1 N; A0 G, I7 }! ?% F8 ?为正数就跳回0x100-0xEA=16字节4 |* M8 ~. z' u b* I
为负数就跳过0x3字节
: |* T/ Q2 s" b; z& n8 g跳转到$0000(简直没有人性了,跳到这里死机,真想得出来)" j+ @+ h5 e- K+ r# r
, L9 a1 f8 d: m2 d正是因为这样,NEStopia运行FC时,6000-7FFF默认是不可写的,必须在ROM文件头第6字节的D1位置1设置ROM有SRAM,对于Mapper 4,还需要向$A001写入#$80来启用SRAM。# O, o0 u, V# r8 s& H6 G
由于$6000不可写,因此想$6000写入#$01后$6000还是#$00,之后读取$07E9的#$01与之相比当然不同了,于是直接跳转到死机程序了。
) o# N1 E5 S5 j解决方法是把ROM中的所有的AD 00 60 29 01 CD E9 07 D0 05 88 10 EA 30 03 4C 00 00
3 p' v4 q1 Z/ {) `. _中的D0 05改为D0 00,然后保存即可。
; v$ y. l& ~" a' X( \测试完美运行。 J1 y l8 C H" ]- w0 {# u
9 c1 W) F5 D6 r6 I3 I% a8 [; u# {
5 l9 h5 e: M3 {( W+ P5 o5 S8 H教程到此结束。
8 ~; z- f7 _" k3 @6 }" u4 b) z+ N% c, U! T
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|