Peretasan Sonic the Hedgehog klasik untuk Sega

Pada artikel ini saya ingin membongkar perangkat internal dari game legendaris Sonic the Hedgehog untuk Sega Mega Drive, serta cara untuk memodifikasinya atau, seperti kata mereka, peretasan. Game ini memiliki sekitar seratus retasan , termasuk pekerjaan yang sangat layak (seperti Pana Der Hejhog atau Sonic Remastered ), dan aneh dan bahkan menyeramkan (seperti An Ordinary Sonic ROM Hack ). Untuk memahami cara membuatnya, Anda perlu mengetahui cara menulis dalam bahasa assembler Motorola 68K (biasanya game untuk konsol pada waktu itu ditulis dalam assembler), di mana mendapatkan versi permainan yang dibongkar dari gim tersebut dan arsitektur apa yang memiliki mesinnya.


Retas sonik


Pembongkaran file ROM untuk Sega dilakukan menggunakan disassembler komersial dan debugger IDA Pro . Lalu ada proses yang melelahkan dalam menandai, menyusun, dan menyisir kode assembler mentah menggunakan debugger (dan kecerdikan). Proses ini membutuhkan pemahaman yang baik tentang fitur teknis platform Sega Mega Drive dan game untuknya.


Untungnya, GitHub telah membongkar dan menandai versi semua game di seri Sonic the Hedgehog, yang dibuat oleh para penggemar dengan dukungan Sonic Retro . Kode sumber gim pertama dalam seri ditandai dan terstruktur terbaik. Versi kode ini ada dalam repositori sonicretro / s1disasm dan akan diuraikan dalam artikel.


Perendaman dalam struktur internal mainan akan dimulai dengan teori.




Sega Mega Drive ( Sega Genesis) 32- Motorola MC68000 ( Motorola 68K) Zilog Z80 ( Z80 ). (RAM) – 64K. ( ) – 320x224 .


Motorola 68K . , . Motorola 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- : D0D7. . A0A7. - . 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, d1d1 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  ;     .foo
nop       ;    (nop)   
.foo:     ;  .foo

SubRoutine:  ;   SubRoutine
nop
rts          ;   

bsr SubRoutine  ;   SubRoutine


68K CCR (Condition Code Register). cmp, tst btst () , beq, bne, bge, ble .


  • cmp –  .
  • tst – .
  • btst – .
  • beq/bne – , / .
  • bge/ble – , / .

:


cmp.w   #32,d0  ;  d0  32
bge.s   .foo    ;  d0 > 32,    .foo

btst    #0,d0  ;   ()  d0  
bne.s   .foo   ;     ,    .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  ; Sonic's top speed
move.w  #$C,(v_sonspeedacc).w    ; Sonic's acceleration
move.w  #$80,(v_sonspeeddec).w   ; Sonic's deceleration

, 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.


Marble Zone, GIF-, 1 :


8192 RAM . v_objspace. , . : , , , , , . DisplaySprite.


Objek permainan sonik


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:  ; Routine 0
    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:   ; Routine 0
    cmp.b   #6,obSubtype(a0)  ;   ?
    beq     DeleteObject      ;  ,  

    addq.b  #2,obRoutine(a0)
    move.b  #$E,obHeight(a0)
    ; ...

, ROM' , . GitHub. , - , .


:


, . Sonic the Hedgehog 3 – .


GIF-, , 1 :

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: ; Routine 2
    tst.b   (v_shield).w  ;    ?
    beq.s   .animate      ;  , 

.dist_from_sonic:
    ;    
    move.w  (v_player+obX).w,d0  ;     X  d0
    sub.w   obX(a0),d0           ; d0 =   X
    move.w  (v_player+obY).w,d1  ;     Y  d1
    sub.w   obY(a0),d1           ; d1 =   Y

.check_magnetised:
    ; ,        
    btst    #0,obStatus(a0)  ;   obStatus  0?
    bne.s   .attract         ;   =>  ,   .attract

.check_near_x:
    ;    ,  
    cmp.w   #64,d0    ;   X > 64?
    bge.s   .animate  ;  , 
    cmp.w   #-64,d0   ;   X < -64?
    ble.s   .animate  ;  , 

.check_near_y:
    cmp.w   #64,d1    ;   Y > 64?
    bge.s   .animate  ;  , 
    cmp.w   #-64,d1   ;   Y < -64?
    ble.s   .animate  ;  , 

    ;    64x64,   
    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:
    ;     X
    move.w #48,d4          ;   d4  48
    move.w  obVelX(a0),d3  ;     X  d3
    eor.w   d0, d3         ;      
    btst    #$F,d3         ;  15-   1 ( )...
    beq.s   .x_towards     ;   x_towards
    move.w #192,d4         ;   ,   d4  192

.x_towards:
    ;    ,    (neg)   (d4)
    cmp.w   #0,d0
    bge.s   .attract_x
    neg d4

.attract_x:
    ;     X    X
    add.w   d4,obVelX(a0)

    ;      Y:
    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!


GIF- , 3.5 :

GitHub , .



. (SonED2, Chaos), , . / Motorola 68K EASy68K, , Sega.


, , . , - , , .




All Articles