|
本帖最后由 yandagui 于 2017-4-16 19:06 编辑
2 l4 B P0 Z4 L& G l+ K. E5 c2 h {& i3 V8 e# D7 ~/ N$ v
Mapper23转Mapper4实例教程4 ~& T* @: z+ S7 }8 M: I0 s# Q
/ e" w" G# `2 L0 k) {3 W- qFlameCyclone 2017.4.14
& u% \4 O4 W6 k2 G- ]. M3 u. P+ `& x9 H7 U T) O
先看看Mapper23文档:% Z. S: v9 C' B3 [7 d" ], d. t
" P) u1 `+ l: ]* T
Mapper 23) q1 {9 p( ?: Z" y! s& C
% w( j/ l4 X# G
$8000: 选择8KB的ROM存储体映射到$8000
6 X, V% q3 V2 w0 w0 H2 B
& _4 V# h" ]; J% R& ^$9000: 0:垂直镜像' a, f1 ]$ [% W( B9 l
1:水平镜像
( a$ H: C4 z# ?" s1 R& v3 j 2:$2400镜像) b% l% @' _, C: A
3:$2000镜像
- w0 B, U6 X8 L. z; w( @
8 N7 `+ D8 ^" g5 y$ E+ |* N$A000: 选择8KB的ROM存储体映射到$A000
/ V3 J U1 B- L5 w2 p+ v" R ?4 k. O* N
$B000: 选择1KB的VROM存储体映射到PPU的$0000(低4位)$ ]% P6 H6 {8 y7 L
$B001: 选择1KB的VROM存储体映射到PPU的$0000(高4位)% b- L! V1 \) e- c, a D
$B002: 选择1KB的VROM存储体映射到PPU的$0400(低4位)' e* {1 ~. y1 n7 Q* V' S# g& b
$B003: 选择1KB的VROM存储体映射到PPU的$0400(高4位)
: O) ]/ y* T) ?7 a1 V! |7 ~" D+ U3 i! w& q, ~! K: g5 A
$C000: 选择1KB的VROM存储体映射到PPU的$0800(低4位)% F( H) L; Y6 t3 w |
$C001: 选择1KB的VROM存储体映射到PPU的$0800(高4位)
9 {& E$ B7 q {! |) K1 Y4 e% K# |$C002: 选择1KB的VROM存储体映射到PPU的$0C00(低4位)
4 D; S$ p9 g; Y" D$ h/ e) s4 f) Y$C003: 选择1KB的VROM存储体映射到PPU的$0C00(高4位)
+ _/ N9 V' A% X, ?3 o
0 E! e/ r" J- i2 d% `$D000: 选择1KB的VROM存储体映射到PPU的$1000(低4位)
; K* u& `* | ] G2 Q$D001: 选择1KB的VROM存储体映射到PPU的$1000(高4位)/ }8 K3 i# a$ \1 x
$D002: 选择1KB的VROM存储体映射到PPU的$1400(低4位)
0 p* C7 X ~8 l2 n6 u5 E) q$D003: 选择1KB的VROM存储体映射到PPU的$1400(高4位)9 ~' C, V! ^& z' @8 N2 W
1 O I- ]4 ]( v, c( y
$E000: 选择1KB的VROM存储体映射到PPU的$1800(低4位). O ^% O# G4 A/ M! k0 L
$E001: 选择1KB的VROM存储体映射到PPU的$1800(高4位)
: v1 ^# u! x. N0 E4 ~+ F1 n; q$E002: 选择1KB的VROM存储体映射到PPU的$1C00(低4位)0 \$ Y9 e$ @+ Q# ]. q) c3 [6 `
$E003: 选择1KB的VROM存储体映射到PPU的$1C00(高4位)
\7 U% L G0 [& L8 a6 v- I0 g: Y0 e" C( X4 g2 i
再看看Mapper 4文档:
3 j5 o, ^: f) j1 \( P9 h
8 P& |" [1 j$ tMapper 4
9 `" j. ?" n" G5 d2 y3 l5 u4 C) O# N) X& q/ c9 u% C
$8000: 模式号! e: n z. E" U6 L& h( z
位D0-D2:3 A6 D+ b5 v2 T2 M3 L0 T
0:选择2KB的VROM存储体映射到PPU的$0000
2 G9 [/ ~1 i0 B) L 1:选择2KB的VROM存储体映射到PPU的$0800
0 P6 N/ f, k. E+ } Q 2:选择1KB的VROM存储体映射到PPU的$10009 C6 H2 S1 f( P$ C
3:选择1KB的VROM存储体映射到PPU的$1400
/ O+ Q, g$ U" F7 R 4:选择1KB的VROM存储体映射到PPU的$1800+ z, a( ` C2 }# I4 _6 x0 U! _
5:选择1KB的VROM存储体映射到PPU的$1C00
7 J4 K; `8 p: C8 U2 i8 K4 c 6:选择8KB的ROM存储体映射到$8000
! W9 M! L$ g, d( B2 c: Z% u 7:选择8KB的ROM存储体映射到$A000
" |% }' I' S* R, p/ u# H 位D6:
6 h" \; E. g J. q* [8 U" V 0:允许擦写$8000和$A000! I% O3 v+ d; `0 C
1:允许擦写$A000和$C000. n. C& P' [2 ?! G8 n" p8 W
位D7:
/ V( R& N( ], x; z' A- k& [ 0:模式号D0-D2使用普通地址
7 _7 B/ `& K, v( F" j 1:模式号D0-D2地址异或$1000
5 N0 E9 P. T6 X. u% P* p
: Y4 }4 T: n" u$8001: 模式页面号
) k& u# S r7 }8 E" h( P9 N9 G' {5 i% C' a 写入一个数(00-07),切换存储体到对应地址
& Q# b) G0 |4 }8 R$ z' v2 ^7 M: L) ~! G
$A000: 镜像选择2 A: T% K8 l& E4 K$ c: x0 R
0:垂直镜像
4 W T, E" O( F 1:水平镜像" x- X; K. i, E5 p, t. R% D
A# _6 X5 c1 z1 h( K; Q0 w
$A001: SaveRAM 切换9 T6 ~$ P1 H L3 W9 A- G2 ?; |
0:禁用$6000-$7FFF
/ F9 s+ \4 |0 R( G3 u/ p, Q 1:启用$6000-$7FFF# x# u6 ]' o* |3 U9 f
6 e: G; e8 ~4 n8 l. }1 L+ T- c; R$C000: IRQ计数器
) I6 N& Z$ w5 q0 j- a- b; X% V5 v IRQ计数器的值存储在此处
1 T: W* Z+ F: L4 q n+ [- |. f& q. z( y5 B2 l+ N* {8 U. ~
$C001: IRQ暂存器
- K7 U0 n) a1 b' A( {& ]1 t, ~2 j IRQ暂存器的值存储在此处5 U8 u( w7 }5 w; K% G5 i+ D' E5 t
2 W7 j$ h4 Y3 W' {9 g' i' `
$E000: IRQ控制计数器0
- I7 T2 Z4 O/ O5 v" \, M 向这里写入任何数来关闭IRQ,并从暂存器中拷贝数据开始计数,进入IRQ- C# N8 ?' D6 G$ M/ `( \
5 X; s$ F/ O0 e1 a" H) R, f' N$E001: IRQ控制计数器13 I- ?1 F3 ^9 H. o o C J
向这里写入任何数,允许IRQ(退出IRQ,允许下一个IRQ进来)$ c. @3 c# ~, m$ q# ?0 D
+ Z0 V+ y- M7 V
c1 P5 [" s( f6 m7 D) Z: l# W' f. v- Q转换思路:# C8 x0 P8 @1 v0 v4 D) V
将Mapper 23 的切bank 方式和切VRAM的方式修改成Mapper 4 的方式。% { o) S1 q* a
+ z. F1 G, u, L/ [) v3 X+ M+ w$ q修改实例:
0 A' X1 j- s9 ]) M/ c. t1 {Contra (J) 256KB Mapper 239 n1 D& [3 B0 ?2 E* _' s3 F
工具:
1 P! H, K! \% C, v2 t% ?1.FCEUX 2。2。3$ _5 O. p( K% T9 \# P
2.HXD/ \/ e- L$ R" w
先来看看这ROM的切bank方式:
1 M1 e. {9 F v) p" v. J- Y3 [F989:AD 00 80 LDA $8000 6 r* S( ~* r1 r; Y# z. J
F98C:8D EC 07 STA $07EC
! f7 c3 a: ^0 V- m0 WF98F:8C 00 80 STY $8000! A+ O9 Z+ \2 X+ Q* }. c
F992:C8 INY2 M% F- B; \% j: \9 Q n
F993:8C 00 A0 STY $A000
' K3 l/ L5 m, _8 rF996:60 RTS
7 }+ G U* Q2 L; H1 A6 k1 F+ |$ W
; U8 ~. B4 y' U8 d* \! s# W再看看它的切VRAM方式:6 y3 L- [0 l- _% E
FACE:AD F0 07 LDA $07F0# W8 W, V% c) q: M9 S
FAD1:8D 00 B0 STA $B000
: s6 J: {3 B# Y0 nFAD4:4A LSR8 j2 o$ A) Y, H
FAD5:4A LSR
8 a; f0 Z) c/ d% ?: U9 L1 SFAD6:4A LSR8 i4 Q" X7 j5 O
FAD7:4A LSR
* D8 X9 \' ]/ r9 b0 o% r; y' [2 |FAD8:8D 01 B0 STA $B0011 |1 E0 E( K' h! P2 d& a: @
FADB:AD F1 07 LDA $07F1
E2 f& ]" `$ ~FADE:8D 02 B0 STA $B002
; U# a$ |; D8 fFAE1:4A LSR d9 P& y) n5 S; z# p
FAE2:4A LSR1 _1 N; p! E2 ?6 H6 a% o) Z) u
FAE3:4A LSR
, x8 m: B" I: N* \& F' eFAE4:4A LSR
6 U+ \8 i5 i; P( U" hFAE5:8D 03 B0 STA $B0030 N$ ]+ b8 G$ e" z
FAE8:AD F2 07 LDA $07F2
( D, J/ \+ b6 @+ I/ p- G. l/ B7 S" yFAEB:8D 00 C0 STA $C000$ g4 R ^2 r! ?) u# p2 k
FAEE:4A LSR
) D. a* j; b+ Q; D- i# @FAEF:4A LSR' E8 J/ H$ X& z
FAF0:4A LSR
/ z/ ^! l2 R* j. x# N" R5 OFAF1:4A LSR# V. U% \) S$ {6 G( P" y
FAF2:8D 01 C0 STA $C001" O- E5 L7 b5 S! C
FAF5:AD F3 07 LDA $07F3& _ m7 f" \& Q/ w8 s: j
FAF8:8D 02 C0 STA $C002
5 u' X9 F6 H2 @2 d' H6 [FAFB:4A LSR, B, q% H. s' Q& L! F2 V
FAFC:4A LSR. t2 _$ j$ ]# J$ }
FAFD:4A LSR& g* J, x$ c/ m- u
FAFE:4A LSR+ N$ a5 u* b0 `' f! i0 `
FAFF:8D 03 C0 STA $C003
b" g* ~- m% w' N% ] ]9 J* iFB02:AD F4 07 LDA $07F4& E7 f! K% Y( R' {2 b. E& ]! r% f
FB05:8D 00 D0 STA $D000
' w6 M* W- c4 i; {% B: e8 |: {FB08:4A LSR+ s7 E; o9 a$ d; e/ Z: A
FB09:4A LSR' Y. R& y# n" ]% g2 o& {6 B
FB0A:4A LSR
; i9 n" d' k) p3 M: ?' ~FB0B:4A LSR: t4 D- q( g! g9 X) x4 W
FB0C:8D 01 D0 STA $D0017 L: G- f6 J$ c0 Q+ g
FB0F:AD F5 07 LDA $07F58 j& _+ S1 B0 A a
FB12:8D 02 D0 STA $D002' _. ]4 w5 d+ Z
FB15:4A LSR
- U5 v" | k" U6 gFB16:4A LSR( d% m/ j9 m' g6 b
FB17:4A LSR/ D: F6 ]% B% ]2 }: P" z
FB18:4A LSR1 ~; }- O. ?3 k: [
FB19:8D 03 D0 STA $D003
0 J! L) C/ S- X9 o! d9 L+ qFB1C:AD F6 07 LDA $07F6$ W( n0 A- [ x' ~
FB1F:8D 00 E0 STA $E0002 j. d! n: o, X. ~/ `, G
FB22:4A LSR
9 q5 @7 x0 K" kFB23:4A LSR7 d& G. ?8 \+ j
FB24:4A LSR
3 f# o0 b7 [& b) i4 ~& J% F% KFB25:4A LSR
! N( N! d/ {) n! PFB26:8D 01 E0 STA $E001
# _8 d$ s; ]9 tFB29:AD F7 07 LDA $07F7
& {$ m/ i( Q! B* K2 B# j1 u P% k5 ]FB2C:8D 02 E0 STA $E0026 i4 ~. e: F& a+ h
FB2F:4A LSR
% [: x+ O% S1 W/ ?, O6 J9 }FB30:4A LSR% f% v3 X; c" `( c- j
FB31:4A LSR4 [1 S+ }5 y$ A( e/ C7 D
FB32:4A LSR
% C- i! y3 o' D! z5 b3 oFB33:8D 03 E0 STA $E003
6 F( Y. H% _8 x1 v! y6 q6 WFB36:A9 00 LDA #$00
1 ?. Z" Z9 X* o9 FFB38:8D 00 90 STA $9000
8 M" w5 H6 \5 k4 z% t% S* ZFB3B:60 RTS. Y! P& N& Z/ i/ k* a
# o, A6 J- q4 c6 }2 ?! k接下来修改切bank方式:% t6 v4 u! `" h8 V$ i5 V( K, F( }
FB2B:48 PHA1 i$ ~2 P B) H" I% I. a
FB2C:A9 06 LDA #$06. Y! d! V% J$ q W
FB2E:8D 00 80 STA $80009 y/ m* a( }* s* E9 t7 U% {, Y
FB31:68 PLA
9 M/ |- \ e" |. IFB32:8C 01 80 STY $8001: s. N5 {+ Q9 J1 p0 A1 @. J
FB35:60 RTS( Y& @- Y( t/ ~# P
& T. F9 Z: q6 @: M( x
FB36:48 PHA
1 i2 e% M1 M2 p. A" g" q$ PFB37:A9 07 LDA #$07
/ p9 A( }! ?" U' @FB39:8D 00 80 STA $8000 = #$14
* {& }( I+ W3 ]( s: C( O" WFB3C:68 PLA
6 q9 t' c+ X+ P& ]% q7 aFB3D:8C 01 80 STY $8001 = #$1D
- j2 t8 t% I2 c# P) g' |, nFB40:60 RTS3 A" j$ Z+ z" ]9 @) A8 P+ S5 D. ^. x
0 N+ j! T4 _+ t5 K2 K b
还要把原ROM的对$8000和$A000进行写入操作的程序修改一下:
* `( ]: y2 I1 AF989:AD 00 80 LDA $8000
* K: Z! D& [3 h$ H# [2 J& [F98C:8D EC 07 STA $07EC
/ V0 }+ |9 Z8 ~% e. wF98F:20 2B FB JSR $FB2B5 P4 j) a: e- h! U: U# h* U% h
F992:C8 INY
# }! r5 x s. G- c. b+ bF993:20 36 FB JSR FB36 v m# A6 F0 s4 ` @
F996:60 RTS7 r# j4 [6 x% r% [
0 O- O5 X' d" z! u% `
再修改切VRAM程序:4 r) z5 U& i' ?. v5 s
FACE:A9 00 LDA #$00
- ^; o/ h, k+ iFAD0:8D 00 80 STA $80002 }5 ~4 T% Q! T2 V# n% Q
FAD3:AD F0 07 LDA $07F0
0 L+ ?8 n2 e% ]8 d& nFAD6:C9 01 CMP #$01
* i* u: h# h& M8 NFAD8:D0 11 BNE $FAEB! x j3 C: ~" M9 r# `+ y' q p
FADA:AD F1 07 LDA $07F1+ V5 o1 }+ w: p
FADD:C9 04 CMP #$048 ?% t' D/ m0 S
FADF:D0 04 BNE $FAE5
& P% i6 F' Z' p* p, s) U7 Y sFAE1:A9 80 LDA #$80
+ k5 Y P* x8 B; t. U9 b* r* j& EFAE3:D0 06 BNE $FAEB
7 i1 x- S8 J! F; ~0 rFAE5:C9 05 CMP #$05
' d, |- U. x5 ?! ?/ XFAE7:D0 02 BNE $FAEB2 \0 i4 w. ^. m9 h" q
FAE9:A9 82 LDA #$827 c+ Y3 d4 T D% b; G8 z4 L( S
FAEB:8D 01 80 STA $80012 i: \: T1 P! N6 v* n
FAEE:A9 01 LDA #$01- j) h" Z! j; D& s
FAF0:8D 00 80 STA $80004 A/ _& o9 x* m7 p# @
FAF3:AD F2 07 LDA $07F2
% F& k1 l" M5 rFAF6:8D 01 80 STA $8001, ]. j, i7 u8 S4 N1 o" v
FAF9:A9 02 LDA #$02
+ r. f% C6 T2 g' I9 CFAFB:8D 00 80 STA $8000
8 g, y, U8 N* U* g$ r4 u( y' C9 {FAFE:AD F4 07 LDA $07F47 R% L3 L" Q3 ]
FB01:8D 01 80 STA $8001
0 |- ?) ]/ |& N2 |FB04:A9 03 LDA #$03
7 e a8 w0 r5 Z+ l( fFB06:8D 00 80 STA $8000
9 W' a7 d6 N+ _* V' `FB09:AD F5 07 LDA $07F5
6 o& k' P9 o$ M* t9 iFB0C:8D 01 80 STA $8001
( d: [7 L/ S7 U0 t6 JFB0F:A9 04 LDA #$04& I0 F; P3 M- Q( q. N, z
FB11:8D 00 80 STA $8000. [$ b& c" P- h; _( x' ?/ W9 \
FB14:AD F6 07 LDA $07F6
) c) i- j" p% v& e1 R8 K2 d6 yFB17:8D 01 80 STA $8001
5 V) e+ J% |+ ?' Z2 j I# t3 t9 r/ IFB1A:A9 05 LDA #$052 v7 i$ } |7 f8 G0 \; ^
FB1C:8D 00 80 STA $8000( b* U6 z/ v! P0 I0 N
FB1F:AD F7 07 LDA $07F7/ l' N3 n8 [2 X* D1 G7 I
FB22:8D 01 80 STA $8001
8 ? v' {: r* [5 {7 [FB25:A9 00 LDA #$00" `9 k' Z6 e2 l: F9 }, C$ S
FB27:8D 00 A0 STA $A000
4 ~( ]7 H) K; Q4 [0 i; [FB2A:60 RTS
' E% W1 B9 q4 _# ?& s5 R* K; @& z, U7 y8 _
然后保存文件。# k7 `, i3 C7 C! L% J& h
使用HXD修改文件头:
7 d, f+ X$ f$ A6 u将Mapper 23
2 j$ t/ D7 }# b& B06字节的高4位是Mapper号的低4位, Q. n- X* @: a- `9 g) W
07字节的高4位是Mapper号的高4位! R; X3 d8 ]1 x# G
组合起来就是0x17=1*16+7=23
! B: J5 G3 y r2 m' E w
7 t" q, B- }3 P: E* J% x, g: j6 C$ G修改成 Mapper 41 ?" D( m* h; w" J

5 A: a3 c+ ]1 T" m% s- P4 X1 G* \, L! H5 C$ o G
' y: o6 m) e/ L; N
再次打开文件:
: Y: \& z! X- Z7 X1 Z) u3 t4 l
8 q- S% H8 F9 m8 Z可以正常运行
: n: ]( l8 v& x. W7 y, H, n通过全面测试,发现出现精灵错乱:
1 l& b' W; f$ r P% x' E+ O第1关:; s, E, O5 ^8 M5 \; {6 o
- L# R( `8 `" R/ ~: X) B4 {: }* D
" Z5 }, |, p) \! ?: I第2关:+ Q" o4 w8 e* r5 |( Y# k. O

" |; H$ H7 X3 r) w X任务失败后:! Z3 W- O2 c/ @ @

8 X7 r1 D: @5 L3 }8 p2 _3 U通关后上飞机画面:
5 T" e2 r3 b' t" e " {0 }% I! Q7 q& \4 d
这是为何呢?
- v) k: l4 R9 V# d这是因为Mapper 23 中精灵VRAM切bank是一次切1KB
1 K6 F3 F2 ]* _) `但是在Mapper 4中精灵VRAM切换却是一次切2KB,而且忽略bank号的D0位
% t( U1 W% }% Z4 z" G1 z比方bank 0和bank 1是同一个bank,同理bank 2和bank 3是同一个bank
" r+ B% }" E& X( X9 a/ k. _也就是说
$ j$ i; z6 A7 \4 P" A+ E" wMapper 23中的VRAM的
) T( g4 n, @+ `bank 0,bank 1,bank 2,bank 3
+ ]5 y" @/ d& ]) k9 f% ^+ X在Mapper 4中对应的是( ]! p# b6 u& N; ]% Q+ m
Bank 0,bank 0,bank 2, bank2
$ h1 U' t" D0 m6 p8 z5 a0 Q然后查找原来的ROM的切VRAM的程序:, r; U2 c! _5 A s
知道是从07F0-07F3切到精灵VRAM的:
7 N. Q5 ^1 o* t8 h如图所示:
5 b6 f0 b, k3 m, i3 N7 F/ |+ e3 C9 E
; {, h7 U9 B1 s 4 p% y/ J5 C8 N9 }9 C2 T1 _2 L. `
作为对比,左边是原版,右边是修改。; w' t7 Q6 y6 x5 k, A* j" h
接下来是完善VRAM切换带来的问题,因为Mapper 4只能切2KB的bank,所以我们不能通过切bank程序解决问题。
5 T% j* n5 C% t+ p6 q% j% G; L通过测试知道1,3,5,6,7,8关的精灵VRAM排序如下(07F0-07F3):
( ?* h( L7 ~5 V% z4 E1 W01 04 06 075 j' C; g8 u+ w+ h0 x- J- V8 `
第2,4关如下:
8 \& R5 |9 t6 |; [. R01 05 08 09
9 F8 R, K6 L; y9 Q7 \任务失败时如下:
" }5 A! C; ]. }1 ]$ C32 00 00 1B
* m2 m9 i0 [& ]. f. o0 x6 x9 A& W; V其中任务失败时对应的VRAM是07F3的1B,只要让07F2为1A或1B即可:
& Q" a# T0 |& d- R5 M& X1 x$ c通过调试找到对07F2写入数据#$00时程序如下,于是修改C7E5的值为1A即可:
; F( S# h8 Z3 J* @ , C/ |+ y! g2 ~+ ~" Y p
转到ROM地址:
" n! T( W3 B( ]/ V: s5 e 7 B6 Y& k) A3 U6 x3 x7 N) w6 } N
修改数据:
7 z7 a9 q' E: Z% h; m, O" J i& F 8 `! p1 f+ ?) {# C) J9 p
重新失败后可以看到修复成功:9 o4 }6 R0 e1 [3 l

/ w* @" J8 i: E) q. ~" t2 O接下来是修复正常进行任务时的精灵错乱问题。
D3 w2 Z& Z) \* T# H0 s9 Y" I9 L! @! f首先运行Mapper 23版本,在1,3,5,6,7,8关任意一关的时候,将PPU导出来
: u4 O0 S: q8 p1 o* I
+ D) z, T3 g* o6 `8 G t' c / z9 [5 h7 q6 h- o5 m/ `* q

W r7 C; a2 l1 k! `8 g- m) m
' B3 Y& p S& N* y然后用Hxd打开修改的Mapper 4的ROM和刚刚保存的PPU的数据文件:' t- |5 o* W' q# P$ ?

0 x( B2 p' Y( D8 w在ROM文件头第05字节改为0x20:
`0 j+ d4 a3 Y) Z3 c1 T + W- U# [" J k' @
然后转到文件末尾,插入0x20000字节空字节:
* v# H3 k3 z/ g9 W& v( D 1 [" v3 l8 q+ x' F5 s- D1 d

# L Q2 b! `9 g7 g, q+ a5 x& ? 9 |3 {! C1 f' |7 ?/ ~+ D3 \* b
# j/ t& X* A/ K3 \' U
然后将第1关的PPU数据的前面2KB数据选定:$ `- e- X7 `- V' j

& q! O- s2 u7 @6 H D+ U0 Y/ \
# t2 T( V9 u5 P' B! p" v! r; F
+ Y; O* O2 l- @1 m7 p复制之后以覆盖方式粘贴到ROM的40010,同样把第2关的PPU数据的前面2KB以覆盖方式粘贴到ROM的40810
# c. r% ~8 s0 K: g6 u. R+ k, ]
& w( h' V: H2 \然后保存文件:
/ X; q2 ]1 U/ d' c+ r j % n/ C0 q, w, h, B5 ^, v- B
最后用FCEUX打开文件,添加07F0-07F3的写入断点
% F* V5 ~; d8 J( @
3 u" b, c1 n7 O* ?地图预览后即将进入第一关画面时程序暂停了,可以知道此时准备将C793的数据写到07F0:3 w% X$ n, v& d1 b& b

: R) F& j* C: X, H2 \5 v8 I测试后知道将C793-0796写入到了07F0-07F3:$ j7 e% `- }- f+ k% G
同理,经测试每4个字节一组,一共17组,其中01 04对应普通关卡精灵以及其BOSS关的精灵VRAM的bank号,01 05对应2,4关卡精灵以及其BOSS关的精灵VRAM的bank号,再加上一个通关后跳上飞机那段动画的精灵VRAM的bank号。- ^1 m+ s* H) ~$ w# J
: Q0 ?$ `& T" l2 `
( R* \/ j ]( }' u: d
然后将文件中标记的01 04修改为 80 04,将01 05 修改为82 04即可:4 m8 I7 T6 } i9 m% G1 W* ?+ Y

8 u5 q' A8 B" s5 k2 W) ~3 ^" ^& [保存之后重新运行后效果如下:
% D2 C6 _; v+ _5 g0 }# c# {9 }, R! L
7 t+ ?) e. {0 v 1 |% b6 j: a1 P; U2 Y
f F' P3 Z9 w% M
当前使用的是FCEUX模拟器,如果用NEStopia玩的话一开始就死机了,这是因为这个ROM有文件保护吧,它会往$6000里写入数据:. ]' D9 P+ [' I
8 N6 T5 y- u: U
F863:A0 03 LDY #$03
$ E4 [8 i C8 Z9 Z0 v6 ~F865:98 TYA" d; |3 c4 G4 ?, v( F0 c d
F866:29 01 AND #$01& D5 P$ [1 W; s9 j/ f
F868:8D E9 07 STA $07E9, o! A& V. t3 O' K2 O: j
F86B:8D 00 60 STA $60003 u) x. O" _% }7 K, \
F86E:AD 00 60 LDA $6000: Z6 |" l9 I6 @' o" R7 X! Q1 y
F871:29 01 AND #$01. H. H2 [5 o$ L
F873:CD E9 07 CMP $07E9
0 B2 B( p2 Z1 Q- X& R. b+ g EF876:D0 05 BNE $F87D- Z3 R, a% n6 R9 |
F878:88 DEY# ^! L$ l( }8 X
F879:10 EA BPL $F8650 O- }. M3 b2 ^
F87B:30 03 BMI $F880
$ V/ b1 p5 p. E9 z" LF87D:4C 00 00 JMP $0000
; T% C0 m6 S9 Z, @$ X% J4 vF880:A5 1A LDA $001A
2 w. f! g/ c# C y- ?+ ^ z2 ]2 \F882:65 34 ADC $0034
# p2 i8 o- \; m7 _' _F884:85 34 STA $0034
. @- M1 X; a, T2 mF886:4C 80 F8 JMP $F880# j, s6 e# s1 l0 r# q ?9 p8 O' L
先取Y值=#$03/ A! k' V8 c5 `0 g0 [
与#$01相与后得到#$01
' h+ e$ T8 y) E& H8 a5 ^写入到$07E96 g7 T" f0 F% J7 a) c, ]
写入到$6000% d. H. |' |6 {% y5 S
再读取$6000的数据和#$01相与后和$07E9的数据比较4 @1 i& S, \# R: z# T! B2 H
不同的话跳过5字节
4 { p% ^1 ^. k7 m: a否则Y递减
$ A* T9 S/ L# l' H9 B G, y) f为正数就跳回0x100-0xEA=16字节
1 a5 h4 F; L+ a$ t3 e# H为负数就跳过0x3字节2 f7 o0 G+ ~0 e" b
跳转到$0000(简直没有人性了,跳到这里死机,真想得出来)
( d# P# v) \/ f- K6 g$ p! e8 t0 O0 F: @
正是因为这样,NEStopia运行FC时,6000-7FFF默认是不可写的,必须在ROM文件头第6字节的D1位置1设置ROM有SRAM,对于Mapper 4,还需要向$A001写入#$80来启用SRAM。
; ~% b' |8 v w# J7 r/ W由于$6000不可写,因此想$6000写入#$01后$6000还是#$00,之后读取$07E9的#$01与之相比当然不同了,于是直接跳转到死机程序了。
- E- o7 p5 y" ~/ S0 d& S( j# ~1 [解决方法是把ROM中的所有的AD 00 60 29 01 CD E9 07 D0 05 88 10 EA 30 03 4C 00 00
d( Q' [" h" I, K2 w2 B中的D0 05改为D0 00,然后保存即可。
6 }0 B* A9 y, q8 Z; {# p7 E" r测试完美运行。9 _- a* v( y, Q! S% j" S5 e& T

- b$ N9 f' L* R- B# i1 y. [& ?" c4 N0 ]4 n1 N+ ?: h( s
教程到此结束。
) D% h* L; Y* f6 J d; c8 V6 C- B" P8 P/ I: V2 M7 |" u* T
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|