Snippet of Sonic 1 Prototype Source Code Found

Discussion in 'Discussion & Q&A' started by Novedicus, Jun 23, 2018.

  1. Novedicus

    Novedicus Well-Known Member Member

    Joined:
    Aug 26, 2013
    Messages:
    799
    So, Yuji Naka found footage of him developing Sonic 1 in February 1990. The footage shows a snippet of prototype ground collision code along with another monitor actually showing the collision data.



    I attempted to transcribe the code and this was the result:

    Code:
    *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
     
    Last edited: Jun 23, 2018
  2. MarkeyJester

    MarkeyJester Blue hair? What a freak! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,622
    Hey, nice work~

    The "bra" to the ?loop appears to actually be "beq"... This may need some heavy cleaning up and verification, but well done, the code salvaged seems mostly plausible and functional.

    I have had a quick look through the current Sonic 1 code to see if I could find anything similar in nature. There are a few instances of familiarity, but not overall.

    I believe the subroutine "scdchk" probably would have been the "FindFloor" equivilent (not necessarily an exact, but you get the idea), given that it returns what appears to be the floor distance into d1 just like the current routine. This is getting the bottom of the object's Y position (so it's definitely the floor and not walls or ceiling), then depending on if the X speed is moving right/left depends on if the right/left side of the object is checked for collision. I am judging by the fact that "btst.b #cd_right,cddot(a0)" is commented out, they were initially using the direction the object was facing before they realised it was a bad idea as an object can face one way but be moving another.

    Not sure about "boseihsub", though it's return result depends on an X speed alteration (not necessarily stopping, so probably not a wall detection), but it's a .b branch, so it'd have to be close by (unless that's a mistake during the code recreation...).

    Oh, also, the code just before it (could be relevant):
    Code:
    	###	scdtblwk,a2
    	move.w	d0,d6
    	andi.w	#7,d6
    	lsl.w	#8,d0
    	adda.w	d0,a2
    
    	move.w	d2,d1
    	lsr.w	#4,d1
    	move.w	d3,d1
    	rol.w	#1,d1
    	andi.w	#$1e,d1
    	addx.w	d1,d0
    
    	swap	d4
    	s###
     
  3. Novedicus

    Novedicus Well-Known Member Member

    Joined:
    Aug 26, 2013
    Messages:
    799
    I put the "bra.b" there, because
    code.png

    Also looking at this, "boseihsub" looks to actually be called "hoseihsub". And "move.w d0,xspeed(a0)" seems to actually be "move.w #0,xspeed(a0)". The code in the original post has been modified to reflect this now.

    Regarding "scdtbknk", according to Clownacy on Sonic Retro, that's the label for the collision block height tables (combined into one). Also, I think it's safe to assume that line uses the "lea" instruction. In the video, you can see the bottom right of the instruction name, which aligns with the "v" in "move". Plus, with how the following code uses a2, it just makes sense to me.

    code2.png

    The bottom instruction is a "swap" instruction. The register used for it is just barely visible on screen,. Looking at it, it looks like "d5" to me.

    code3.png
     
    Last edited: Jun 23, 2018
    ProjectFM likes this.
  4. Clownacy

    Clownacy UP - ON - CPU Staff

    Joined:
    Aug 15, 2014
    Messages:
    811
    Location:
    Englandland
    I guess I'll crosspost the file list too.

    Code:
                            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¥
    Presumably the '¥' means it's a folder.
     
    Last edited: Jun 24, 2018
    ProjectFM and Calvin like this.
  5. LazloPsylus

    LazloPsylus A Certain Scientific Railgun The Railgun

    Joined:
    Nov 25, 2009
    Messages:
    Location:
    Academy City
    For reference, the assembler they used was from a company called 2500AD. Sega of Japan used it extensively, and Sega of America's SDKs have mentions of this on some code that they just provide raw without translations. The 32x DDK has evidence of such, and the code in there follows the same styling. Just to give an idea of what to look up for why the syntax is as it is...
     
  6. Clownacy

    Clownacy UP - ON - CPU Staff

    Joined:
    Aug 15, 2014
    Messages:
    811
    Location:
    Englandland
    I think it was Novedicus that told me Sonic 1 was assembled with asm68k, since it accepted the same syntax as the known source snippets. At the time, I forgot about this, but that can't be the case because Sonic 1 uses an exg instruction that asm68k technically doesn't support. Just bringing that up in case a debate crops up.
     
    Novedicus and MarkeyJester like this.
  7. Novedicus

    Novedicus Well-Known Member Member

    Joined:
    Aug 26, 2013
    Messages:
    799
    Could you elaborate one the "exg instruction that asm68k technically doesn't support"?
     
  8. MarkeyJester

    MarkeyJester Blue hair? What a freak! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,622
    I believe he's refering to the fact that asm68k doesn't assemble it in the register order you supply. One instance in Sonic 1 is an "exg d1,d0", the assembler assembles it as "exg d0,d1", this doesn't affect the instruction's function, but it does cause a problem with assembling the ROM 1:1 to the original.

    Ah, on different frames of the video, the instructions seem to meld, so I wasn't sure I was seeing what I was seeing. In this shot for instance, the move looks like a bsr which is proposterous:

    upload_2018-6-24_1-25-25.png

    I agree with you, except possibly the d5 notion, but it's difficult to tell. I only wanted to put in the characters that were 100% visible on the screen, but I believe you're right about the lea and swap.
     
  9. Clownacy

    Clownacy UP - ON - CPU Staff

    Joined:
    Aug 15, 2014
    Messages:
    811
    Location:
    Englandland
    Whoops. This might get a little derail-y, but before someone tests the S1 Git disasm and finds that the exg thing is not actually true, the disasm produces a 1:1 build nowadays only because I patched its copy of asm68k.
     
  10. Novedicus

    Novedicus Well-Known Member Member

    Joined:
    Aug 26, 2013
    Messages:
    799
    I've done some of my own tests to make sure, and 2500AD's X68K assembler assembles it to C3 40, which matches the instruction in a clean Sonic 1 ROM, while ASM68K will just assemble it to C141. (Note, I used the original Win32 version of ASM68K, without any additional patches made to it)

    However, I should probably state that I think I made that claim without knowing anything about X68K beforehand, and I also believe I was referring to the Sonic 2 Nick Arcade build, not really Sonic 1. I've went and looked into this more and I now do believe Sonic 1 used X68K, because of the local label symbol in the Sonic 1 prototype code being "?" and the EXG instruction thing.

    However, regarding Sonic 2 Nick Arcade, looking at the source snippet found in the ROM, I found some things that wouldn't have worked in X68K, such as using quotation marks for INCLUDE directives and the local label symbol being "." instead of "?", neither of which I was able to get working in my version X68K (which is from 2001). I dunno if you can change the local label symbol in X68K, though, but I don't think you can get quotation marks to work in INCLUDE directives. I did find that neither ASM68K nor X68K natively support "addsym", so I have no idea what that's about.

    Gotta love it when assemblers use very similar syntax.
     
  11. Novedicus

    Novedicus Well-Known Member Member

    Joined:
    Aug 26, 2013
    Messages:
    799
    This Famitsu article covers a presentation by Yuji Naka during his early days at SEGA. It mentions the Sonic 1 prototype collision code and the Digitizer System III from the video he posted. Also a development board called M5 and a mention of competing with the SNES' rotation capabilities with software on the Genesis.
     
    AkumaYin likes this.