[Sonic 1 Github]: MSU-MD Implementation (Follow it at your own risk)

Discussion in 'Tutorials' started by Red2010 is now, Aug 16, 2024.

  1. Red2010 is now

    Red2010 is now A Normal RomHacker with occupations. Member

    Joined:
    Apr 24, 2023
    Messages:
    53
    Location:
    Somewhere in Spain
    Hello! It's been a while since I made guides for this site. So it was about time to do it.

    A few years ago, Sonic hacks began to appear, which included the ability to play CD quality music in the game. (Although they have been developing since the last decade)

    Many still don't know how to do this, and decide to install modifications to the DAC Channel to use PCM music, which when making a larger hack rom ends up being a space inconvenience in the long term.

    So if you are one of those people who want CD quality music without spending so much space on a rom without mappers for Sonic 1, this is your guide.

    Quick explanation of what MSU-MD is:

    MSU-MD is a driver that is installed on Sega Genesis games to enable Sega CD Mode 1. In short, it gives the game access to use the Sega CD. BUT only for music.

    If you want to access more features of the Sega CD through a Sega Genesis cartridge, I recommend you look elsewhere because I won't teach you how to turn on Mode 1 completely here.

    With that explained we can now move on to the guide itself:

    This guide is very prone to failure so it is only recommended if you want to try and fail constantly

    Installing the Driver:

    You don't have to be a genius to know what to do in a first step like this
    I'll also be basing this Sonic 1 mod disassembly for this guide.

    Now the installation starts inside the game:
    After:
    Code:
    ZoneCount:    equ 6    ; discrete zones are: GHZ, MZ, SYZ, LZ, SLZ, and SBZ
    We will insert:
    Code:
    ; MSU-MD vars
    HW_version        EQU    $A10001                    ; hardware version in low nibble
                                                ; bit 6 is PAL (50Hz) if set, NTSC (60Hz) if clear
                                                ; region flags in bits 7 and 6:
                                                ;         USA NTSC = $80
                                                ;         Asia PAL = $C0
                                                ;         Japan NTSC = $00
                                                ;         Europe PAL = $C0
    MCD_STAT:       equ $A12020                 ; 0-ready, 1-init, 2-cmd busy
    MCD_CMD:        equ $A12010
    MCD_ARG:        equ $A12011
    MCD_CMD_CK:     equ $A1201F
    v_LAST_MSU      equ $FFF60E
    In EntryPoint. Right after the label we will insert this:

    Code:
            btst    #$6,(HW_version).l          ; Check for PAL or NTSC, 0=60Hz, 1=50Hz
            bne.s    jmpLockout                    ; if !=0, branch to lockout
          
            jsr     MSUMD_DRV
            tst.b     d0                            ; if 1: no CD Hardware found
            bne.s    jmpLockout                    ; if no, branch to lockout
            move.w     #($1500|255),MCD_CMD        ; Set CD Volume to MAX
            addq.b     #1,MCD_CMD_CK                 ; Increment command clock
          
            bra.s   msuOK                       ; skip jmpLockout
          
    jmpLockout:
            jmp     msuLockout
    
    msuOK:
    With this we would only need to include this at the end of the file:
    Code:
    MSUMD_DRV:  binclude  "sound\msu-drv.bin"
            even
          
    msuLockout:     binclude "msuLockout.bin"
            even
    Although we still have a long way to go, so let's continue.

    Initialize it in Game Modes:

    I'm going to remove the mentions on GM_Sega since they are not very relevant and can disable the Sega Scream

    In GM_Title we should comment:
    Code:
            move.b    #bgm_Title,d0
            bsr.w    PlaySound_Special    ; play title screen music
    and instead put:
    Code:
            jsr     msuPlayTrack_10
    Later we will see how to make the game detect if there is an active Sega CD to keep the FM songs.

    In Level_FadeDemo just after the label we will put this:
    Code:
            jsr     msuStop
    In Gm Special I commented the following:
    Code:
            move.w    #bgm_SS,d0
            bsr.w    PlaySound    ; play special stage BG    music
    and instead put:
    Code:
            jsr     msuPlayTrack_09
    In loc_47D4 I commented the following:
    Code:
            move.w    #bgm_GotThrough,d0
            jsr    (PlaySound_Special).l     ; play end-of-level music
    and instead put:
    Code:
         jsr     msuPlayTrack_14
    And finally, in GM_Ending put this after bgm_Stop:
    Code:
            jsr msuStop
    Don't delete the code we just mentioned yet. It will be useful later...

    There are still several steps left so keep going.

    Modifying the Sound Driver from the inside
    This will be the shortest of the guide but still. Pay attention.

    In .backupramloop Before:
    Code:
            move.b    #$80,f_1up_playing(a6)
    put this:
    Code:
            jsr     msuStop
    In .nextpsg Before:
    Code:
            clr.b    f_1up_playing(a6)
    put this:
    Code:
            jsr     msuResume
    With that, it's done. You just need to modify a few more files and the MSU-MD is ready.

    Modifying more files (I want to kill myself. This guide became too long for me)
    In PauseGame.asm which is located in _inc. Right in Pause_StopGame we will add this:
    Code:
            jsr msuStop
    In the same file only in Pause_EndMusic We will add this too:
    Code:
            jsr msuResume
    
    in GotThroughAct. Commented This:
    Code:
            move.w    #bgm_GotThrough,d0
            jsr    (PlaySound_Special).l    ; play "Sonic got through" music
    And Put This:
    Code:
            jsr     msuPlayTrack_14
    On Sonic Display Add this:
    Code:
            move.b    #0,(v_shoes).w    ; This Not
            jsr     msuRestoreTrackSpeed     ; This yes
    And Comment This:
    Code:
            jmp    (PlaySound).l    ; run music at normal speed
    Modifying Sub PlaySound
    This will probably be the biggest code we will have to do. Pay close attention to what follows as it will be quite complicated in points.

    First let's comment on this line:
    Code:
            move.b    d0,(v_snddriver_ram+v_soundqueue0).w
    Just Below That. We do this:
    Code:
            jsr     findAndPlayTrack
    With that we copy the modified disassembly routine just below the "rts"
    Code:
    findAndPlayTrack:
            cmp.b   #$80,d0                 ; Stop MSU Sounds
            beq     msuStop
            cmp.b   #$81,d0                 ; Green Hill Zone
            beq     msuPlayTrack_01
            cmp.b   #$82,d0                 ; Labyrinth Zone
            beq     msuPlayTrack_02
            cmp.b   #$83,d0                 ; Marble Zone
            beq     msuPlayTrack_03
            cmp.b   #$84,d0                 ; Star Light Zone
            beq     msuPlayTrack_04
            cmp.b   #$85,d0                 ; Spring Yard Zone
            beq     msuPlayTrack_05
            cmp.b   #$86,d0                 ; Scrap Brain Zone
            beq     msuPlayTrack_06
            cmp.b   #$87,d0                 ; Invincibility
            beq     msuPlayTrack_07
            ;cmp.b   #$88,d0                 ; Extra Life
            ;beq     msuPlayTrack_08
            cmp.b   #$89,d0                 ; Special Stage
            beq     msuPlayTrack_09
            cmp.b   #$8A,d0                 ; Title Screen
            beq     msuPlayTrack_10
            cmp.b   #$8B,d0                 ; Ending
            beq     msuPlayTrack_11
            cmp.b   #$8C,d0                 ; Boss
            beq     msuPlayTrack_12
            cmp.b   #$8D,d0                 ; Final Zone
            beq     msuPlayTrack_13
            cmp.b   #$8E,d0                 ; Sonic Got Through
            beq     msuPlayTrack_14
            cmp.b   #$8F,d0                 ; Game Over
            beq     msuPlayTrack_15
            cmp.b   #$90,d0                 ; Continue Screen
            beq     msuPlayTrack_16
            cmp.b   #$91,d0                 ; Credits
            beq     msuPlayTrack_17
            cmp.b   #$92,d0                 ; Drowning
            beq     msuPlayTrack_18
            cmp.b   #$93,d0                 ; Get Emerald
            beq     msuPlayTrack_19
            ; track 20                      ; Seegaaa
     
            rts
    Just after the PlaySoundSpecial routine ends and before the Unused Play Sound. We paste this:
    Code:
    msuPlayTrack_01:                        ; Green Hill Zone
        tst.b    (v_shoes).w                    ; does Sonic have speed    shoes?
        bne.w    msuPlayTrack_21                ; if yes, branch to play fast track
    
        tst.b   MCD_STAT
        bne.s   msuPlayTrack_01
          
        move.w  #($1200|1),MCD_CMD          ; send cmd: play track #1, loop
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        move.b  #$81,(v_LAST_MSU)
        rts
      
    msuPlayTrack_02:                        ; Labyrinth Zone
        tst.b    (v_shoes).w                    ; does Sonic have speed    shoes?
        bne.w    msuPlayTrack_22                ; if yes, branch to play fast track
    
        tst.b   MCD_STAT
        bne.s   msuPlayTrack_02
          
        move.w  #($1200|2),MCD_CMD          ; send cmd: play track #2, loop
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        move.b  #$82,(v_LAST_MSU)
        rts
      
    msuPlayTrack_03:                        ; Marble Zone
        tst.b    (v_shoes).w                    ; does Sonic have speed    shoes?
        bne.w    msuPlayTrack_23                ; if yes, branch to play fast track
    
        tst.b   MCD_STAT
        bne.s   msuPlayTrack_03
          
        move.w  #($1200|3),MCD_CMD          ; send cmd: play track #3, loop
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        move.b  #$83,(v_LAST_MSU)
        rts
      
    msuPlayTrack_04:                        ; Star Light Zone
        tst.b    (v_shoes).w                    ; does Sonic have speed    shoes?
        bne.w    msuPlayTrack_24                ; if yes, branch to play fast track
    
        tst.b   MCD_STAT
        bne.s   msuPlayTrack_04
          
        move.w  #($1200|4),MCD_CMD          ; send cmd: play track #4, loop
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        move.b  #$84,(v_LAST_MSU)
        rts
      
    msuPlayTrack_05:                        ; Spring Yard Zone
        tst.b    (v_shoes).w                    ; does Sonic have speed    shoes?
        bne.w    msuPlayTrack_25                ; if yes, branch to play fast track
    
        tst.b   MCD_STAT
        bne.s   msuPlayTrack_05
          
        move.w  #($1200|5),MCD_CMD          ; send cmd: play track #5, loop
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        move.b  #$85,(v_LAST_MSU)
        rts
      
    msuPlayTrack_06:                        ; Scrap Brain Zone
        tst.b    (v_shoes).w                    ; does Sonic have speed    shoes?
        bne.w    msuPlayTrack_26                ; if yes, branch to play fast track
    
        tst.b   MCD_STAT
        bne.s   msuPlayTrack_06
          
        move.w  #($1200|6),MCD_CMD          ; send cmd: play track #6, loop
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        move.b  #$86,(v_LAST_MSU)
        rts
      
    msuPlayTrack_07:                        ; Invincibility
        tst.b    (v_shoes).w                    ; does Sonic have speed    shoes?
        bne.w    msuPlayTrack_27                ; if yes, branch to play fast track
          
        tst.b   MCD_STAT
        bne.s   msuPlayTrack_07
          
        move.w  #($1100|7),MCD_CMD          ; send cmd: play track #7, no loop
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        ;move.b  #$87,(v_LAST_MSU)
        rts
      
    msuPlayTrack_08:                        ; Extra Life
        tst.b   MCD_STAT
        bne.s   msuPlayTrack_08
          
        move.w  #($1100|8),MCD_CMD          ; send cmd: play track #8, no loop
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        rts
      
    msuPlayTrack_09:                        ; Special Stage
        tst.b   MCD_STAT
        bne.s   msuPlayTrack_09
          
        move.w  #($1200|9),MCD_CMD          ; send cmd: play track #9, loop
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        move.b  #$89,(v_LAST_MSU)
        rts
      
    msuPlayTrack_10:                        ; Title Screen
        tst.b   MCD_STAT
        bne.s   msuPlayTrack_10
          
        move.w  #($1100|10),MCD_CMD         ; send cmd: play track #10, no loop
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        rts
      
    msuPlayTrack_11:                        ; Ending
        tst.b   MCD_STAT
        bne.s   msuPlayTrack_11
          
        move.w  #($1100|11),MCD_CMD         ; send cmd: play track #11, no loop
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        rts
      
    msuPlayTrack_12:                        ; Boss
        tst.b   MCD_STAT
        bne.s   msuPlayTrack_12
          
        move.w  #($1200|12),MCD_CMD         ; send cmd: play track #12, loop
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        rts
      
    msuPlayTrack_13:                        ; Final Zone
        tst.b   MCD_STAT
        bne.s   msuPlayTrack_13
          
        move.w  #($1200|13),MCD_CMD         ; send cmd: play track #13, loop
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        rts
      
    msuPlayTrack_14:                        ; Sonic Got Through
        tst.b   MCD_STAT
        bne.s   msuPlayTrack_14
          
        move.w  #($1100|14),MCD_CMD         ; send cmd: play track #14, no loop
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        rts
      
    msuPlayTrack_15:                        ; Game Over
        tst.b   MCD_STAT
        bne.s   msuPlayTrack_15
          
        move.w  #($1100|15),MCD_CMD         ; send cmd: play track #15, no loop
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        rts
      
    msuPlayTrack_16:                        ; Continue Screen
        tst.b   MCD_STAT
        bne.s   msuPlayTrack_16
          
        move.w  #($1100|16),MCD_CMD         ; send cmd: play track #16, no loop
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        rts
      
    msuPlayTrack_17:                        ; Credits
        tst.b   MCD_STAT
        bne.s   msuPlayTrack_17
          
        move.w  #($1100|17),MCD_CMD         ; send cmd: play track #17, no loop
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        rts
      
    msuPlayTrack_18:                        ; Drowning
        tst.b   MCD_STAT
        bne.s   msuPlayTrack_18
          
        move.w  #($1100|18),MCD_CMD         ; send cmd: play track #18, no loop
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        rts
      
    msuPlayTrack_19:                        ; Get Emerald
        tst.b   MCD_STAT
        bne.s   msuPlayTrack_19
          
        move.w  #($1100|19),MCD_CMD         ; send cmd: play track #19, no loop
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        rts
      
    msuPlayTrack_20:                        ; SEEEGAAAAA
        tst.b   MCD_STAT
        bne.s   msuPlayTrack_20
          
        move.w  #($1100|20),MCD_CMD         ; send cmd: play track #20, no loop
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        rts
      
    ; ----- Fast Tracks :
    
    msuPlayTrack_21:                        ; FAST Green Hill Zone
        tst.b   MCD_STAT
        bne.s   msuPlayTrack_21
          
        move.w  #($1200|21),MCD_CMD         ; send cmd: play track #1, loop
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        rts
      
    msuPlayTrack_22:                        ; FAST Labyrinth Zone
        tst.b   MCD_STAT
        bne.s   msuPlayTrack_22
          
        move.w  #($1200|22),MCD_CMD         ; send cmd: play track #2, loop
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        rts
      
    msuPlayTrack_23:                        ; FAST Marble Zone
        tst.b   MCD_STAT
        bne.s   msuPlayTrack_23
          
        move.w  #($1200|23),MCD_CMD         ; send cmd: play track #3, loop
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        rts
      
    msuPlayTrack_24:                        ; FAST Star Light Zone
        tst.b   MCD_STAT
        bne.s   msuPlayTrack_24
          
        move.w  #($1200|24),MCD_CMD         ; send cmd: play track #4, loop
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        rts
      
    msuPlayTrack_25:                        ; FAST Spring Yard Zone
        tst.b   MCD_STAT
        bne.s   msuPlayTrack_25
          
        move.w  #($1200|25),MCD_CMD         ; send cmd: play track #5, loop
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        rts
      
    msuPlayTrack_26:                        ; FAST Scrap Brain Zone
        tst.b   MCD_STAT
        bne.s   msuPlayTrack_26
          
        move.w  #($1200|26),MCD_CMD         ; send cmd: play track #6, loop
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        rts
      
    msuPlayTrack_27:                        ; FAST Invincibility
        tst.b   MCD_STAT
        bne.s   msuPlayTrack_27
    
        ;move.b  #$87,(v_LAST_MSU)
    
        move.w  #($1100|27),MCD_CMD         ; send cmd: play track #7, no loop
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        rts
      
    ; ----- end Tracks
    
    msuStop:
        tst.b   MCD_STAT
        bne.s   msuStop
        move.w  #($1300|40),MCD_CMD         ; send cmd: pause track
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        rts
      
    msuResume:
        tst.b   MCD_STAT
        bne.s   msuResume
        move.w  #($1400),MCD_CMD            ; send cmd: resume track
        addq.b  #1,MCD_CMD_CK               ; Increment command clock
        rts
      
    msuChangeTrackSpeed:                    ; Sonic got shoes
        move.b  (v_LAST_MSU),d0
        jsr     findAndPlayFastTrack
        rts
      
    msuRestoreTrackSpeed:                   ; Sonic lost his shoes
        tst.b   (v_invinc).w                ; is Sonic invincible?
        bne.w   msuPlayTrack_07             ; if yes, play invincible music
    
        move.b  (v_LAST_MSU),d0
        jsr     findAndPlayTrack
        rts
      
    findAndPlayFastTrack:
            cmp.b   #$80,d0                 ; Stop MSU Sounds
            beq     msuStop
            cmp.b   #$81,d0                 ; Fast: Green Hill Zone
            beq     msuPlayTrack_21
            cmp.b   #$82,d0                 ; Fast: Labyrinth Zone
            beq     msuPlayTrack_22
            cmp.b   #$83,d0                 ; Fast: Marble Zone
            beq     msuPlayTrack_23
            cmp.b   #$84,d0                 ; Fast: Star Light Zone
            beq     msuPlayTrack_24
            cmp.b   #$85,d0                 ; Fast: Spring Yard Zone
            beq     msuPlayTrack_25
            cmp.b   #$86,d0                 ; Fast: Scrap Brain Zone
            beq     msuPlayTrack_26
            cmp.b   #$87,d0                 ; Fast: Invincibility
            beq     msuPlayTrack_27
            rts
    Now to make the Fast Musics load we will not go to the 2E object (the one with the monitor objects)
    In Pow_ChkShoes we will comment
    Code:
            jmp    (PlaySound).l        ; Speed    up the music
    and just before bgm_SpeedUp we will paste:
    Code:
            jsr     msuChangeTrackSpeed
    If you think it is not necessary to use faster versions of the music, then you are free to not follow this small modification.

    This would have finished the guide but there are still a few things left to cover so...

    Second part: Remove this screen:
    17/08 Edit: I've decided to remove this part for now, while I look for a way to make the code stable. Sincere apologies and better wait for a new code.

    Final notes:
    1. If you have the DMA Sonic. Kega fusion will a graphic bug when starting mode 1
    2. Some Sounds will not play

    Credits:
    ArcadeTV: Creator of the Driver
     

    Attached Files:

    Last edited: Aug 17, 2024
    DarkexNaru115 likes this.
  2. Red2010 is now

    Red2010 is now A Normal RomHacker with occupations. Member

    Joined:
    Apr 24, 2023
    Messages:
    53
    Location:
    Somewhere in Spain
    Let's see how many errors a professional can detect in this thing...
     
  3. Devon

    Devon DROWN, DROWN, DROWN MYSELF! Member

    Joined:
    Aug 26, 2013
    Messages:
    1,400
    Location:
    your mom
    It would have been better if you tried to ask around for someone to peer review the guide before publishing it, knowing that there's flaws with it that need to be addressed first, and also first learn to better understand what the code is even actually doing.
     
    Last edited: Aug 17, 2024
    ProjectFM, RepellantMold and DeltaW like this.
  4. RepellantMold

    RepellantMold Newcomer Trialist

    Joined:
    Jan 9, 2024
    Messages:
    3
    I decided I'd try and apply this guide (despite me not being a professional so I have no idea how much I'm qualified to be speaking here), and I had no errors reported when I attempted it (though I'm with Devon on the point that there should've been a proofread first before it was posted.)
    My main complaint would be that there's no mention of adding the MSU's stop commands at the SEGA screen and Title Screen (meaning the CD audio could potentially play forever until interrupted by the title screen music), but otherwise, eh. I would've also credited krikzz as the person who made the driver rather than ArcadeTV who essentially made the base of this whole guide.