don't click here

Everything That I Know About Sonic the Hedgehog's Source Code

Discussion in 'General Sonic Discussion' started by Clownacy, Mar 30, 2022.

  1. Clownacy

    Clownacy

    Tech Member
    929
    241
    43
    (This is another cross-post from my blog, duplicated here because it's relevant, and for preservation in case the blog ever disappears).

    I've been meaning to write this for years:

    To my understanding, not much is commonly known about the source code of the original Sonic the Hedgehog games. As someone who's been obsessed with the programming of these games for almost ten years, I believe that I know a lot more than most people do. Unfortunately, my memory is awful, and I'm not going to be a Sonic hacker forever, so I want to preserve this information however I can before it's lost again.

    As of writing, the source code for the 'classic' Mega Drive Sonic the Hedgehog games has never been found. We do have an exhaustive list of disassemblies, however those do not capture all information that proper source code would give us. For example, while the logic of code is recovered by these disassemblies, the meaning of it might not be. Sometimes, the logic isn't all you need to understand code: it may do something that seems pointless or nonsensical, leaving nearby labels and comments to explain it fully. However, a disassembly cannot reproduce the original labels and comments: those are lost. Likewise, a disassembly cannot reproduce code that was never in the ROM to begin with, such as disabled (or "commented-out") prototype code. Because of this, a disassembly cannot truly replace source code.

    However, small snippets of source code have surfaced over the years. The most obvious example I can think of is a fully-intact copy of a single source file (likely "EDIT.ASM") in Sonic 2's "Nick Arcade" prototype.

    Sonic 2 "Nick Arcade" prototype's source file
    Inside one of Sonic 2's prototypes is a fully intact copy of the source file responsible for the game's "edit mode" (commonly known as "debug mode"):

    Code (ASM):
    1.         addsym
    2.         nolist
    3.         include "equ.lib"
    4.         include "macro.lib"
    5.         list
    6.  
    7.         xref    colichgpat
    8.         xref    ringpat,itempat,butapat,kanipat,hachipat,togepat
    9.         xref    fishpat,fish2pat,mogurapat,shimapat2,jyamapat
    10.         xref    musipat,sjumppat,kamerepat,arumapat,kagebpat,ballpat
    11.         xref    firepat,fblockpat,signalpat,bobinpat,yoganpat,yogan2pat
    12.         xref    usapat,yadopat,boxpat,bryukapat,daipat,break2pat,yogancpat
    13.         xref    batpat,z5daipat,dai2pat,switch2pat,z4daipat
    14.         xref    elevpat,pedalpat,steppat,funpat,sisoopat,hassyapat
    15.         xref    brobopat,unipat,yaripat,udaipat,dai3pat,kazaripat,kassyapat
    16.         xref    awapat,mizupat,boupat,benpat,fetamapat,mawarupat,hagurumapat
    17.         xref    patapat,yukafpat,nokopat,dai4pat,doorpat,yukaepat,fire6pat
    18.         xref    elepat,yukaipat,scolipat,imopat,savepat,bigringpat,btenpat
    19.         xref    actionsub,actwkchk,frameout,playpat,dualmodesub
    20.         xref    flicpat,usagipat,pengpat,azarpat,fbutapat,niwapat,risupat
    21.  
    22.         xref    kaitenpat,prodaipat,buranko0dpat
    23.         xref    frntlitpat,gempat,wfallpat,pltfrmpat
    24.         xref    takipat,banepat,dai00pat
    25.  
    26.         xref    redzpat,bfishpat,seahorsepat,horsepat
    27.         xref    stegopat,wasppat,gatorpat,bbatpat,octpat,wfish2pat,snailpat
    28.  
    29.         xdef    edit
    30.  
    31. ;------------------------------------------------------------------------------
    32. edit:
    33.         moveq   #0,d0
    34.         move.b  editmode,d0
    35.         move.w  edit_move_tbl(pc,d0.w),d1
    36.         jmp     edit_move_tbl(pc,d1.w)
    37. edit_move_tbl:
    38.         dc.w    editinit-edit_move_tbl
    39.         dc.w    editmove-edit_move_tbl
    40. editinit:
    41.         addq.b  #word,editmode
    42.         move.w  scralim_up,editstack
    43.         move.w  scralim_n_down,editstack2
    44.         move.w  #$0000,scralim_up
    45.         move.w  #$0720,scralim_n_down
    46.         andi.w  #$07ff,playerwk+yposi
    47.         andi.w  #$07ff,scra_v_posit
    48.         andi.w  #$03ff,scrb_v_posit
    49.         move.b  #0,patno(a0)
    50.         move.b  #0,mstno(a0)
    51.         cmpi.b  #spgamemd,gmmode
    52.         bne.b   .jump0
    53. *       move.b  #7-1,stageno
    54. *       move.w  #$000,rotspd
    55. *       move.w  #$000,rotdir
    56.         moveq   #7-1,d0
    57.         bra.b   .jump1
    58. .jump0:
    59.         moveq   #0,d0
    60.         move.b  stageno,d0
    61. .jump1:
    62.         lea     edittbl,a2
    63.         add.w   d0,d0
    64.         adda.w  (a2,d0.w),a2
    65.         move.w  (a2)+,d6
    66.         cmp.b   editno,d6
    67.         bhi.b   .jump
    68.         move.b  #0,editno
    69. .jump:
    70.         bsr.w   editpatchg
    71.         move.b  #12,edittimer
    72.         move.b  #1,edittimer+1
    73. editmove:
    74.         moveq   #7-1,d0
    75.         cmpi.b  #spgamemd,gmmode
    76.         beq.b   .jump
    77.         moveq   #0,d0
    78.         move.b  stageno,d0
    79. .jump:
    80.         lea     edittbl,a2
    81.         add.w   d0,d0
    82.         adda.w  (a2,d0.w),a2
    83.         move.w  (a2)+,d6
    84.         bsr.w   editwalk
    85. *       bsr.w   dirsprset
    86.         jmp     actionsub
    87. editwalk:
    88.         moveq   #0,d4
    89.         move.w  #1,d1
    90.         move.b  swdata1+1,d4
    91.         andi.w  #$0f,d4
    92.         bne.b   .jump0
    93.         move.b  swdata1,d0
    94.         andi.w  #$0f,d0
    95.         bne.b   .jump
    96.         move.b  #12,edittimer
    97.         move.b  #$0f,edittimer+1
    98.         bra.w   .lend
    99. .jump:
    100.         subq.b  #1,edittimer
    101.         bne.b   .jump1
    102.         move.b  #1,edittimer
    103.         addq.b  #1,edittimer+1
    104. *       cmpi.b  #255,edittimer+1
    105.         bne.b   .jump0
    106.         move.b  #255,edittimer+1
    107. .jump0:
    108.         move.b  swdata1,d4
    109. .jump1:
    110.         moveq   #0,d1
    111.         move.b  edittimer+1,d1
    112.         addq.w  #1,d1
    113.         swap    d1
    114.         asr.l   #4,d1
    115.         move.l  yposi(a0),d2
    116.         move.l  xposi(a0),d3
    117.         btst.l  #0,d4                   *swdata+0
    118.         beq.b   .jump2
    119.         sub.l   d1,d2                   *yposi
    120.         bcc.b   .jump2
    121.         moveq   #0,d2
    122. .jump2:
    123.         btst.l  #1,d4                   *swdata+0
    124.         beq.b   .jump3
    125.         add.l   d1,d2                   *yposi
    126.         cmpi.l  #$7ff0000,d2
    127.         bcs.b   .jump3
    128.         move.l  #$7ff0000,d2
    129. .jump3:
    130.         btst.l  #2,d4                   *swdata+0
    131.         beq.b   .jump4
    132.         sub.l   d1,d3                   *xposi
    133.         bcc.b   .jump4
    134.         moveq   #0,d3
    135. .jump4:
    136.         btst.l  #3,d4                   *swdata+0
    137.         beq.b   .jump5
    138.         add.l   d1,d3                   *xposi
    139. .jump5:
    140.         move.l  d2,yposi(a0)
    141.         move.l  d3,xposi(a0)
    142. .lend:
    143.         btst.b  #6,swdata1+0
    144.         beq.b   .jump7
    145.         btst.b  #5,swdata1+1            * c button check
    146.         beq.b   .jump77
    147.         subq.b  #1,editno
    148.         bcc.b   .jump6
    149.         add.b   d6,editno
    150.         bra.b   .jump6
    151. .jump77:
    152.         btst.b  #6,swdata1+1
    153.         beq.b   .jump7
    154.         addq.b  #1,editno
    155.         cmp.b   editno,d6
    156.         bhi.b   .jump6
    157.         move.b  #0,editno
    158. .jump6:
    159.         bra.w   editpatchg
    160. .jump7:
    161.         btst.b  #5,swdata1+1            * c button check
    162.         beq.b   .jump8
    163.         jsr     actwkchk
    164.         bne.b   .worknai                ;z=0:ok z=1:no
    165.         move.w  xposi(a0),xposi(a1)
    166.         move.w  yposi(a0),yposi(a1)
    167.         move.b  patbase(a0),actno(a1)
    168.         move.b  actflg(a0),actflg(a1)
    169.         move.b  actflg(a0),cddat(a1)
    170.         andi.b  #$7f,cddat(a1)
    171.         moveq   #0,d0
    172.         move.b  editno,d0
    173.         lsl.w   #3,d0
    174.         move.b  4(a2,d0.w),userflag(a1)
    175.         rts
    176. .worknai:
    177. .jump8:
    178.         btst.b  #4,swdata1+1            * b button check
    179.         beq.b   .jump9
    180.         moveq   #0,d0
    181.         move.w  d0,editmode
    182.         move.l  #playpat,playerwk+patbase
    183.         move.w  #$0780,playerwk+sproffset
    184.         tst.w   dualmode                ; dual mode check
    185.         beq.b   .end
    186.         move.w  #$0780/2,playerwk+sproffset
    187. .end:
    188.         move.b  d0,playerwk+mstno
    189.         move.w  d0,xposi+2(a0)
    190.         move.w  d0,yposi+2(a0)
    191.         move.w  editstack,scralim_up
    192.         move.w  editstack2,scralim_n_down
    193.         cmpi.b  #spgamemd,gmmode
    194.         bne.b   .jump9
    195. *       clr.w   rotdir
    196. *       move.w  #$040,rotspd
    197. *       move.l  #playpat,playerwk+patbase
    198. *       move.w  #$0780,playerwk+sproffset
    199.         move.b  #02,playerwk+mstno
    200.         bset.b  #cd_ball,playerwk+cddat
    201.         bset.b  #cd_jump,playerwk+cddat
    202. .jump9:
    203.         rts
    204. editpatchg:
    205.         moveq   #0,d0
    206.         move.b  editno,d0
    207.         lsl.w   #3,d0
    208.         move.l  0(a2,d0.w),patbase(a0)
    209.         move.w  6(a2,d0.w),sproffset(a0)
    210.         move.b  5(a2,d0.w),patno(a0)
    211. *       move.b  4(a2,d0.w),userflag(a0)
    212.         bsr.w   dualmodesub
    213.         rts
    214.  
    215. dcblw   macro   \1,\2,\3,\4,\5
    216.         dc.l    (\1)*$1000000+(\2)
    217.         dc.w    (\4)+(\5)*$100
    218.         dc.w    (\3)
    219.         endm
    220.  
    221. edittbl:
    222.         dc.w    edit1tbl-edittbl
    223.         dc.w    edit2tbl-edittbl
    224.         dc.w    edit3tbl-edittbl
    225.         dc.w    edit4tbl-edittbl
    226.         dc.w    edit5tbl-edittbl
    227.         dc.w    edit6tbl-edittbl
    228.         dc.w    edit7tbl-edittbl
    229. edit1tbl:
    230.         dc.w    14
    231.         dcblw   ring_act,ringpat,$26bc,0,$00            ;1:
    232.         dcblw   item_act,itempat,$0680,0,$00            ;2:
    233.         dcblw   kani_act,kanipat,$0400,0,$00            ;3:
    234.         dcblw   hachi_act,hachipat,$0444,0,$00          ;4:
    235.         dcblw   fish_act,fishpat,$0470,0,$00            ;5:
    236.         dcblw   toge_act,togepat,$04a0,0,$00            ;6:
    237.         dcblw   shima_act,shimapat2,$4000,0,$00         ;7:
    238.         dcblw   jyama_act,jyamapat,$66c0,0,$00          ;8:
    239.         dcblw   musi_act,musipat,$04e0,0,$00            ;9:
    240.         dcblw   sjump_act,sjumppat,$04a8,0,$00          ;10:
    241.         dcblw   kamere_act,kamerepat,$249b,0,$00        ;11:
    242.         dcblw   kageb_act,kagebpat,$434c,0,$00          ;12:
    243.         dcblw   save_act,savepat,$26bc,0,$01            ;13:
    244.         dcblw   colichg_act,colichgpat,$26bc,0,$00      ;14:
    245.  
    246. edit2tbl:
    247. edit3tbl:
    248. ;zone0d
    249.         dc.w    07
    250.         dcblw   ring_act,ringpat,$26bc,0,$00            ;01:
    251.         dcblw   item_act,itempat,$0680,0,$00            ;02:
    252.         dcblw   sjump_act,sjumppat,$04a8,0,$00          ;03:
    253.         dcblw   colichg_act,colichgpat,$07bc,0,$00      ;04:
    254.         dcblw   kaiten_act,kaitenpat,$e000,0,$00        ;05:
    255.         dcblw   prodai_act,prodaipat,$e418,0,$00        ;06:
    256.         dcblw   buranko_act,buranko0dpat,$2418,0,$08    ;07:
    257.  
    258. edit4tbl:
    259. ;zone00
    260.         dc.w    18
    261.         dcblw   ring_act,ringpat,$26bc,0,$00            ;1:
    262.         dcblw   item_act,itempat,$0680,0,$00            ;2:
    263.         dcblw   save_act,savepat,$047c,0,$01            ;3:
    264.  
    265.         dcblw   colichg_act,colichgpat,$26bc,0,$00      ;6:
    266.         dcblw   taki_act,takipat,$23ae,0,$00            ;7:
    267.         dcblw   taki_act,takipat,$23ae,3,$02            ;7:
    268.         dcblw   shima_act,dai00pat,$4000,0,$01          ;8:
    269.         dcblw   shima_act,dai00pat,$4000,1,$0a          ;8:
    270.         dcblw   toge_act,togepat,$2434,0,$00            ;10:
    271.         dcblw   sisoo_act,sisoopat,$03ce,0,$00          ;9:
    272.  
    273.         dcblw   sjump_act,banepat,$045c,0,$80           ;3: banev
    274.         dcblw   sjump_act,banepat,$0470,3,$90           ;3: baneh
    275.         dcblw   sjump_act,banepat,$045c,6,$a0           ;3: banevr
    276.         dcblw   sjump_act,banepat,$043c,7,$30           ;3: bane45
    277.         dcblw   sjump_act,banepat,$043c,10,$40          ;3: bane45r
    278.  
    279.         dcblw   wasp_act,wasppat,$03e6,0,$00            ;25   ""    ""
    280.         dcblw   snail_act,snailpat,$0402,0,$00          ;25   ""    ""
    281.         dcblw   wfish2_act,wfish2pat,$041c,0,$00        ;21   ""    ""
    282.  
    283.  
    284.  
    285.         dcblw   redz_act,redzpat,$0500,0,$00            ;20: will change
    286.         dcblw   bfish_act,bfishpat,$2530,0,$00          ;21   ""    ""
    287.         dcblw   seahorse_act,horsepat,$2570,0,$00       ;22   ""    ""
    288.         dcblw   skyhorse_act,horsepat,$2570,0,$00       ;23   ""    ""
    289.         dcblw   stego_act,stegopat,$23c4,0,$00          ;24   ""    ""
    290.         dcblw   wasp_act,wasppat,$032c,0,$00            ;25   ""    ""
    291.         dcblw   gator_act,gatorpat,$2300,0,$00          ;26   ""    ""
    292.         dcblw   bbat_act,bbatpat,$2350,0,$00            ;27   ""    ""
    293.         dcblw   oct_act,octpat,$238a,0,$00              ;28   ""    ""
    294.  
    295. edit5tbl:
    296. edit6tbl:
    297. edit7tbl:
    298. ;zone08
    299.         dc.w    15
    300.         dcblw   ring_act,ringpat,$26bc,0,$00            ;1:
    301.         dcblw   item_act,itempat,$0680,0,$00            ;2:
    302.  
    303.         dcblw   bgspr_act,frntlitpat,$e485,3,$21        ;3:
    304.         dcblw   wfall_act,wfallpat,$e415,4,$04          ;4:
    305.         dcblw   break_act,pltfrmpat,$4475,0,$00         ;5:
    306.         dcblw   colichg_act,colichgpat,$26bc,0,$00      ;6:
    307.  
    308.         dcblw   redz_act,redzpat,$0500,0,$00            ;20: will change
    309.         dcblw   bfish_act,bfishpat,$2530,0,$00          ;21   ""    ""
    310.         dcblw   seahorse_act,horsepat,$2570,0,$00       ;22   ""    ""
    311.         dcblw   skyhorse_act,horsepat,$2570,0,$00       ;23   ""    ""
    312.         dcblw   stego_act,stegopat,$23c4,0,$00          ;24   ""    ""
    313.         dcblw   wasp_act,wasppat,$032c,0,$00            ;25   ""    ""
    314.         dcblw   gator_act,gatorpat,$2300,0,$00          ;26   ""    ""
    315.         dcblw   bbat_act,bbatpat,$2350,0,$00            ;27   ""    ""
    316.         dcblw   oct_act,octpat,$238a,0,$00              ;28   ""    ""
    317.  
    318. ;------------------------------------------------------------------------------
    319.         align
    320. ;------------------------------------------------------------------------------
    321.         end
    322.  
    323.  
    324. edit2tbl:
    325.         dc.w    25
    326.         dcblw   ring_act,ringpat,$26bc,0,$00            ;1:
    327.         dcblw   item_act,itempat,$0680,0,$00            ;2:
    328.         dcblw   sjump_act,sjumppat,$0523,0,$00          ;3:
    329.         dcblw   fish2_act,fish2pat,$2486,0,$08          ;4:
    330.         dcblw   mogura_act,mogurapat,$84a6,2,$00        ;5:
    331.         dcblw   yari_act,yaripat,$03cc,0,$00            ;6:
    332.         dcblw   yari_act,yaripat,$03cc,3,$02            ;7:
    333.         dcblw   box_act,boxpat,$43de,0,$00              ;8:
    334.         dcblw   switch2_act,switch2pat,$0513,0,$00      ;9:
    335.         dcblw   toge_act,togepat,$051b,0,$00            ;10:
    336.         dcblw   dai_act,udaipat,$43bc,0,$04             ;11:
    337.         dcblw   dai3_act,dai3pat,$43e6,0,$01            ;12:
    338.         dcblw   dai3_act,dai3pat,$43e6,1,$13            ;13:
    339.         dcblw   dai3_act,dai3pat,$43e6,0,$05            ;14:
    340.         dcblw   kazari_act,kazaripat,$443e,0,$00        ;15:
    341.         dcblw   dai3_act,dai3pat,$43e6,2,$27            ;16:
    342.         dcblw   dai3_act,dai3pat,$43e6,3,$30            ;17:
    343.         dcblw   kassya_act,kassyapat,$03f6,0,$7f        ;18:
    344.         dcblw   uni_act,unipat,$0467,0,$00              ;19:
    345.         dcblw   awa_act,awapat,$8348,19,$84             ;20:
    346.         dcblw   mizu_act,mizupat,$c259,2,$02            ;21:
    347.         dcblw   mizu_act,mizupat,$c259,9,$09            ;22:
    348.         dcblw   bou_act,boupat,$43de,0,$00              ;23:
    349.         dcblw   ben_act,benpat,$4328,0,$02              ;24:
    350.         dcblw   save_act,savepat,$26bc,0,$01            ;25:
    351.  
    352. *       dcblw   dai4_act,dai4pat,$41f0,4,$80            ;25:
    353. edit3tbl:
    354.         dc.w    18
    355.         dcblw   ring_act,ringpat,$26bc,0,$00            ;1:
    356.         dcblw   item_act,itempat,$0680,0,$00            ;2:
    357.         dcblw   hachi_act,hachipat,$0444,0,$00          ;3:
    358.         dcblw   toge_act,togepat,$051b,0,$00            ;4:
    359.         dcblw   sjump_act,sjumppat,$0523,0,$00          ;5:
    360.         dcblw   mfire_act,firepat,$0345,0,$00           ;6:
    361.         dcblw   fblock_act,fblockpat,$4000,0,$00        ;7:
    362.         dcblw   myogan_act,yoganpat,$63a8,0,$00         ;8:
    363.         dcblw   yogan2_act,yogan2pat,$63a8,0,$00        ;9:
    364.         dcblw   box_act,boxpat,$42b8,0,$00              ;10:
    365.         dcblw   yado_act,yadopat,$247b,0,$00            ;11:
    366.         dcblw   bryuka_act,bryukapat,$42b8,0,$00        ;12:
    367.         dcblw   dai_act,daipat,$02b8,0,$00              ;13:
    368.         dcblw   break2_act,break2pat,$62b8,0,$00        ;14:
    369.         dcblw   yoganc_act,yogancpat,$8680,0,$00        ;15:
    370.         dcblw   bat_act,batpat,$04b8,0,$00              ;16:
    371.         dcblw   imo_act,imopat,$24ff,0,$00              ;17:
    372.         dcblw   save_act,savepat,$26bc,0,$01            ;18:
    373. edit4tbl:
    374.         dc.w    15
    375.         dcblw   ring_act,ringpat,$26bc,0,$00            ;1:
    376.         dcblw   item_act,itempat,$0680,0,$00            ;2:
    377.         dcblw   elev_act,elevpat,$4000,0,$00            ;3:
    378.         dcblw   break2_act,break2pat,$44e0,2,$00        ;4:
    379.         dcblw   shima_act,z4daipat,$4000,0,$00          ;5:
    380.         dcblw   pedal_act,pedalpat,$4000,0,$00          ;6:
    381.         dcblw   step_act,steppat,$4000,0,$00            ;7:
    382.         dcblw   fun_act,funpat,$43a0,0,$00              ;8:
    383.         dcblw   sisoo_act,sisoopat,$0374,0,$00          ;9:
    384.         dcblw   sjump_act,sjumppat,$0523,0,$00          ;10:
    385.         dcblw   mfire_act,firepat,$0480,0,$00           ;11:
    386.         dcblw   bgspr_act,hassyapat,$44d8,0,$00         ;12:
    387.         dcblw   brobo_act,brobopat,$0400,0,$00          ;13:
    388.         dcblw   uni_act,unipat,$2429,0,$00              ;14:
    389.         dcblw   save_act,savepat,$26bc,0,$01            ;15:
    390. edit5tbl:
    391.         dc.w    15
    392.         dcblw   ring_act,ringpat,$26bc,0,$00            ;1:
    393.         dcblw   item_act,itempat,$0680,0,$00            ;2:
    394.         dcblw   toge_act,togepat,$051b,0,$00            ;3:
    395.         dcblw   sjump_act,sjumppat,$0523,0,$00          ;4:
    396.         dcblw   aruma_act,arumapat,$04b8,0,$00          ;5:
    397.         dcblw   signal_act,signalpat,$0000,0,$00        ;6:
    398.         dcblw   bobin_act,bobinpat,$0380,0,$00          ;7:
    399.         dcblw   kani_act,kanipat,$0400,0,$00            ;8:
    400.         dcblw   hachi_act,hachipat,$0444,0,$00          ;9:
    401.         dcblw   yado_act,yadopat,$247b,0,$00            ;10:
    402.         dcblw   shima_act,z5daipat,$4000,0,$00          ;11:
    403.         dcblw   dai2_act,dai2pat,$4000,0,$00            ;12:
    404.         dcblw   switch2_act,switch2pat,$0513,0,$00      ;13:
    405.         dcblw   imo_act,imopat,$24ff,0,$00              ;14:
    406.         dcblw   save_act,savepat,$26bc,0,$01            ;15:
    407. edit6tbl:
    408.         dc.w    29
    409.         dcblw   ring_act,ringpat,$26bc,0,$00            ;1:
    410.         dcblw   item_act,itempat,$0680,0,$00            ;2:
    411.         dcblw   brobo_act,brobopat,$0400,0,$00          ;3:
    412.         dcblw   uni_act,unipat,$0429,0,$00              ;4:
    413.         dcblw   imo_act,imopat,$22b0,0,$00              ;5:
    414.         dcblw   buranko_act,fetamapat,$4391,2,$07       ;6:
    415.         dcblw   haguruma_act,hagurumapat,$c344,00,$e0   ;7:
    416.         dcblw   dai_act,daipat,$22c0,2,$28              ;8:
    417.         dcblw   switch2_act,switch2pat,$0513,0,$00      ;9:
    418.         dcblw   pata_act,patapat,$4492,0,$03            ;10:
    419.         dcblw   pata_act,yukafpat,$04df,0,$83           ;11:
    420.         dcblw   noko_act,nokopat,$43b5,0,$02            ;12:
    421.         dcblw   break2_act,break2pat,$43f5,0,$00        ;13:
    422.         dcblw   dai_act,daipat,$4460,3,$39              ;14:
    423.         dcblw   dai4_act,dai4pat,$22c0,0,$00            ;15:
    424.         dcblw   door_act,doorpat,$42e8,0,$00            ;16:
    425.         dcblw   dai4_act,dai4pat,$22c0,1,$13            ;17:
    426.         dcblw   noko_act,nokopat,$43b5,0,$01            ;18:
    427.         dcblw   dai4_act,dai4pat,$22c0,1,$24            ;19:
    428.         dcblw   noko_act,nokopat,$43b5,2,$04            ;20:
    429.         dcblw   dai4_act,dai4pat,$22c0,1,$34            ;21:
    430.         dcblw   yukae_act,yukaepat,$44c3,0,$00          ;22:
    431.         dcblw   fire6_act,fire6pat,$83d9,0,$64          ;23:
    432.         dcblw   fire6_act,fire6pat,$83d9,11,$64         ;24:
    433.         dcblw   ele_act,elepat,$047e,0,$04              ;25:
    434.         dcblw   yukai_act,yukaipat,$42f0,0,$00          ;26:
    435.         dcblw   scoli_act,scolipat,$8680,0,$11          ;27:
    436.         dcblw   buta_act,butapat,$2302,0,$04            ;28:
    437.         dcblw   save_act,savepat,$26bc,0,$01            ;29:
    438.  
    439. *       dcblw   ring_act,playpat,$0780,50,$00           ;28:
    440. *       dcblw   usa_act,usapat,$0448,0,$00              ;5:
    441. *       dcblw   mawaru_act,mawarupat,$4348,16,$00       ;7:
    442.  
    443. edit7tbl:
    444.         dc.w    02      *13
    445.         dcblw   ring_act,ringpat,$26bc,0,$00            ;1:
    446.         dcblw   ring_act,ringpat,$26bc,8,$00            ;2:
    447. *       dcblw   bobin_act,bobinpat,$0380,0,$00          ;2:
    448. *       dcblw   usagi_act,flicpat,$05a0,0,$0a           ;3
    449. *       dcblw   usagi_act,flicpat,$05a0,0,$0b           ;4
    450. *       dcblw   usagi_act,flicpat,$05a0,0,$0c           ;5
    451. *       dcblw   usagi_act,usagipat,$0553,0,$0d          ;6
    452. *       dcblw   usagi_act,usagipat,$0553,0,$0e          ;7
    453. *       dcblw   usagi_act,pengpat,$0573,0,$0f           ;8
    454. *       dcblw   usagi_act,pengpat,$0573,0,$10           ;9
    455. *       dcblw   usagi_act,azarpat,$0585,0,$11           ;10
    456. *       dcblw   usagi_act,fbutapat,$0593,0,$12          ;11
    457. *       dcblw   usagi_act,niwapat,$0565,0,$13           ;12
    458. *       dcblw   usagi_act,risupat,$05b3,0,$14           ;13
    This source code contains everything: code, comments, labels, and even disabled prototype code that we never knew even existed before. Notably, these labels give the internal names of enemies and objects used throughout the game, while the comments elaborate on the intended level order. The source code snippet even gives some insight into the exact assembler used to build the source code into a ROM.

    That's not the only useful data in this prototype however...

    Sonic 2 "Nick Arcade" prototype's symbol list
    Starting at ROM address 0x418A8 is what appears to be a partial copy of the assembler's symbol table. Oddly, it doesn't appear to match the ROM, as labels that appear in the above source code are recorded in this symbol table at different addresses to where they are in the actual ROM. It can be assumed, based on this, that this symbol table is leftover from a previous execution of the assembler, rather than the one that produced the ROM that we have.

    From roughly 0x418A8 to 0x47B14, the symbol table follows this format:
    • The first four bytes denote the length of the symbol identifier divided by four, and rounded up. That is to say, it denotes the number of longwords needed to hold the identifier. Notably, this length is stored in big-endian format.
    • The following longwords contain the label. Unused bytes are set to 00.
    • The following four bytes contain the value that is assigned to that symbol. This value is also in big-endian.

    Here's an example:

    00 00 00 02 65 64 69 74 69 6E 69 74 00 01 AB 12

    The first four bytes are 00000002, indicating an identifier that is 2 longwords (or 8 bytes) long.

    The next eight bytes are 65646974696E6974. When interpreted as ASCII, it is "editinit", which is one of the labels seen in the above source code.

    The following four bytes are 0001AB12, which is the ROM address that was assigned to this label when the assembler that produced this symbol table was ran. In the ROM we have, however, "editinit" is located at 0001BABE.

    Past 0x47B14, the format of the symbol table changes. Unfortunately, the entries don't seem to specify what each symbol's value is, instead containing what appears to be three pointers. This format continues to 0x50000, when actual game data resumes.

    The symbol table begins again at 0x50A9C, but in another format that seems to just contain identifiers and pointers.

    [EDIT: I'm a dummy: apparently you *can* extract meaningful data from the later parts of the symbol table, as someone else was able to and produce this massive list.]

    While the later symbols don't contain any useful information, they are still useful for determining the original names of various bits of code. For example, the label 'random' is certainly what we've been calling 'RandomNumber' in the Sonic 2 disassembly. Additionally, 'bgmset' and 'soundset' are more than likely 'PlayMusic' and 'PlaySound'. What's notable about that last one is that it answers the question of whether 'PlayMusic' really was intended to play music, since sometimes it's used to play sounds instead, which caused people to question whether it actually was a dedicated music-playing function, or simply a generic 'play something' function.

    One might be wondering why there's an intact source file and a partial symbol table in the middle of a ROM. Well, the space that this data occupies is what would normally be padding: towards the end of the ROM, the game's data is spaced-out for some reason, leaving big gaps. My theory is that whatever tool the devs were using to produce the final ROM simply malloc'd a huge buffer, and pasted data where it was needed, never initialising the unused space. This resulted in the unused space containing garbage data, leftover in memory from other programs.

    This isn't the only time that symbol data appears in a Sonic game:

    Sonic & Knuckles Collection's symbol list
    Unfortunately, I can't comment too much on this due to not having a copy of Sonic & Knuckles Collection on hand. However, this game contains another instance of symbol data, inside its main EXE.

    For the most complete set of symbols, however, one need not look further than...

    Sonic CD's unstripped ELF files
    Sonic Gems is a compilation of various emulated classic Sonic titles. Its version of Sonic CD, however, is not emulated: rather, it is a port of Sonic CD's PC port.

    One might be wondering how a game written in Motorola 68000 assembly could have ever been ported to anything with a different CPU architecture. The answer to that is that its code was machine-converted from assembly to C. Notably, this process preserved the original labels, and possibly even the original comments.

    Within the files of Sonic Gems, you can find a series of ELF files, which parallel the DLL files of Sonic CD's original PC port. What's special about these ELF files is that they are unstripped, containing huge amounts of symbol data.

    When loaded into something like IDA or Ghidra, this symbol data is taken advantage of while disassembling or decompiling the code. This reverse-engineered code will have its original labels intact, giving a great look into the original source code. Unfortunately, the code you'll be looking at is the disassembled/decompiled output of PowerPC/MIPS assembly which was generated from C which was converted from 68k assembly. That is to say, it's hideous and practically unreadable. Still, if you're able to draw parallels between this code and the original 68k assembly, you effectively have a pre-labelled disassembly.

    These ELF files also contain some debug data, such as the paths of various source files. I was able to extract a bunch of them back in 2018:

    C:\project\GEMS\application\SonicCD\src\ps2\main\DLLMAIN.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\ACTION.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\ACTSET.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\DAI_K.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\DAI_RD1.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\DIRCOL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\DUMMY.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\EDIT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\EMIE1.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\EMIE1CG.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\ENEMY.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\EQU.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\ET1.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\ETC.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\FCOL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\GAME.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\GOAL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\IO.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\ITEM.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\PLAYER.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\PLAYPAT1.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\PLAYSP.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\PLAYSUB.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\PLCHG.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\RIDECHK.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\RING.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\SCORE.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\SCRCHK.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\SPRING.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\SUICIDE.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TAKI.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TBL0.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TBL1.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TREE.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\ZONE.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\ZONETBL1.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\ACT11A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\COL1A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\DEV11A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\EDTBL11A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\KOWASI1.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\KUZUR11A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\KUZURE.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\SCR11A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\SHOOT1.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\SIKAKE.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\Z11ACT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\BLOCK.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\LOADER2.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\BMP.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\COLI1.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\Z11ATBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\SAVE.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\FRIEND1.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\MOVIE1.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\ACT11B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\COL1B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\DEV11B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\EDTBL11B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\KUZUR11B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\SCR11B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\Z11BTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\DEV11C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\SCR11C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\Z11CTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\EDTBL11C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\KUZUR11C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\COL1C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\DEV11D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\EDTBL11D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\KUZUR11D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\Z11DTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\COL1D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\SCR11D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\ACT12A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\DEV12A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\EDTBL12A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\KUZUR12A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\BRANKO1.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\SCR12A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\Z12ACT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\Z12ATBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\DEV12B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\EDTBL12B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\KUZUR12B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\SCR12B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\Z12BTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\DEV12C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\EDTBL12C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\KUZUR12C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\SCR12C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\Z12CTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\DEV12D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\EDTBL12D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\KUZUR12D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\SCR12D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\Z12DTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\ACT13C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\DEV13C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\EDTBL13C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\SCR13C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\Z13ACT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\Z13CTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\BOSS_1.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\DEV13D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\SCR13D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R1\Z13DTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\BANPA.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\BOBIN.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\BOBINB.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\COLI3.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\EDTBL31A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\ET3.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\FRIEND3.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\GA3.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\PLAYSP3.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\POCKET.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\TOGEBL3A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\TRAP_R3.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\Z31ATBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\MIRACLE.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\COL3A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\SCR31A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\Z31ACT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\DEV31A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\ACT31A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\MECASNC.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\MSNCCG.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\TENTOU.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\KAMA.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\PLPAT6.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\MOVIE3.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\ZONETBL3.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\ACT31B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\COL3B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\DEV31B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\EDTBL31B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\Z31BTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\SCR31B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\TOGEBL3B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\COL3C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\DEV31C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\EDTBL31C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\Z31CTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\SCR31C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\TOGEBL3D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\COL3D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\DEV31D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\EDTBL31D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\Z31DTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\SCR31D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\DEV32A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\EDTBL32A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\Z32ACT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\Z32ATBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\SCR32A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\ACT32A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\DEV32B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\EDTBL32B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\Z32BTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\SCR32B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\DEV32C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\EDTBL32C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\Z32CTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\SCR32C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\DEV32D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\EDTBL32D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\Z32DTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\SCR32D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\ACT33C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\DEV33C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\EDTBL33C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\Z33CTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\Z33ACT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\SIKAKE33.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\LIGHT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\STOPPER.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\BOSS_3.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\GATE.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\ROLLPLAT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\SCR33C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\DEV33D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\Z33DTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R3\SCR33D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\ACT41A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\COL4A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\COLI4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\DEV41A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\EDTBL41A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\ET4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\SCR41A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\SCRCHK4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\SW4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\SWBLK4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\Z41ACT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\Z41ATBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\ZONETBL4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\GAME4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\PLAYSUB4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\AWA.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\HARID4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\TOBIRA4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\HARIR4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\WALLS.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\WTBL41A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\FUNSUI4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\WALL1.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\SCREW_A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\ESCAL4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\BRUNKO4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\TONBO.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\AMENBO.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\TAGAMEB4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\YAGO.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\FRIEND4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\TEKKYU.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\PLAYPAT4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\KUZURE4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\LRBLK4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\COL4B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\SCR41B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\ACT41B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\EDTBL41B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\DEV41B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\MOVIE4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\RBLK4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\Z41BTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\UDBLK4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\WTBL41B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\ACT41C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\COL4C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\DEV41C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\EDTBL41C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\SCREW_C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\TEKKYU4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\WTBL41C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\RENKETU4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\SCR41C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\Z41CTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\SWGUN4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\COL4D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\SCR41D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\DEV41D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\Z41DTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\SCR42A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\DEV42A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\EDTBL42A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\Z42ATBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\WTBL42A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\TOBIRAS4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\OSUMIZU.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\WALL4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\ACT42A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\UKIDAI.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\Z42ACT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\TEKKYU1.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\WALL42.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\ACT42B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\EDTBL42B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\WTBL42B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\DEV42B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\Z42BTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\ACT42C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\DEV42C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\EDTBL42C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\WTBL42C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\Z42CTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\BANEIWA.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\DAID4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\SCR42C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\KOWASI4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\DEV42D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\Z42DTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\ACT43C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\DEV43C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\EDTBL43C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\SCR43C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\Z43ACT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\BOSS_4.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\BOSS_4_2.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\Z43CTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\WTBL43.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\DEV43D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\SCR43D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R4\Z43DTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\ACT51A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\COL5A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\COLI5.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\DEV51A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\EDTBL5.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\GAME5.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\PLAYSP5.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\SCR51A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\Z51ACT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\Z51ATBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\ZONETBL5.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\BELTSW5.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\MOVIE5.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\FRIEND5.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\KEMUSI.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\SHOOT5.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\KUMO.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\IWA5.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\IWA5WAVE.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\DENDEN.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\HASHI5.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\HARI5F.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\HARIR5.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\IWA5ROLL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\KOWASI5.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\KUZURE5.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\SASORI.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\HASIRA5.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\ET5.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\BURANKO5.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\DAI_RD5.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\COL5B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\DEV51B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\SCR51B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\Z51BTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\COL5C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\DEV51C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\SCR51C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\Z51CTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\COL5D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\DEV51D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\SCR51D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\Z51DTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\DEV52A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\SCR52A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\Z52ACT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\Z52ATBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\DEV52B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\SCR52B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\Z52BTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\DEV52C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\SCR52C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\Z52CTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\DEV52D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\SCR52D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\Z52DTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\ACT53.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\DEV53C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\SCR53C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\Z53ACT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\Z53CTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\BOSS_5.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\EDTBL53.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\DEV53D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\SCR53D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R5\Z53DTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\ACT61A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\COLI6.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\EDTBL61A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\SW6.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\TOBIRA6.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\TRAP_R6.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\KDAI6.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\BEEM6.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\BLOCK6.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\COL6A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\DAIR6.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\EGG6.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\ET6.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\FRIEND6.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\HACHI6.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\MINOMUSI.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\MOVIE6.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\PISTON6.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\SCR61A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\SEMI.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\SHOOT6.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\TOBIDAI6.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\UDBLK6.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\Z61ACT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\Z61ATBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\DEV61A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\BATTA.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\SEESAW6.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\PLAYER6.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\PLCHG6.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\ZONETBL6.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\COL6B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\SCR61B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\DEV61B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\EDTBL61B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\Z61BTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\COL6C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\DEV61C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\SCR61C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\Z61CTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\EDTBL61C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\COL6D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\DEV61D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\SCR61D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\Z61DTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\EDTBL62A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\Z62ACT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\Z62ATBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\TOGEBL6A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\DEV62A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\SCR62A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\ACT62A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\DEV62B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\EDTBL62B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\SCR62B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\Z62BTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\TOGEBL6B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\DEV62C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\EDTBL62C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\Z62CTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\TOGEBL6D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\SCR62C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\DEV62D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\EDTBL62D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\SCR62D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\Z62DTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\ACT63.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\DEV63C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\EDTBL63C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\SCR63C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\Z63CTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\Z63ACT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\BOSS_6.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\DEV63D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\SCR63D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R6\Z63DTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\ACT71A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\CHGBAN.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\CHGWALL7.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\COL7A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\COLI7.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\DEV71A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\EDTBL7.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\PLAYSP7.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\SCR71A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\Z71ACT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\Z71ATBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\ZONETBL7.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\WALL7.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\TEKKYU7.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\TEKKYU7J.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\SLIGHT7.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\FRIEND7.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\BRANKO7.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\ET7.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\KANABUN.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\DANGO7.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\MOVIE7.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\KABASIRA.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\HOTARU7.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\COL7B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\SCR71B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\DEV71B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\Z71BTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\COL7C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\Z71CTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\SCR71C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\DEV71C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\COL7D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\DEV71D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\SCR71D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\Z71DTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\SCR72A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\Z72ACT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\DEV72A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\Z72ATBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\DEV72B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\SCR72B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\Z72BTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\DEV72C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\SCR72C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\Z72CTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\DEV72D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\SCR72D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\Z72DTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\SCR73C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\ACT73.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\EDTBL73.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\Z73ACT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\GAITOU73.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\WALL73.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\EMIE7.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\Z73CTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\DEV73C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\HARI73.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\EMIE7CG.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\BOSS_7.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\SCR73D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\DEV73D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R7\Z73DTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\PLPAT8.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\ACT81A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\COL8A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\COLI8.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\DEV81A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\EDTBL81.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\SCR81A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\Z81ACT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\Z81ATBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\ZONETBL8.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\TRAP_R81.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\KABUTO8.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\KOMA8.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\SW8.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\OKUSIESO.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\TOBIRA.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\KONBEA.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\SCARAB.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\KUZURE8.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\NOKOGIRI.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\PROPERA8.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\DAI8.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\HACHI8.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\ET8.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\FRIEND8.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\PISTON.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\HAGURUMA.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\SCRCHK8.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\COL8B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\SCR81B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\Z81BTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\DEV81B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\COL8C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\SCR81C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\Z81CTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\DEV81C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\COL8D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\SCR81D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\Z81DTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\DEV81D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\PLAYSP8.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\ACT82A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\EDTBL82.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\TRAP_R82.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\Z82ACT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\Z82ATBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\BEAM.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\SHUT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\DEV82A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\SHOOT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\DANGO8.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\LEGMECA8.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\BIGBOM8.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\SCR82A.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\JETTOGE8.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\PIPE8.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\DEV82B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\SCR82B.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\Z82BTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\DEV82C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\SCR82C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\Z82CTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\DEV82D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\SCR82D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\Z82DTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\EDTBL83.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\SCR83C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\Z83ACT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\Z83CTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\BOSS_8.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\DEV83C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\ACT83.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\EMIE8.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\KONBEA83.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\TRAP_R83.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\HOTA8C.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\DEV83D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\SCR83D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\Z83DTBL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\R8\HOTA8D.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\SPECIAL\ACT_S.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\SPECIAL\BACT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\SPECIAL\BMP.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\SPECIAL\COLI_S.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\SPECIAL\COMMON.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\SPECIAL\DATA_S1.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\SPECIAL\ENS.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\SPECIAL\ETC_M.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\SPECIAL\ETC_S.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\SPECIAL\FADEIN.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\SPECIAL\GAME.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\SPECIAL\KAITEN.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\SPECIAL\PLS.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\SPECIAL\SPM_EQU.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\SPECIAL\SPS_EQU.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\SPECIAL\SIN.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\AVIGOOD\AVIGODDO.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\AVIGOOD\AVIGODEN.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\AVIOPEN\AVIOPNDO.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\AVIOPEN\AVIOPNEN.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\BESTTIME\BESENTRY.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\BESTTIME\BESTBMP.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\BESTTIME\BESTDO.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\BESTTIME\BESTGRID.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\BESTTIME\BESTITEM.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\BESTTIME\BESTPALT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\BESTTIME\BESTSPRT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\COMMON\HMX_OEEACTL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\OPENING\OPNBMP.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\OPENING\OPNDO.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\OPENING\OPNENTRY.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\OPENING\OPNGRID.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\OPENING\OPNPALT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\PLANET\ACTM.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\PLANET\ASCIISET.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\PLANET\ASCMAP.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\PLANET\CHAMOV.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\PLANET\DATA_M.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\PLANET\ETC.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\PLANET\FLASH.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\PLANET\KAITEN.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\PLANET\LPLMAIN.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\PLANET\PALET.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\PLANET\PLM.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\PLANET\PLS.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\PLANET\SPM_EQU.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\PLANET\SPS_EQU.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\SAVEDATA\SVDBMP.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\SAVEDATA\SVDDO.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\SAVEDATA\SVDEDIT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\SAVEDATA\SVDENTRY.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\SAVEDATA\SVDFILE.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\SAVEDATA\SVDGRID.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\SAVEDATA\SVDMENU.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\SAVEDATA\SVDPALT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\SAVEDATA\SVDSPRT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\SOUNDTST\SNDENTRY.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\SOUNDTST\SNDBMP.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\SOUNDTST\SNDDO.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\SOUNDTST\SNDGRID.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\SOUNDTST\SNDPALT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\SOUNDTST\SNDSPRT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\STAGETST\STGENTRY.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\STAGETST\STGBMP.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\STAGETST\STGDO.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\STAGETST\STGGRID.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\STAGETST\STGITEM.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\STAGETST\STGPALT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\STAGETST\STGSPRT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\TA\TA.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\TA\FADEIN.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\TA\TACOLOR.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\TA\TAEACTRL.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\THANKS\ACT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\THANKS\BM_M.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\THANKS\CHRSET.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\THANKS\DATA_SP.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\THANKS\ETC_M.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\THANKS\FADE.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\THANKS\GAME.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\THANKS\IO.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\THANKS\SPM.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\THANKS\SPRMOVE.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\VISUALMD\VMDBMP.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\VISUALMD\VMDDO.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\VISUALMD\VMDENTRY.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\VISUALMD\VMDGRID.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\VISUALMD\VMDPALT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\TITLE\VISUALMD\VMDSPRT.C
    C:\project\GEMS\application\SonicCD\src\ps2\main\WARP\WARP.C

    This file list gives you a look at the layout of Sonic CD's source code. Notably, you can see 'EDIT.C', which is very likely the file that originally contained the code seen in Sonic 2's "Nick Arcade" prototype.

    Sonic Gems isn't the only game to contain unstripped executables like this. For instance, The Legend of Zelda Collector's Edition contains an unstripped executable for its Nintendo 64 emulator (or "simulator", as it calls itself. Yeah, sure, Nintendo).

    Yuji Naka's video
    A few years back, Yuji Naka found some old footage of him working on Sonic 1 back in February 1990. In this video, he scrolls through a portion of the game's source code, giving us yet another sighting of authentic source code:



    Sonic hackers looked into this footage, and were able to produce a transcription of the source code, 'FCOL3.ASM':

    Code (ASM):
    1. *cd_walk           equ 0*2
    2. *cd_jump           equ 1*2
    3. *cd_up             equ 2*2
    4. *cd_down           equ 3*2
    5.  
    6. updotmax       equ -4
    7. downdotmax     equ 4
    8. jumpdotmax     equ 8
    9.  
    10. ;sprvo          equ $1c
    11. ;sprho          equ $1d
    12. ;sprvs          equ $1e
    13. ;sprhs          equ $1f
    14. ;------------------------------------------------------------------------
    15. ;   foot colition
    16. ;
    17. ;col:
    18.     move.w  yposi(a0),d4
    19.     move.b  sprvo(a0),d1
    20.     add.b   sprvs(a0),d1
    21.     ext.w   d1
    22.     add.w   d1,d4
    23.     move.w  xposi(a0),d5
    24.     move.b  sprho(a0),d1
    25.     ext.w   d1
    26.     add.w   d1,d5
    27.     move.w  xspeed(a0),scrhithz
    28. ?loop:
    29.     move.w  d4,d2
    30.     move.w  d5,d3
    31.     moveq   #0,d0
    32.     move.b  sprhs(a0),d0
    33.     tst.w   xspeed(a0)
    34.     bpl.b   ?jump
    35. *   btst.b  #cd_right,cddot(a0)
    36. *   beq.b   ?jump
    37.     neg.w   d0
    38. ?jump:
    39.     add.w   d0,d3
    40.     bsr.w   scdchk
    41.     tst.w   d1
    42.     beq.b   ?end
    43.     bpl.b   ?down
    44. ?up:
    45.     cmp.w   #updotmax,d1
    46.     blt.b   ?nomove
    47.     add.w   d1,yposi(a0)
    48. ?end:
    49.     rts
    50. ?nomove:
    51.     bsr.b   hoseihsub
    52.     bra.b   ?loop
    53.     move.w  #0,xspeed(a0)
    54.     rts
    55. ?down:
    56.     move.w  d1,d6
    57.     swap    d6
    58. ?down2:
    59.     move.w  d4,d2
    60.     move.w  d6,d3
    61.     moveq   #0,d0
    62.     move.b  sprhs(a0),d0
    63.     tst.w   xspeed(a0)
    64.     bpl.b   ?jump3
    65. *   btst    #cd_left,cddot(a0)
    66. *   bne.s   ?jump3
    67.     neg.w   d0
    68. ?jump3:
    69.     add.w   d0,d3
    70.     bsr.w   scdchk
    71.     tst.w   d1
    72.     beq.b   ?end2
    73.     bpl.b   ?down1
    74. ?up2:
    75.     cmp.w   #updotmax,d1
    76.     blt.b   ?nomove2
    Also visible in the footage was a brief glance of a partial file list:

    Code (Text):
    1.                         ENEMY.ASM
    2.             FCOL.ASM    FCOL.BAK
    3. FCOL3.ASM   GAME.ASM    INT.ASM
    4. LOGO.ASM    MACRO.LIB   MAIN.ASM
    5. ML.EVT      ML.S28      OBJ¥
    6. S           S.CMD       SCORE.ASM
    7. SOUND¥      TR¥
    Some of these filenames may seem familiar, as they survived into Sonic CD. Note that the items ending with the Yen symbol are actually directories, and not files.

    This footage is also noteworthy for showing that Sonic 1 was developed on DOS. This is something that I'll come back to later.

    Patent US5411272A
    A tiny snippet of source code can be found in a patent that Sega filed around the time of Sonic 2's release. It contains two tables that are responsible for Emerald Hill Zone's spiral loops. While it's not all that insightful, it does give you a look at the original formatting of these tables, and how the data was grouped.

    J2ME
    The developers of the J2ME version of Sonic 1 appear to have had access to Sonic 1's source code, or at least its assets: this is evident through how its filenames reflect labels found in the original source code. For instance, 'scdtblwk.scd', matches the label 'scdtblwk' that is found in Sonic 2's "Nick Arcade" prototype.

    Most notably, however, some of the files in this version appear to be 'raw', unprocessed versions of the data found in the ROM of the Mega Drive version. For example, there's an unused function in Sonic 2 that converts the collision data from a previously-unknown format to the format that is seen in the ROM itself, and it was discovered that the collision files in the J2ME version are in this mysterious format.

    There are other file format oddities as well, such as block priority being stored in its own file, instead of being embedded in the chunk data. It's possible that this too is how the data was originally formatted, before being converted into its final form for inclusion in the ROM.

    Assembler
    So we have all this information about the source code itself, and the game's assets, but what about the development environment? Well, for starters, from the footage we saw earlier, we can tell that Sonic 1 was developed on DOS computers.

    According to LazloPsylus, Sonic 1 was very evidently assembled with the 2500AD assembler, X68k, based partly on the fact that the syntax of the code snippet seen in Yuji Naka's footage is unusual, and unlikely to have built with any other assembler.

    However, it does not appear that Sonic 2 was assembled with X68k, as the "Nick Arcade" source code snippet uses a different syntax. It's plausible that Sonic 2 was assembled with SN 68k, also known as asm68k, however the presence of an 'addsym' directive, which is not supported by asm68k, calls this into question.

    Further complicating matters is something that I discovered while writing this very blog post: the "Nick Arcade" symbol table uses big-endian integers. DOS PCs are x86, and store their integers in little-endian. This suggests that Sonic 2 wasn't assembled on a DOS PC at all, unlike Sonic 1, and rather that it was assembled on a big-endian platform like a 68k-powered Macintosh. Another indication of this is that the "Nick Arcade" source snippet uses Unix-style line endings (0x0A), instead of DOS-style line endings (0x0D 0x0A).

    There's some evidence to suggest that Sonic 2 used a different assembler between REV01 and REV02: cross-object-file function calls behave differently, 'dc.b' directives are automatically padded, some 'addi' and 'subi' instructions were optimised to 'addq' and 'subq' instructions, and some 'lea' instructions were unoptimised from PC-relative addressing to absolute long addressing. The cross-object-file behaviour of REV00 and REV01 matches that of the "Nick Arcade" prototype, so it can be assumed that Sonic 2 used the same assembler throughout development up until REV02.

    Something I just discovered while writing this blog post is that Sonic 1's machine code is similar to Sonic 2 REV02: in code that is shared between Sonic 1 and Sonic 2, the same 'addi' and 'subi' instructions are 'addq' and 'subq' in both Sonic 1 and Sonic 2 REV02. Likewise, the same 'lea' instructions are unoptimised. With this in mind, it would appear that Sonic 2 was migrated back to X68k during the development of REV02, and it would continue to use this assembler as it was used to develop Sonic 3, Knuckles in Sonic 2, and the Mega Play arcade version of Sonic 2.

    Sonic 2's source file boundaries
    While we don't have an exact list of Sonic 2's source files, we do have a way of determining where its original source files began and ended: the assembler used by Sonic 2 before REV02 would resolve cross-object-file function calls in a clunky way, basically proxying them to little 'JmpTo' functions. To put it literally, a 'bsr' instruction that referenced a label which was outside of the current object file would instead branch to a single-instruction function that was appended to the end of the object file, which would itself jump to the 'bsr' instruction's original destination. Because these 'JmpTo' functions are inserted at the end of the object file, they can be used to tell where an object file (and thus a source file) ended.

    From this, we can determine things like that the ring object (object 0x25), the scattered ring object (object 0x37), the big Special Stage ring object leftover from Sonic 1, and the Casino Night Zone ring prize object (object 0xDC) were all stored in the same source file.

    Sonic 2 "Simon Wai" prototype's unassembled Kosinski file
    Like the "Nick Arcade" prototype before it, Sonic 2's "Simon Wai" prototype includes another source code file. This one, however, is not entirely complete, but it contains more than enough useful information:

    Code (ASM):
    1. ; 圧縮前 $8000  圧縮後 $2c00  圧縮率 34.4%  セル数 1024
    2.    dc.b    $1d,$7f,$00,$ff,$f8,$7e,$04,$01,$fb,$02,$00,$03,$04,$05,$04,$80
    3.    dc.b    $ff,$fa,$ff,$07,$54,$0b,$54,$0a,$50,$0c,$50,$ff,$8f,$0d,$54,$0f
    4.    dc.b    $54,$0e,$50,$10,$50,$11,$52,$19,$52,$18,$ff,$ff,$fc,$1a,$52,$1b
    5.    dc.b    $51,$8a,$51,$8b,$52,$1c,$02,$1e,$02,$1f,$02,$2a,$9f,$ff,$02,$2b
    6.    dc.b    $01,$8c,$01,$8d,$f4,$1d,$02,$2c,$02,$2d,$01,$ff,$f4,$88,$01,$89
    7.    dc.b    $01,$8e,$01,$8f,$02,$1a,$e4,$02,$2e,$02,$46,$c0,$2f,$e0,$ff,$1b
    8.    dc.b    $ec,$fc,$dc,$00,$70,$02,$c4,$d4,$ee,$18,$02,$19,$01,$3f,$f6,$fd
    9.    dc.b    $e4,$e6,$04,$2e,$04,$2d,$04,$9d,$fe,$77,$bd,$00,$be,$f9,$50,$31
    10.    dc.b    $54,$30,$54,$2f,$7f,$f8,$56,$03,$56,$02,$56,$01,$05,$ff,$f0,$52
    11.    dc.b    $1d,$52,$1e,$e1,$9f,$52,$1f,$fc,$50,$3e,$54,$3c,$56,$04,$54,$36
    12.    dc.b    $09,$e0,$c4,$9c,$f8,$ea,$1a,$50,$48,$24,$41,$ba,$a4,$b2,$fc,$fc
    13.    dc.b    $21,$9a,$f2,$80,$f6,$9c,$fc,$1d,$5e,$92,$68,$01,$8a,$01,$8b,$ee
    14.    dc.b    $fc,$68,$f2,$fd,$d5,$fd,$ce,$f7,$f7,$80,$fd,$f0,$f8,$0f,$04,$35
    15.    dc.b    $f0,$f8,$0d,$54,$3f,$54,$39,$7f,$fe,$54,$38,$01,$ff,$02,$00,$06
    16.    dc.b    $00,$60,$1a,$54,$43,$54,$ff,$f3,$42,$55,$fe,$55,$fd,$55,$fc,$55
    17.    dc.b    $fb,$54,$46,$a4,$1c,$ff,$11,$50,$49,$54,$44,$54,$52,$50,$51,$54
    18.    dc.b    $50,$80,$b2,$12,$8e,$8f,$4e,$06,$fc,$f2,$f2,$3c,$90,$fa,$58,$5c
    19.    dc.b    $80,$f8,$20,$60,$f8,$20,$40,$f3,$02,$0a,$02,$2c,$3c,$0b,$70,$40
    20.    dc.b    $f6,$86,$2a,$54,$29,$52,$f4,$62,$f8,$11,$c0,$f1,$2a,$52,$2b,$bc
    21.    dc.b    $f4,$fc,$1a,$62,$f1,$72,$6e,$f2,$f2,$78,$00,$16,$bd,$fe,$00,$17
    22.    dc.b    $fc,$f8,$0c,$18,$00,$19,$fc,$f8,$0c,$e0,$f8,$2e,$54,$06,$54,$04
    23.    dc.b    $50,$fb,$be,$08,$50,$09,$f8,$fe,$50,$12,$50,$13,$fc,$f8,$0b,$00
    24.    dc.b    $14,$00,$15,$f7,$fc,$fc,$f8,$0c,$1e,$00,$1f,$fc,$f8,$0c,$20,$00
    25.    dc.b    $21,$fc,$f4,$50,$f5,$f7,$07,$50,$f6,$50,$f7,$e8,$fe,$50,$f8,$50
    26.    dc.b    $87,$52,$1b,$3c,$1f,$fd,$e0,$fc,$50,$f9,$50,$85,$40,$ae,$f1,$50
    27.    dc.b    $fa,$50,$fb,$07,$e1,$50,$fc,$50,$8b,$f6,$86,$f1,$2a,$1c,$50,$2f
    28.    dc.b    $b2,$8c,$50,$8d,$50,$8e,$24,$f1,$24,$ee,$0a,$24,$9a,$eb,$92,$f3
    29.    dc.b    $7c,$f2,$0a,$f2,$e0,$ec,$af,$9f,$dc,$05,$6d,$ae,$ef,$60,$f2,$1a
    30.    dc.b    $06,$25,$01,$89,$45,$94,$e4,$4e,$ed,$e0,$e8,$2a,$f3,$11,$ae,$e0
    31.    dc.b    $f0,$c0,$28,$02,$29,$38,$f6,$00,$8c,$c0,$fd,$ce,$e4,$a0,$59,$44
    32.    dc.b    $c0,$8d,$ce,$00,$ea,$bc,$e0,$0b,$a8,$d6,$fc,$1b,$dc,$e2,$f8,$f0
    33.    dc.b    $68,$ec,$ea,$bd,$f8,$e5,$20,$f0,$15,$a0,$e8,$09,$20,$f0,$16,$50
    34.    dc.b    $54,$0d,$20,$f5,$1b,$52,$1c,$92,$a0,$dc,$e4,$60,$e5,$a8,$6e,$e2
    35.    dc.b    $80,$6e,$e4,$82,$28,$12,$fc,$4e,$e2,$80,$6e,$e2,$44,$ee,$e7,$fa
    36.    dc.b    $00,$66,$8e,$fe,$56,$25,$51,$8c,$c0,$c2,$e4,$bc,$f0,$fe,$38,$02
    37.    dc.b    $15,$d8,$80,$fc,$06,$f8,$9d,$59,$f0,$12,$02,$11,$02,$10,$80,$fc
    38.    dc.b    $f6,$5a,$30,$fe,$e0,$ee,$13,$80,$2e,$52,$2f,$f9,$6d,$7f,$f5,$05
    39.    dc.b    $f9,$02,$16,$00,$23,$00,$24,$e4,$f3,$f2,$f1,$80,$ea,$50,$2b,$20
    40.    dc.b    $8c,$50,$76,$5a,$f3,$84,$51,$89,$40,$a0,$5c,$58,$60,$6e,$00,$f9
    41.    dc.b    $11,$95,$ae,$f5,$1b,$5a,$f6,$6a,$e3,$6a,$fc,$02,$82,$e8,$10,$96
    42.    dc.b    $ee,$ea,$47,$0f,$ce,$f2,$13,$02,$14,$76,$b2,$f2,$16,$02,$17,$44
    43.    dc.b    $8c,$ee,$e4,$88,$ea,$33,$fa,$d4,$04,$23,$f2,$e4,$e6,$fc,$54,$27
    44.    dc.b    $54,$4f,$e4,$94,$54,$93,$04,$92,$e0,$ea,$e4,$f2,$54,$af,$af,$85
    45.    dc.b    $54,$97,$04,$98,$c6,$fd,$52,$f3,$54,$87,$54,$99,$bc,$fc,$ff,$ff
    46.    dc.b    $00,$e8,$39,$50,$6b,$50,$6c,$50,$6d,$50,$73,$50,$74,$50,$75,$50
    47.    dc.b    $76,$50,$ff,$8f,$77,$50,$78,$50,$79,$50,$15,$50,$7a,$50,$7b,$50
    48.    dc.b    $7c,$5e,$51,$f8,$20,$ee,$12,$00,$13,$fc,$f8,$0c,$00,$e8,$0e,$08
    49.    dc.b    $6e,$e2,$4d,$d2,$fc,$f2,$bc,$d2,$8a,$32,$ee,$f6,$60,$04,$f0,$fa
    50.    dc.b    $22,$fa,$00,$23,$06,$5c,$32,$fc,$80,$f1,$26,$54,$25,$67,$c1,$50
    51.    dc.b    $27,$f6,$58,$20,$80,$f2,$20,$60,$d1,$51,$55,$f1,$6d,$d8,$80,$f3
    52.    dc.b    $cc,$f3,$28,$f1,$80,$f0,$09,$12,$dc,$2d,$a3,$04,$e1,$d8,$ea,$18
    53.    dc.b    $84,$d6,$a0,$d8,$4f,$41,$80,$f4,$02,$25,$01,$24,$ae,$05,$c0,$80
    54.    dc.b    $f4,$88,$23,$f0,$25,$92,$12,$05,$fa,$ab,$02,$d6,$e0,$ff,$92,$f3
    55.    dc.b    $e0,$fc,$8a,$f1,$e0,$86,$a7,$88,$10,$88,$01,$f9,$01,$fa,$80,$5d
    56.    dc.b    $21,$05,$fa,$60,$fc,$50,$28,$80,$fe,$e0,$e9,$fc,$2d,$1b,$94,$84
    57.    dc.b    $bc,$c9,$52,$86,$c0,$ce,$64,$ea,$2a,$7c,$74,$19,$fa,$e9,$76,$d2
    58.    dc.b    $58,$55,$05,$48,$01,$5d,$f9,$5e,$f2,$fc,$f4,$57,$05,$52,$85,$e9
    59.    dc.b    $1b,$05,$49,$f4,$fe,$02,$d5,$ff,$f2,$f4,$f8,$09,$ff,$f8,$32,$32
    60.    dc.b    $d6,$96,$ca,$ff,$d8,$38,$50,$39,$50,$3f,$a2,$49,$a2,$4a,$fc,$54
    61.    dc.b    $ea,$fe,$7f,$af,$02,$0d,$02,$0e,$02,$0f,$06,$0d,$cc,$f8,$0a,$c1
    62.    dc.b    $00,$c2,$bc,$f8,$0c,$d2,$f9,$f0,$f8,$2c,$c0,$e1,$f0,$07,$04,$05
    63.    dc.b    $f1,$07,$51,$bf,$aa,$75,$50,$c1,$50,$c2,$54,$31,$a0,$c6,$ac,$da
    64.    dc.b    $ee,$f5,$46,$f2,$aa,$20,$60,$f3,$e4,$f3,$dc,$de,$d2,$cc,$6e,$de
    65.    dc.b    $d4,$52,$d8,$0c,$b2,$ac,$e2,$e8,$5c,$f3,$d8,$c8,$e2,$82,$b2,$20
    66.    dc.b    $de,$34,$f3,$ec,$1a,$f2,$84,$db,$b8,$84,$6a,$e8,$fe,$c4,$b8,$c0
    67.    dc.b    $b8,$49,$20,$fc,$c0,$b8,$10,$1b,$2d,$e8,$08,$f3,$00,$f1,$51,$fc
    68.    dc.b    $da,$8a,$f2,$bd,$ae,$d7,$97,$01,$73,$06,$99,$fc,$fe,$98,$f6,$e4
    69.    dc.b    $04,$0a,$fc,$f6,$f4,$9b,$7f,$46,$f6,$06,$9f,$02,$e2,$0a,$98,$0a
    70.    dc.b    $f4,$e6,$38,$e9,$fe,$e3,$04,$00,$fa,$f4,$fc,$50,$f5,$93,$43,$e2
    71.    dc.b    $06,$91,$02,$fe,$92,$f8,$f0,$07,$84,$98,$06,$96,$02,$fe,$b0,$f8
    72.    dc.b    $91,$20,$06,$95,$f0,$c4,$fe,$9a,$8d,$87,$f8,$06,$9c,$f0,$e4,$02
    73.    dc.b    $e5,$aa,$08,$fe,$02,$bc,$f8,$fa,$eb,$32,$50,$33,$50,$34,$9f,$ff
    74.    dc.b    $50,$b4,$50,$b5,$50,$b6,$fc,$b7,$50,$b8,$50,$b9,$54,$e1,$fb,$b9
    75.    dc.b    $f0,$fe,$ba,$f0,$bb,$f0,$bc,$68,$d2,$06,$19,$fc,$ff,$f4,$ae,$fc
    76.    dc.b    $ad,$fc,$ac,$fc,$ab,$fc,$aa,$f0,$fc,$a6,$fc,$fb,$8b,$a5,$fc,$a4
    77.    dc.b    $48,$d6,$30,$be,$3c,$a3,$3c,$a2,$38,$d0,$09,$c5,$56,$f0,$a1,$58
    78.    dc.b    $c0,$0b,$f0,$a0,$f0,$f8,$0e,$9f,$40,$b0,$52,$58,$d5,$b5,$6e,$80
    79.    dc.b    $f7,$58,$d5,$80,$f0,$0d,$f1,$72,$cc,$80,$f7,$01,$6d,$c0,$f8,$1e
    80.    dc.b    $58,$45,$fd,$48,$f6,$bc,$fc,$c0,$c0,$ee,$9c,$ea,$18,$a1,$6d,$01
    81.    dc.b    $4b,$f8,$48,$05,$55,$8e,$cc,$a6,$f0,$52,$05,$57,$d1,$a0,$05,$56
    82.    dc.b    $ec,$38,$ea,$88,$a0,$32,$cb,$c0,$fe,$ec,$fe,$c6,$f0,$ec,$fe,$01
    83.    dc.b    $1f,$02,$5d,$01,$ff,$bf,$0f,$01,$10,$02,$45,$02,$30,$02,$31,$c1
    84.    dc.b    $da,$c2,$33,$c2,$32,$ff,$cf,$d2,$e2,$02,$34,$02,$35,$02,$32,$c1
    85.    dc.b    $db,$c2,$3c,$02,$3d,$7f,$00,$f0,$47,$02,$36,$02,$37,$c1,$dc,$e0
    86.    dc.b    $ea,$0e,$ff,$f0,$44,$ce,$c5,$d8,$c1,$d9,$02,$40,$02,$f0,$ff,$41
    87.    dc.b    $f0,$c1,$d4,$c1,$d5,$c1,$d6,$c1,$d7,$02,$3e,$02,$ff,$3f,$3f,$02
    88.    dc.b    $46,$c0,$c1,$c0,$c2,$c2,$3a,$c2,$3b,$02,$38,$02,$39,$01,$02,$d8
    89.    dc.b    $f0,$d0,$c8,$02,$7e,$c0,$c4,$f8,$30,$01,$29,$01,$2a,$02,$44,$92
    90.    dc.b    $d6,$aa,$c0,$a3,$aa,$80,$d3,$8b,$2e,$ca,$d3,$a0,$c9,$9a,$d2,$a4
    91.    dc.b    $cd,$aa,$eb,$80,$cf,$a4,$cd,$66,$d2,$a8,$ce,$80,$d6,$04,$5e,$72
    92.    dc.b    $ce,$60,$d5,$5d,$97,$f6,$54,$61,$54,$60,$e4,$fc,$ea,$52,$1c,$e0
    93.    dc.b    $a9,$63,$54,$ff,$da,$62,$54,$67,$54,$66,$54,$65,$54,$64,$f2,$bc
    94.    dc.b    $e0,$ac,$54,$e0,$a9,$7f,$e1,$51,$fb,$51,$fc,$51,$fd,$51,$fe,$80
    95.    dc.b    $e8,$0f,$fc,$50,$ba,$5b,$50,$50,$bb,$50,$80,$e8,$14,$0c,$80,$e8
    96.    dc.b    $0c,$f0,$80,$e8,$7b,$e0,$d8,$3f,$fd,$ef,$ec,$e9,$9a,$f2,$1e,$54
    97.    dc.b    $9d,$54,$9c,$54,$90,$54,$8f,$92,$b7,$1c,$1f,$d5,$54,$8e,$54,$8d
    98.    dc.b    $50,$50,$e0,$e8,$ba,$b2,$9e,$80,$9a,$aa,$aa,$1d,$9c,$bb,$c4,$da
    99.    dc.b    $7c,$ea,$ba,$b2,$36,$db,$f8,$9d,$00,$be,$aa,$f4,$a0,$c8,$09,$8e
    100.    dc.b    $a6,$0e,$a3,$92,$c6,$c0,$9a,$d4,$04,$24,$00,$c2,$ff,$5a,$32,$f0
    101.    dc.b    $09,$e6,$54,$4f,$54,$4e,$54,$4d,$54,$4c,$54,$d5,$7e,$59,$54,$9c
    102.    dc.b    $c3,$a8,$b1,$00,$ea,$1c,$80,$99,$57,$54,$56,$54,$5f,$11,$55,$60
    103.    dc.b    $ff,$aa,$ea,$80,$9a,$a0,$fe,$06,$bc,$95,$54,$68,$d6,$5c,$d6,$12
    104.    dc.b    $9c,$56,$dc,$e4,$9a,$ea,$84,$c4,$8f,$3f,$5c,$ac,$51,$09,$83,$f2
    105.    dc.b    $62,$02,$63,$01,$88,$05,$7c,$a2,$f6,$51,$00,$91,$09,$24,$f2,$fc
    106.    dc.b    $10,$25,$05,$64,$91,$f0,$96,$b2,$ee,$61,$1d,$92,$c1,$f2,$50,$91
    107.    dc.b    $a8,$c2,$fc,$fe,$f0,$96,$ac,$b0,$f0,$48,$b1,$8d,$64,$e1,$20,$c3
    108.    dc.b    $f0,$00,$9e,$8c,$aa,$92,$95,$78,$f2,$60,$f8,$09,$8e,$93,$92,$f3
    109.    dc.b    $d1,$f5,$72,$90,$09,$1f,$36,$44,$ef,$00,$53,$40,$b1,$fa,$f1,$50
    110.    dc.b    $4a,$ff,$ff,$50,$4b,$50,$4c,$50,$4d,$50,$4e,$50,$4f,$50,$55,$50
    111.    dc.b    $56,$50,$57,$3d,$48,$50,$3d,$f8,$f5,$18,$50,$40,$f6,$fc,$f7,$2a
    112.    dc.b    $a9,$2a,$20,$9a,$b6,$bb,$20,$90,$0a,$e8,$ee,$fe,$e8,$a4,$a4,$ff
    113.    dc.b    $e4,$f4,$c6,$80,$de,$0e,$b5,$50,$46,$50,$47,$50,$48,$50,$3f,$c2
    114.    dc.b    $3a,$50,$3b,$50,$42,$50,$43,$a0,$ff,$51,$5f,$55,$50,$52,$50,$44
    115.    dc.b    $50,$45,$d8,$f1,$3c,$f2,$e4,$c3,$2e,$f8,$09,$a0,$8e,$95,$05,$a0
    116.    dc.b    $fd,$80,$88,$0a,$e0,$ef,$0e,$b2,$c5,$ce,$55,$62,$00,$bb,$5c,$f8
    117.    dc.b    $0a,$60,$f6,$5c,$8a,$3c,$5a,$2b,$2a,$d2,$fe,$01,$12,$a0,$09,$52
    118.    dc.b    $f3,$f0,$5a,$f3,$8e,$fe,$30,$91,$f0,$b6,$f2,$ea,$8a,$32,$c0,$d1
    119.    dc.b    $96,$fd,$2e,$bd,$f0,$b2,$fe,$12,$cb,$2c,$c0,$40,$fd,$0e,$a0,$5c
    120.    dc.b    $8f,$be,$56,$a0,$a6,$4e,$a2,$51,$82,$b8,$09,$88,$a1,$53,$22,$b8
    121.    dc.b    $2d,$c0,$82,$f5,$27,$f0,$f8,$0b,$a6,$b9,$c0,$81,$54,$34,$54,$33
    122.    dc.b    $54,$32,$f0,$ed,$92,$40,$d1,$e0,$ea,$1a,$c0,$82,$54,$37,$c0,$81
    123.    dc.b    $68,$68,$55,$72,$f2,$58,$aa,$81,$41,$00,$e0,$60,$8e,$b0,$0a,$c0
    124.    dc.b    $80,$09,$7a,$b0,$0a,$bf,$28,$80,$c0,$40,$c0,$be,$cc,$a3,$cc,$00
    125.    dc.b    $d8,$0a,$f0,$00,$d8,$0c,$8a,$ba,$f0,$00,$d8,$0c,$f0,$00,$d8,$0a
    126.    dc.b    $88,$fe,$54,$b4,$7f,$fd,$cc,$f4,$f4,$bc,$f4,$bb,$f4,$ba,$f4,$80
    127.    dc.b    $d1,$7c,$d1,$bf,$50,$c0,$f8,$ff,$fa,$aa,$f8,$ab,$f8,$ac,$f8,$ad
    128.    dc.b    $f8,$ae,$d4,$91,$26,$b7,$f8,$b1,$f8,$fb,$dd,$b2,$f8,$b3,$16,$b0
    129.    dc.b    $0b,$38,$af,$38,$b0,$30,$06,$b0,$0c,$38,$a9,$f0,$f8,$0e,$d6,$ed
    130.    dc.b    $a8,$f0,$f8,$0e,$a7,$f0,$f8,$0d,$ff,$f8,$13,$f0,$d5,$f0,$f8,$0e
    131.    dc.b    $d6,$f0,$f8,$0e,$d7,$fd,$ff,$05,$6e,$f2,$f8,$09,$f4,$d8,$f0,$d9
    132.    dc.b    $55,$71,$55,$70,$55,$6f,$50,$dd,$7f,$7f,$f0,$de,$f0,$df,$f0,$e0
    133.    dc.b    $f2,$18,$00,$f1,$72,$51,$73,$50,$ef,$f0,$d8,$f0,$ff,$f1,$f2,$00
    134.    dc.b    $d9,$a2,$fe,$1f,$a1,$88,$7f,$70,$a1,$89,$a2,$2c,$a2,$2d,$a2,$1a
    135.    dc.b    $f4,$f8,$c8,$67,$02,$59,$5d,$ef,$a0,$6c,$f0,$fe,$f2,$5a,$00,$d4
    136.    dc.b    $9b,$f8,$4c,$2d,$00,$2e,$ac,$e8,$0a,$2f,$ff,$6d,$50,$30,$50,$31
    137.    dc.b    $50,$36,$50,$37,$50,$3c,$40,$df,$1e,$40,$d9,$1b,$ad,$6a,$7c,$e7
    138.    dc.b    $54,$e2,$8d,$88,$94,$f8,$d4,$a0,$8c,$92,$8e,$ee,$cb,$8f,$05,$19
    139.    dc.b    $ee,$bf,$2a,$e2,$f4,$80,$88,$0a,$e6,$04,$14,$f2,$e0,$ba,$f6,$ee
    140.    dc.b    $c0,$d3,$94,$f5,$e0,$c0,$d0,$15,$58,$85,$80,$84,$da,$
    'Kosinski' is the nickname of a compression format used by various Mega Drive games, and this source file contains data compressed in this format. The header, when translated, says...

    Code (ASM):
    1. ; Before compression $8000  After compression $2c00  Compression ratio 34.4%  Number of cells 1024
    'Cells' refers to Mega Drive tile graphics, which are 32 bytes each. It doesn't make such sense in this context, since it's not tiles that are being compressed, but rather Aquatic Ruin Zone's level chunk data.

    Anyway, what we can learn from this source file is that Kosinski-compressed data wasn't included into the ROM as binary data, but rather assembly data for the assembler to process. This is unusual, as every assembler that I've worked with supports including binary data directly, without requiring this odd shim.

    Regardless, this assembly file also possibly indicates why Kosinski files are always padded to 0x10 bytes: each 'dc.b' directive in the source file is 0x10 values long, so perhaps the tool that produced this assembly file was unable to output a 'dc.b' that was less than 0x10 values long, and so it would instead output dummy 0 values until the 'dc.b' was 'full'.

    Closing
    Aaaaaaand... that's it. I think that's all I know about Sonic the Hedgehog's source code. Hopefully this information is of use to someone.
     
    Last edited: Apr 1, 2022
    • Informative Informative x 19
    • Like Like x 2
    • Agree Agree x 1
    • List
  2. Pengi

    Pengi

    Member
    1,751
    441
    63
  3. SystemsReady

    SystemsReady

    I Have No Idea What I'm Doing At Any Given Moment Member
    925
    309
    63
    The Twin Cities
    trying to not fall asleep while writing Selenium tests
    queeeestion. given that ELFs are unix-based and Sonic CD was developed around the same time as Sonic 2, does this mean that maybe Sonic CD was developed on the same type of computer hardware as Sonic 2 (the 68k-powered mac)? Would imply that they changed out hardware within the company, which is a totally pointless observation but still interesting.
     
  4. Clownacy

    Clownacy

    Tech Member
    929
    241
    43
    I don't have a copy of those Pastebin links, but I've dumped my own copies of Sonic CD's symbol information and attached them to this post. They were made from the PS2 version of Sonic Gems, using 'objdump -t x.ELF > x.txt'.

    The ELF files aren't really relevant because they only exist in the Sonic Gems port as a replacement for the PC port's DLL files.

    I don't imagine that Sonic 2 and Sonic CD were developed on the same type of computer, as IIRC Sonic 2 was developed in the US with Sega Technical Institute, while Sonic CD was developed in Japan. Being developed in the US is likely the reason why Sonic 2 presumably uses a different assembler to Sonic 1, as apparently Sega of America didn't promote X68k, favouring asm68k. This is evident in the "32X DDK" that's floating around the internet.
     

    Attached Files:

    • Like Like x 2
    • Agree Agree x 1
    • Informative Informative x 1
    • List
  5. MainMemory

    MainMemory

    Kate the Wolf Tech Member
    4,648
    214
    43
    SonLVL
    LOst and I figured out this format a long while ago. I don't know that it's "leftover memory", however, as the way Windows programs are built makes that rather unlikely. S&KC was built with Microsoft Visual C++, and in fact it was built in debug mode ('Microsoft Visual C++ Debug Library' shows up in the string list). The symbol data is contained within its own section of the EXE file, adding to the idea that it's there deliberately. The game itself is constructed of the original 68000 assembly code, machine converted to x86 ASM, with absolutely no attempt at optimization, with a C shell around it acting as the sound driver, VDP, and providing the window and menus the game needs to function as a Windows program. For some reason, not all the routines in the game are represented in this symbol table, but as the code in S&KC is largely unchanged compared to the original, what is there would be fairly easy to transfer over to the MD version.
     
    • Informative Informative x 3
    • Like Like x 1
    • List
  6. Brainulator

    Brainulator

    Regular garden-variety member Member
    Funny, I've just been looking into this exact thing - among other things, trying to create a disassembly of the Sonic 1 prototype that's structured and labeled, though not commented, as closely as possible to the original source code. In consulting everything, I've noticed several odd things that give insight into the game's development:
    • The S3K symbol table shows that "dev" is some name that's attached to what we call PLCs (pattern load cues). Not sure what it means.
    • Each value in the oscillating table is given its own label. Such labels also match those used for the synchronized animations.
    • The animal object, $28, is usagi_act, with "usagi" being Japanese for "rabbit". Indeed, the first animal variant is Pocky, the rabbit. This makes me wonder at what point the others were implemented. Similarly, the routine for the capsule object that spawns animals is called masinusagi, with "masin" referring to the capsule (note that this is an Engrish spelling for "machine").
    • That patent you linked to earlier seems to corroborate the meaning of certain constants; what we call an object's ID is referred to there as its "action number", which matches the label actno. Weirdly, however, it doesn't seem to explain where the name cddat comes from (note that this label appears in the aforementioned February 1990 video, the transcription is just incorrect).
    • In the Sonic 2 Nick Arcade source code bit, have you noticed how .jump0 and .jump1 precede .jump during editinit? Or better yet, how .jump77 precedes both .jump6 and .jump7 during editwalk? Why would this be? It's almost as if these labels are going by the order in which they were added, rather than the order in which they'll be executed or top-to-bottom. Indeed, looking at the Sonic 1 prototype's code, we can see that the code requiring those labels is absent!
     
    • Informative Informative x 1
    • List
  7. kazblox

    kazblox

    Member
    178
    26
    18
    Diassemblies and decompilations.
  8. evilhamwizard

    evilhamwizard

    Researcher
    1,371
    362
    63
    Might as well mention it here since I mentioned it in the Supreme Topic of Other Knowledge:


    [​IMG]

    In the Feb 1990 video, Naka is using a NEC PC-98XL2 (squared). This particular model uses a distinct keyboard layout that was pretty much only used for this model and uses an extremely large case.

    [​IMG]

    There was a similar model, the NEC PC-98XL that looks almost identical but is just a bit smaller.

    [​IMG]

    Here are some specs (taken from http://classic.pasocomclub.co.jp/datas/nec_pc98_xl2.html and translated with Deepl)
    Released in October of 1987, this would've set you back 988000 yen or over $10,000 today.

    This was one of the first PC98 computers to come equipped with the 80386 processor, which was released just a year or two prior. The 80386 was a significant improvement over the 80286, and was possibly chosen since it could assemble programs much faster. I believe the PC98 considered the use of the 80386 to be a "graphics mode", capable of higher resolutions and running modern MSDOS programs, while the V30 CPU was included as backward compatibility for older PC98 software.

    upload_2022-3-31_1-23-45.png
    (Sourced from Hobby Consolas)

    For Sonic CD, since development stayed in Japan and work was based off of the source code for Sonic 1, its likely the environment was the same as Sonic 1 as well. Not sure what the PC above could be though.

    I'm not sure what the assembler could've been for Sonic 2, but I noticed with a quick Google search that two assemblers popped up that existed around that time and supported "addsym", "nolist" "xref", and that macro declaration style.

    There was Devpac (2?) for the Atari ST/STE/TT/Falcon030
    http://info-coach.fr/atari/software/_development/Devpac_v3_Manual_txt.pdf

    And ProASM (This was for Amiga, but there might've been a ProASM that was created by Iwasaki Electronics. A "Pro-Asm II" for DOS was used to build the Columns Game Gear source code. This probably isn't the same software, but maybe it was used?
    https://retro-commodore.eu/files/downloads/amigamanuals-xiik.net/Applications/ProAsm - Manual-ENG.pdf

    upload_2022-3-31_1-42-16.png
    (Source Sega Saturn Magazine (Japan) 1998-07 issue)

    Here's a picture of Naka while he was at STI working on Sonic 3 (I think). No idea what the white PC is, you can probably come up with a make if you can identify the monitor. The PC on the right looks like a Teradrive but who knows. I swear I saw a better quality photo somewhere.
     
    Last edited: Mar 31, 2022
    • Informative Informative x 11
    • List
  9. The Joebro64

    The Joebro64

    SAY HELLO TO MY CHOCOLATE BLEND Member
    2,020
    1,324
    93
    This is a fascinating read. Thank you Clownacy!
     
  10. YuTwo

    YuTwo

    Member
    61
    100
    33
    I posted the higher quality photo before. Here it is if you want to see it again:
    [​IMG]
    I got it from Naka's Facebook account: https://www.facebook.com/photo.php?fbid=2699065823453866&set=t.100000514240758&type=3
    Archived link: https://archive.ph/P22Qi

    I had no idea this image appeared in a magazine before so thanks for at least finding that as well.
     
    • Like Like x 5
    • Informative Informative x 1
    • List
  11. Pengi

    Pengi

    Member
    1,751
    441
    63
    That's the SegaSonic the Hedgehog 1993 Calendar on the top right. (Or at least a piece of art from it, if not the actual calendar.)

    [​IMG]

    Assuming it IS the actual calendar...

    The front cover looks like this:
    [​IMG]

    These calendars each had six images, with each image covering 2 months.

    Going from top left to bottom right, this image is number 5, which would be September/October 1993 (thus, the autumnal orange colour scheme). Image number 6 has Santa on it, which would have to be be November/December. Image number 4 is tropical and sea themed, fitting of July/August. So I'm confident that the images on the cover of the calendar are in order.

    So unless Naka had an old calendar pinned up (or art from it), this photo is presumably from September-October 1993. You can vaguely make out what appears to be a 9 and a 10 just below the image.
     
    Last edited: Mar 31, 2022
    • Informative Informative x 6
    • List
  12. Brainulator

    Brainulator

    Regular garden-variety member Member
    Hmm...
     
  13. SystemsReady

    SystemsReady

    I Have No Idea What I'm Doing At Any Given Moment Member
    925
    309
    63
    The Twin Cities
    trying to not fall asleep while writing Selenium tests
    so...were they removed by the time of that prototype then? :o
     
  14. Brainulator

    Brainulator

    Regular garden-variety member Member
    It's just a failure to properly check. The tables those labels point to are in the final game.
     
  15. evilhamwizard

    evilhamwizard

    Researcher
    1,371
    362
    63
    I knew there was a higher quality version out there! Thanks for posting it. It looks like he's definitely running some 386/486 machine running Windows 3.0 based on the GUI there. I had a feeling the monitor on the right wasn't a Teradrive as the monitor and base didn't seem exact.

    Come to think of it, speaking of leftovers - every Sonic 2 prototype ROM has leftovers being used as padding, including the QA roms. But, the final REV00 ROM uses 00s for padding. The Sonic 3 and Knuckles prototypes also have leftover data used as padding while the final ROMs have FF used as the padding byte.
     
  16. biggestsonicfan

    biggestsonicfan

    Model2wannaB Tech Member
    1,491
    340
    63
    ALWAYS Sonic the Fighters
    I really wish I finished my blog post about Sonic the Fighters original labels being left in the PS3/X360 executables. It's not complete, but Virtua Fighter 2 and Fighting Vipers also have source labels and by comparing where those labels are called in the disassembles and the near identical function of each disassembled routine, more labels can be added. I currently have over 1000 official labels in Sonic the Fighters applied.
     
    • Informative Informative x 2
    • List
  17. MainMemory

    MainMemory

    Kate the Wolf Tech Member
    4,648
    214
    43
    SonLVL
    On the subject of other Sonic games, the prototype for the Xbox 360 port of Sonic Adventure DX contains a PDB file for the main executable, which can be loaded by IDA Pro and will give you full symbols for the game, including every function's signature, variable names, structure definitions, and enums. It also contains information on the source files, including the full directory tree and which data comes from which object file. With all this information, it should be possible to produce a pretty good approximation of the source code, however, neither IDA nor Ghidra's PowerPC decompilers are perfect, and the game is fairly large, so such a project will take a long time to complete.
     
    • Informative Informative x 8
    • Like Like x 1
    • Useful Useful x 1
    • List
  18. Clownacy

    Clownacy

    Tech Member
    929
    241
    43
    Fixed, thanks.
     
  19. Black Squirrel

    Black Squirrel

    often the real thing™ Wiki Sysop
    7,332
    1,311
    93
    Northumberland, UK
    It's wiki time. There's no need to be afraid.
    Except there's a Sonic 3 cap.

    Wasn't it a theory that during Sonic 3's development, the logo colours were inverted (i.e rather than the SONIC text being blue on yellow, it became yellow on blue).

    [​IMG]
    our proto is dated 3rd November. Not sure it means a whole lot, but it's a thing.

    My gut feeling is that Sega of America wouldn't want to put out any evidence of Sonic 3's existence until after the Christmas 1993 season, else it might undermine sales of Sonic CD or Spinball. I don't think they'd be producing merchandise until 1994, so I would vote that the calendar is wrong.
     
    • Like Like x 2
    • Informative Informative x 1
    • List
  20. Blastfrog

    Blastfrog

    See ya starside. Member
    I think it'd be really neat if there were an attempted partial reconstruction of the source code, taking the disassemblies and using as many of the known labels as possible (and extrapolating for likely ones), organize and name the ASM files the same way, etc.

    It's a clearly unfinished placeholder title screen, chances are it was already outdated by the time of that build. Given how Sonic 2's final title just suddenly showed up one build and how the final level select still has an icon for HPZ, I suspect that a lot of this type of content is developed well in advance and isn't put into the game until it's finished.

    My guess is that the logo was already redesigned and the game's title just hadn't been updated to reflect that because it was just a placeholder version that was going to be replaced. I mean, it would be pretty silly for Naka (a very busy man) to have a calendar in his office and use it so little as to forget to change it to the current month.
     
    Last edited: Apr 8, 2022