在本文中,我想为Sega Mega Drive拆解传奇游戏《刺猬索尼克》的内部设备,以及对其进行修改或黑客入侵的方法。该游戏大约有一百种hack,包括真正值得做的工作(例如Pana Der Hejhog或Sonic Remastered),以及奇怪甚至令人毛骨悚然的游戏(例如An Sonic ROM hack)。要了解如何创建它们,您需要弄清楚如何用汇编语言Motorola 68K(通常用于那个时代的控制台的游戏是用汇编语言编写)的编写方法,在何处获得游戏的反汇编版本以及具有其引擎的体系结构。

世嘉ROM文件的反汇编是使用商业反汇编器和IDA Pro调试器完成的。然后是使用调试器(和巧思)标记,构造和组合原始汇编程序代码的艰苦过程。此过程需要对Sega Mega Drive平台及其游戏的技术特征有很好的了解。
幸运的是,GitHub已经拆解并标记了Sonic the Hedgehog系列中所有游戏的版本,该版本由发烧友在Sonic Retro的支持下创建。系列中第一款游戏的源代码具有最佳标记和结构。此版本的代码位于存储库sonicretro / s1disasm中,并将在本文中对其进行解析。
浸入玩具的内部结构将从理论开始。
控制台技术概述

Sega Mega Drive(在美国称为Sega Genesis)配备了32位中央处理器Motorola MC68000(缩写为Motorola 68K)和一个附加的声音协处理器Zilog Z80(与Z80的交互是通过共享内存进行的)。RAM(RAM)的数量-64K。主模式(美国版)的屏幕分辨率为320x224像素。
当时使用的摩托罗拉68K处理器非常普遍。从流行的家用计算机和游戏机到航天飞机,该芯片已用于各种系统中。摩托罗拉68K的其中一种改进甚至安装在传奇的Apple Macintosh中。
Mega Drive Yamaha YM7101 80 . ; Sega Mega Drive " Sega Mega Drive: Video Display Processor".
AS. 82 . : ResearchGate Intel Core i7 338 .
32- : D0–D7. . A0–A7. - . A7 SP.
. .l (long) 32- . .w (word) .b (byte) 16- 8- .
Motorola 68K.
move – .
:
move.l #48, d4 – 48 d4.move.w d5, d6 – 16 d5 d6.move.w #$12FF, obStatus(a0) – 12FF , obStatus , a0.
, #. #$.
:
move.l #5, (a0) – 5 , a0.move.l (a1), d2 – , a1, d2.
(a*).
add – .sub – .mulu – ; muls – .divu – ; divs – .
:
add.b #$08, d0 – 08 d0.sub.w (v_screenposx).w, d1 – d1 v_screenposx ( 16- ).mulu.w #10, d0 – d0 10 ( d0 ).divs.w #$68, d2 – d2 68 ( d2 ).
jmp, bra – .jsr, bsr – , rts – ( call ret x86).
:
jmp .foo
nop
.foo:
SubRoutine:
nop
rts
bsr SubRoutine
68K CCR (Condition Code Register). cmp, tst btst () , beq, bne, bge, ble .
cmp – .tst – .btst – .beq/bne – , / .bge/ble – , / .
:
cmp.w #32,d0
bge.s .foo
btst #0,d0
bne.s .foo
Motorola 68K ( ) , .
s1disasm Python-, . Sonic the Hedgehog "Kosinski compression", ( ).
, , git- AS (git checkout AS) :
./build.py
ROM- s1built.bin. Sega Mega Drive. macOS, , OpenEmu.
– sonic.asm. : Zilog Z80 (WaitForZ80), (VDPSetupGame) . GameInit MainGameLoop, .
, Variables.asm. RAM, .
v_gamemode. :
- 00 – "Sega",
- 01 – ,
- 08 – ,
- 0C – ,
- 10 – special stage,
- 14 – "Continue",
- 18 – ,
- 1C – ,
- 8C – .
move.b #id_Sega,(v_gamemode).w GameInit v_gamemode , . id_Sega id_Title ./build.py, , "Sega" , .
v_gamemode , . , id_Title GM_Title, id_Level – GM_Level.
, Variables.asm . v_sonspeedmax, v_sonspeedacc v_sonspeeddec.
, Sonic_Main, : , , :
move.w #$600,(v_sonspeedmax).w
move.w #$C,(v_sonspeedacc).w
move.w #$80,(v_sonspeeddec).w
, 256. , 0xC / 256 = 0.046875, – 0x80 / 256 = 0.5 ( ).
Mega Drive Sega 315‑5313 (Video Display Processor, VDP). VDP , vdp_data_port vdp_control_port. VDPSetupGame, VDPSetupArray. , , . , GM_Level. VDP Sega Retro.
Low Color ( Mode Register 1 ):
Video Display Processor – background ( B) foreground ( A), , . 8x8 . ; – 4x4 . , 32x32 .
(LoadTilesAsYouMove, DrawChunks) (BuildSprites) , :
, LoadTilesAsYouMove . Sonic the Hedgehog 64x32 512x256 .
foreground- Green Hill Zone, GIF-, 5 : , , . , . , 3D- . Sonic the Hedgehog.
8192 RAM . v_objspace. , . : , , , , , . DisplaySprite.

64 . , , Constants.asm. a0. , :
ObX(a0), ObY(a0) – .ObVelX(a0), ObVelX(a1) – 1/256 .obHeight(a0), obWidth(a0) – .obSubtype(a0) – (: ).obStatus(a0) – .obRoutine(a0) – .
, X , Y, .
ExecuteObjects . , . Object Pointers.asm. _incObj.
, (, , , "" ). , , obRoutine.
SpeedToPos. , .
: no-ring challenge
, : no-ring challenge. . , ( ).
"" – Ring_Main (bra) :
Ring_Main:
bra.w Ring_Delete
lea (v_objstate).w,a2
moveq #0,d0
move.b obRespawnNo(a0),d0
. "" 26 Monitor.asm. obSubtype 1 . , 6. cmp beq , :
Mon_Main:
cmp.b #6,obSubtype(a0)
beq DeleteObject
addq.b #2,obRoutine(a0)
move.b #$E,obHeight(a0)
, ROM' , . GitHub. , - , .
:
, . Sonic the Hedgehog 3 – .
Sonic the Hedgehog 3
, , Sonic Retro. , , , 64 , . . 0.1875 , . , 0.75.
, , , , , "" .
"", 25 & 37 Rings.asm. :
Ring_Index:
ptr_Ring_Main: dc.w Ring_Main-Ring_Index
ptr_Ring_Animate: dc.w Ring_Animate-Ring_Index
ptr_Ring_Collect: dc.w Ring_Collect-Ring_Index
ptr_Ring_Sparkle: dc.w Ring_Sparkle-Ring_Index
ptr_Ring_Delete: dc.w Ring_Delete-Ring_Index
: Main – ; Animate – ; Collect – ; Sparkle – ; Delete – . , , ptr_Ring_Animate.
obStatus. , . obStatus ( ) . bset, , – btst.
Ring_Animate , , , 64 :
Ring_Animate:
tst.b (v_shield).w
beq.s .animate
.dist_from_sonic:
move.w (v_player+obX).w,d0
sub.w obX(a0),d0
move.w (v_player+obY).w,d1
sub.w obY(a0),d1
.check_magnetised:
btst #0,obStatus(a0)
bne.s .attract
.check_near_x:
cmp.w #64,d0
bge.s .animate
cmp.w #-64,d0
ble.s .animate
.check_near_y:
cmp.w #64,d1
bge.s .animate
cmp.w #-64,d1
ble.s .animate
bset #0,obStatus(a0)
.attract:
.animate:
, , . :
if sign(obVelX) == sign(distX):
, ( Motorola 68K) , 0 , 1 – . "" – XOR (eor Motorola 68K).
, ( ) , (0.1875 0.75) 256 ( 48 192 ).
:
.attract:
move.w #48,d4
move.w obVelX(a0),d3
eor.w d0, d3
btst #$F,d3
beq.s .x_towards
move.w #192,d4
.x_towards:
cmp.w #0,d0
bge.s .attract_x
neg d4
.attract_x:
add.w d4,obVelX(a0)
move.w #48,d4
move.w obVelY(a0),d3
eor.w d1,d3
btst #$F,d3
beq.s .y_towards
move.w #192,d4
.y_towards:
cmp.w #0,d1
bge.s .attract_y
neg d4
.attract_y:
add.w d4,obVelY(a0)
.animate:
, , SpeedToPos:
.animate:
jsr (SpeedToPos).l
ROM , — — Sonic 3 Sonic 1!
GitHub , .
. (SonED2, Chaos), , . / Motorola 68K EASy68K, , Sega.
, , . , - , , .