|
|
本帖最后由 yandagui 于 2017-4-16 19:06 编辑 8 {: m9 r$ [" j) H6 y
/ i- Z6 q1 o# _, e. u
Mapper23转Mapper4实例教程
: F6 H; Z6 c: a3 [2 F2 g( x7 v' Q
FlameCyclone 2017.4.14+ Q5 k: g7 ^7 b! e4 ?8 m0 Q
' d' I; i" g( T7 V
先看看Mapper23文档:
4 Y' r6 c; Y3 J1 i: R# q6 r. k: z
; y) C, U% @* Z( }Mapper 23
# {, u8 d u& n8 _0 I& V# U9 j
: T" X3 D' a6 s* T$8000: 选择8KB的ROM存储体映射到$8000- |. i% X6 Y) a6 A/ ~: F$ V B
# Z& s1 T+ R6 }) {* L0 d$9000: 0:垂直镜像
4 |/ n" G- q& ?; d8 D9 x 1:水平镜像/ u+ o/ E3 z1 X. [( k
2:$2400镜像, E5 c+ m7 P5 j* _% y- h5 U
3:$2000镜像, G. [% k( w# f0 y: A, b
# t9 \' `0 e7 B B: o+ \- z8 l
$A000: 选择8KB的ROM存储体映射到$A000
y Z3 G/ \2 o( p4 D
; z( w, d& |6 H9 d$B000: 选择1KB的VROM存储体映射到PPU的$0000(低4位)
: _! `- S( R( l/ h# ?$B001: 选择1KB的VROM存储体映射到PPU的$0000(高4位)
! O6 p4 o, e! v1 q$B002: 选择1KB的VROM存储体映射到PPU的$0400(低4位)
; Q7 W# I' T% P$ `$ @ ~$B003: 选择1KB的VROM存储体映射到PPU的$0400(高4位)2 ]# v# C5 d: g, |
3 x" o+ b7 o x3 X
$C000: 选择1KB的VROM存储体映射到PPU的$0800(低4位)
- R0 ?# i! M' n! }5 s: v6 u$C001: 选择1KB的VROM存储体映射到PPU的$0800(高4位)
/ B7 d% M9 c2 y) J2 d" ^- e9 b$C002: 选择1KB的VROM存储体映射到PPU的$0C00(低4位)
/ `5 `/ O# y8 c4 r( I9 J' d$C003: 选择1KB的VROM存储体映射到PPU的$0C00(高4位)
6 V" i8 Y- e$ `& S& k) M( r. f
. d( x4 ?; Z. K$D000: 选择1KB的VROM存储体映射到PPU的$1000(低4位)
4 T) |- ?7 ^" r" _5 v$D001: 选择1KB的VROM存储体映射到PPU的$1000(高4位)
) w7 x& a$ L: a( ]" Q$D002: 选择1KB的VROM存储体映射到PPU的$1400(低4位)$ K" r6 j& E% I, A( d$ {
$D003: 选择1KB的VROM存储体映射到PPU的$1400(高4位)
% e1 E* A: p& L$ i$ D( S; T' o$ L4 r1 V" q
$E000: 选择1KB的VROM存储体映射到PPU的$1800(低4位)
2 [9 S+ F6 e7 p. o1 H$E001: 选择1KB的VROM存储体映射到PPU的$1800(高4位)
7 V! n7 e/ F% \: v. w$E002: 选择1KB的VROM存储体映射到PPU的$1C00(低4位)' Z! O( \! h8 O) k8 d
$E003: 选择1KB的VROM存储体映射到PPU的$1C00(高4位)
$ z% G! J7 G( [4 d8 q3 [% |6 a+ j- y5 J) F: B7 A, T/ s _
再看看Mapper 4文档:2 I2 s l5 q3 W, g! J
/ V, k F0 {0 H$ yMapper 4- H; E' y+ }8 ? b; e5 g$ Z+ ?
1 s$ X; i5 c" s: \& U; Y
$8000: 模式号
1 n+ }# T0 C8 C2 }( }! W 位D0-D2:' ~. y! J& |5 \
0:选择2KB的VROM存储体映射到PPU的$0000
- `' p; S4 Y' V 1:选择2KB的VROM存储体映射到PPU的$0800$ m& }+ l- ?' g/ S
2:选择1KB的VROM存储体映射到PPU的$1000
; {/ P/ w" ]6 ~1 o 3:选择1KB的VROM存储体映射到PPU的$1400
/ n: e9 Y9 |0 Q8 w5 E 4:选择1KB的VROM存储体映射到PPU的$1800
2 m7 u9 [2 t( t N, s% o. s( D 5:选择1KB的VROM存储体映射到PPU的$1C006 O, M& z( C8 O4 f# J
6:选择8KB的ROM存储体映射到$8000" M9 L7 o; o! z
7:选择8KB的ROM存储体映射到$A000
`" y% f# z5 @, D% D# b, T3 x 位D6:
# I4 F$ i* ?! D, H9 } 0:允许擦写$8000和$A000" ], ]5 X+ \' S! y- D. S
1:允许擦写$A000和$C000
: g2 g1 W p/ R2 E& @9 ?2 Z! z' P 位D7:
: r5 d+ `# }5 ?3 a 0:模式号D0-D2使用普通地址
+ @ N5 y5 ~3 X! _ h# l5 L 1:模式号D0-D2地址异或$1000
9 o' T- i( \ }1 j [2 y z# }$ Z; t& L
$8001: 模式页面号7 h* x6 }( `, M
写入一个数(00-07),切换存储体到对应地址
: z; Q/ |4 `, x. \, y; a7 {$ D. Y1 H- t9 H( H7 D2 V
$A000: 镜像选择. o i, L2 d s3 X6 I; c, Q
0:垂直镜像* n( I5 J2 w' e9 J9 E
1:水平镜像! L' A, T* ?7 F9 \5 y# W" h. ^* C
# Z" D, G; V; W8 |/ H2 U5 S$A001: SaveRAM 切换
$ f9 |& ]0 m* ]. g# h+ J$ R ~ 0:禁用$6000-$7FFF
' w2 }, s& n# H* Y/ N 1:启用$6000-$7FFF9 u: d8 s8 |. _3 b
- P+ O& } P' o& T/ h! o! j, g
$C000: IRQ计数器
" ^, y5 k# B$ {6 M- \" A IRQ计数器的值存储在此处% _3 y9 p4 a% v
2 j+ v$ _7 w3 T
$C001: IRQ暂存器
7 ~2 D, ~% O/ ?+ O3 C5 t5 X# u IRQ暂存器的值存储在此处
5 B+ ]4 O2 U: R1 y, ?6 e5 ^
& U) N; }5 Q% E5 }$E000: IRQ控制计数器0
$ ~* l4 w' n# }- e. j 向这里写入任何数来关闭IRQ,并从暂存器中拷贝数据开始计数,进入IRQ
% x8 z- D. d O& {% o( H7 [4 c7 F3 j8 ^# l# [' g0 X8 c: [
$E001: IRQ控制计数器1: _- A* `9 S; ~! E% K
向这里写入任何数,允许IRQ(退出IRQ,允许下一个IRQ进来)
9 k/ N+ l9 R6 ~2 `. ~- N- A* `+ c! N3 W5 |. Y
, r+ Q, V7 B5 Y转换思路:
6 e7 |/ e) y9 |1 t( V' z; r将Mapper 23 的切bank 方式和切VRAM的方式修改成Mapper 4 的方式。
6 ~% r4 x( T0 H0 A! S6 \0 o$ r4 C, k( j u2 ^
修改实例: Y r9 Z3 P: \7 V
Contra (J) 256KB Mapper 238 P; x8 K, l, F* w6 F. v+ i
工具:
5 g, P) k2 J0 k6 z7 j/ B3 E1.FCEUX 2。2。3/ n8 L! J9 D3 M6 g
2.HXD; H# B0 Q( Z, t1 u
先来看看这ROM的切bank方式:& k, y7 q/ y9 l
F989:AD 00 80 LDA $8000 , Y; u! ?8 }! S( X0 Y1 i7 M; \
F98C:8D EC 07 STA $07EC! I1 {, ^9 A" E) x3 x0 j
F98F:8C 00 80 STY $8000% k D4 H5 H- _1 E3 D, f/ x
F992:C8 INY
6 b8 H/ i) K5 B& ]5 i0 ^ X8 ~ nF993:8C 00 A0 STY $A000, ^$ T$ D: p% l
F996:60 RTS
9 S* d3 T0 D8 R. z) d5 T8 b& T4 N) d0 I! f) p, z
再看看它的切VRAM方式:
, k" ~- @ Y7 J: o2 PFACE:AD F0 07 LDA $07F0 \5 q q0 b$ h/ k5 k* V
FAD1:8D 00 B0 STA $B000/ I0 b5 a6 z4 @& b3 Z# W3 M
FAD4:4A LSR. w" J9 m7 }0 v4 M7 h% ^
FAD5:4A LSR
. H; u$ Y, A7 NFAD6:4A LSR
; P) Q# J! g4 i, j; L9 V& i$ r- UFAD7:4A LSR6 f8 K/ L! B$ l) r- b! m
FAD8:8D 01 B0 STA $B001, ]0 \& p( T6 S6 n. [4 m& S" L
FADB:AD F1 07 LDA $07F1
6 W- \* w( Q' q0 {) I; M2 M0 `FADE:8D 02 B0 STA $B002
- n# i5 p8 U$ G5 j/ u# hFAE1:4A LSR
7 I' D$ I& a, m0 o& H( jFAE2:4A LSR
& Q/ R, P# I: I: w8 xFAE3:4A LSR$ j$ r b2 m& o$ q
FAE4:4A LSR+ n/ T9 P2 x* a% i
FAE5:8D 03 B0 STA $B0032 q4 j% I, E- x2 O: a
FAE8:AD F2 07 LDA $07F2
# \: K6 u+ o0 L. V% B" RFAEB:8D 00 C0 STA $C000
$ ]* t p y e) xFAEE:4A LSR6 W2 [) B5 ~! X4 b
FAEF:4A LSR
" r; q/ b _ x5 w; K( n3 j9 RFAF0:4A LSR Y* T9 x) L: Q) W1 i. L6 k1 G
FAF1:4A LSR# ~$ c/ R6 v4 ?/ g
FAF2:8D 01 C0 STA $C001
! `8 V! \' I2 bFAF5:AD F3 07 LDA $07F3- X! w) {0 k! V0 v
FAF8:8D 02 C0 STA $C002. {* c8 B% W, ?( x* S
FAFB:4A LSR
; E# o; B6 H' q2 R; i% Z% nFAFC:4A LSR1 S! W; v3 x0 b! e# {8 F0 V2 n
FAFD:4A LSR$ `# o0 ]$ b4 v. U( S: v! z6 Y/ Q: @
FAFE:4A LSR- E `* A1 W6 \- r
FAFF:8D 03 C0 STA $C0038 _$ P1 N" k' X ]% x1 _) s
FB02:AD F4 07 LDA $07F4
! J& D. T* t$ HFB05:8D 00 D0 STA $D000
+ X* n/ h: ?+ u; c5 g/ C3 `9 eFB08:4A LSR7 e. v: n1 y, U( c4 s$ [, z+ Q( N1 }
FB09:4A LSR
! |! ?( }, r0 c! o! VFB0A:4A LSR, k* m" u8 j: c/ L0 U& ~2 q
FB0B:4A LSR' u, m2 b, R+ h4 D# |; z& p
FB0C:8D 01 D0 STA $D0013 C/ ?1 q) L3 z: B4 ?
FB0F:AD F5 07 LDA $07F5) h8 f% U# s, N7 {: q4 i0 a
FB12:8D 02 D0 STA $D002
# F4 O7 X( F% P3 q+ Q+ o0 a! wFB15:4A LSR
3 t. w( b3 D. c/ Z; m6 q7 AFB16:4A LSR
+ J; x' o) _9 DFB17:4A LSR
: ?0 F! \8 W& \( X* p2 p! LFB18:4A LSR+ t$ P/ }! B4 o8 y3 f, L- Y N
FB19:8D 03 D0 STA $D003
) K3 M! M; T$ `. r# Y _$ TFB1C:AD F6 07 LDA $07F6) s( k# A5 w3 O/ a
FB1F:8D 00 E0 STA $E000# B4 t* Q. y5 `& s) q' M: H. |
FB22:4A LSR
$ o; f) }" K3 B+ UFB23:4A LSR
( z$ _8 Z- c- J/ d3 y% b: dFB24:4A LSR: g( x+ L" Z7 B, R/ {$ S
FB25:4A LSR& c) _/ O1 y+ u/ }* c: ~7 H
FB26:8D 01 E0 STA $E001 T: [' I9 p! e
FB29:AD F7 07 LDA $07F7
! P- W0 m; ]! U2 D, e, CFB2C:8D 02 E0 STA $E002, K1 A7 E% m1 H% ?" s/ o3 o7 {
FB2F:4A LSR1 V1 D L& R9 `& X
FB30:4A LSR
5 ~3 l7 E1 Z6 | g0 _FB31:4A LSR- e0 u- X' T# z% \7 z
FB32:4A LSR4 S$ P v' {. A: d
FB33:8D 03 E0 STA $E003+ o8 Q1 y Y: j8 E- e4 _6 X* H- J
FB36:A9 00 LDA #$00
! { Q3 b2 T0 P. iFB38:8D 00 90 STA $9000 v. ~# h* m, L5 q4 F: {
FB3B:60 RTS
$ W; @6 `7 h; {" g7 }& z: d( E" v; X1 m
+ `6 \9 L/ |( X- {6 g, f接下来修改切bank方式:5 X! [# L6 n: y
FB2B:48 PHA9 T. M W/ h+ Z
FB2C:A9 06 LDA #$06/ J% U4 X, A, v# P# | {
FB2E:8D 00 80 STA $80003 A+ q" \: F0 R% i9 X$ T' K$ J1 i
FB31:68 PLA+ g0 T2 z0 F) O
FB32:8C 01 80 STY $8001
" |5 g. c; d z/ VFB35:60 RTS
8 v% s% L& [3 U' o- W! h/ W
4 S: J [# P9 W4 T* ~9 S: QFB36:48 PHA
% a8 G4 a1 a& K5 P9 E7 C# l9 YFB37:A9 07 LDA #$07
% P7 B& r' P& X" l- }1 b. r, hFB39:8D 00 80 STA $8000 = #$14; S8 G4 }9 c- i9 {- b
FB3C:68 PLA
& F7 V6 u$ l! G/ }1 |. Z, G7 IFB3D:8C 01 80 STY $8001 = #$1D) h, `' P1 i( F0 v
FB40:60 RTS
, ?) [% k6 W/ e) M2 O2 a- J3 W( Q/ |* s U, G2 v* ?1 k
还要把原ROM的对$8000和$A000进行写入操作的程序修改一下:
/ ]8 x/ S: u/ X8 T+ |1 n" L, c- rF989:AD 00 80 LDA $8000 7 A. L( I. ^& J8 E* s( G% i
F98C:8D EC 07 STA $07EC
8 F& H( m7 O5 ~5 ?8 EF98F:20 2B FB JSR $FB2B
( o' l9 b5 L4 }5 o7 s$ J# UF992:C8 INY
6 X! W$ n! ?& kF993:20 36 FB JSR FB36
6 E7 R q' {# P/ T; B9 t) vF996:60 RTS
/ x: I+ N4 g1 n* W" d: L, W5 L
9 N& m% N' C' E- ]9 ]3 T再修改切VRAM程序:
9 w, v W1 O6 I$ O0 z- }/ TFACE:A9 00 LDA #$004 z1 ~& T0 C; W& r7 K
FAD0:8D 00 80 STA $8000) B+ S' f% r7 Y/ W3 Q
FAD3:AD F0 07 LDA $07F0+ o, y1 b! R' J& C7 u
FAD6:C9 01 CMP #$01$ ?& ]- u D; Z+ z7 H% D
FAD8:D0 11 BNE $FAEB: c! B0 I: O- }% R9 n1 l9 i& }; a
FADA:AD F1 07 LDA $07F1
! {6 M. H. r" j! d$ Z3 m# d8 YFADD:C9 04 CMP #$04 X% P" P+ Y% E8 l
FADF:D0 04 BNE $FAE5
7 W: {* G/ r. A U+ v! xFAE1:A9 80 LDA #$80
! B7 t0 m) U1 ^2 N5 X: lFAE3:D0 06 BNE $FAEB) r; v. T7 u8 M+ }
FAE5:C9 05 CMP #$05
2 P N( J5 [/ F. U0 T; SFAE7:D0 02 BNE $FAEB
4 W' @ {, M1 DFAE9:A9 82 LDA #$820 j1 _: J! s: B$ D# ~( o, g# d
FAEB:8D 01 80 STA $8001
7 X" V! k& }9 r- l c2 GFAEE:A9 01 LDA #$01
4 f6 F' q: n# E1 M, VFAF0:8D 00 80 STA $8000) o# U/ j* R8 \% \; b7 R
FAF3:AD F2 07 LDA $07F2
1 l( i" b5 p. |6 jFAF6:8D 01 80 STA $8001
& B; q7 N3 U! T2 }# O3 _% \1 @) ?FAF9:A9 02 LDA #$02
0 \" [* N Q7 c2 y" ?$ ^ FFAFB:8D 00 80 STA $8000
/ I# `8 t! p. V3 KFAFE:AD F4 07 LDA $07F4
' w: Y; P) `/ p; U g2 I6 vFB01:8D 01 80 STA $80013 ]" \' [' c/ s9 Q# B* R% X! L
FB04:A9 03 LDA #$03
5 Z# O+ ~+ {/ R1 g5 N9 C+ _8 M- ^FB06:8D 00 80 STA $8000
' X1 x% D$ a9 B% ~; [/ QFB09:AD F5 07 LDA $07F5
/ Q" _9 l8 B" s8 e! ?2 L2 U3 lFB0C:8D 01 80 STA $8001' Q; ?8 B2 N3 t: E4 Q0 s9 p/ H
FB0F:A9 04 LDA #$04
* C9 F' t( V" l0 [$ WFB11:8D 00 80 STA $8000
V3 C% G! ?# @6 K! g# P# Y0 rFB14:AD F6 07 LDA $07F6
1 f% L( ?9 `( J; D: MFB17:8D 01 80 STA $8001: ~/ k& M* O9 R! ]) U0 O" }
FB1A:A9 05 LDA #$05
) J6 {; g1 Q( `" |FB1C:8D 00 80 STA $80003 e9 _0 }. B* Z$ j5 K
FB1F:AD F7 07 LDA $07F7& L4 k% M9 @: y/ U' P) ]5 E7 Z
FB22:8D 01 80 STA $8001
4 j9 l2 L5 A! sFB25:A9 00 LDA #$00
% Y4 z0 e% `( T |, JFB27:8D 00 A0 STA $A000
$ Z& f- @+ |% }3 {( K: K* c1 P1 l) dFB2A:60 RTS5 ?' k5 x/ K) }6 m% q
5 h- f9 I* {# e7 _然后保存文件。
! Z4 e" e1 ^, Q7 v: p4 N使用HXD修改文件头:
' D7 o+ O0 {1 E5 f# \0 K) R, Z将Mapper 23
4 j! d! q6 K- F06字节的高4位是Mapper号的低4位
. I7 m- i m' B+ R9 z07字节的高4位是Mapper号的高4位
7 c4 F' x! o Y% b! k, U! X组合起来就是0x17=1*16+7=23
) w4 a2 ` N, a8 o- {
4 Z' K# G. f' x/ K) `0 g修改成 Mapper 4
4 M" Z* Z, | y* L1 f2 f8 o$ g5 [- _
% a* ~3 W& _: h& j$ P6 l' ^7 O# E6 v, K4 O
) i1 m& k+ j' m, i, S! h- F再次打开文件:6 }$ W' K9 d3 X9 S/ Y2 k/ C
7 [ e' a3 u- w9 d
可以正常运行5 o! c, Z4 R5 I
通过全面测试,发现出现精灵错乱:
j6 P' J1 g5 i+ A* w5 t5 n: r第1关:
3 b# S6 T! b7 i" R: w) G
) Q; j6 Q ?) \- g5 f1 z3 ~/ x+ x5 N; H
1 ]& @0 j3 B6 h+ Q% i4 C第2关:7 @# v* L0 I/ B) u; b: O
, I3 W: v2 ~. s0 I; \3 E2 J
任务失败后:5 ` e6 Q+ c, @: Y8 `2 L, d0 U* _; h* I

' q1 o' b$ O+ M& B- ]# C, b通关后上飞机画面:
0 j. {4 S2 {* ? $ X" W1 G; d6 B1 t7 a* o& V
这是为何呢?
7 L. q4 n& r, o& R$ o8 M8 G这是因为Mapper 23 中精灵VRAM切bank是一次切1KB
6 J; c( x \& M. c8 L9 y但是在Mapper 4中精灵VRAM切换却是一次切2KB,而且忽略bank号的D0位9 L( o) t: j9 l. H+ p9 q$ h
比方bank 0和bank 1是同一个bank,同理bank 2和bank 3是同一个bank
) i6 x* Z9 O8 l5 u- h( _% \4 W6 ]也就是说8 m/ I# V/ J" v7 E/ ~) l
Mapper 23中的VRAM的
; H6 Z2 X; [" D1 S7 w8 L$ H4 pbank 0,bank 1,bank 2,bank 3
# G( Q# i- R: ^在Mapper 4中对应的是) m: S4 W& Z; p; b; |5 M
Bank 0,bank 0,bank 2, bank24 g' s# A9 J0 m" w* Q
然后查找原来的ROM的切VRAM的程序:
! J' Z+ B6 i1 c/ o$ z2 A) w' T知道是从07F0-07F3切到精灵VRAM的:1 p) n, o4 i) `3 k, M* A
如图所示:
, D K5 w/ A. d/ b# f6 p0 u( x) `/ Z- o
& m1 d; b. l+ q+ \' \! N 5 A7 d' A5 q! @- ^6 |, ?& y
作为对比,左边是原版,右边是修改。
. L6 R1 l% P' H4 ^接下来是完善VRAM切换带来的问题,因为Mapper 4只能切2KB的bank,所以我们不能通过切bank程序解决问题。( t8 x+ I) S, O) S- q* p
通过测试知道1,3,5,6,7,8关的精灵VRAM排序如下(07F0-07F3):- y2 x+ f- a7 j+ O2 c% d
01 04 06 076 m. S7 c H' c* \, k% O
第2,4关如下:3 T- F1 v9 b) t. Q
01 05 08 09
/ G- w% I( R( m, h# ?6 y任务失败时如下:) |% s" z: Q, {) X( a
32 00 00 1B9 ~% d6 W3 Z& g, N; q( u$ q
其中任务失败时对应的VRAM是07F3的1B,只要让07F2为1A或1B即可:
9 v$ p3 R X1 e3 M通过调试找到对07F2写入数据#$00时程序如下,于是修改C7E5的值为1A即可:
- M7 L: n3 x, X" L0 { T; O
9 ?- a9 H2 x# g. L) A, n/ \# R2 O转到ROM地址:
}" D+ f. a) z7 n
( z% E5 J+ W1 Y7 V/ K修改数据:4 v+ [8 d: T1 \
F- z/ C2 ?& e6 v7 f9 f
重新失败后可以看到修复成功:! y# F- `( p, [/ P* W7 V; Q* Z
* b8 t8 l) c8 H$ g: v! G
接下来是修复正常进行任务时的精灵错乱问题。
6 @. Y. @* R1 x( N* @, Q首先运行Mapper 23版本,在1,3,5,6,7,8关任意一关的时候,将PPU导出来
* _9 v1 d# A/ h& j4 c9 x' l
( o3 d( l5 y* |0 v" Y) w: M7 Z
/ ]! }- F" E( \; D4 R9 \6 f
+ v+ v6 u+ I" X7 n. j! w
9 r/ L& [* `& d# i然后用Hxd打开修改的Mapper 4的ROM和刚刚保存的PPU的数据文件:
9 H- ~, g( K, b6 c
% J3 Y. G5 b5 T在ROM文件头第05字节改为0x20:
`+ p& d6 k1 h* F; ^
2 G/ b0 `! n* w |然后转到文件末尾,插入0x20000字节空字节:2 F' b9 ^% w2 q7 E
/ Q3 s4 W' Q' a5 t# L
8 v5 s; a% |6 @5 b F

2 ?# X" n( z/ `2 `! J. L) F7 P& ~ " C! C) f5 o: l b) o
然后将第1关的PPU数据的前面2KB数据选定:( j4 z" ?, M$ m; X R( ~
' Q; k# f6 s5 |9 T
3 D6 {0 @2 h+ d. C

* S# I( d. I+ }+ e! k& J复制之后以覆盖方式粘贴到ROM的40010,同样把第2关的PPU数据的前面2KB以覆盖方式粘贴到ROM的408102 L; q# K# K3 n/ e
( c6 Y4 i3 I! N% s p
然后保存文件:: U9 l8 N5 r" E: o+ C, t* k

* A6 o7 l) e& S最后用FCEUX打开文件,添加07F0-07F3的写入断点
& _/ _5 I6 N' z& G1 F
2 s+ s: i s2 x J2 {地图预览后即将进入第一关画面时程序暂停了,可以知道此时准备将C793的数据写到07F0:% T5 P% C* C% I( T- M7 C
8 p% P+ I4 U, W! U: h
测试后知道将C793-0796写入到了07F0-07F3:
+ L* M9 O- e- M同理,经测试每4个字节一组,一共17组,其中01 04对应普通关卡精灵以及其BOSS关的精灵VRAM的bank号,01 05对应2,4关卡精灵以及其BOSS关的精灵VRAM的bank号,再加上一个通关后跳上飞机那段动画的精灵VRAM的bank号。
# X1 A2 r# E; J1 \/ |; s
: S( {8 o! n; J& p6 l$ v8 {& S
, N1 C* L8 ?1 C) Q3 Z; z. A3 w然后将文件中标记的01 04修改为 80 04,将01 05 修改为82 04即可:4 C/ H8 L f$ r d; U; ?

8 |# N, j: X, }/ S保存之后重新运行后效果如下:! U% N$ d, n2 Q2 B7 ^
- Y* o6 a+ x# j7 N3 T" M

& Q4 ?0 X$ e, [2 k) P$ r7 g P
. Q8 i, h7 _& F. r4 }1 [6 q当前使用的是FCEUX模拟器,如果用NEStopia玩的话一开始就死机了,这是因为这个ROM有文件保护吧,它会往$6000里写入数据:
" s* q5 r7 w3 s' F- `1 h : p6 N/ x% ?" f7 o. W! K
F863:A0 03 LDY #$034 Y- ]. q9 g6 }4 k) ^7 j! v
F865:98 TYA; J, V' Y7 I0 A/ H2 z' X- z
F866:29 01 AND #$01* {) O! Y2 G1 |
F868:8D E9 07 STA $07E9
7 e' n2 Q W" c, ~- DF86B:8D 00 60 STA $6000* G/ {- @, ^. G* ~; d) y" X
F86E:AD 00 60 LDA $6000
% I) K. S$ l& W0 Q) IF871:29 01 AND #$01) k6 [! |1 N( F" H
F873:CD E9 07 CMP $07E9# |- {5 e# d$ t7 Q
F876:D0 05 BNE $F87D
9 L7 P1 S" d0 Q B! G) o, fF878:88 DEY) W: B$ \* M) b4 {2 J9 i3 N
F879:10 EA BPL $F865) _ j+ ?% F) ]2 I; W: z
F87B:30 03 BMI $F8807 g/ L) Q. @. j; ^/ z G5 T( O' n
F87D:4C 00 00 JMP $0000
; y/ ^5 b9 S! }' d7 F# R$ {F880:A5 1A LDA $001A1 \# b$ _& x$ {" ~. Y
F882:65 34 ADC $0034
" l. q; B* O( X! tF884:85 34 STA $0034
. a( @$ g$ n5 l% u/ u X" R* E( QF886:4C 80 F8 JMP $F880
7 A% K' y( t5 V8 H9 z' t先取Y值=#$03% [0 v0 z* `# q! [; s8 V; ?' z+ U8 F
与#$01相与后得到#$01
% Q& }' r% ]8 O8 \2 v5 z- w写入到$07E99 i8 ?8 H8 d1 I
写入到$6000+ F% M5 A! Z! U( K
再读取$6000的数据和#$01相与后和$07E9的数据比较) U- @/ i* ^9 c) U
不同的话跳过5字节
- s! Z7 E& w; }" e" n2 {/ z3 W否则Y递减
3 o1 ^/ \- n& L0 N为正数就跳回0x100-0xEA=16字节
* o3 k* g/ u7 t7 m为负数就跳过0x3字节8 y1 X& k3 B- y: v- W$ p' V- x
跳转到$0000(简直没有人性了,跳到这里死机,真想得出来)& Y" \: ?0 D' X! w( e7 \- p- S
9 Z( X9 d3 Y2 z0 M' b3 i2 L
正是因为这样,NEStopia运行FC时,6000-7FFF默认是不可写的,必须在ROM文件头第6字节的D1位置1设置ROM有SRAM,对于Mapper 4,还需要向$A001写入#$80来启用SRAM。+ w3 J1 p6 u) s
由于$6000不可写,因此想$6000写入#$01后$6000还是#$00,之后读取$07E9的#$01与之相比当然不同了,于是直接跳转到死机程序了。. l+ o; ^9 Y& E6 J
解决方法是把ROM中的所有的AD 00 60 29 01 CD E9 07 D0 05 88 10 EA 30 03 4C 00 00
5 }3 y- H* o" R5 A8 y* M' H中的D0 05改为D0 00,然后保存即可。
' s: `, d! }% G3 m: o/ m7 `7 ]测试完美运行。( U) Y& w) q% u4 t( Z" g5 P" `. t! l
7 Z0 W3 k! v" l3 u
1 f* J2 A- A% S6 D B+ K5 D教程到此结束。
% i0 X- b& J' ^5 \- V* H& S$ D: [3 c& ~+ p! t% ]5 P4 o
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|