|
本帖最后由 yandagui 于 2017-4-16 19:06 编辑
! S( B0 o) B0 R: \; y3 s4 M! V7 h( h- j
Mapper23转Mapper4实例教程, ~& Y# v, U9 p, B) t4 k
% J6 P8 p3 D" z5 FFlameCyclone 2017.4.14
. a2 g5 g$ k0 l' K
* a1 q6 u- Q% a; X- m. ]% D先看看Mapper23文档:
5 m8 x$ ]% P' \) R
% _1 u6 V; \6 V5 [Mapper 23
8 @8 e" I) P) d+ u8 z8 h/ `: w8 |1 A
$8000: 选择8KB的ROM存储体映射到$8000; D+ |7 a e7 F2 }# n
; k& J% o3 w3 [. N: B. O" a$9000: 0:垂直镜像
0 X" w* R, f, x) T% T) X$ b 1:水平镜像1 b8 O6 r) q+ e9 A. C/ c
2:$2400镜像* k: q6 b( N/ ^* O% N$ v+ @
3:$2000镜像
# _) i6 t4 d% H/ ]9 Z# L2 `& f g9 Z1 x4 R( f
$A000: 选择8KB的ROM存储体映射到$A000
! W3 G, @6 q& }0 U1 y7 x( ~) g+ w# W7 m4 Y* {4 _4 E7 h* `5 O" n, N
$B000: 选择1KB的VROM存储体映射到PPU的$0000(低4位)# d2 l7 t, G" ~+ |9 I0 n2 _5 b
$B001: 选择1KB的VROM存储体映射到PPU的$0000(高4位)4 S8 Z q) b- g* ]) f( ]4 E
$B002: 选择1KB的VROM存储体映射到PPU的$0400(低4位): `. Z3 F, q3 P$ U
$B003: 选择1KB的VROM存储体映射到PPU的$0400(高4位)
& r3 E9 L8 @: N9 Z4 L# ^7 W7 j! T, C; @6 p) E
$C000: 选择1KB的VROM存储体映射到PPU的$0800(低4位)
4 n0 Y' `$ C4 z# V, n, o. a, k9 q$C001: 选择1KB的VROM存储体映射到PPU的$0800(高4位)* N6 }) y; c6 R5 d: N9 R' E
$C002: 选择1KB的VROM存储体映射到PPU的$0C00(低4位)# s* D9 T; G) i0 T( T ?
$C003: 选择1KB的VROM存储体映射到PPU的$0C00(高4位)8 e, H7 P7 D% {' `7 @" A# L
7 |! @2 m- ?8 W
$D000: 选择1KB的VROM存储体映射到PPU的$1000(低4位)7 }7 F) Z/ b; I
$D001: 选择1KB的VROM存储体映射到PPU的$1000(高4位)
: E& C2 L7 L! b! E( v; t" t- U3 _% [) d$D002: 选择1KB的VROM存储体映射到PPU的$1400(低4位)$ {$ F% n8 e9 i" N- U0 ?
$D003: 选择1KB的VROM存储体映射到PPU的$1400(高4位)
/ B- f+ F* `0 r3 F3 B: @6 v, d- h. ~% p
$E000: 选择1KB的VROM存储体映射到PPU的$1800(低4位)
$ v; z0 m! ~ m" F( R$E001: 选择1KB的VROM存储体映射到PPU的$1800(高4位)
6 [ H' X# D0 s% k9 N0 @6 ], c7 ^) N$E002: 选择1KB的VROM存储体映射到PPU的$1C00(低4位)
* f: L+ R& Q* p9 p Z) J6 n$E003: 选择1KB的VROM存储体映射到PPU的$1C00(高4位)! Z/ M4 D6 Y9 }2 v4 W
) W* N" X2 z8 y4 x& G) J再看看Mapper 4文档:
* Y, X5 F2 C3 D; j$ o- @3 c: N8 y* E5 b7 T' j
Mapper 4
# a8 b- D7 F" C5 n3 E
" `( F s. _( b1 z8 N2 _: j/ ], T$8000: 模式号
6 i. f+ C1 v' D7 s: w 位D0-D2:( r6 t& w; E# g- |) u
0:选择2KB的VROM存储体映射到PPU的$0000" E1 U3 j D' o2 S* ]- v2 M
1:选择2KB的VROM存储体映射到PPU的$0800
; ~ {9 s9 [# X 2:选择1KB的VROM存储体映射到PPU的$1000
* y4 u6 l6 J( P4 a; Y2 A% R 3:选择1KB的VROM存储体映射到PPU的$1400
% W8 k$ K1 ~! L1 j# m. q" ~, Y 4:选择1KB的VROM存储体映射到PPU的$1800. b0 h- z% T) w+ B/ [
5:选择1KB的VROM存储体映射到PPU的$1C00
2 L- J9 Z' G+ ^% z+ y! Z 6:选择8KB的ROM存储体映射到$8000
9 l2 w* ?+ x6 [* ?) R) P 7:选择8KB的ROM存储体映射到$A0008 e' @; z0 [9 u: p4 K$ H/ |* t2 X
位D6:
# A' t/ h( K- i6 O; u! X+ \ 0:允许擦写$8000和$A000
" Z w/ m0 [8 ]3 Y5 e! R. a 1:允许擦写$A000和$C000
3 ~' v! x6 {, {* x9 p 位D7:
! X0 w4 n7 m) C/ ~% w1 c) C 0:模式号D0-D2使用普通地址
# H0 ~: Z! b" H; _: Y/ l* `2 @ 1:模式号D0-D2地址异或$1000& S: _8 u+ |5 a: C- ?
8 ^' a6 j7 M( i; L$8001: 模式页面号) O4 e& p( F0 }. I
写入一个数(00-07),切换存储体到对应地址8 {* n4 B) |3 {1 H
5 @, q- K- j( H8 p! u: O$A000: 镜像选择0 g: V& c+ t, v+ J% i1 t1 K
0:垂直镜像
m9 H) A* }, A' B5 U+ b; S 1:水平镜像
. f2 o" Z& x8 A1 ~
0 c6 s" Q1 m# L+ h& b# Y0 l1 h$A001: SaveRAM 切换
7 q5 d' U/ N$ s 0:禁用$6000-$7FFF
7 H$ j1 O1 C( O2 M4 W 1:启用$6000-$7FFF! D4 i" T1 Y" U4 m9 Y, O; e
* ], s4 i& A7 `1 e$C000: IRQ计数器
5 d: @) i$ R- j2 a IRQ计数器的值存储在此处
, S5 [: f) Y* O' S: q
/ ?7 F' I$ i. ]' N% F9 `$C001: IRQ暂存器4 o$ a) s9 z/ {
IRQ暂存器的值存储在此处
4 ]9 Y: c9 F( N& w* I' s9 C. x5 o: Q) C5 W5 J* C; p' R4 r
$E000: IRQ控制计数器0$ K' b# U; T/ k$ D. M
向这里写入任何数来关闭IRQ,并从暂存器中拷贝数据开始计数,进入IRQ" S4 X: F8 H2 G- G& s' I
- l" s; ?, `- U$E001: IRQ控制计数器15 `' e% O, o" l( R0 E G4 V
向这里写入任何数,允许IRQ(退出IRQ,允许下一个IRQ进来)
" M& E5 v. n* {, l3 i
! n8 s, F, o7 j
; v: p$ o* q2 G转换思路:
/ M* a2 o) m5 B- }" @5 w将Mapper 23 的切bank 方式和切VRAM的方式修改成Mapper 4 的方式。. n& u% d( P6 v' ^
2 x8 W% F* R6 _+ b修改实例:# Y. X% a* U3 Z9 V9 k7 K F1 S2 z
Contra (J) 256KB Mapper 23, W8 K. `, [# Y z! Y, i
工具:
! I$ E/ p8 b' ?1.FCEUX 2。2。3/ o. z0 l# j- J+ |9 n
2.HXD
! K, B+ _/ F8 i) J }% [2 v) Y$ _+ f先来看看这ROM的切bank方式:
+ O% Y) r) \! h7 R7 X# G- JF989:AD 00 80 LDA $8000 $ n" W& `2 M, X. X, C6 R7 L
F98C:8D EC 07 STA $07EC! c2 d7 R. o; R+ f5 r! C8 e
F98F:8C 00 80 STY $8000( \, V% q b0 T% _
F992:C8 INY
+ d1 l9 r6 J+ w) W( c6 S, M6 DF993:8C 00 A0 STY $A000
) c$ |. l- G& F2 P% _F996:60 RTS
6 K" Y, j& o v! v1 [" [' A
& F3 {/ m2 Z6 v5 o# g再看看它的切VRAM方式:. w* Y- q& G r3 w8 I8 X
FACE:AD F0 07 LDA $07F0, k4 b! `. u# L( b6 }% s8 ^
FAD1:8D 00 B0 STA $B000
) u5 x& @' r. V# L6 ^4 _FAD4:4A LSR
7 h. e( z: {) e/ _FAD5:4A LSR/ L9 H1 q& O. [0 H
FAD6:4A LSR. j; F5 Z4 U: r1 C, i1 \
FAD7:4A LSR5 a" ]% i6 ~! s7 _5 g4 H, i0 S
FAD8:8D 01 B0 STA $B001# }2 a0 q# k+ x% m
FADB:AD F1 07 LDA $07F1" X1 y5 ~' v W
FADE:8D 02 B0 STA $B002! K9 z8 F! a! r* h0 M" H
FAE1:4A LSR
" W+ t6 O% l/ ]9 D! f& S- CFAE2:4A LSR
3 d) g0 I1 f! N8 O0 Q. l' D BFAE3:4A LSR
. g2 m2 \) U& F, mFAE4:4A LSR
" C7 [$ N% w! U% u+ s! l3 ^FAE5:8D 03 B0 STA $B003
! d# Q$ Y0 U! g8 _FAE8:AD F2 07 LDA $07F2 l6 l# W( R1 u' T9 B2 P# p
FAEB:8D 00 C0 STA $C0009 H6 r5 @9 O- N+ k8 u I2 @; c2 x9 ^: g
FAEE:4A LSR8 ~2 e& c4 L v) n$ F
FAEF:4A LSR% B( h$ r, | P4 r3 f% `, p
FAF0:4A LSR5 J, Z4 j2 s, [. F5 R3 u
FAF1:4A LSR) o8 j! E. N8 s4 j T( ~, }
FAF2:8D 01 C0 STA $C001, n/ ?5 R/ S" \8 g- w& d0 [
FAF5:AD F3 07 LDA $07F3
! l$ E- q m; kFAF8:8D 02 C0 STA $C002" x: {* i9 U7 t1 _
FAFB:4A LSR
! U* |' [" Z0 `3 C: AFAFC:4A LSR$ R, N+ l$ J! |0 p" Q; ?% H9 j* `# |$ y
FAFD:4A LSR
3 ? D5 j7 _, x, Z- e/ mFAFE:4A LSR
0 n2 M. K: ^4 I0 N& |FAFF:8D 03 C0 STA $C0036 }9 ]$ [ N6 ]8 N) J! w2 `' o! `
FB02:AD F4 07 LDA $07F43 N& f0 Q. R* s6 f' j+ @
FB05:8D 00 D0 STA $D000! ~! F+ W7 T. U, p. F; F: |8 U7 k
FB08:4A LSR" T" g( U4 k( A7 _" k. a. B
FB09:4A LSR! f$ R2 z3 {& h/ l9 ^4 v$ w% i
FB0A:4A LSR+ M8 d h4 }" w _" o" @$ d0 t7 j7 h
FB0B:4A LSR+ O% P8 f5 H; L: @
FB0C:8D 01 D0 STA $D001
3 w6 ]1 h- N6 E- F3 F/ ~& O5 lFB0F:AD F5 07 LDA $07F5* V: B: A9 [1 p* a) z
FB12:8D 02 D0 STA $D002
8 i' H8 t+ R; D1 }1 c, `FB15:4A LSR
X& o# p' Z1 k: N0 RFB16:4A LSR
% f+ a" W3 J$ z" B+ R' NFB17:4A LSR; q7 }1 A+ v" {0 C5 m& ?
FB18:4A LSR
1 \- a4 w2 W& B9 CFB19:8D 03 D0 STA $D003
( y |" `) [0 O# A" G2 C- ^9 c) h5 ZFB1C:AD F6 07 LDA $07F6
7 `* o Q+ L* m8 WFB1F:8D 00 E0 STA $E000! F+ n; ]9 G# D Q _) y7 o* Y
FB22:4A LSR
# ^$ y W K5 l0 E, t2 YFB23:4A LSR
. ~4 @0 g+ r. }8 O4 mFB24:4A LSR
' b2 Z& l* E, X4 Y* _FB25:4A LSR/ j. u+ t6 J0 s' M* _% X( }0 N
FB26:8D 01 E0 STA $E001
0 ^# w8 I4 V1 lFB29:AD F7 07 LDA $07F7
/ ^ d# [) ^+ v) Z; iFB2C:8D 02 E0 STA $E0029 U* m* L* @- y0 p& _8 \% u. A3 @
FB2F:4A LSR
. {+ X5 u1 t* n9 i6 N7 ?% @* gFB30:4A LSR
9 G2 W) a( V' V( i+ GFB31:4A LSR
& y. o- _# `# Q! d. O h5 _FB32:4A LSR
" S& X% E# z" O0 v( m8 M( P1 HFB33:8D 03 E0 STA $E003
( s) ~% G) E: X2 h/ H7 c* d) p. YFB36:A9 00 LDA #$00* a0 ~9 v3 O, }9 `! ? F3 g; @" \
FB38:8D 00 90 STA $9000. M$ g! Y' Z8 j( A1 J' k5 u
FB3B:60 RTS
! I1 K* n- X, b6 x5 K' y6 {4 }4 S/ v7 ]
接下来修改切bank方式:% q6 H6 Q, \6 E) D2 G
FB2B:48 PHA
9 b# D+ |1 \& k& B0 J8 yFB2C:A9 06 LDA #$06
+ @! f6 X, k4 F3 s7 @, XFB2E:8D 00 80 STA $8000
' \9 e5 g2 F& `' X6 UFB31:68 PLA
3 @- M* o6 S6 t! nFB32:8C 01 80 STY $8001
$ Z$ c0 y! `9 A. x( wFB35:60 RTS
/ ?6 f! j/ W: W$ |8 T5 L: G0 [: A" p# Y& }3 S* D; ?5 P/ v
FB36:48 PHA: R/ x! S3 l7 x0 t
FB37:A9 07 LDA #$07' b4 x" {: b: e0 {4 f: ^: c
FB39:8D 00 80 STA $8000 = #$14
. o8 r" Z( I9 ~* E1 `& _FB3C:68 PLA1 }+ Q; X) Q* f* y3 W
FB3D:8C 01 80 STY $8001 = #$1D4 v0 A+ h& v( d U7 B% F3 D, M7 w
FB40:60 RTS
' k% K2 D; _ [! ~
" X$ @7 B' i! ^; Y5 v4 R还要把原ROM的对$8000和$A000进行写入操作的程序修改一下:
' W3 ^2 W6 b" @1 h0 F9 \F989:AD 00 80 LDA $8000
" V( R- v4 s6 H6 q B9 b" wF98C:8D EC 07 STA $07EC
0 Q" e4 M/ b0 @& j1 rF98F:20 2B FB JSR $FB2B
9 P7 [) x7 N9 W7 c+ m+ C7 CF992:C8 INY, H! W S% F3 s5 S# x
F993:20 36 FB JSR FB36* V c' m. M! e" L1 k% j
F996:60 RTS+ L0 s4 c3 b% p. @0 c
- R" v8 S, J& B* e! R6 t3 a再修改切VRAM程序:7 d4 ^. m4 E3 r0 _) x! x
FACE:A9 00 LDA #$001 M7 G, I& q- z2 L5 v& w
FAD0:8D 00 80 STA $8000" u3 f0 d. M; e8 H2 t: G2 _. M
FAD3:AD F0 07 LDA $07F0
. ~9 X1 y& ?' K( c" UFAD6:C9 01 CMP #$01
" D* L. A0 e' D6 FFAD8:D0 11 BNE $FAEB
) s7 o% Q8 L! I* T2 SFADA:AD F1 07 LDA $07F12 B" F! C* R6 P5 `9 h
FADD:C9 04 CMP #$041 P4 L" |- R2 J, K R0 J
FADF:D0 04 BNE $FAE5
7 l0 y0 H, b& W1 a7 z+ F+ KFAE1:A9 80 LDA #$80
( B H, v+ r( g' e5 o2 x% MFAE3:D0 06 BNE $FAEB
) F9 x# D) T# CFAE5:C9 05 CMP #$05
+ S# d+ J/ W9 e1 d" F4 S5 zFAE7:D0 02 BNE $FAEB
( @* u# d" H" U0 UFAE9:A9 82 LDA #$82; S# t4 m6 |9 Q/ F' |' X# c
FAEB:8D 01 80 STA $8001! S7 y! n. a$ _6 f6 {- A- _
FAEE:A9 01 LDA #$01
. q+ `8 r+ k: w7 [ [3 [/ OFAF0:8D 00 80 STA $8000
6 w/ V& h! `' x1 {FAF3:AD F2 07 LDA $07F2
& H* _5 ?3 j3 W# T! q3 u c! DFAF6:8D 01 80 STA $8001
6 k9 x- s0 S$ r4 _4 A3 [% B4 EFAF9:A9 02 LDA #$02
0 _# z7 c3 Z$ Z7 cFAFB:8D 00 80 STA $80005 R$ K- F! y& v
FAFE:AD F4 07 LDA $07F42 _# T s: K Z# H0 i
FB01:8D 01 80 STA $8001
8 a; R) R; D5 |* X- \$ B* G, H8 AFB04:A9 03 LDA #$03; p0 m V9 c- J6 H, @
FB06:8D 00 80 STA $8000
+ H# `' K+ {6 o2 l7 P$ q. LFB09:AD F5 07 LDA $07F5+ `; U7 e4 c _# b$ f
FB0C:8D 01 80 STA $8001
! f9 i3 A! K, Z, f DFB0F:A9 04 LDA #$045 t; e/ L- e5 v1 M j
FB11:8D 00 80 STA $8000" n5 L- y: ]* S& L5 `8 S" g
FB14:AD F6 07 LDA $07F66 ^- w5 _2 g; _. B9 c* c4 z
FB17:8D 01 80 STA $80013 ^/ c3 } B% S
FB1A:A9 05 LDA #$05
( d( b* K. {1 `) O; I& e0 `FB1C:8D 00 80 STA $8000
$ f" p" m+ F% Z9 yFB1F:AD F7 07 LDA $07F70 S4 O4 Y1 S, E5 L- u) X
FB22:8D 01 80 STA $8001
) d3 I6 F" H* t' H, C( eFB25:A9 00 LDA #$001 l! E _2 k4 p
FB27:8D 00 A0 STA $A000
/ M, a3 u0 n9 B9 ]( O8 Z9 AFB2A:60 RTS: j6 c h; v3 U5 g
) P$ R+ |5 b& L, R5 W1 `
然后保存文件。
8 Y1 ]# @" x( l$ N, z使用HXD修改文件头:( b9 _! @3 F" ]9 ~8 J
将Mapper 230 B6 Q% ?9 L' s% ]
06字节的高4位是Mapper号的低4位0 T6 t; `! k0 v N3 q
07字节的高4位是Mapper号的高4位
3 A. i# I) C B% U- W* P# N4 p5 Z. Y组合起来就是0x17=1*16+7=23) o! J& a3 M" l6 K" l) k% N5 q

+ C2 r: Z7 O }+ o修改成 Mapper 4
2 U/ N. L, R$ F
3 E& q: h; c' v) E% S
1 ?: {) u! k4 t. K
5 D* H% H9 z, t) |3 m再次打开文件:" \- H, k5 `; }- _

* z- ?1 K! |; r* ~% J6 R! Z可以正常运行
2 t, e0 W1 N9 x; W通过全面测试,发现出现精灵错乱:
4 l) [5 g+ s! z V1 ]' Q) p第1关:" H! _3 |+ e e! a5 f
7 V7 l: x5 U9 m2 v8 r2 L
8 @- y* m, s# a; [1 K7 V# S
第2关:
) M5 ?) ~* {: t- b. W8 s& k" q
1 S8 i+ _3 T9 G任务失败后:) R& A7 R0 b9 N$ y9 r( ^
: `/ Y8 {3 W1 ]0 c Q2 U. |9 G
通关后上飞机画面:7 w. A. |5 \/ z0 |6 P$ N

V" m S S3 T0 F1 H1 A2 C这是为何呢?; m" x* \) E3 d' s9 {0 G
这是因为Mapper 23 中精灵VRAM切bank是一次切1KB8 x2 w, p, b' Q
但是在Mapper 4中精灵VRAM切换却是一次切2KB,而且忽略bank号的D0位
% ~% C' Q" c4 `. B# D比方bank 0和bank 1是同一个bank,同理bank 2和bank 3是同一个bank/ }! V) [; d9 t% _1 m& B ^# k
也就是说
' w5 |+ |7 x; K5 i4 A/ M8 PMapper 23中的VRAM的
; k; h v0 g; ^* g5 l* Qbank 0,bank 1,bank 2,bank 3/ n; u% j3 l. S. j6 _* i
在Mapper 4中对应的是7 p" h- A6 \) }: S0 z
Bank 0,bank 0,bank 2, bank2
6 r# _1 H0 A3 T) u; @- G6 ^. ]3 n然后查找原来的ROM的切VRAM的程序:
* {# U1 K+ p9 r( W6 T W知道是从07F0-07F3切到精灵VRAM的:
4 N. |3 ^8 F0 e0 M' M如图所示:7 k! S8 I6 B7 u; R
0 [1 N" R/ H+ |) ^8 ~
 
2 `) S+ ]% g5 ~+ X作为对比,左边是原版,右边是修改。0 ^# O9 j+ N! o3 ]+ r0 c) ~
接下来是完善VRAM切换带来的问题,因为Mapper 4只能切2KB的bank,所以我们不能通过切bank程序解决问题。
- G- k- Q t2 |: F通过测试知道1,3,5,6,7,8关的精灵VRAM排序如下(07F0-07F3):. F$ `. X3 O7 d, P) ?
01 04 06 07& o# I8 J0 |! g; K3 ~
第2,4关如下:
* M4 c: y) n- d01 05 08 09) ^9 m/ n. |' s4 F$ F( V
任务失败时如下:) v* V( b+ k1 _
32 00 00 1B
& Y3 G. `* h0 J; d, g$ P" }其中任务失败时对应的VRAM是07F3的1B,只要让07F2为1A或1B即可:
0 R; V6 ?! V+ C6 Q通过调试找到对07F2写入数据#$00时程序如下,于是修改C7E5的值为1A即可:/ A l0 w+ g! Q2 H1 H: f* Z; d4 i
3 F% x* e6 b. f4 w; z- l0 a" F0 l3 p+ p4 i
转到ROM地址:
* c: l+ A) b0 e5 K
2 Y4 f4 @3 a/ j! @修改数据:! P/ B: i% N, `+ s- _# D
; O! \: h) k+ B, s
重新失败后可以看到修复成功:% q( t7 y7 a! l: j+ R

( P) n7 k5 i) O w0 F$ h接下来是修复正常进行任务时的精灵错乱问题。6 e! w$ J7 z% k- j6 @% t; u6 _
首先运行Mapper 23版本,在1,3,5,6,7,8关任意一关的时候,将PPU导出来
* W3 ~ F$ Q4 c- } $ M- j X: i, p/ o& A4 E
, t# d2 Z' ?! C+ `9 @9 ?' E8 @

$ m+ i# |# Y& v% M w5 F1 d1 v2 O7 ?! a2 a1 H% N
然后用Hxd打开修改的Mapper 4的ROM和刚刚保存的PPU的数据文件:
% N0 r& R4 n7 q: ?+ K: @ ) ^: ]2 r4 n+ E" M* K
在ROM文件头第05字节改为0x20:4 f% {, E+ H6 M! K7 B6 ^ n

- F) r- m/ R& B! A6 |8 A Z6 A然后转到文件末尾,插入0x20000字节空字节:2 Q4 @0 _; g4 D4 M, j- L5 @8 d

* Z( Z5 S. R2 k) R
% a" V) L4 J3 N! s! h
) E$ \$ Z' \: D3 |+ I . r/ r; X8 i9 s2 x
然后将第1关的PPU数据的前面2KB数据选定:
% l8 Y/ P& v6 v" z, S3 l0 Y3 Z ; }( j6 c) ^" Z: K6 J) T0 `0 o
- v* u: `4 q$ |7 H. ~
0 w3 q5 ^; l- Q) Z7 ^
复制之后以覆盖方式粘贴到ROM的40010,同样把第2关的PPU数据的前面2KB以覆盖方式粘贴到ROM的40810
. W d' o1 x) W4 Q/ v * M( `; `3 ]6 P$ ~6 L5 | a% G
然后保存文件:
, m6 u! k2 {0 ~2 ?
7 u# d8 N% A: U' A! W4 }最后用FCEUX打开文件,添加07F0-07F3的写入断点
. z* V, H3 S. A2 W% O5 l
6 u7 o9 J7 t& a! \7 ^地图预览后即将进入第一关画面时程序暂停了,可以知道此时准备将C793的数据写到07F0:
: y$ r0 k z% H3 p% u- A7 i
+ |; f( N% P' c1 V3 a# I1 G) o测试后知道将C793-0796写入到了07F0-07F3:
; E. w! Q0 `9 L/ ?# C同理,经测试每4个字节一组,一共17组,其中01 04对应普通关卡精灵以及其BOSS关的精灵VRAM的bank号,01 05对应2,4关卡精灵以及其BOSS关的精灵VRAM的bank号,再加上一个通关后跳上飞机那段动画的精灵VRAM的bank号。& T! y/ d+ F) ^; n' [7 W
4 i& c7 O1 Q/ D0 }0 u

. |* `$ v2 _2 v8 K6 V然后将文件中标记的01 04修改为 80 04,将01 05 修改为82 04即可:
; e- @4 l4 ?9 J4 S8 Z1 } & V: x6 o& C# F% k; A1 z
保存之后重新运行后效果如下:, H |' p+ C0 g3 b6 P* l
3 o7 k, c. H# u0 E/ `
; z) O/ L* a( C4 k9 e
; R0 d! F" k; {6 P t; G! k. S
当前使用的是FCEUX模拟器,如果用NEStopia玩的话一开始就死机了,这是因为这个ROM有文件保护吧,它会往$6000里写入数据:
u4 \* H$ i- N6 R $ Y7 G, p* I" h% m8 ?) n, _" Z
F863:A0 03 LDY #$03
e2 t' y+ s9 x7 r0 h8 SF865:98 TYA) X* r1 u% i; U7 H
F866:29 01 AND #$01" c' {, l/ f! ^, M
F868:8D E9 07 STA $07E9- a8 F( V& J. A3 w
F86B:8D 00 60 STA $6000, K! j& X, {: e9 y& N
F86E:AD 00 60 LDA $6000
2 E+ `) k. R) ]$ f+ AF871:29 01 AND #$01% ^4 p) H5 I% I& j
F873:CD E9 07 CMP $07E9
- F% j) \8 b0 {1 L- uF876:D0 05 BNE $F87D; k, T) b& }) e' x5 x! a$ W
F878:88 DEY
! Y, q3 ]/ Q- L8 c4 t9 WF879:10 EA BPL $F8659 I8 T9 B" v+ s4 c
F87B:30 03 BMI $F880
) e0 o* `( Y; X. }" v' {6 R$ qF87D:4C 00 00 JMP $00003 ~) k; c: {) W4 d5 z3 L- @9 e: M2 g( w
F880:A5 1A LDA $001A5 ^, A* v" r- }! @& W8 m" {) k% F
F882:65 34 ADC $0034( `+ p- R4 [" v8 Q
F884:85 34 STA $00342 z- R# t3 c3 Z/ \
F886:4C 80 F8 JMP $F880
- M7 l. d; C" V4 ^( w; n6 S先取Y值=#$03( e8 R/ I. Z( R- M8 A" @# {* j: S# B
与#$01相与后得到#$01
?8 m2 a6 x! i+ h写入到$07E9
& k8 m# f! h8 v N/ q( }. {) F写入到$60002 A) s1 c' ?0 ~ }
再读取$6000的数据和#$01相与后和$07E9的数据比较! `% ~& N: W. i- E& @/ ~
不同的话跳过5字节# H3 n- |* _5 y* x9 @4 M+ T, q. B
否则Y递减
x& Q `9 I/ H6 g* F8 j. b- D为正数就跳回0x100-0xEA=16字节
) y3 a* k( L" Y8 p' `为负数就跳过0x3字节. n+ V9 o3 r' x6 V" V( \4 y
跳转到$0000(简直没有人性了,跳到这里死机,真想得出来)$ B4 z1 A6 W* \- ?9 u9 s
7 T1 Z( V- y+ }) X& `4 T) `
正是因为这样,NEStopia运行FC时,6000-7FFF默认是不可写的,必须在ROM文件头第6字节的D1位置1设置ROM有SRAM,对于Mapper 4,还需要向$A001写入#$80来启用SRAM。
' b2 L* G9 E& ^1 z& S. x由于$6000不可写,因此想$6000写入#$01后$6000还是#$00,之后读取$07E9的#$01与之相比当然不同了,于是直接跳转到死机程序了。3 f+ l1 f; H4 z3 @3 c0 Z
解决方法是把ROM中的所有的AD 00 60 29 01 CD E9 07 D0 05 88 10 EA 30 03 4C 00 003 r' x, |1 |# A4 F
中的D0 05改为D0 00,然后保存即可。
6 k1 x8 e/ t1 I测试完美运行。
% R' h8 I) |3 r. z% m- F; r ?6 M ) Q2 c* f- Z+ \6 E7 E
; \1 T9 k2 \8 w+ r7 Z
教程到此结束。
2 s* f. i( p- r9 d: s8 {; i7 {( H# Q) _- M. L7 {9 R# R1 f
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|