(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): addsym nolist include "equ.lib" include "macro.lib" list xref colichgpat xref ringpat,itempat,butapat,kanipat,hachipat,togepat xref fishpat,fish2pat,mogurapat,shimapat2,jyamapat xref musipat,sjumppat,kamerepat,arumapat,kagebpat,ballpat xref firepat,fblockpat,signalpat,bobinpat,yoganpat,yogan2pat xref usapat,yadopat,boxpat,bryukapat,daipat,break2pat,yogancpat xref batpat,z5daipat,dai2pat,switch2pat,z4daipat xref elevpat,pedalpat,steppat,funpat,sisoopat,hassyapat xref brobopat,unipat,yaripat,udaipat,dai3pat,kazaripat,kassyapat xref awapat,mizupat,boupat,benpat,fetamapat,mawarupat,hagurumapat xref patapat,yukafpat,nokopat,dai4pat,doorpat,yukaepat,fire6pat xref elepat,yukaipat,scolipat,imopat,savepat,bigringpat,btenpat xref actionsub,actwkchk,frameout,playpat,dualmodesub xref flicpat,usagipat,pengpat,azarpat,fbutapat,niwapat,risupat xref kaitenpat,prodaipat,buranko0dpat xref frntlitpat,gempat,wfallpat,pltfrmpat xref takipat,banepat,dai00pat xref redzpat,bfishpat,seahorsepat,horsepat xref stegopat,wasppat,gatorpat,bbatpat,octpat,wfish2pat,snailpat xdef edit ;------------------------------------------------------------------------------ edit: moveq #0,d0 move.b editmode,d0 move.w edit_move_tbl(pc,d0.w),d1 jmp edit_move_tbl(pc,d1.w) edit_move_tbl: dc.w editinit-edit_move_tbl dc.w editmove-edit_move_tbl editinit: addq.b #word,editmode move.w scralim_up,editstack move.w scralim_n_down,editstack2 move.w #$0000,scralim_up move.w #$0720,scralim_n_down andi.w #$07ff,playerwk+yposi andi.w #$07ff,scra_v_posit andi.w #$03ff,scrb_v_posit move.b #0,patno(a0) move.b #0,mstno(a0) cmpi.b #spgamemd,gmmode bne.b .jump0 * move.b #7-1,stageno * move.w #$000,rotspd * move.w #$000,rotdir moveq #7-1,d0 bra.b .jump1 .jump0: moveq #0,d0 move.b stageno,d0 .jump1: lea edittbl,a2 add.w d0,d0 adda.w (a2,d0.w),a2 move.w (a2)+,d6 cmp.b editno,d6 bhi.b .jump move.b #0,editno .jump: bsr.w editpatchg move.b #12,edittimer move.b #1,edittimer+1 editmove: moveq #7-1,d0 cmpi.b #spgamemd,gmmode beq.b .jump moveq #0,d0 move.b stageno,d0 .jump: lea edittbl,a2 add.w d0,d0 adda.w (a2,d0.w),a2 move.w (a2)+,d6 bsr.w editwalk * bsr.w dirsprset jmp actionsub editwalk: moveq #0,d4 move.w #1,d1 move.b swdata1+1,d4 andi.w #$0f,d4 bne.b .jump0 move.b swdata1,d0 andi.w #$0f,d0 bne.b .jump move.b #12,edittimer move.b #$0f,edittimer+1 bra.w .lend .jump: subq.b #1,edittimer bne.b .jump1 move.b #1,edittimer addq.b #1,edittimer+1 * cmpi.b #255,edittimer+1 bne.b .jump0 move.b #255,edittimer+1 .jump0: move.b swdata1,d4 .jump1: moveq #0,d1 move.b edittimer+1,d1 addq.w #1,d1 swap d1 asr.l #4,d1 move.l yposi(a0),d2 move.l xposi(a0),d3 btst.l #0,d4 *swdata+0 beq.b .jump2 sub.l d1,d2 *yposi bcc.b .jump2 moveq #0,d2 .jump2: btst.l #1,d4 *swdata+0 beq.b .jump3 add.l d1,d2 *yposi cmpi.l #$7ff0000,d2 bcs.b .jump3 move.l #$7ff0000,d2 .jump3: btst.l #2,d4 *swdata+0 beq.b .jump4 sub.l d1,d3 *xposi bcc.b .jump4 moveq #0,d3 .jump4: btst.l #3,d4 *swdata+0 beq.b .jump5 add.l d1,d3 *xposi .jump5: move.l d2,yposi(a0) move.l d3,xposi(a0) .lend: btst.b #6,swdata1+0 beq.b .jump7 btst.b #5,swdata1+1 * c button check beq.b .jump77 subq.b #1,editno bcc.b .jump6 add.b d6,editno bra.b .jump6 .jump77: btst.b #6,swdata1+1 beq.b .jump7 addq.b #1,editno cmp.b editno,d6 bhi.b .jump6 move.b #0,editno .jump6: bra.w editpatchg .jump7: btst.b #5,swdata1+1 * c button check beq.b .jump8 jsr actwkchk bne.b .worknai ;z=0:ok z=1:no move.w xposi(a0),xposi(a1) move.w yposi(a0),yposi(a1) move.b patbase(a0),actno(a1) move.b actflg(a0),actflg(a1) move.b actflg(a0),cddat(a1) andi.b #$7f,cddat(a1) moveq #0,d0 move.b editno,d0 lsl.w #3,d0 move.b 4(a2,d0.w),userflag(a1) rts .worknai: .jump8: btst.b #4,swdata1+1 * b button check beq.b .jump9 moveq #0,d0 move.w d0,editmode move.l #playpat,playerwk+patbase move.w #$0780,playerwk+sproffset tst.w dualmode ; dual mode check beq.b .end move.w #$0780/2,playerwk+sproffset .end: move.b d0,playerwk+mstno move.w d0,xposi+2(a0) move.w d0,yposi+2(a0) move.w editstack,scralim_up move.w editstack2,scralim_n_down cmpi.b #spgamemd,gmmode bne.b .jump9 * clr.w rotdir * move.w #$040,rotspd * move.l #playpat,playerwk+patbase * move.w #$0780,playerwk+sproffset move.b #02,playerwk+mstno bset.b #cd_ball,playerwk+cddat bset.b #cd_jump,playerwk+cddat .jump9: rts editpatchg: moveq #0,d0 move.b editno,d0 lsl.w #3,d0 move.l 0(a2,d0.w),patbase(a0) move.w 6(a2,d0.w),sproffset(a0) move.b 5(a2,d0.w),patno(a0) * move.b 4(a2,d0.w),userflag(a0) bsr.w dualmodesub rts dcblw macro \1,\2,\3,\4,\5 dc.l (\1)*$1000000+(\2) dc.w (\4)+(\5)*$100 dc.w (\3) endm edittbl: dc.w edit1tbl-edittbl dc.w edit2tbl-edittbl dc.w edit3tbl-edittbl dc.w edit4tbl-edittbl dc.w edit5tbl-edittbl dc.w edit6tbl-edittbl dc.w edit7tbl-edittbl edit1tbl: dc.w 14 dcblw ring_act,ringpat,$26bc,0,$00 ;1: dcblw item_act,itempat,$0680,0,$00 ;2: dcblw kani_act,kanipat,$0400,0,$00 ;3: dcblw hachi_act,hachipat,$0444,0,$00 ;4: dcblw fish_act,fishpat,$0470,0,$00 ;5: dcblw toge_act,togepat,$04a0,0,$00 ;6: dcblw shima_act,shimapat2,$4000,0,$00 ;7: dcblw jyama_act,jyamapat,$66c0,0,$00 ;8: dcblw musi_act,musipat,$04e0,0,$00 ;9: dcblw sjump_act,sjumppat,$04a8,0,$00 ;10: dcblw kamere_act,kamerepat,$249b,0,$00 ;11: dcblw kageb_act,kagebpat,$434c,0,$00 ;12: dcblw save_act,savepat,$26bc,0,$01 ;13: dcblw colichg_act,colichgpat,$26bc,0,$00 ;14: edit2tbl: edit3tbl: ;zone0d dc.w 07 dcblw ring_act,ringpat,$26bc,0,$00 ;01: dcblw item_act,itempat,$0680,0,$00 ;02: dcblw sjump_act,sjumppat,$04a8,0,$00 ;03: dcblw colichg_act,colichgpat,$07bc,0,$00 ;04: dcblw kaiten_act,kaitenpat,$e000,0,$00 ;05: dcblw prodai_act,prodaipat,$e418,0,$00 ;06: dcblw buranko_act,buranko0dpat,$2418,0,$08 ;07: edit4tbl: ;zone00 dc.w 18 dcblw ring_act,ringpat,$26bc,0,$00 ;1: dcblw item_act,itempat,$0680,0,$00 ;2: dcblw save_act,savepat,$047c,0,$01 ;3: dcblw colichg_act,colichgpat,$26bc,0,$00 ;6: dcblw taki_act,takipat,$23ae,0,$00 ;7: dcblw taki_act,takipat,$23ae,3,$02 ;7: dcblw shima_act,dai00pat,$4000,0,$01 ;8: dcblw shima_act,dai00pat,$4000,1,$0a ;8: dcblw toge_act,togepat,$2434,0,$00 ;10: dcblw sisoo_act,sisoopat,$03ce,0,$00 ;9: dcblw sjump_act,banepat,$045c,0,$80 ;3: banev dcblw sjump_act,banepat,$0470,3,$90 ;3: baneh dcblw sjump_act,banepat,$045c,6,$a0 ;3: banevr dcblw sjump_act,banepat,$043c,7,$30 ;3: bane45 dcblw sjump_act,banepat,$043c,10,$40 ;3: bane45r dcblw wasp_act,wasppat,$03e6,0,$00 ;25 "" "" dcblw snail_act,snailpat,$0402,0,$00 ;25 "" "" dcblw wfish2_act,wfish2pat,$041c,0,$00 ;21 "" "" dcblw redz_act,redzpat,$0500,0,$00 ;20: will change dcblw bfish_act,bfishpat,$2530,0,$00 ;21 "" "" dcblw seahorse_act,horsepat,$2570,0,$00 ;22 "" "" dcblw skyhorse_act,horsepat,$2570,0,$00 ;23 "" "" dcblw stego_act,stegopat,$23c4,0,$00 ;24 "" "" dcblw wasp_act,wasppat,$032c,0,$00 ;25 "" "" dcblw gator_act,gatorpat,$2300,0,$00 ;26 "" "" dcblw bbat_act,bbatpat,$2350,0,$00 ;27 "" "" dcblw oct_act,octpat,$238a,0,$00 ;28 "" "" edit5tbl: edit6tbl: edit7tbl: ;zone08 dc.w 15 dcblw ring_act,ringpat,$26bc,0,$00 ;1: dcblw item_act,itempat,$0680,0,$00 ;2: dcblw bgspr_act,frntlitpat,$e485,3,$21 ;3: dcblw wfall_act,wfallpat,$e415,4,$04 ;4: dcblw break_act,pltfrmpat,$4475,0,$00 ;5: dcblw colichg_act,colichgpat,$26bc,0,$00 ;6: dcblw redz_act,redzpat,$0500,0,$00 ;20: will change dcblw bfish_act,bfishpat,$2530,0,$00 ;21 "" "" dcblw seahorse_act,horsepat,$2570,0,$00 ;22 "" "" dcblw skyhorse_act,horsepat,$2570,0,$00 ;23 "" "" dcblw stego_act,stegopat,$23c4,0,$00 ;24 "" "" dcblw wasp_act,wasppat,$032c,0,$00 ;25 "" "" dcblw gator_act,gatorpat,$2300,0,$00 ;26 "" "" dcblw bbat_act,bbatpat,$2350,0,$00 ;27 "" "" dcblw oct_act,octpat,$238a,0,$00 ;28 "" "" ;------------------------------------------------------------------------------ align ;------------------------------------------------------------------------------ end edit2tbl: dc.w 25 dcblw ring_act,ringpat,$26bc,0,$00 ;1: dcblw item_act,itempat,$0680,0,$00 ;2: dcblw sjump_act,sjumppat,$0523,0,$00 ;3: dcblw fish2_act,fish2pat,$2486,0,$08 ;4: dcblw mogura_act,mogurapat,$84a6,2,$00 ;5: dcblw yari_act,yaripat,$03cc,0,$00 ;6: dcblw yari_act,yaripat,$03cc,3,$02 ;7: dcblw box_act,boxpat,$43de,0,$00 ;8: dcblw switch2_act,switch2pat,$0513,0,$00 ;9: dcblw toge_act,togepat,$051b,0,$00 ;10: dcblw dai_act,udaipat,$43bc,0,$04 ;11: dcblw dai3_act,dai3pat,$43e6,0,$01 ;12: dcblw dai3_act,dai3pat,$43e6,1,$13 ;13: dcblw dai3_act,dai3pat,$43e6,0,$05 ;14: dcblw kazari_act,kazaripat,$443e,0,$00 ;15: dcblw dai3_act,dai3pat,$43e6,2,$27 ;16: dcblw dai3_act,dai3pat,$43e6,3,$30 ;17: dcblw kassya_act,kassyapat,$03f6,0,$7f ;18: dcblw uni_act,unipat,$0467,0,$00 ;19: dcblw awa_act,awapat,$8348,19,$84 ;20: dcblw mizu_act,mizupat,$c259,2,$02 ;21: dcblw mizu_act,mizupat,$c259,9,$09 ;22: dcblw bou_act,boupat,$43de,0,$00 ;23: dcblw ben_act,benpat,$4328,0,$02 ;24: dcblw save_act,savepat,$26bc,0,$01 ;25: * dcblw dai4_act,dai4pat,$41f0,4,$80 ;25: edit3tbl: dc.w 18 dcblw ring_act,ringpat,$26bc,0,$00 ;1: dcblw item_act,itempat,$0680,0,$00 ;2: dcblw hachi_act,hachipat,$0444,0,$00 ;3: dcblw toge_act,togepat,$051b,0,$00 ;4: dcblw sjump_act,sjumppat,$0523,0,$00 ;5: dcblw mfire_act,firepat,$0345,0,$00 ;6: dcblw fblock_act,fblockpat,$4000,0,$00 ;7: dcblw myogan_act,yoganpat,$63a8,0,$00 ;8: dcblw yogan2_act,yogan2pat,$63a8,0,$00 ;9: dcblw box_act,boxpat,$42b8,0,$00 ;10: dcblw yado_act,yadopat,$247b,0,$00 ;11: dcblw bryuka_act,bryukapat,$42b8,0,$00 ;12: dcblw dai_act,daipat,$02b8,0,$00 ;13: dcblw break2_act,break2pat,$62b8,0,$00 ;14: dcblw yoganc_act,yogancpat,$8680,0,$00 ;15: dcblw bat_act,batpat,$04b8,0,$00 ;16: dcblw imo_act,imopat,$24ff,0,$00 ;17: dcblw save_act,savepat,$26bc,0,$01 ;18: edit4tbl: dc.w 15 dcblw ring_act,ringpat,$26bc,0,$00 ;1: dcblw item_act,itempat,$0680,0,$00 ;2: dcblw elev_act,elevpat,$4000,0,$00 ;3: dcblw break2_act,break2pat,$44e0,2,$00 ;4: dcblw shima_act,z4daipat,$4000,0,$00 ;5: dcblw pedal_act,pedalpat,$4000,0,$00 ;6: dcblw step_act,steppat,$4000,0,$00 ;7: dcblw fun_act,funpat,$43a0,0,$00 ;8: dcblw sisoo_act,sisoopat,$0374,0,$00 ;9: dcblw sjump_act,sjumppat,$0523,0,$00 ;10: dcblw mfire_act,firepat,$0480,0,$00 ;11: dcblw bgspr_act,hassyapat,$44d8,0,$00 ;12: dcblw brobo_act,brobopat,$0400,0,$00 ;13: dcblw uni_act,unipat,$2429,0,$00 ;14: dcblw save_act,savepat,$26bc,0,$01 ;15: edit5tbl: dc.w 15 dcblw ring_act,ringpat,$26bc,0,$00 ;1: dcblw item_act,itempat,$0680,0,$00 ;2: dcblw toge_act,togepat,$051b,0,$00 ;3: dcblw sjump_act,sjumppat,$0523,0,$00 ;4: dcblw aruma_act,arumapat,$04b8,0,$00 ;5: dcblw signal_act,signalpat,$0000,0,$00 ;6: dcblw bobin_act,bobinpat,$0380,0,$00 ;7: dcblw kani_act,kanipat,$0400,0,$00 ;8: dcblw hachi_act,hachipat,$0444,0,$00 ;9: dcblw yado_act,yadopat,$247b,0,$00 ;10: dcblw shima_act,z5daipat,$4000,0,$00 ;11: dcblw dai2_act,dai2pat,$4000,0,$00 ;12: dcblw switch2_act,switch2pat,$0513,0,$00 ;13: dcblw imo_act,imopat,$24ff,0,$00 ;14: dcblw save_act,savepat,$26bc,0,$01 ;15: edit6tbl: dc.w 29 dcblw ring_act,ringpat,$26bc,0,$00 ;1: dcblw item_act,itempat,$0680,0,$00 ;2: dcblw brobo_act,brobopat,$0400,0,$00 ;3: dcblw uni_act,unipat,$0429,0,$00 ;4: dcblw imo_act,imopat,$22b0,0,$00 ;5: dcblw buranko_act,fetamapat,$4391,2,$07 ;6: dcblw haguruma_act,hagurumapat,$c344,00,$e0 ;7: dcblw dai_act,daipat,$22c0,2,$28 ;8: dcblw switch2_act,switch2pat,$0513,0,$00 ;9: dcblw pata_act,patapat,$4492,0,$03 ;10: dcblw pata_act,yukafpat,$04df,0,$83 ;11: dcblw noko_act,nokopat,$43b5,0,$02 ;12: dcblw break2_act,break2pat,$43f5,0,$00 ;13: dcblw dai_act,daipat,$4460,3,$39 ;14: dcblw dai4_act,dai4pat,$22c0,0,$00 ;15: dcblw door_act,doorpat,$42e8,0,$00 ;16: dcblw dai4_act,dai4pat,$22c0,1,$13 ;17: dcblw noko_act,nokopat,$43b5,0,$01 ;18: dcblw dai4_act,dai4pat,$22c0,1,$24 ;19: dcblw noko_act,nokopat,$43b5,2,$04 ;20: dcblw dai4_act,dai4pat,$22c0,1,$34 ;21: dcblw yukae_act,yukaepat,$44c3,0,$00 ;22: dcblw fire6_act,fire6pat,$83d9,0,$64 ;23: dcblw fire6_act,fire6pat,$83d9,11,$64 ;24: dcblw ele_act,elepat,$047e,0,$04 ;25: dcblw yukai_act,yukaipat,$42f0,0,$00 ;26: dcblw scoli_act,scolipat,$8680,0,$11 ;27: dcblw buta_act,butapat,$2302,0,$04 ;28: dcblw save_act,savepat,$26bc,0,$01 ;29: * dcblw ring_act,playpat,$0780,50,$00 ;28: * dcblw usa_act,usapat,$0448,0,$00 ;5: * dcblw mawaru_act,mawarupat,$4348,16,$00 ;7: edit7tbl: dc.w 02 *13 dcblw ring_act,ringpat,$26bc,0,$00 ;1: dcblw ring_act,ringpat,$26bc,8,$00 ;2: * dcblw bobin_act,bobinpat,$0380,0,$00 ;2: * dcblw usagi_act,flicpat,$05a0,0,$0a ;3 * dcblw usagi_act,flicpat,$05a0,0,$0b ;4 * dcblw usagi_act,flicpat,$05a0,0,$0c ;5 * dcblw usagi_act,usagipat,$0553,0,$0d ;6 * dcblw usagi_act,usagipat,$0553,0,$0e ;7 * dcblw usagi_act,pengpat,$0573,0,$0f ;8 * dcblw usagi_act,pengpat,$0573,0,$10 ;9 * dcblw usagi_act,azarpat,$0585,0,$11 ;10 * dcblw usagi_act,fbutapat,$0593,0,$12 ;11 * dcblw usagi_act,niwapat,$0565,0,$13 ;12 * 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: Spoiler 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): *cd_walk equ 0*2 *cd_jump equ 1*2 *cd_up equ 2*2 *cd_down equ 3*2 updotmax equ -4 downdotmax equ 4 jumpdotmax equ 8 ;sprvo equ $1c ;sprho equ $1d ;sprvs equ $1e ;sprhs equ $1f ;------------------------------------------------------------------------ ; foot colition ; ;col: move.w yposi(a0),d4 move.b sprvo(a0),d1 add.b sprvs(a0),d1 ext.w d1 add.w d1,d4 move.w xposi(a0),d5 move.b sprho(a0),d1 ext.w d1 add.w d1,d5 move.w xspeed(a0),scrhithz ?loop: move.w d4,d2 move.w d5,d3 moveq #0,d0 move.b sprhs(a0),d0 tst.w xspeed(a0) bpl.b ?jump * btst.b #cd_right,cddot(a0) * beq.b ?jump neg.w d0 ?jump: add.w d0,d3 bsr.w scdchk tst.w d1 beq.b ?end bpl.b ?down ?up: cmp.w #updotmax,d1 blt.b ?nomove add.w d1,yposi(a0) ?end: rts ?nomove: bsr.b hoseihsub bra.b ?loop move.w #0,xspeed(a0) rts ?down: move.w d1,d6 swap d6 ?down2: move.w d4,d2 move.w d6,d3 moveq #0,d0 move.b sprhs(a0),d0 tst.w xspeed(a0) bpl.b ?jump3 * btst #cd_left,cddot(a0) * bne.s ?jump3 neg.w d0 ?jump3: add.w d0,d3 bsr.w scdchk tst.w d1 beq.b ?end2 bpl.b ?down1 ?up2: cmp.w #updotmax,d1 blt.b ?nomove2 Also visible in the footage was a brief glance of a partial file list: Code (Text): ENEMY.ASM FCOL.ASM FCOL.BAK FCOL3.ASM GAME.ASM INT.ASM LOGO.ASM MACRO.LIB MAIN.ASM ML.EVT ML.S28 OBJ¥ S S.CMD SCORE.ASM 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): ; 圧縮前 $8000 圧縮後 $2c00 圧縮率 34.4% セル数 1024 dc.b $1d,$7f,$00,$ff,$f8,$7e,$04,$01,$fb,$02,$00,$03,$04,$05,$04,$80 dc.b $ff,$fa,$ff,$07,$54,$0b,$54,$0a,$50,$0c,$50,$ff,$8f,$0d,$54,$0f dc.b $54,$0e,$50,$10,$50,$11,$52,$19,$52,$18,$ff,$ff,$fc,$1a,$52,$1b dc.b $51,$8a,$51,$8b,$52,$1c,$02,$1e,$02,$1f,$02,$2a,$9f,$ff,$02,$2b dc.b $01,$8c,$01,$8d,$f4,$1d,$02,$2c,$02,$2d,$01,$ff,$f4,$88,$01,$89 dc.b $01,$8e,$01,$8f,$02,$1a,$e4,$02,$2e,$02,$46,$c0,$2f,$e0,$ff,$1b dc.b $ec,$fc,$dc,$00,$70,$02,$c4,$d4,$ee,$18,$02,$19,$01,$3f,$f6,$fd dc.b $e4,$e6,$04,$2e,$04,$2d,$04,$9d,$fe,$77,$bd,$00,$be,$f9,$50,$31 dc.b $54,$30,$54,$2f,$7f,$f8,$56,$03,$56,$02,$56,$01,$05,$ff,$f0,$52 dc.b $1d,$52,$1e,$e1,$9f,$52,$1f,$fc,$50,$3e,$54,$3c,$56,$04,$54,$36 dc.b $09,$e0,$c4,$9c,$f8,$ea,$1a,$50,$48,$24,$41,$ba,$a4,$b2,$fc,$fc dc.b $21,$9a,$f2,$80,$f6,$9c,$fc,$1d,$5e,$92,$68,$01,$8a,$01,$8b,$ee dc.b $fc,$68,$f2,$fd,$d5,$fd,$ce,$f7,$f7,$80,$fd,$f0,$f8,$0f,$04,$35 dc.b $f0,$f8,$0d,$54,$3f,$54,$39,$7f,$fe,$54,$38,$01,$ff,$02,$00,$06 dc.b $00,$60,$1a,$54,$43,$54,$ff,$f3,$42,$55,$fe,$55,$fd,$55,$fc,$55 dc.b $fb,$54,$46,$a4,$1c,$ff,$11,$50,$49,$54,$44,$54,$52,$50,$51,$54 dc.b $50,$80,$b2,$12,$8e,$8f,$4e,$06,$fc,$f2,$f2,$3c,$90,$fa,$58,$5c dc.b $80,$f8,$20,$60,$f8,$20,$40,$f3,$02,$0a,$02,$2c,$3c,$0b,$70,$40 dc.b $f6,$86,$2a,$54,$29,$52,$f4,$62,$f8,$11,$c0,$f1,$2a,$52,$2b,$bc dc.b $f4,$fc,$1a,$62,$f1,$72,$6e,$f2,$f2,$78,$00,$16,$bd,$fe,$00,$17 dc.b $fc,$f8,$0c,$18,$00,$19,$fc,$f8,$0c,$e0,$f8,$2e,$54,$06,$54,$04 dc.b $50,$fb,$be,$08,$50,$09,$f8,$fe,$50,$12,$50,$13,$fc,$f8,$0b,$00 dc.b $14,$00,$15,$f7,$fc,$fc,$f8,$0c,$1e,$00,$1f,$fc,$f8,$0c,$20,$00 dc.b $21,$fc,$f4,$50,$f5,$f7,$07,$50,$f6,$50,$f7,$e8,$fe,$50,$f8,$50 dc.b $87,$52,$1b,$3c,$1f,$fd,$e0,$fc,$50,$f9,$50,$85,$40,$ae,$f1,$50 dc.b $fa,$50,$fb,$07,$e1,$50,$fc,$50,$8b,$f6,$86,$f1,$2a,$1c,$50,$2f dc.b $b2,$8c,$50,$8d,$50,$8e,$24,$f1,$24,$ee,$0a,$24,$9a,$eb,$92,$f3 dc.b $7c,$f2,$0a,$f2,$e0,$ec,$af,$9f,$dc,$05,$6d,$ae,$ef,$60,$f2,$1a dc.b $06,$25,$01,$89,$45,$94,$e4,$4e,$ed,$e0,$e8,$2a,$f3,$11,$ae,$e0 dc.b $f0,$c0,$28,$02,$29,$38,$f6,$00,$8c,$c0,$fd,$ce,$e4,$a0,$59,$44 dc.b $c0,$8d,$ce,$00,$ea,$bc,$e0,$0b,$a8,$d6,$fc,$1b,$dc,$e2,$f8,$f0 dc.b $68,$ec,$ea,$bd,$f8,$e5,$20,$f0,$15,$a0,$e8,$09,$20,$f0,$16,$50 dc.b $54,$0d,$20,$f5,$1b,$52,$1c,$92,$a0,$dc,$e4,$60,$e5,$a8,$6e,$e2 dc.b $80,$6e,$e4,$82,$28,$12,$fc,$4e,$e2,$80,$6e,$e2,$44,$ee,$e7,$fa dc.b $00,$66,$8e,$fe,$56,$25,$51,$8c,$c0,$c2,$e4,$bc,$f0,$fe,$38,$02 dc.b $15,$d8,$80,$fc,$06,$f8,$9d,$59,$f0,$12,$02,$11,$02,$10,$80,$fc dc.b $f6,$5a,$30,$fe,$e0,$ee,$13,$80,$2e,$52,$2f,$f9,$6d,$7f,$f5,$05 dc.b $f9,$02,$16,$00,$23,$00,$24,$e4,$f3,$f2,$f1,$80,$ea,$50,$2b,$20 dc.b $8c,$50,$76,$5a,$f3,$84,$51,$89,$40,$a0,$5c,$58,$60,$6e,$00,$f9 dc.b $11,$95,$ae,$f5,$1b,$5a,$f6,$6a,$e3,$6a,$fc,$02,$82,$e8,$10,$96 dc.b $ee,$ea,$47,$0f,$ce,$f2,$13,$02,$14,$76,$b2,$f2,$16,$02,$17,$44 dc.b $8c,$ee,$e4,$88,$ea,$33,$fa,$d4,$04,$23,$f2,$e4,$e6,$fc,$54,$27 dc.b $54,$4f,$e4,$94,$54,$93,$04,$92,$e0,$ea,$e4,$f2,$54,$af,$af,$85 dc.b $54,$97,$04,$98,$c6,$fd,$52,$f3,$54,$87,$54,$99,$bc,$fc,$ff,$ff dc.b $00,$e8,$39,$50,$6b,$50,$6c,$50,$6d,$50,$73,$50,$74,$50,$75,$50 dc.b $76,$50,$ff,$8f,$77,$50,$78,$50,$79,$50,$15,$50,$7a,$50,$7b,$50 dc.b $7c,$5e,$51,$f8,$20,$ee,$12,$00,$13,$fc,$f8,$0c,$00,$e8,$0e,$08 dc.b $6e,$e2,$4d,$d2,$fc,$f2,$bc,$d2,$8a,$32,$ee,$f6,$60,$04,$f0,$fa dc.b $22,$fa,$00,$23,$06,$5c,$32,$fc,$80,$f1,$26,$54,$25,$67,$c1,$50 dc.b $27,$f6,$58,$20,$80,$f2,$20,$60,$d1,$51,$55,$f1,$6d,$d8,$80,$f3 dc.b $cc,$f3,$28,$f1,$80,$f0,$09,$12,$dc,$2d,$a3,$04,$e1,$d8,$ea,$18 dc.b $84,$d6,$a0,$d8,$4f,$41,$80,$f4,$02,$25,$01,$24,$ae,$05,$c0,$80 dc.b $f4,$88,$23,$f0,$25,$92,$12,$05,$fa,$ab,$02,$d6,$e0,$ff,$92,$f3 dc.b $e0,$fc,$8a,$f1,$e0,$86,$a7,$88,$10,$88,$01,$f9,$01,$fa,$80,$5d dc.b $21,$05,$fa,$60,$fc,$50,$28,$80,$fe,$e0,$e9,$fc,$2d,$1b,$94,$84 dc.b $bc,$c9,$52,$86,$c0,$ce,$64,$ea,$2a,$7c,$74,$19,$fa,$e9,$76,$d2 dc.b $58,$55,$05,$48,$01,$5d,$f9,$5e,$f2,$fc,$f4,$57,$05,$52,$85,$e9 dc.b $1b,$05,$49,$f4,$fe,$02,$d5,$ff,$f2,$f4,$f8,$09,$ff,$f8,$32,$32 dc.b $d6,$96,$ca,$ff,$d8,$38,$50,$39,$50,$3f,$a2,$49,$a2,$4a,$fc,$54 dc.b $ea,$fe,$7f,$af,$02,$0d,$02,$0e,$02,$0f,$06,$0d,$cc,$f8,$0a,$c1 dc.b $00,$c2,$bc,$f8,$0c,$d2,$f9,$f0,$f8,$2c,$c0,$e1,$f0,$07,$04,$05 dc.b $f1,$07,$51,$bf,$aa,$75,$50,$c1,$50,$c2,$54,$31,$a0,$c6,$ac,$da dc.b $ee,$f5,$46,$f2,$aa,$20,$60,$f3,$e4,$f3,$dc,$de,$d2,$cc,$6e,$de dc.b $d4,$52,$d8,$0c,$b2,$ac,$e2,$e8,$5c,$f3,$d8,$c8,$e2,$82,$b2,$20 dc.b $de,$34,$f3,$ec,$1a,$f2,$84,$db,$b8,$84,$6a,$e8,$fe,$c4,$b8,$c0 dc.b $b8,$49,$20,$fc,$c0,$b8,$10,$1b,$2d,$e8,$08,$f3,$00,$f1,$51,$fc dc.b $da,$8a,$f2,$bd,$ae,$d7,$97,$01,$73,$06,$99,$fc,$fe,$98,$f6,$e4 dc.b $04,$0a,$fc,$f6,$f4,$9b,$7f,$46,$f6,$06,$9f,$02,$e2,$0a,$98,$0a dc.b $f4,$e6,$38,$e9,$fe,$e3,$04,$00,$fa,$f4,$fc,$50,$f5,$93,$43,$e2 dc.b $06,$91,$02,$fe,$92,$f8,$f0,$07,$84,$98,$06,$96,$02,$fe,$b0,$f8 dc.b $91,$20,$06,$95,$f0,$c4,$fe,$9a,$8d,$87,$f8,$06,$9c,$f0,$e4,$02 dc.b $e5,$aa,$08,$fe,$02,$bc,$f8,$fa,$eb,$32,$50,$33,$50,$34,$9f,$ff dc.b $50,$b4,$50,$b5,$50,$b6,$fc,$b7,$50,$b8,$50,$b9,$54,$e1,$fb,$b9 dc.b $f0,$fe,$ba,$f0,$bb,$f0,$bc,$68,$d2,$06,$19,$fc,$ff,$f4,$ae,$fc dc.b $ad,$fc,$ac,$fc,$ab,$fc,$aa,$f0,$fc,$a6,$fc,$fb,$8b,$a5,$fc,$a4 dc.b $48,$d6,$30,$be,$3c,$a3,$3c,$a2,$38,$d0,$09,$c5,$56,$f0,$a1,$58 dc.b $c0,$0b,$f0,$a0,$f0,$f8,$0e,$9f,$40,$b0,$52,$58,$d5,$b5,$6e,$80 dc.b $f7,$58,$d5,$80,$f0,$0d,$f1,$72,$cc,$80,$f7,$01,$6d,$c0,$f8,$1e dc.b $58,$45,$fd,$48,$f6,$bc,$fc,$c0,$c0,$ee,$9c,$ea,$18,$a1,$6d,$01 dc.b $4b,$f8,$48,$05,$55,$8e,$cc,$a6,$f0,$52,$05,$57,$d1,$a0,$05,$56 dc.b $ec,$38,$ea,$88,$a0,$32,$cb,$c0,$fe,$ec,$fe,$c6,$f0,$ec,$fe,$01 dc.b $1f,$02,$5d,$01,$ff,$bf,$0f,$01,$10,$02,$45,$02,$30,$02,$31,$c1 dc.b $da,$c2,$33,$c2,$32,$ff,$cf,$d2,$e2,$02,$34,$02,$35,$02,$32,$c1 dc.b $db,$c2,$3c,$02,$3d,$7f,$00,$f0,$47,$02,$36,$02,$37,$c1,$dc,$e0 dc.b $ea,$0e,$ff,$f0,$44,$ce,$c5,$d8,$c1,$d9,$02,$40,$02,$f0,$ff,$41 dc.b $f0,$c1,$d4,$c1,$d5,$c1,$d6,$c1,$d7,$02,$3e,$02,$ff,$3f,$3f,$02 dc.b $46,$c0,$c1,$c0,$c2,$c2,$3a,$c2,$3b,$02,$38,$02,$39,$01,$02,$d8 dc.b $f0,$d0,$c8,$02,$7e,$c0,$c4,$f8,$30,$01,$29,$01,$2a,$02,$44,$92 dc.b $d6,$aa,$c0,$a3,$aa,$80,$d3,$8b,$2e,$ca,$d3,$a0,$c9,$9a,$d2,$a4 dc.b $cd,$aa,$eb,$80,$cf,$a4,$cd,$66,$d2,$a8,$ce,$80,$d6,$04,$5e,$72 dc.b $ce,$60,$d5,$5d,$97,$f6,$54,$61,$54,$60,$e4,$fc,$ea,$52,$1c,$e0 dc.b $a9,$63,$54,$ff,$da,$62,$54,$67,$54,$66,$54,$65,$54,$64,$f2,$bc dc.b $e0,$ac,$54,$e0,$a9,$7f,$e1,$51,$fb,$51,$fc,$51,$fd,$51,$fe,$80 dc.b $e8,$0f,$fc,$50,$ba,$5b,$50,$50,$bb,$50,$80,$e8,$14,$0c,$80,$e8 dc.b $0c,$f0,$80,$e8,$7b,$e0,$d8,$3f,$fd,$ef,$ec,$e9,$9a,$f2,$1e,$54 dc.b $9d,$54,$9c,$54,$90,$54,$8f,$92,$b7,$1c,$1f,$d5,$54,$8e,$54,$8d dc.b $50,$50,$e0,$e8,$ba,$b2,$9e,$80,$9a,$aa,$aa,$1d,$9c,$bb,$c4,$da dc.b $7c,$ea,$ba,$b2,$36,$db,$f8,$9d,$00,$be,$aa,$f4,$a0,$c8,$09,$8e dc.b $a6,$0e,$a3,$92,$c6,$c0,$9a,$d4,$04,$24,$00,$c2,$ff,$5a,$32,$f0 dc.b $09,$e6,$54,$4f,$54,$4e,$54,$4d,$54,$4c,$54,$d5,$7e,$59,$54,$9c dc.b $c3,$a8,$b1,$00,$ea,$1c,$80,$99,$57,$54,$56,$54,$5f,$11,$55,$60 dc.b $ff,$aa,$ea,$80,$9a,$a0,$fe,$06,$bc,$95,$54,$68,$d6,$5c,$d6,$12 dc.b $9c,$56,$dc,$e4,$9a,$ea,$84,$c4,$8f,$3f,$5c,$ac,$51,$09,$83,$f2 dc.b $62,$02,$63,$01,$88,$05,$7c,$a2,$f6,$51,$00,$91,$09,$24,$f2,$fc dc.b $10,$25,$05,$64,$91,$f0,$96,$b2,$ee,$61,$1d,$92,$c1,$f2,$50,$91 dc.b $a8,$c2,$fc,$fe,$f0,$96,$ac,$b0,$f0,$48,$b1,$8d,$64,$e1,$20,$c3 dc.b $f0,$00,$9e,$8c,$aa,$92,$95,$78,$f2,$60,$f8,$09,$8e,$93,$92,$f3 dc.b $d1,$f5,$72,$90,$09,$1f,$36,$44,$ef,$00,$53,$40,$b1,$fa,$f1,$50 dc.b $4a,$ff,$ff,$50,$4b,$50,$4c,$50,$4d,$50,$4e,$50,$4f,$50,$55,$50 dc.b $56,$50,$57,$3d,$48,$50,$3d,$f8,$f5,$18,$50,$40,$f6,$fc,$f7,$2a dc.b $a9,$2a,$20,$9a,$b6,$bb,$20,$90,$0a,$e8,$ee,$fe,$e8,$a4,$a4,$ff dc.b $e4,$f4,$c6,$80,$de,$0e,$b5,$50,$46,$50,$47,$50,$48,$50,$3f,$c2 dc.b $3a,$50,$3b,$50,$42,$50,$43,$a0,$ff,$51,$5f,$55,$50,$52,$50,$44 dc.b $50,$45,$d8,$f1,$3c,$f2,$e4,$c3,$2e,$f8,$09,$a0,$8e,$95,$05,$a0 dc.b $fd,$80,$88,$0a,$e0,$ef,$0e,$b2,$c5,$ce,$55,$62,$00,$bb,$5c,$f8 dc.b $0a,$60,$f6,$5c,$8a,$3c,$5a,$2b,$2a,$d2,$fe,$01,$12,$a0,$09,$52 dc.b $f3,$f0,$5a,$f3,$8e,$fe,$30,$91,$f0,$b6,$f2,$ea,$8a,$32,$c0,$d1 dc.b $96,$fd,$2e,$bd,$f0,$b2,$fe,$12,$cb,$2c,$c0,$40,$fd,$0e,$a0,$5c dc.b $8f,$be,$56,$a0,$a6,$4e,$a2,$51,$82,$b8,$09,$88,$a1,$53,$22,$b8 dc.b $2d,$c0,$82,$f5,$27,$f0,$f8,$0b,$a6,$b9,$c0,$81,$54,$34,$54,$33 dc.b $54,$32,$f0,$ed,$92,$40,$d1,$e0,$ea,$1a,$c0,$82,$54,$37,$c0,$81 dc.b $68,$68,$55,$72,$f2,$58,$aa,$81,$41,$00,$e0,$60,$8e,$b0,$0a,$c0 dc.b $80,$09,$7a,$b0,$0a,$bf,$28,$80,$c0,$40,$c0,$be,$cc,$a3,$cc,$00 dc.b $d8,$0a,$f0,$00,$d8,$0c,$8a,$ba,$f0,$00,$d8,$0c,$f0,$00,$d8,$0a dc.b $88,$fe,$54,$b4,$7f,$fd,$cc,$f4,$f4,$bc,$f4,$bb,$f4,$ba,$f4,$80 dc.b $d1,$7c,$d1,$bf,$50,$c0,$f8,$ff,$fa,$aa,$f8,$ab,$f8,$ac,$f8,$ad dc.b $f8,$ae,$d4,$91,$26,$b7,$f8,$b1,$f8,$fb,$dd,$b2,$f8,$b3,$16,$b0 dc.b $0b,$38,$af,$38,$b0,$30,$06,$b0,$0c,$38,$a9,$f0,$f8,$0e,$d6,$ed dc.b $a8,$f0,$f8,$0e,$a7,$f0,$f8,$0d,$ff,$f8,$13,$f0,$d5,$f0,$f8,$0e dc.b $d6,$f0,$f8,$0e,$d7,$fd,$ff,$05,$6e,$f2,$f8,$09,$f4,$d8,$f0,$d9 dc.b $55,$71,$55,$70,$55,$6f,$50,$dd,$7f,$7f,$f0,$de,$f0,$df,$f0,$e0 dc.b $f2,$18,$00,$f1,$72,$51,$73,$50,$ef,$f0,$d8,$f0,$ff,$f1,$f2,$00 dc.b $d9,$a2,$fe,$1f,$a1,$88,$7f,$70,$a1,$89,$a2,$2c,$a2,$2d,$a2,$1a dc.b $f4,$f8,$c8,$67,$02,$59,$5d,$ef,$a0,$6c,$f0,$fe,$f2,$5a,$00,$d4 dc.b $9b,$f8,$4c,$2d,$00,$2e,$ac,$e8,$0a,$2f,$ff,$6d,$50,$30,$50,$31 dc.b $50,$36,$50,$37,$50,$3c,$40,$df,$1e,$40,$d9,$1b,$ad,$6a,$7c,$e7 dc.b $54,$e2,$8d,$88,$94,$f8,$d4,$a0,$8c,$92,$8e,$ee,$cb,$8f,$05,$19 dc.b $ee,$bf,$2a,$e2,$f4,$80,$88,$0a,$e6,$04,$14,$f2,$e0,$ba,$f6,$ee 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): ; 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.
There was an old thread about Sonic CD's symbol lists: https://forums.sonicretro.org/index.php?threads/original-sonic-cd-symbol-label-list.17557/ Unfortunately some of the Pastebin links are dead. Are these available in full anywhere? People were able to figure out what all of the enemies were labeled, but I don't think it's been done for the animals.
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.
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.
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.
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!
Don't forget this! https://forums.sonicretro.org/index...riginal-s1-cd-2-3-k-source-code-labels.38990/
Might as well mention it here since I mentioned it in the Supreme Topic of Other Knowledge: 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. There was a similar model, the NEC PC-98XL that looks almost identical but is just a bit smaller. 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. (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 (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.
I posted the higher quality photo before. Here it is if you want to see it again: 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.
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.) Assuming it IS the actual calendar... The front cover looks like this: 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.
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.
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.
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.
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). 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.
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.