|
|
本帖最后由 yandagui 于 2017-4-16 19:06 编辑 0 s; e* {9 Z& m$ @1 ^4 Q( X9 C
7 ?+ k; P, F! O: b
Mapper23转Mapper4实例教程0 C; \5 [2 q. W6 o
) O' ]; x9 i( w( I! J ^6 Y
FlameCyclone 2017.4.14
* Z* X' f# x( M2 \9 R9 p& J' q4 V, \! j* N5 G/ y* v: k0 x
先看看Mapper23文档:0 D, e' [ @+ n" z7 C, w
6 f7 X) {6 `1 VMapper 23
& h+ h1 D4 `4 T+ N! v$ n. W) {% f+ b: G' y+ _
$8000: 选择8KB的ROM存储体映射到$8000
/ T$ L+ {$ S: J5 _; @" K8 U1 S6 o& _6 w( Z$ F4 B3 s( v8 P
$9000: 0:垂直镜像; X; y2 X. \5 s
1:水平镜像7 h k# X. x! H9 z( s
2:$2400镜像; P W9 ?: O( X( L; c$ ~
3:$2000镜像. R4 u7 o: X( w9 ^
; m+ [. _7 x, D2 \* g( F$A000: 选择8KB的ROM存储体映射到$A0002 E4 l" l2 j0 Z% v7 y
2 T4 L% h- ]( a, ^1 u$B000: 选择1KB的VROM存储体映射到PPU的$0000(低4位)
3 y+ c# ?. s: m9 F) {( D& g$B001: 选择1KB的VROM存储体映射到PPU的$0000(高4位)1 ? O6 d, Z" ?1 f. |
$B002: 选择1KB的VROM存储体映射到PPU的$0400(低4位)/ F& x! o$ v) j, V8 G9 }6 r
$B003: 选择1KB的VROM存储体映射到PPU的$0400(高4位)( u7 t1 Q" U% L+ G+ c R C" ^
( s ~7 @3 f+ t D$C000: 选择1KB的VROM存储体映射到PPU的$0800(低4位)4 Q5 B/ v! m( [3 n9 R w- e
$C001: 选择1KB的VROM存储体映射到PPU的$0800(高4位)
# I- Y" I& I* H, R+ f$C002: 选择1KB的VROM存储体映射到PPU的$0C00(低4位)
2 Y N. X3 e! D: r$ Q1 M$C003: 选择1KB的VROM存储体映射到PPU的$0C00(高4位)+ U( h, O! S7 n- M8 o0 J
6 d5 R, r1 c' p. m" j$D000: 选择1KB的VROM存储体映射到PPU的$1000(低4位)
, Q+ M5 ?# c: e$D001: 选择1KB的VROM存储体映射到PPU的$1000(高4位)+ [. j/ K9 x& g( x( `4 F ^8 b
$D002: 选择1KB的VROM存储体映射到PPU的$1400(低4位)
, A( `7 n+ i" y) E$D003: 选择1KB的VROM存储体映射到PPU的$1400(高4位)! M2 t: n* E& ~- y: W V
6 D# }9 }* Q+ F5 u+ c3 x2 x5 l
$E000: 选择1KB的VROM存储体映射到PPU的$1800(低4位)
; E& i$ J& f6 Y2 A6 @+ \4 C: a$E001: 选择1KB的VROM存储体映射到PPU的$1800(高4位)9 |' z# d: a8 {& `& z9 ]
$E002: 选择1KB的VROM存储体映射到PPU的$1C00(低4位)! N' g& _( D& f7 p7 f" r1 e
$E003: 选择1KB的VROM存储体映射到PPU的$1C00(高4位)
5 G1 E" S2 X/ y3 a' n, z1 p
! @9 q1 f! N5 X再看看Mapper 4文档:
5 ^2 {2 ]" \, N: |6 i( O5 f5 D3 Y2 w2 I/ _
Mapper 4
" i5 P3 y: F& C% `# @
+ g+ X* M1 i' R( J1 `& ~! f" P! p$8000: 模式号( `1 w% ~: V. n* { w! H
位D0-D2:
) w7 f- X) g0 l! d0 N5 P! M 0:选择2KB的VROM存储体映射到PPU的$0000* N+ C& p* W2 \( T' T
1:选择2KB的VROM存储体映射到PPU的$0800
9 ^$ d) L4 j$ _; N3 x 2:选择1KB的VROM存储体映射到PPU的$1000
- @4 }- O% ]# m) ?0 C; j 3:选择1KB的VROM存储体映射到PPU的$1400
9 I! V" f5 o% |) r) Y* G- a 4:选择1KB的VROM存储体映射到PPU的$1800; _+ U% p* C3 l8 d B1 h
5:选择1KB的VROM存储体映射到PPU的$1C00- U3 ~) C5 Z! `6 U5 f
6:选择8KB的ROM存储体映射到$8000
, S- x8 ^' V* p& w8 _1 ^ 7:选择8KB的ROM存储体映射到$A000
5 e& u$ c) f% e$ i0 E0 P 位D6:
7 F/ W b# R+ E8 \% A' s: U 0:允许擦写$8000和$A0001 {6 ]: k t0 O: G* H
1:允许擦写$A000和$C0005 @* C( I3 n- l6 v4 I8 ?
位D7:
9 _& g' r$ z# z" K3 g4 v) j% U 0:模式号D0-D2使用普通地址
- j/ [; A; |4 u) E 1:模式号D0-D2地址异或$1000
9 V, S1 u" I$ D) s! U4 P T* [0 @% U, w- r2 v, N
$8001: 模式页面号
& Y9 L/ G) z# j8 d$ s; w" f `" M7 a 写入一个数(00-07),切换存储体到对应地址! a+ I, e2 }, @" P4 G; G8 [/ }
& H, I* g+ M* o7 Z/ }8 D
$A000: 镜像选择
R) c+ I" i; a0 V 0:垂直镜像
* A$ F; R% g0 j2 L 1:水平镜像
( F+ L, h' n5 I4 ?2 u4 G- H0 Y2 N2 [" x, W1 k
$A001: SaveRAM 切换
/ o; S1 ]" V& r, t2 I2 s0 D7 z* T H8 g9 X 0:禁用$6000-$7FFF( d; s6 s" M/ }( a8 O0 V5 Z
1:启用$6000-$7FFF
/ b; ~. x& F0 K3 [4 {) s( y; E1 `7 H& p Q
$C000: IRQ计数器" Z9 Q1 k8 I U- O) x4 x
IRQ计数器的值存储在此处
& w$ n7 U: q) ?# G5 C% M8 p
8 q1 d0 Y3 c l6 b$C001: IRQ暂存器 w4 V' d# s9 R+ D$ L$ y% p) j
IRQ暂存器的值存储在此处
4 K7 }$ M2 Q: O7 v' S& g8 W' M7 X" @
$E000: IRQ控制计数器02 }" I- }" e0 e1 e4 ]1 ]( X
向这里写入任何数来关闭IRQ,并从暂存器中拷贝数据开始计数,进入IRQ
# T5 f! L+ y7 f/ ?$ \2 L% k! B7 ~2 j' g) o/ ]" {
$E001: IRQ控制计数器1" A7 p& F+ k; ]4 _ v8 t8 n) s
向这里写入任何数,允许IRQ(退出IRQ,允许下一个IRQ进来)
; p1 r- ]7 K, g0 ]( i+ W% L3 ]7 m- z* ?/ _# [
$ J8 d9 e- l* s+ L! ]
转换思路:
) R! z& A/ W! Q1 P6 k" ?* `/ r将Mapper 23 的切bank 方式和切VRAM的方式修改成Mapper 4 的方式。
4 t; n2 g* B8 Q- L) {
8 S1 I& Y; D0 W( S) s; A修改实例:" a3 R: ^7 l9 Y0 y" o) }7 s R
Contra (J) 256KB Mapper 23
H/ a# ]& w1 H( I" p* _工具:
5 N- k" P" b) R4 R Z1.FCEUX 2。2。38 M: W7 _' ^- H( j
2.HXD
4 M- |# V- D! i) L! f先来看看这ROM的切bank方式:- J# l8 {! [7 J' @8 |
F989:AD 00 80 LDA $8000 ! w, |1 K6 M6 B
F98C:8D EC 07 STA $07EC! t3 c1 R7 M9 D9 A) r
F98F:8C 00 80 STY $8000
1 T' P( a3 m( e! D0 R6 RF992:C8 INY( ~ }* q" Y- h& K* H
F993:8C 00 A0 STY $A000' q3 O; d7 C$ o, N! T5 L
F996:60 RTS6 |/ J: ?7 m* b8 d; g# t
" l/ b2 J1 L% D. e6 c8 ^再看看它的切VRAM方式:7 x* ~% N6 R( T# w4 L1 a! O
FACE:AD F0 07 LDA $07F09 p% M$ x+ I' O8 j y; [$ c1 U
FAD1:8D 00 B0 STA $B000
6 D' {4 r- f: {) s" M/ PFAD4:4A LSR' }) K. I8 V7 a7 `1 j6 o, b( I
FAD5:4A LSR7 E6 L# o5 a% i4 }# V
FAD6:4A LSR+ o& }' v4 p3 ~9 p( L2 g& v( F
FAD7:4A LSR6 W! J) s% F# i- |; L* ^7 o
FAD8:8D 01 B0 STA $B001
$ O' ] A( y7 h6 x5 l1 [+ t3 X6 RFADB:AD F1 07 LDA $07F1
: H: n3 y% N$ f5 hFADE:8D 02 B0 STA $B002. y: ^# q# d l6 L$ b
FAE1:4A LSR
7 g% B9 F2 G5 R7 b+ C6 M NFAE2:4A LSR
) B& i9 J4 [7 |! H% X- ]( q- \FAE3:4A LSR
; T# E2 I; N5 t7 R* N5 ]( _% ?FAE4:4A LSR3 n% U4 S% F6 |) e! d
FAE5:8D 03 B0 STA $B0030 i& O8 W" v: F* T
FAE8:AD F2 07 LDA $07F2; \, F1 O5 ?% W: a+ b8 y; y
FAEB:8D 00 C0 STA $C0009 E& l& d- u$ z/ x2 w
FAEE:4A LSR
% h1 w8 `1 ^' J( F) g; d$ ]7 NFAEF:4A LSR
" c3 I; ~4 V4 c6 \6 g9 U$ J2 i6 MFAF0:4A LSR* r6 h; U9 t; j
FAF1:4A LSR+ R9 ?0 Q/ }4 C8 n- K7 d
FAF2:8D 01 C0 STA $C001
9 \, @' p. S3 |; UFAF5:AD F3 07 LDA $07F3
3 t' S: _& h) Y, `FAF8:8D 02 C0 STA $C002
, F6 H, k9 T( F* p; FFAFB:4A LSR- B0 z- |0 H$ V6 Z& M, z
FAFC:4A LSR/ X% f: |+ _3 X+ ?. w' B$ G0 ^
FAFD:4A LSR
9 S$ n A& N9 f& ~6 m" T7 x d' R5 xFAFE:4A LSR
1 }& e X/ e# |8 DFAFF:8D 03 C0 STA $C003" b' \) M# X: O* W! }/ M
FB02:AD F4 07 LDA $07F4
% s/ v/ i8 ^! n% e) jFB05:8D 00 D0 STA $D0007 o2 z' N% t2 `- U1 f
FB08:4A LSR
+ \+ j' h* D2 R# v8 ZFB09:4A LSR; r" q7 L. ^/ ]& S9 Y( ^- ]
FB0A:4A LSR
, B0 G) f& r4 G; J' j4 mFB0B:4A LSR
* a) @6 x( u! t. J5 y# B( u, AFB0C:8D 01 D0 STA $D0012 y4 H$ t1 u! x- q* f/ g4 C/ ~
FB0F:AD F5 07 LDA $07F5. N/ k$ ]: U" l4 a# z$ @) u! A
FB12:8D 02 D0 STA $D002" I9 E$ A5 [6 Z$ e: m
FB15:4A LSR
0 S, W! l6 L' Y9 b: p8 SFB16:4A LSR
3 m& ~5 \, {! T3 }' I- nFB17:4A LSR
8 q/ H8 E( \2 _FB18:4A LSR# P- h+ X4 T' h$ E3 h) R
FB19:8D 03 D0 STA $D003 F9 H ^: [! k! N4 C: L
FB1C:AD F6 07 LDA $07F6% W% B. g7 t/ Z A5 D5 w
FB1F:8D 00 E0 STA $E000# a: N' z: A! k* H! T- E
FB22:4A LSR
! f. W; L( }# T4 }: j- jFB23:4A LSR: q5 P, I2 s8 i7 e: A
FB24:4A LSR' \, S5 S1 g6 i1 ~. ^, A# n& l
FB25:4A LSR
6 Z+ w' h l( A$ EFB26:8D 01 E0 STA $E001
j. k J& L. n4 s* h5 k/ q( XFB29:AD F7 07 LDA $07F7
) R2 P% p& l5 b1 R3 v% U! `2 l0 nFB2C:8D 02 E0 STA $E002& I9 b- N) {6 `/ h
FB2F:4A LSR6 w/ S6 k. i' X( X7 o' T7 T3 V
FB30:4A LSR
% y% \) G6 @% r, ^+ NFB31:4A LSR, p$ t0 t3 b% k0 c6 L% ^8 ~/ d1 n
FB32:4A LSR; I6 L8 T J$ b9 ]% W
FB33:8D 03 E0 STA $E0031 S6 P8 L6 y6 h2 X
FB36:A9 00 LDA #$00
0 j6 ]( z2 G) D8 Z9 nFB38:8D 00 90 STA $90006 C3 ]7 w+ F# c; I' H [
FB3B:60 RTS
" g, W0 O6 ^$ C$ I& S
: j, `1 Y. u3 A' [0 I6 n接下来修改切bank方式:4 M* `& k# M# ]( Y; k* A
FB2B:48 PHA
- ~9 q5 C% }- N% \% k' @4 q- \FB2C:A9 06 LDA #$06
/ ]: y& G" q) ]' {& O% \+ [FB2E:8D 00 80 STA $8000; a9 L" o& y7 K" ^8 @, L# R' e
FB31:68 PLA+ ~+ x8 d$ I& b! h4 z m( j" }; W5 D
FB32:8C 01 80 STY $8001
% |* a1 S$ K5 Y$ \FB35:60 RTS
# S3 g: I; {5 i0 |: j% y
' }2 G/ f& T6 ^# Y. `0 P! ~FB36:48 PHA F. e) R- V$ g# ]
FB37:A9 07 LDA #$077 ~, X' a; a& H
FB39:8D 00 80 STA $8000 = #$14
0 @' m. J& B8 HFB3C:68 PLA
" E5 f9 ^( m, WFB3D:8C 01 80 STY $8001 = #$1D
9 ?4 S+ m# z- ?, m+ g9 `& ]. VFB40:60 RTS" [; a/ p3 k3 W0 G
+ |9 S; [# I5 w" N- f' ^7 ]- D还要把原ROM的对$8000和$A000进行写入操作的程序修改一下:9 |# k: m3 {4 Z3 y7 s4 Q
F989:AD 00 80 LDA $8000 : \/ d" H: t, I) {& q
F98C:8D EC 07 STA $07EC
1 v' R1 H' e2 c9 j7 U- {( K- e6 }F98F:20 2B FB JSR $FB2B) M; p+ x6 I, X, t- {+ ?! e8 C
F992:C8 INY5 I7 M8 ]3 e' G' _! n4 A
F993:20 36 FB JSR FB362 q& Q ]- n2 A& O- t% ]+ I, X, k
F996:60 RTS4 X3 u. B! R( a: ?, `
% ~' G/ J' {' q. M: d; n
再修改切VRAM程序:& m& q. O( \' K8 x1 r; l/ m
FACE:A9 00 LDA #$003 ^0 b8 `6 R) ?5 b! F9 F) x9 j" s
FAD0:8D 00 80 STA $8000
) x! h- x. f) tFAD3:AD F0 07 LDA $07F0
0 ~0 Z5 a9 H- V9 o* QFAD6:C9 01 CMP #$01
- K% ^: E" Y% EFAD8:D0 11 BNE $FAEB
1 W5 b( {) Y6 d2 xFADA:AD F1 07 LDA $07F1
3 Z7 S0 @( X L2 b* u Y+ PFADD:C9 04 CMP #$044 K+ B- _: Q7 f1 |# J/ L
FADF:D0 04 BNE $FAE5
0 O' t4 H8 N8 o9 kFAE1:A9 80 LDA #$801 ^/ R4 ?% ^ V+ x. r( g6 k
FAE3:D0 06 BNE $FAEB( N5 O/ S+ H% Y, w
FAE5:C9 05 CMP #$05
1 n9 c1 n7 M% D; b7 Y7 M" RFAE7:D0 02 BNE $FAEB
5 ]2 F% a6 T4 Q, J& v3 t; ]3 TFAE9:A9 82 LDA #$82
4 {/ j8 Z6 x1 }" k7 k5 L _. t$ ]8 OFAEB:8D 01 80 STA $80013 W/ e. M. M; b2 x; X# Z/ }# X
FAEE:A9 01 LDA #$017 V4 K2 r6 p* e
FAF0:8D 00 80 STA $8000
, E, o" K5 @3 `8 l5 DFAF3:AD F2 07 LDA $07F2
7 I+ U; x6 ?- C. d s" [& I- EFAF6:8D 01 80 STA $8001
. N' ?; B, B) s, ]+ WFAF9:A9 02 LDA #$02
9 Y, [( y2 L& bFAFB:8D 00 80 STA $8000
: l s# |* Y, {( G1 j* O9 q" _/ BFAFE:AD F4 07 LDA $07F4' j/ p0 r; O& z p" K! {) i9 i
FB01:8D 01 80 STA $8001% e6 r( |( T4 b; B0 \9 Y5 d7 x
FB04:A9 03 LDA #$039 s$ _4 f- M1 r0 W" P+ ]5 O
FB06:8D 00 80 STA $8000: W( D0 p7 x( l- [' f
FB09:AD F5 07 LDA $07F5
. k" V% K( s, iFB0C:8D 01 80 STA $8001 N5 T! E2 s: s. l2 \- t
FB0F:A9 04 LDA #$04
& n/ h- U. U/ @$ z( }FB11:8D 00 80 STA $8000
3 M1 r5 s2 |( G* r1 p4 {. jFB14:AD F6 07 LDA $07F6
c6 @; u/ S) TFB17:8D 01 80 STA $8001
5 w9 _) R. Y5 |3 q( z. D+ o% OFB1A:A9 05 LDA #$05# S- [4 Z# k( Y, C
FB1C:8D 00 80 STA $8000
1 f6 h) k% Q! O; E. AFB1F:AD F7 07 LDA $07F7
U& Y8 C7 z! p/ ]) c aFB22:8D 01 80 STA $8001
/ m$ p/ k9 }. o- FFB25:A9 00 LDA #$00
% ] T. B& g: R, AFB27:8D 00 A0 STA $A0007 f) y3 P$ P. W& w/ n7 a- i
FB2A:60 RTS
# R- N5 D, C: n# f' Q- R) c4 a. w" @/ F0 ^/ w" s9 G9 A
然后保存文件。% q% u: }# ^0 n; }* Y5 b, w
使用HXD修改文件头:
$ W ^7 q) [3 Y将Mapper 23' z7 Q% C$ k' {" |" ]3 U& W" Z2 M4 ?
06字节的高4位是Mapper号的低4位) U) e9 r$ U1 x( C4 {3 x9 A
07字节的高4位是Mapper号的高4位
" R( J5 o/ n4 V* [组合起来就是0x17=1*16+7=23
9 j. ?* e; q1 s
) N% a# W% }, P% D修改成 Mapper 4
7 s2 h. V: _! g$ @; A
$ Y7 e' [0 W, P2 R4 U' a
8 c3 M& G9 _& i# t' y
5 {( l) A" a" ~% A* t2 U& q+ a再次打开文件:( D0 O9 f1 |- G4 Y

7 b* I% @2 c6 V* `4 X x可以正常运行
; u6 n0 ^; J! E; E0 q3 q" n+ {% L+ t5 E通过全面测试,发现出现精灵错乱:
: H) W! u0 ^9 X: |第1关:6 t' E N3 R% P$ g) A5 e2 V% ?
9 O5 \5 U {1 X5 D4 y0 ~: s5 s
$ V2 x. C/ l+ w1 U# ?% L- r
第2关:
: e, m5 r' _2 s ) p7 Y* n4 E0 F. |' n! Z" z/ c. W
任务失败后:
9 H( O Z. j" v, z" ^: G/ R0 [ $ ]2 b3 w. b' a
通关后上飞机画面:5 n$ W3 a7 s% S

$ U1 A+ X& I' b2 U& ?8 z: g- h这是为何呢?: [) }) P4 A4 [% z' K
这是因为Mapper 23 中精灵VRAM切bank是一次切1KB
5 N+ |: g* c. `+ E2 G但是在Mapper 4中精灵VRAM切换却是一次切2KB,而且忽略bank号的D0位
% l. d+ @ h, E! R; _/ g7 v! @( Z+ q比方bank 0和bank 1是同一个bank,同理bank 2和bank 3是同一个bank
4 K. P! i! c: B* E( H也就是说' d2 z; M& M0 d2 [1 J
Mapper 23中的VRAM的
3 Z; d# C/ _' p! V1 g* O+ `$ [bank 0,bank 1,bank 2,bank 3
7 n9 v2 u. d3 g4 |在Mapper 4中对应的是3 Q7 C" u3 S' B- w# T
Bank 0,bank 0,bank 2, bank25 }4 W% N) T% h1 [/ @2 C& g
然后查找原来的ROM的切VRAM的程序:/ E3 x" ?. J4 S8 k1 e- f, B
知道是从07F0-07F3切到精灵VRAM的:% k8 s; q# i0 Y& u6 R- K$ Y
如图所示:
) k5 C, S* n% g + C5 b. S$ ^5 i( Q
 
# _7 q; q+ b/ m1 l: m/ j4 v* P2 \作为对比,左边是原版,右边是修改。
+ c; ^- S/ s0 D- d8 R8 i0 ?接下来是完善VRAM切换带来的问题,因为Mapper 4只能切2KB的bank,所以我们不能通过切bank程序解决问题。/ y, q6 Q9 e1 m. P- [6 e% |
通过测试知道1,3,5,6,7,8关的精灵VRAM排序如下(07F0-07F3):, P6 X" ?: N' R3 }; d
01 04 06 07
( N' t8 c- h/ n$ V第2,4关如下:
# L. d. M6 g0 H" T# z01 05 08 09$ M; n' G( @0 S; c' i M
任务失败时如下:
! l2 B) m _: n- W0 |5 y8 K/ b) m# H32 00 00 1B
" ~2 F X; t3 G T# z其中任务失败时对应的VRAM是07F3的1B,只要让07F2为1A或1B即可:7 m5 T a7 r* b# v. }6 K* O
通过调试找到对07F2写入数据#$00时程序如下,于是修改C7E5的值为1A即可:
1 I( ~. D5 }; S" n2 B3 _, W1 V
% Y3 h# ^& J! ]; d8 I, b3 v转到ROM地址:
+ a9 P8 L. N i6 e3 e0 s7 a ( r8 v8 K7 S, G. \+ d( B7 r
修改数据:
0 C6 d) J; n3 O/ M% |
7 ~% w& `/ ~/ R# _0 ?) M重新失败后可以看到修复成功:
|( s$ X% O5 P$ O$ [* ] 1 s/ W; }& n1 W- d K
接下来是修复正常进行任务时的精灵错乱问题。8 r% \2 }8 @! x# |1 C: H) m( T
首先运行Mapper 23版本,在1,3,5,6,7,8关任意一关的时候,将PPU导出来4 R! W1 L, H" P- O. k
6 j6 C* T9 T: h2 h3 P; \
; g5 ]6 y' q! g1 v) l+ D6 b

! |" t- z0 B& @0 i' {
: e) d) a6 G& L* L' R/ `然后用Hxd打开修改的Mapper 4的ROM和刚刚保存的PPU的数据文件:$ X% v5 F2 A( Z, x* H9 `
% k8 f3 V9 U, a
在ROM文件头第05字节改为0x20:
+ `# Z( K& ^; m8 K8 q. ?
6 \1 m3 n# p: {9 r然后转到文件末尾,插入0x20000字节空字节:
* A) q7 X* |" S+ Q; U# S
# E/ P0 ]5 Y! \# U
9 t5 _& M! r( f1 f3 w 5 H- I7 q( G ]% `/ t$ ?! }6 t" v9 Z
. y8 ^, J0 v- D, L4 `# E
然后将第1关的PPU数据的前面2KB数据选定:/ o4 L+ R4 h l+ }

' [0 m3 ?: B3 u, d . A- E+ c/ Z- i- v. D7 w' f
' x5 l# L; `4 h0 S, h; E! k
复制之后以覆盖方式粘贴到ROM的40010,同样把第2关的PPU数据的前面2KB以覆盖方式粘贴到ROM的408104 x o( w3 o5 S8 j7 C! u, t5 i

# _8 j$ R) \0 Z* f6 R; w% \3 c: O然后保存文件:2 w$ d; @; K" M" W- K7 [

( J# P+ q1 e+ N; w最后用FCEUX打开文件,添加07F0-07F3的写入断点
4 h9 P6 g8 J+ I
6 f2 J1 d5 n. T4 f8 @* }( u. |地图预览后即将进入第一关画面时程序暂停了,可以知道此时准备将C793的数据写到07F0:, Z. N1 \ S3 I2 c' M& [7 L9 C
' M2 K: i$ T% ^; F$ s* }4 c4 H
测试后知道将C793-0796写入到了07F0-07F3:
6 s1 w0 @ w% V1 p7 f6 b5 e同理,经测试每4个字节一组,一共17组,其中01 04对应普通关卡精灵以及其BOSS关的精灵VRAM的bank号,01 05对应2,4关卡精灵以及其BOSS关的精灵VRAM的bank号,再加上一个通关后跳上飞机那段动画的精灵VRAM的bank号。
3 V1 w* M* k# R2 W* q0 N$ l$ h5 Y! a6 C6 l

' T6 _# Y! Q7 o/ |9 v& \1 l) }然后将文件中标记的01 04修改为 80 04,将01 05 修改为82 04即可:0 W) N, d1 `1 g. P' G# j
9 |$ k2 m2 P) J- p
保存之后重新运行后效果如下:
' d8 X. A$ D+ _" T, ?
" `* T2 x& J, X: I& V* h 9 Y, S5 h. i8 {9 {+ L7 |' K: b

: K2 ^# e7 C# ?当前使用的是FCEUX模拟器,如果用NEStopia玩的话一开始就死机了,这是因为这个ROM有文件保护吧,它会往$6000里写入数据:' D; T( F7 j9 _8 S/ d
* ?' L8 u, C F1 G% \! [ v
F863:A0 03 LDY #$03. Q* }0 j8 i6 D. c
F865:98 TYA" n) Y7 V8 N! W. O& v) m
F866:29 01 AND #$01
, C4 u- u; P3 _ u, }; q3 WF868:8D E9 07 STA $07E99 I( @ y% F0 G: m& r6 H( v' ^$ L/ R
F86B:8D 00 60 STA $6000
% Q1 j. }# B$ h* i3 R0 {0 sF86E:AD 00 60 LDA $6000) ?! i& w, M) S
F871:29 01 AND #$01
P- _6 x, \1 u9 |8 mF873:CD E9 07 CMP $07E9
9 H/ t" D. l- x% Y {F876:D0 05 BNE $F87D' `5 N7 i( m; b. S, S6 Z
F878:88 DEY
5 h( }% P. T. n5 Y6 E3 iF879:10 EA BPL $F865
$ C7 B4 S2 ?# O1 _9 r# xF87B:30 03 BMI $F880+ N$ o6 o7 C5 V8 q
F87D:4C 00 00 JMP $0000
+ T4 V* W2 ~* a" b$ gF880:A5 1A LDA $001A% N, Y; x5 s/ H+ M, ^
F882:65 34 ADC $00342 V* t8 }* L8 S+ A; g
F884:85 34 STA $0034
5 z" q3 r7 Y! @. m8 E5 f' r7 k/ TF886:4C 80 F8 JMP $F880
6 O9 s- E) R& R0 V. E9 [$ j _先取Y值=#$030 U) w0 G' F* r8 I
与#$01相与后得到#$01
& J1 L$ J. \% ?* @' p( {" U写入到$07E9
* y. Q! b1 Q' @# y, o+ t写入到$6000( w" y7 o6 j" Y, f
再读取$6000的数据和#$01相与后和$07E9的数据比较4 {- R5 E* Z8 W4 E3 O6 r3 T! S
不同的话跳过5字节( i U7 o: @& @& T/ v& E) M3 f
否则Y递减
5 y) W4 g& A! \' Q# @( [8 B为正数就跳回0x100-0xEA=16字节
8 m: ]8 W. P& T" L: C5 O为负数就跳过0x3字节* Q6 `! s( w, r$ C* g! W; }
跳转到$0000(简直没有人性了,跳到这里死机,真想得出来)* k" L3 K \" J, T U0 }5 Q3 |2 |
. W5 l- I7 o& {
正是因为这样,NEStopia运行FC时,6000-7FFF默认是不可写的,必须在ROM文件头第6字节的D1位置1设置ROM有SRAM,对于Mapper 4,还需要向$A001写入#$80来启用SRAM。( }% W2 G8 [2 |) p) S6 P, d
由于$6000不可写,因此想$6000写入#$01后$6000还是#$00,之后读取$07E9的#$01与之相比当然不同了,于是直接跳转到死机程序了。
; X9 \- r) F7 E4 Z* {$ \' C4 `解决方法是把ROM中的所有的AD 00 60 29 01 CD E9 07 D0 05 88 10 EA 30 03 4C 00 00
% A A! l3 _/ o( F' {6 }9 w* ?中的D0 05改为D0 00,然后保存即可。; D& P, o+ _! c1 Z% ?
测试完美运行。
5 B! m: I7 q, U: w
8 h. Y1 b% N+ V6 f' ~4 c/ }! A1 ~& n- ^. ?
教程到此结束。4 K9 B( }" a. F0 V p
+ i3 q! f7 e _/ f |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|