don't click here

Utility Sonic 2 Clone Driver v2

Discussion in 'Engineering & Reverse Engineering' started by Clownacy, Mar 31, 2014.

  1. Clownacy

    Clownacy

    Tech Member
    1,053
    581
    93
    The Sonic 2 Clone Driver v2 is a custom SMPS sound driver inspired by the original Sonic 2 Clone Driver. It is essentially a heavily-modified version of Sonic 1's sound driver designed to be compatible with songs and sound effects from other Sonic games. As well as this, the driver includes bugfixes, minor optimisations, and additional features.

    More information can be found on the driver's GitHub wiki. There you can find a list of features, as well as installation instructions.

    Old post contents:
    Recently, I noticed that the Sonic 2 Clone Driver is painfully outdated, even to the point of an unhealthily large chunk of the guide that was supposed to simply detail porting it being about bringing the old thing up to date and making it actually imitate Sonic 2's driver. So I chose to do something about it, by giving the thing a Git disassembly overhaul!

    Looking closer at the Sonic 2 Clone Driver, I saw that it was made with old components and older methods, so I scrapped it, and started from scratch with a fresh copy of Sonic 1's sound driver. Here is the result:

    Sonic 2 Clone Driver v2
    version 2.7

    About
    So, what is the Sonic 2 Clone Driver v2?

    This is a heavily modified version of Sonic 1's sound driver, with a greater level of compatibility with music and sounds from other Sonic titles, along with numerous bugfixes, optimisations, and added features. However, to really understand the driver, you need to understand its history, and its ties (or lack thereof) to the original Sonic 2 Clone Driver.

    Both the original Sonic 2 Clone Driver and the Sonic 2 Clone Driver v2 are modified versions of Sonic 1's sound driver (modified early(?) SMPS 68k Type 1b), designed to act as total replacements of Sonic 2's sound driver (improved Z80 port of Sonic 1's driver).

    At the time of the original Sonic 2 Clone Driver's creation, working with Sonic 2's driver was considered extremely difficult, compared to Sonic 1's driver. This was down to several factors, such as the driver being designed for the Z80 sound coprocessor, which sported a language few were willing to learn, and many changes to the music format. Not helping matters was also the fact that the driver was largely unexplored and lacking documentation. In contrast to Sonic 1's documented, easy-to-understand driver, Sonic 2's driver just seemed unfeasible to use, even though it had additional features, such as added DAC samples and PSG envelopes. This pushed hackers away from hacking Sonic 2.

    One of the earlier efforts to counter this was the porting of Sonic 1's driver to Sonic 2. While this did help to ease the addition of custom music, compatibility with Sonic 2's original music and SFX was practically non-existent. Because of this, a hybrid was made, the original Sonic 2 Clone Driver, allowing access to Sonic 2's music, SFXs and DACs, while having the ease-of-use of Sonic 1's driver.

    That was the past, however. Over time, advancements in documentation and tools have made both drivers just as easy to use, and the need for something like the original Sonic 2 Clone Driver has diminished. Still, people continue to use the ancient thing, despite the fact that it wasn't really a feature-complete replica of Sonic 2's driver to begin with: missing PSG envelopes, incorrect music/SFX priorities, broken speed-up tempos, broken tempos in general, there were many problems with the original Sonic 2 Clone Driver that made the hacks that used it suffer. Today, simply sticking to Sonic 2's driver would be a better choice.

    This is why I made the Sonic 2 Clone Driver v2, an attempt at making as close a mimicry of S2's driver as possible: the aforementioned errors were corrected, and many more S2 elements were crammed in, in an effort to make the drivers near indistinguishable.

    The purpose of the Sonic 2 Clone Driver v2 has changed over its lifetime: while originally meant as a simple update to replace the original Sonic 2 Clone Driver, it no longer shares the same goals as its predecessor: while the original was made for ease-of-use, the Sonic 2 Clone Driver v2 exists for the sake of pushing the Mega Drive's hardware to its limit, by avoiding the biggest bottleneck: the Z80's limitations. Problem areas such as driver size and poor DAC quality can be avoided by not using a Z80-based driver such as Sonic 2's or even Sonic 3's. This allows a hack to push its sounds to the limit, without having to downgrade to the smaller feature pool of Sonic 1's original driver.


    So, what isn't the Sonic 2 Clone Driver v2?

    As said before, the Sonic 2 Clone Driver v2 is not meant for the purpose of making the process of adding custom music easier, rather, it's for those that wished to implement features that the Z80 would not allow, due to its limitations. One example can be seen in the hack Sonic 2 Recreation, a hack that was based on Sonic 2, but used a 68k-based driver (a heavily modified version of the original Sonic 2 Clone Driver) because a Z80-based driver would not allow all of the features needed. The Sonic 2 Clone Driver v2 uses Vladikcomper's Mega PCM, a custom DAC driver only available for 68k-based sound drivers. Mega PCM allows for greater playback quality and control. This is just one of the things possible when the sound driver is not entirely based on the Z80.

    Of course, 68k-based drivers have their downsides. Sonic 1's driver operates on the 68k, the main processor of the Mega Drive. Sonic 2's driver operates on the Z80, the sound co-processor. So, there's the obvious performance penalty on the 68k, and thus your hack's gameplay. It may not be much, but ask yourself, is it worth it? Are you going to make any good use of it? There is also the RAM requirement: Sonic 2's driver just uses the Z80's RAM. In contrast, Sonic 1's driver uses $5C0 bytes of the very RAM that has to be juggled with the level chunks, blocks, layout, decompression queues, camera RAM, and much more. Again, you can use that RAM for a million other things, so why use it on this? What would all that RAM and performance be going into? If your answer is just 'doing something that Sonic 2's driver can already do', then this driver is not for you.

    You need to know if your hack's goals justify the costs. Are you doing some Mega CD work that the Z80 can't handle? If you just want to have S3K music in your hack, go use S3K's driver (or better yet, a good version of S3K's driver), or a (modern) music-porting tool.

    + - That said, by using this driver, you acknowledge that if I find it being used just so you can use S3K music, I will call you out on it. =P  

    Features
    • Enhanced Mega PCM - High-quality DPCM/PCM playback, with greater playback control. Now with DAC volume control
    • SMPS2ASM - Edit music and sounds in ASM, and port them with ease
    • Bugfixes - A lot of them. Sonic 1's, and even Sonic 2's, sound driver is a buggy mess, but you don't have to worry about that
    • Less HAX - Real support for music slots >=$E0
    • More HAX - Support for music slots <$80 (Git only)
    • Enough slots for up to $7C DAC samples for use by music or SFX
    • 'Delay on overflow' tempo algorithm. Allows for more accurate conversions of S2/S3K tempos than S1's 'delay on timeout' algorithm
    • Supports music and SFX from Sonic 1 and Sonic 2
    • Partially supports music and SFX from Sonic 3 & Knuckles, Sonic 3D Blast, Sonic Crackers, and Knuckles' Chaotix
    • All DACs (drum and voice samples) from S1, S2, S3K, S3D and Crackers
    • All PSG envelopes (PSG instruments) from S1, S2, S3K, S3D and Chaotix
    • All PWM samples from Chaotix
    • Support for special Sonic 2 sound driver features:
      • Spin Dash SFX support (rev increases in pitch)
      • Gloop SFX support (only plays every other time it's called)
      • StopSFX sound command (used by EHZ boss' propeller)
      • Runs at full speed on PAL consoles ("PAL mode")
      • Song-sensitive PAL mode (S2's drowning theme plays slower on PAL)
      • Absolute FM voice pointers - You can put your voices anywhere, even in a universal bank, like S3K
      • Support for negative track pointers - Within range, you can point to data before or after the song itself
      • More sound queues - Currently at 4, the same as Sonic 2. Sonic 1 only had 2 working ones, and a third broken one
    • Support for special Sonic 3 sound driver features:
      • PSG flags (reset, rest)
      • Universal Voice Bank
      • Continuous SFX system
      • FM voice TL output is decided by sign bit, increasing compatibility with certain voices
    • Support for special Knuckles' Chaotix sound driver features:
      • PWM playback

    Requirements
    • The following games and disassemblies are supported:
      • Sonic 2 - Git disassembly, Xenowhirl's 2007 disassembly
      • Sonic 1 - Git disassembly (AS branch)
    • Sound files must be in SMPS2ASM v0.2 (.asm) format; assembled (.bin) files are unsupported
    • This driver is designed for use with the AS Macro Assembler
    • Users of Xenowhirl's 2007 disassembly will need to update their copy of AS to get the driver to build properly. Just copy over Git's version of AS. Newer versions are broken
    • Obviously, in order to utilise PWM playback, your hacks needs to be ported to the 32X

    Downloads
    The driver can be downloaded here.

    There is also a branch that uses the original (v1.1) Mega PCM, without my modifications, meaning it uses much less Z80 RAM, lacks volume control, and has higher playback speeds.

    In addition, there's a branch that uses Valley Bell's DAC driver, however, it is not public (for reasons that are obvious if you read its thread).

    Demonstration ROMs are available here (S1) and here (S2) (v2.5; outdated).

    Installation
    Sonic 2 Git disassembly
    Setting up your disassembly
    Let's start by removing the old S2 sound driver's files: Delete s2.sounddriver.asm and the contents of the sound folder.

    Inside the now-empty sound folder, extract the contents of the driver's zip/tar.gz file.

    Since we're working on an S2 disassembly, move the files and folders from the Sonic 2 files folder out to the sound folder. You can now delete the Sonic 1 files, Sonic 2 files, and Sonic 2 Xenowhirl files folders; we won't be needing them anymore. You can also delete the following files/folders, if you're not porting your hack to the 32X:

    Folders:
    • Chaotix music
    • PWM
    • Stub 32X
    Files:
    • Chaotix PWM Driver.bin
    • Sonic 2 Clone Driver v2 - PWM Driver.asm
    • Sonic 2 Clone Driver v2 - PWM Samples.asm
    • Sonic 2 Clone Driver v2 - Stub SH2.asm

    Now we need to update the disassembly's main build tool: s2p2bin. It performs a special function, where it compresses the sound driver. In vanilla Sonic 2, the entire sound driver is compressed using the Saxman compression. For the Sonic 2 Clone Driver v2, however, it should instead compress the DAC driver using the Kosinski compression. For Windows users, an alternate binary of the s2p2bin.exe is packaged with the driver, but for OSX/Linux users, source code is also available. You can find these in the Build tools folder. Windows users: copy the win32 folder over the original win32 folder in your disassembly's main folder. With that done, you can delete the Build tools folder. You can also delete the build_plus.bat/build_plus.sh files in your main disassembly folder, as those still use the old Saxman compression. From now on, just use build.bat.

    Replacing the old sound driver's code
    Now your disassembly has been fully set up for use with the Sonic 2 Clone Driver v2. Onto modifying your hack's code to use the driver.

    First, we'll include constants and the like for the driver: at the start of your disassembly (s2.asm), after the 'include "s2.macros.asm"', insert this:

    Code (ASM):
    1. ; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    2. ; Sonic 2 Clone Driver v2 and SMPS2ASM
    3.     include "sound/Sonic 2 Clone Driver v2 - Macros.asm"
    4.     include "sound/Sonic 2 Clone Driver v2 - Sound IDs.asm"
    5.     include "sound/Sonic 2 Clone Driver v2 - Compatibility.asm"
    6.     include "sound/Sonic 2 Clone Driver v2 - RAM.asm"
    7.     include "sound/Sonic 2 Clone Driver v2 - Constants.asm"
    8.     include "sound/_smps2asm_inc.asm"
    Next we'll replace some old sound driver functions with new ones. Find JmpTo_SoundDriverLoad, and delete it and everything up to, but not including, PauseGame. Where that code used to be, insert this:

    Code (ASM):
    1.     include "sound/Sonic 2 Clone Driver v2 - Functions.asm"
    Finally we'll replace the bulk of the old sound driver: find SoundDriverLoad, and delete everything from there until, but not including, ArtNem_Buzzer_Fireball. You can also remove the nearby 'align $1000'. After that, find 'cnop -Size_of_SEGA_sound, $8000', and delete everything until '; end of 'ROM''.

    In this new space, we'll add the Sonic 2 Clone Driver v2's code, with this:

    Code (ASM):
    1.     include "sound/Sonic 2 Clone Driver v2.asm"
    There are still bits of the old driver's code that need removing. Find sndDriverInput, and delete it. Then delete every branch to it. Also, replace every instance of 'move.b #MusID_Pause,(Music_to_play).w' with 'SMPS_PauseMusic', and 'move.b #MusID_Unpause,(Music_to_play).w' with 'SMPS_UnpauseMusic'. Then remove the reference to movewZ80CompSize in the line just above EndOfRom.

    Finally, we need to make the game actually run the Sonic 2 Clone Driver v2: under VintRet, insert this:

    Code (ASM):
    1.     SMPS_UpdateSoundDriver
    s2.constants.asm still contains some code for the old sound driver. Find the 'Music IDs', and delete everything up to '; 2P VS results screens'.

    While you're in s2.constants.asm, you should allocate some RAM to the Sonic 2 Clone Driver v2. By default, for Sonic 2, it needs $39B bytes. When you've found the RAM for the driver, give it the label 'Clone_Driver_RAM'.

    Sonic 2 Xenowhirl disassembly
    Setting up your disassembly
    Before we do anything, you'll need to update your disassembly's assembler, AS. The Sonic 2 Clone Driver v2 targets the version included in the Git disassembly. Windows users: copy asw.exe and the msg folder in the win32 folder to your disassembly's win32 folder.

    Now we can begin removing the old S2 sound driver's files: Delete s2.sounddriver.asm and the contents of the sound folder.

    Inside the now-empty sound folder, extract the contents of the driver's zip/tar.gz file.

    Since we're working on an S2 disassembly, move the files and folders from the Sonic 2 files folder out to the sound folder. Then do the same for the Sonic 2 Xenowhirl files folder. You can now delete the Sonic 1 files, Sonic 2 files, and Sonic 2 Xenowhirl files folders; we won't be needing them anymore. You can also delete the following files/folders, if you're not porting your hack to the 32X:

    Folders:
    • Chaotix music
    • PWM
    • Stub 32X
    Files:
    • Chaotix PWM Driver.bin
    • Sonic 2 Clone Driver v2 - PWM Driver.asm
    • Sonic 2 Clone Driver v2 - PWM Samples.asm
    • Sonic 2 Clone Driver v2 - Stub SH2.asm

    Now we need to update the disassembly's main build tool: s2p2bin. It performs a special function, where it compresses the sound driver. In vanilla Sonic 2, the entire sound driver is compressed using the Saxman compression. For the Sonic 2 Clone Driver v2, however, it should instead compress the DAC driver using the Kosinski compression. For Windows users, an alternate binary of the s2p2bin.exe is packaged with the driver, but for OSX/Linux users, source code is also available. You can find these in the Build tools folder. Windows users: copy the win32 folder over the original win32 folder in your disassembly's main folder.

    Replacing the old sound driver's code
    Now your disassembly has been fully set up for use with the Sonic 2 Clone Driver v2. Onto modifying your hack's code to use the driver.

    First, we'll include constants and the like for the driver: near the start of your disassembly (s2.asm), before '; start of ROM', insert this:

    Code (ASM):
    1. ; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    2. ; Sonic 2 Clone Driver v2 and SMPS2ASM
    3.     include "sound/Sonic 2 Clone Driver v2 - Macros.asm"
    4.     include "sound/Sonic 2 Clone Driver v2 - Sound IDs.asm"
    5.     include "sound/Sonic 2 Clone Driver v2 - Compatibility.asm"
    6.     include "sound/Sonic 2 Clone Driver v2 - RAM.asm"
    7.     include "sound/Sonic 2 Clone Driver v2 - Constants.asm"
    8.     include "sound/_smps2asm_inc.asm"
    Next we'll replace some old sound driver functions with new ones. Find JmpTo_SoundDriverLoad, and delete it and everything up to, but not including, PauseGame. Where that code used to be, insert this:

    Code (ASM):
    1.     include "sound/Sonic 2 Clone Driver v2 - Functions.asm"
    Finally we'll replace the bulk of the old sound driver: find SoundDriverLoad, and delete everything from there until, but not including, ArtNem_Buzzer_Fireball. You can also remove the nearby 'align $1000'. After that, find 'cnop -Size_of_SEGA_sound, $8000', and delete everything until '; end of 'ROM''.

    In this new space, we'll add the Sonic 2 Clone Driver v2's code, with this:

    Code (ASM):
    1.     include "sound/Sonic 2 Clone Driver v2.asm"
    There are still bits of the old driver's code that need removing. Find sndDriverInput, and delete it. Then delete every branch to it. Also, replace every instance of 'move.b #-2,(Music_to_play).w' with 'SMPS_PauseMusic', and 'move.b #-1,(Music_to_play).w' with 'SMPS_UnpauseMusic'. Then remove the reference to movewZ80CompSize in the line just above EndOfRom.

    Finally, we need to make the game actually run the Sonic 2 Clone Driver v2: under VintRet, insert this:

    Code (ASM):
    1.     SMPS_UpdateSoundDriver
    You should allocate some RAM to the Sonic 2 Clone Driver v2. By default, for Sonic 2, it needs $39B bytes. When you've found the RAM for the driver, give it the label 'Clone_Driver_RAM'.

    Sonic 1 Git disassembly
    Setting up your disassembly
    Let's start by removing the old S1 sound driver's files: Delete s1.sounddriver.asm and the contents of the sound folder.

    Inside the now-empty sound folder, extract the contents of the driver's zip/tar.gz file.

    Since we're working on an S1 disassembly, move the files and folders from the Sonic 1 files folder out to the sound folder. You can now delete the Build tools, Sonic 1 files, Sonic 2 files, and Sonic 2 Xenowhirl files folders; we won't be needing them anymore. You can also delete the following files/folders, if you're not porting your hack to the 32X:

    Folders:
    • Chaotix music
    • PWM
    • Stub 32X
    Files:
    • Chaotix PWM Driver.bin
    • Sonic 2 Clone Driver v2 - PWM Driver.asm
    • Sonic 2 Clone Driver v2 - PWM Samples.asm
    • Sonic 2 Clone Driver v2 - Stub SH2.asm

    Replacing the old sound driver's code
    Now your disassembly has been fully set up for use with the Sonic 2 Clone Driver v2. Onto modifying your hack's code to use the driver.

    First, we'll include constants and the like for the driver: at the start of your disassembly (sonic.asm), after the 'include "Macros.asm"', insert this:

    Code (ASM):
    1. ; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    2. ; Sonic 2 Clone Driver v2 and SMPS2ASM
    3.         include "sound/Sonic 2 Clone Driver v2 - Macros.asm"
    4.         include "sound/Sonic 2 Clone Driver v2 - Sound IDs.asm"
    5.         include "sound/Sonic 2 Clone Driver v2 - Compatibility.asm"
    6.         include "sound/Sonic 2 Clone Driver v2 - RAM.asm"
    7.         include "sound/Sonic 2 Clone Driver v2 - Constants.asm"
    8.         include "sound/_smps2asm_inc.asm"
    Next we'll replace some old sound driver functions with new ones. Find SoundDriverLoad, and delete it and everything up to, but not including, 'include "_inc/PauseGame.asm"'. Where that code used to be, insert this:

    Code (ASM):
    1.         include "sound/Sonic 2 Clone Driver v2 - Functions.asm"
    Finally we'll replace the bulk of the old sound driver: find SoundDriver, and replace this:

    Code (ASM):
    1. SoundDriver:    include "s1.sounddriver.asm"
    ...with this:

    Code (ASM):
    1.         include "sound/Sonic 2 Clone Driver v2.asm"
    There are still bits of the old driver's code that need removing. Replace every instance of 'move.b #1,(v_snddriver_ram+f_stopmusic).w' with 'SMPS_PauseMusic', and 'move.b #$80,(v_snddriver_ram+f_stopmusic).w' with 'SMPS_UnpauseMusic'.

    Finally, we need to make the game actually run the Sonic 2 Clone Driver v2: under VBla_Music, replace this:

    Code (ASM):
    1.         jsr    (UpdateMusic).l
    ...with this:

    Code (ASM):
    1.         SMPS_UpdateSoundDriver
    Constants.asm still contains some code for the old sound driver. Remove Size_of_SegaPCM, Size_of_DAC_driver_guess, z80_dac3_pitch, z80_dac_status, and z80_dac_sample. Also, find the '; Sound driver constants', and delete everything up to '; VRAM data', as well as everything from '; Background music' to 'flg__Last'.

    Variables.asm contains some RAM-related stuff for S1's sound driver, which also needs removing. Delete everything from here:

    Code (ASM):
    1. ; =================================================================================
    2. ; From here on, until otherwise stated, all offsets are relative to v_snddriver_ram
    3. ; =================================================================================
    ...to here:

    Code (ASM):
    1. ; =================================================================================
    2. ; From here on, no longer relative to sound driver RAM
    3. ; =================================================================================

    Other Guides
    Extend + Enhance Sound Test
    Sonic 2 Git disassembly
    LEVEL SELECT SOUND TEST
    Go to LevSelControls_CheckLR and remove these two lines:

    Code (ASM):
    1.     bcc.s    +
    2.     moveq    #$7F,d0


    Then remove these three:

    Code (ASM):
    1.     cmpi.w    #$80,d0
    2.     blo.s    +
    3.     moveq    #0,d0


    Then change this...

    Code (ASM):
    1.     btst    #button_A,d1
    2.     beq.s    +
    3.     addi.b    #$10,d0
    4.     andi.b    #$7F,d0
    5.  
    6. +


    ...into this:

    Code (ASM):
    1.     btst    #button_A,d1
    2.     beq.s    +
    3.     addi.b    #$10,d0
    4.     bcc.s    +
    5.     moveq    #0,d0
    6.  
    7. +


    And remove this:

    Code (ASM):
    1.     addi.w    #$80,d0

    OPTIONS SOUND TEST
    Go to OptionScreen_Controls, and change this...

    Code (ASM):
    1.     btst    #button_A,d0
    2.     beq.s    +
    3.     addi.b    #$10,d2
    4.     cmp.b    d3,d2
    5.     bls.s    +
    6.     moveq    #0,d2
    7.  
    8. +


    ...into this:

    Code (ASM):
    1.     cmpi.b    #2,(Options_menu_box).w
    2.     bne.s    +
    3.     btst    #button_A,d0
    4.     beq.s    +
    5.     addi.b    #$10,d2
    6.     bcc.s    +
    7.     moveq    #0,d2
    8.  
    9. +


    Under that, remove this:

    Code (ASM):
    1.     addi.w    #$80,d0


    Then go to OptionScreen_Choices, and change this...

    Code (ASM):
    1.     dc.l ($80-1)<<24


    ...into:

    Code (ASM):
    1.     dc.l ($FF<<24)

    Sonic 2 Xenowhirl 2007 disassembly
    LEVEL SELECT SOUND TEST
    Go to LevSelControls_CheckLR and remove these two lines:

    Code (ASM):
    1.     bcc.s    +
    2.     moveq    #$7F,d0


    Then remove these three:

    Code (ASM):
    1.     cmpi.w    #$80,d0
    2.     blo.s    +
    3.     moveq    #0,d0


    Then change this...

    Code (ASM):
    1.     btst    #button_A,d1
    2.     beq.s    +
    3.     addi.b    #$10,d0
    4.     andi.b    #$7F,d0
    5.  
    6. +


    ...into this:

    Code (ASM):
    1.     btst    #button_A,d1
    2.     beq.s    +
    3.     addi.b    #$10,d0
    4.     bcc.s    +
    5.     moveq    #0,d0
    6.  
    7. +


    And remove this:

    Code (ASM):
    1.     addi.w    #$80,d0

    OPTIONS SOUND TEST
    Go to OptionScreen_Controls, and change this...

    Code (ASM):
    1.     btst    #button_A,d0
    2.     beq.s    +
    3.     addi.b    #$10,d2
    4.     cmp.b    d3,d2
    5.     bls.s    +
    6.     moveq    #0,d2
    7.  
    8. +


    ...into this:

    Code (ASM):
    1.     cmpi.b    #2,(Options_menu_box).w
    2.     bne.s    +
    3.     btst    #button_A,d0
    4.     beq.s    +
    5.     addi.b    #$10,d2
    6.     bcc.s    +
    7.     moveq    #0,d2
    8.  
    9. +


    Under that, remove this:

    Code (ASM):
    1.     addi.w    #$80,d0


    Then go to OptionScreen_Choices, and change this...

    Code (ASM):
    1.     dc.l ($80-1)<<24


    ...into:

    Code (ASM):
    1.     dc.l ($FF<<24)

    Sonic 1 Git disassembly
    LEVEL SELECT SOUND TEST
    In sonic.asm, go to LevelSelect and change this...

    Code (ASM):
    1.         andi.b    #btnABC+btnStart,(v_jpadpress1).w ; is A, B, C, or Start pressed?


    ...into this:

    Code (ASM):
    1.         andi.b    #btnB+btnStart,(v_jpadpress1).w ; is B or Start pressed?


    Then change this...

    Code (ASM):
    1.         bne.s    LevSel_Level_SS    ; if not, go to    Level/SS subroutine


    ...into this:

    Code (ASM):
    1.         beq.s    .checkB                ; if so, branch
    2.         andi.b    #btnStart,(v_jpadpress1).w    ; is start pressed?
    3.         beq.s    LevelSelect            ; if not, branch
    4.         bra.s    LevSel_Level_SS            ; if so, go to    Level/SS subroutine
    5.  
    6. .checkB:
    7.         andi.b    #btnB,(v_jpadpress1).w    ; is B pressed?
    8.         beq.s    LevelSelect        ; if not, branch
    9.  
    10. .soundtest:


    After that, remove this line:

    Code (ASM):
    1.         addi.w    #$80,d0


    Then delete these lines:

    Code (ASM):
    1.         ; This is a workaround for a bug, see Sound_ChkValue for more.
    2.         ; Once you've fixed the bugs there, comment these four instructions out
    3.         cmpi.w    #bgm__Last+1,d0    ; is sound $80-$93 being played?
    4.         blo.s    LevSel_PlaySnd    ; if yes, branch
    5.         cmpi.w    #sfx__First,d0    ; is sound $94-$9F being played?
    6.         blo.s    LevelSelect    ; if yes, branch
    7.  
    8. LevSel_PlaySnd:


    After that, go to LevSel_SndTest, and change this...

    Code (ASM):
    1.         andi.b    #btnR+btnL,d1    ; is left/right    pressed?


    ...into this:

    Code (ASM):
    1.         andi.b    #btnA+btnC+btnR+btnL,d1    ; is left/right/A/C pressed?


    and remove this:

    Code (ASM):
    1.         bhs.s    LevSel_Right
    2.         moveq    #$4F,d0        ; if sound test    moves below 0, set to $4F


    And then change this...

    Code (ASM):
    1.         btst    #bitR,d1    ; is right pressed?
    2.         beq.s    LevSel_Refresh2    ; if not, branch
    3.         addq.w    #1,d0        ; add 1    to sound test
    4.         cmpi.w    #$50,d0
    5.         blo.s    LevSel_Refresh2
    6.         moveq    #0,d0        ; if sound test    moves above $4F, set to    0
    7.  
    8. LevSel_Refresh2:


    ...into this:

    Code (ASM):
    1.         btst    #bitR,d1    ; is right pressed?
    2.         beq.s    LevSel_ButtonA    ; if not, branch
    3.         addq.w    #1,d0        ; add 1    to sound test
    4.  
    5. LevSel_ButtonA:
    6.         btst    #bitA,d1    ; is A pressed?
    7.         beq.s    LevSel_ButtonC    ; if not, branch
    8.         addi.b    #$10,d0        ; add $10 to sound test
    9.         bcc.s    LevSel_ButtonC    ; did the addition overflow?
    10.         moveq    #0,d0        ; if so, set value to $00
    11.  
    12. LevSel_ButtonC:
    13.         btst    #bitC,d1    ; is C pressed?
    14.         beq.s    LevSel_Refresh2    ; if not, branch
    15.         subi.b    #$10,d0        ; subtract $10 from sound test
    16.         bcc.s    LevSel_Refresh2
    17.         cmpi.b    #$F0,d0
    18.         beq.s    LevSel_Refresh2    ; do not set to 0 if already at 0
    19.         moveq    #0,d0        ; if the subtraction overflowed, set value to $00
    20.  
    21. LevSel_Refresh2:


    Now go to LevSel_DrawSnd, and remove this line:

    Code (ASM):
    1.         addi.w    #$80,d0

    FAQ
    How do I use SMPS2ASM? (Windows users)
    It's a command line tool. The most basic setup you'll want is to get smps2asm.exe in a folder, in the same folder, have GHZ's music in .bin S1 format then hold Shift key and right-click in the Explorer window without anything selected, select "Open command window here", then input the following:

    smps2asm.exe -v 1 "GHZ.bin" "GHZ.asm" GHZ

    If you just enter "smps2asm.exe" you'll get an explanation of what these are: "-v" being driver version, and "1" the variable following it, which matches the driver which the file came from. After that is the input .bin filename, then the output .asm filename, and finally, the name the .asm file uses to identify itself. So labels such as the voices label are "GHZ_Voices".

    There are more settings that are worth using in other situations, like Offset for Z80 driver sound files.

    How do I play DAC samples during gameplay using Mega PCM?
    As Mega PCM's topic will tell you, you can play DPCM/PCM samples, not as part of the music, but during gameplay. As part of this driver's installation, a subroutine called 'SMPS_PlaySample' was added; we'll need to be using this.

    Using it is identical to using PlayMusic, and the others: simply put the ID of the sample you want to play in d0, then branch to SMPS_PlaySample, like so:

    Code (ASM):
    1.     move.b    #dSega_S2,d0
    2.     jsr    (SMPS_PlaySample).w

    Changelog
    12/08/2016 (dd/mm/yyyy)
    v2.7
    • Support for the 32X
    • Support for four PWM tracks
    • Fixed bug where Special SFX incorrectly mute PSG3 while it's being used by SFX (thanks, Markey)
    • Added proper volume cap check to DoFadeIn (thanks again, Markey)
    • Fixed bug where PSG 1&2 are not muted during SFX initialisation (Markey, stop, please)
    • Added a bugfix from S2's driver that stops cfStopTrack from altering the stack too much on DAC channels
    • Tried to reduce name collision with MegaPCM by adding a prefix to most labels
    • UpdateDAC has been restructured, so its stack usage is identical to FM and PSG (kind of undoing that last bugfix :(/>/>/>/> )
    • Made MegaPCM check that YM2612 isn't busy before enabling DAC (fixes muted drums at start of some songs)
    • SFX now properly update on the frame that a new song is played

    02/07/2016
    v2.6
    • New DPCM tables were ported from SMPS-Treasure, speeding up DPCM loop (unlike SMPS-Treasure, these tables are generated by the DAC driver during initialisation, so they don't waste ROM like the volume table)
    • Made Spin Dash toggleable, so its code isn't assembled if you're not using it
    • Fixed bug during song initialisation that caused the last two sound queues to be accidentally cleared
    • Ported S2's version of Sound_Play (zCycleQueue)
    • Music/SFX/SpecSFX data has been merged into 'metadata tables', simplifying their addition or modification (for example, the music metadata table contains the music's pointer, speed-shoes tempo, and playback flags)
    • Restored compatibility with official (flamewing's) SMPS2ASM
    • All tracks use zTrack.VoicePtr now (saves some RAM)
    • Overall RAM cleanup
    • Some Z80 access was made 'safe' (interrupt can't interrupt Z80 bus request, and accidentally deassert it)
    • Fixed OOZ oil slide SFX (was updating FM volume on a PSG channel)
    • Added check to prevent above bug from having any negative effects, just like S2's driver
    • A branch is available that uses the stock v1.1 MegaPCM

    18/01/2016
    v2.5
    • Fixed hanging notes on music that doesn't define all tracks
    • Optimised some track RAM write looping
    • Added missing S3/S3D PSG envelopes
    • Overhauled SMPS2ASM PSG defining
    • Slightly lowered pitch on all DAC samples
    • Updated SMPS2ASM
    • Renamed DAC_Entry arguments to not conflict with comments
    • Removed support for other drivers from _smps2asm_inc.asm (a pain to maintain)
    • Updated sound driver disassembly (track RAM is better-defined)
    • Made some 'move' instructions safer
    • Made disabled coordination flags safer
    • Removed old unused SMPS 68k Type 1a track pointers
    • Made SFX_SFXChannelRAM and SFX_BGMChannelRAM word-sized
    • Ported SMPS Z80's TL handling, fixing S3K DEZ1 (bit 7 lets it be changed by volume)
    • Added support for transposition division overflow, fixing S3D intro (S3D uses these)
    • Shrinked FM_Notes, to allow for negative transpositions
    • Removed ReverseFreqs. It was fun while it lasted, but I'm not about to waste time figuring out how to make a negative shrunken FM_Notes
    • Corrected smpsVcTotalLevel errors in OOZ, Ending, and Title Screen
    • Corrected smpsVcTotalLevel errors in SFX 55 and 5C (D5 and DC)
    • Corrected FM5 channel transposition in SFX BC (Spin Dash release)
    • Added 'readme.txt' files to 'music' and 'SFX' folders, detailing bugfixes made and where to find SMPS2ASM
    • Added URLs to Mega PCM's thread at start of Mega PCM files
    • Split PSG volume envelopes to 'Sonic 2 Clone Driver v2 - PSG Volume Envelopes.asm'
    • Split FM Universal Voice Bank to 'Sonic 2 Clone Driver v2 - FM Universal Voice Bank.asm'
    • Slightly reordered data at end of driver
    • Added option to not include FM Universal Voice Bank
    • Added option to not include certain games' PSG volume envelopes
    • Removed SetDuration_pea
    • Fixed cfSetPSGTone when it's run on FM track (forgot to advance the track pointer)
    • Enhanced SMPS2ASM to ignore S3-specific smpsFade
    • Reverted bugged optimisations to PSG volume envelopes (fixes VVZ2)
    • Added support for negative track pointers, fixing SFX CC (holy cow, another one I haven't noticed since v2.0)

    12/12/2015
    v2.4.2
    • Removed redundant instructions under .silencefm6
    • Removed WriteFMIorIIMain, and merged its function into the one thing that used it, like S2's driver
    • Fixed PSG noise channel not shutting up when a new song starts
    • Rewrote PauseMusic to be more like it was in S2's driver
    • Fixed Mega PCM DAC samples not pausing properly (holy shit this has been here since v2.0)

    05/12/2015
    v2.4.1
    • Added (proper, unlike S2!) fix for music interrupting SFX, causing distortion
    • Made .silencefm6 more like it was in S2's driver
    • Removed some instances where DAC is enabled with WriteFMI. Mega PCM can do that on its own
    • Allowed FM6 to enable itself, letting a song use both FM6 and DAC tracks (the channel itself alternates, so they can't run at the same time)
    • Removed some instances where DAC is disabled with WriteFMI. The above change means FM6 can do that on its own
    • Made PlaySega (68k mode) manually enable DAC

    01/12/2015
    v2.4
    • Added Vladikcomper's fix for interrupt crash, and optimisation of horizontal interrupts
    • Made Mega PCM assemble with the rest of the driver
    • Merged DAC_Table into Mega PCM source code
    • Split 'Sonic 2 Clone Driver v2.asm' from 'Sonic 2 Clone Driver v2 - Compatibility.asm', because of how constants are now generated
    • Added DAC volume control
    • Removed some excessive optimisation
    • Removed needless 'Clownacy |' comments
    • Removed pointless commented-out code
    • Rearranged constants and flags, allowing DAC ID constants to be used in your hack's code
    • Switched back to S1's Sega chant sample (S2's is just S1's with a bit cut off at the end)
    • Fixed mistake in Mega PCM's code I made at some point (an iy+3 was changed to iy+2, breaking panning)
    • Made everything case-sensitive-friendly

    09/07/2015
    v2.3
    • Made FadeOutSFX use d6 instead of d7, so that it doesn't conflict with Sound_PlayBGM
    • Optimised PSG envelopes with more efficient use of flags
    • Made previous version's bugs toggleable with Fix_DriverBugs
    • Added Valley Bell's Sega chant pan fix
    • Added Valley Bell's 0 FM track fix
    • Added Valley Bell's cfFadeInToPrevious PSG noise type fix
    • Added a (commented out) call to FadeOutSpecSFX in Sound_PlayBGM
    • Un-commented-out the calls under Sound_PlayBGM
    • S2-ified FadeOutSFX
    • Corrected StopSoundAndMusic comment
    • Improved cfFadeInToPrevious FM6 fix
    • Reduced RAM usage by employing a trick from S&K's driver: the SFX/special SFX share RAM with the 1up music backup
    • Switched to using 'STRUCT' to define track RAM
    • Defined driver RAM with phase/ds.b combo
    • Split v_1up_ram_copy into v_1up_ram_copy and v_1up_variables (variables now go after tracks)
    • As part of the SFX/track backup share, the playback control bytes of all tracks are separately backed-up
    • Made Sound_PlayBGM's extra life code clear the special SFX tracks' 'is playing' bit
    • Special SFX code above FMDACInitBytes now uses tst.b instead of tst.w
    • Moved v_special_voice_ptr back next to v_voice_ptr (RAM is dynamic now, so it can go here without wasting any RAM if unused)
    • Made continuous SFX RAM toggleable
    • Reduced zTrack size to $2E by changing LoopCounters from 4 bytes to 2 bytes, as S&K's driver has it
    • Reduced zTrack size to $2C with some track-specific RAM usage
    • FinishTrackUpdate no longer clears VolFlutter on non-PSG tracks
    • Removed now-useless label (loc_721B6)

    09/03/2015
    v2.2.6
    • Sonic 2-ifications
      • Added to FMUpdateTrack and PSGUpdateTrack the way S2's driver does
      • Made TrackSetRest no longer continue to FinishTrackUpdate
      • Fixed modulation on rests by adding a check to DoModulation (noticeable at start of ARZ's theme after it's looped)
      • Relocated a check in FMPrepareNote to occur a little earlier
      • Changed a reference to a locret in Sound_PlayBGM with one to .bgm_loadMusic, which should make it so that the extra life music can interrupt itself
      • Made .bgmnot1up clear v_fadeout_counter
      • .bmg_fmloadloop and .bgm_psgloadloop now set the 'track at rest' bit, avoiding hanging notes (noticable at start of DEZ's theme)
      • Optimised .silencefm6 using some S2 logic
      • Sound_PlaySFX no longer checks v_fadeout_counter
      • FadeOutMusic no longer calls FadeOutSFX
      • SpeedUpMusic and SlowDownMusic no longer set v_main_tempo_timeout
      • PSGSetVolume now corrects values that are >=$10
      • PSGSetFreq and .restpsg don't continue to FinishTrackUpdate
      • An 'add' in PSGSendVolume is replaced with an 'ori'
      • cfPanningAMSFMS has an additional check
      • Added a (commented out) call to FadeOutSFX in Sound_PlayBGM
    • .nospeedshoes no longer sets v_main_tempo_timeout to the header tempo. This is to avoid unintended tempo overflow on the first frame of playback, delaying the song by a frame. This also helps to prevent hanging notes (noticable at start of DEZ's theme)
    • Removed useless 'even' from under FMDACInitBytes
    • Removed last '0's from FMDACInitBytes and PSGInitBytes (were actually 'even's)

    03/03/2015
    v2.2.5.2
    • Added waitZ80 macro, for S1 compatibility
    • Added cfSendFMI
    • Replaced cfOpF9 with above
    • Added cfChanFMCommand
    • Added some flag documentation from S3K and flamewing's driver
    • Better-formatted Sonic 2 Clone Driver v2 - Compatibility.asm
    • Relocated DAC ID equates from _smps2asm_inc.asm to Sonic 2 Clone Driver v2 - Compatibility.asm
    • Made said IDs dynamic, in the same way as the music and SFXs
    • Corrected IDs to account for absent dHipHopHitKick3
    • Added id function to Sonic 2 Clone Driver v2 - Compatibility.asm

    21/02/2015
    v2.2.5.1
    • Updated SMPS2ASM

    27/12/2014
    v2.2.5
    • Updated to latest Git (fixing a newly-pointed-out bug along the way)
    • Merged all compatibility layers into s1.sounddriver.compatibility.asm
    • Moved v2.2.4.1b's toggles to s1.sounddriver.compatibility.asm
    • Reverted some dangerous 'moveq's to 'move.b's
    • Optimised a branch under PSGUpdateVolFX
    • Optimised a branch under VolEnv_Reset
    • Removed a branch under VolEnv_Off by moving it above the branch's target
    • Size-optimised MegaPCM, reducing the uncompressed binary's size from 210h to 1E5h
    • Added another nop instruction to waitYM (the beginning of S2's title screen theme plays a goofy note in Regen with just the one)
    • Optimised FMSetFreq by making it write directly from FM_Notes to zTrackFreq
    • Replaced the 'clr.b's under bgmnot1up with a faster moveq/move.b combination
    • Removed the redundant 'clr.b v_sndprio'
    • Optimised Sound_PlayBGM and Sound_PlaySpecial by making them write their voice pointers directly to v_voice_ptr/v_special_voice_ptr (old leftover from v2.1's longword voice pointer hack)
    • Optimised SpeedUpMusic, SpeedUpMusic_1up, SlowDownMusic and SlowDownMusic_1up with some register usage
    • Optimised some zTrackVolume(a5) usage under DoFadeOut
    • Optimised .bgm_psgloadloop by using an addq to skip the 'redundant' byte
    • Optimised Sound_ChkValue by removing the redundant check for Sound Commands
    • bsr -> bra in .specfmdone
    • Renamed all s1.sounddriver files and moved them to the sound folder
    • Changed which v_sndprio clear is used in Sound_PlayBGM (Sonic 2 uses the last one)
    • Added new waitYMspec macro that uses parameter as target for tst
    • Used above modification to optimise WriteFMI
    • Optimised cfSetPSGNoise with better register use
    • Rearranged files at end of driver (Mega PCM, PSGs, music, sounds, others) to put many within 'SoundIndex(pc)' range
    • Fixed oversight in cfNoteFillS3K (d1 isn't loaded if tempo divider = 1), increasing compatibility with S3K music
    • Added two missing S1 equates
    • Excluded nops from waitYM loop
    • Used more appropriate locret under FMNoteOn
    • Added S3K tweak to cfSetPSGTone and cfSetVoice

    17/10/2014
    v2.2.4.1b
    • Added several toggles to allow for Sonic 1 support

    15/10/2014
    v2.2.4.1
    • Optimised WriteFMI(I) with a nice trick I picked up from Ristar's driver
    • Optimised some writes to psg_input
    • Optimised all adda.x #x,aN to lea x(aN),aN
    • Optimised FM and PSG's .gotduration by replacing them with SetDuration_pea
    • Added a nop to WaitYM to avoid missed writes
    • Optimised PSG flags by reordering their checks in order of most-to-least common
    • Replaced a 'branch to rts' with an rts
    • Restored the music and SFXs to their 'as-of-2011' state. They shouldn't be modified in the first place
    • Added to _smps2asm_inc.asm to fix DAC typo

    06/10/2014
    v2.2.4
    • Fixed FM6 fade-in
    • Modified cfFadeToPrevious to work on FM and PSG tracks
    • Optimised some locrets (recycling!)
    • Annotated Vladikcomper's modified WriteFMI(I)
    • Removed a startZ80 that I missed back in v2.0
    • Renamed several constants to be more S1-like
    • Restored original local labels (With tweaks for compatibility)
    • Optimised lea Clone_Driver_RAM into .w
    • Optimised 68k version of PlaySega
    • Ported S3K's NoteFill
    • Optimised some 'bsr & bra' into 'pea & bra'
    • Further optimised the waitYM macro by using tst.b instead of btst
    • Optimised all btst #7 to tst
    • Even further optimised waitYM by moving ym2612_a0 to a register
    • Updated channel RAM addresses description
    • Optimised NoteFillUpdate

    13/09/2014
    v2.2.3.1
    • Moved troublesome PSG frequency
    • Reverted PSGPitchConvert to an earlier, more readable state

    11/09/2014
    v2.2.3
    • Added S3K's additional PSG frequencies
    • Added S3K's continuous SFX system
    • Split sound priorities and speedup tempos from main asm into s1.sounddriver.other.asm
    • Improved guide to update driver on H_Int when available

    14/08/2014
    v2.2.2.1
    • Made slight optimisation around the branch to TempoWait by removing the branch altogether :P
    • Optimised some lsl into add
    • Optimised some clr.l into move.l
    • Optimised some branches from .w to .s
    • Made a bunch of bsr.w into bsr.s
    • Fixed (my) error in _smps2asm_inc.asm that caused missing coordination flags to not be detected

    18/07/2014
    v2.2.2
    • Added fourth sound queue
    • Replaced all 'jsr's with 'bsr.w's, and 'jmp's with 'bra.w's
    • Made small optimisations under PBGM_BGMLoadMusic, PSGUpdate_NoteGoing, SetVoice_SendTL, UnpausedAllFM, FadeIn_FadedDone, FM_UpdateFreq
    • Renamed Snd_FadeOutSFX and Snd_FadeOutSFX2
    • Changed bcc into bhs under PSFX_TimerActive
    • Optimised some of the Spin Dash rev code
    • Optimised waitYM macro (nothing uses d2 afterwards, and bit instructions can affect memory)
    • Restored cfUnused1 (cfSetCommunication)
    • Removed Size_of_SegaPCM macro (unused leftover from 2.0 :P)
    • Fixed error made while removing Special SFX code under FadeOut_TrackPSG
    • Fixed (my) error in the smpsStopSpecial macro
    • Optimised some code around PSFX_SFXInitPSG (code was made less efficient back when I was trying to fix the $40+ index bug)
    • Fixed Sound_PlaySpecial (it didn't support absolute voice pointers, and also has the $40+ index bug)

    04/07/2014
    v2.2.1.2
    • Removed some 'jsr's that interfered with the Stack

    03/07/2014
    v2.2.1.1
    • Optimised PAL mode
    • Ported S2's PAL timer system
    • Made PAL_Audio_CountDown part of the Clone Driver's RAM

    01/07/2014
    v2.2.1
    • Removed 68k-freeze code in PlaySega, it has negative effects in Sonic 2
    • Added coordination flag cfSilenceStopTrack
    • Added coordination flag cfPlayDACSample
    • Added coordination flag cfPlaySound
    • Added coordination flag cfSetKey
    • Added coordination flag cfSetVolume
    • Added FMSilenceChannel
    • Removed two unused coordination flags
    • Redone PAL mode
    • Replicated S2's ability to force PAL slowness on certain songs

    29/06/2014
    v2.2
    • Rearranged indexes and data again, now they are all located after the driver's code
    • Reformatted PSGDoVolFX
    • Ported three new PSG flags, two are used by S3K's PSGs, the final is unused, but added for the sake of completion
    • Now using stock S3K PSGs instead of converted-to-S1 equivalents
    • Ported S1 & S2 PSGs
    • Added missing 'even' after the Universal Voice Bank
    • Optimised the unused coordination flags' code
    • Optimised some code under Sound_Play
    • Corrected some comments
    • Ported S3K's TempoWait, allowing full access to S3K-style tempos
    • Added S2 speedup tempos, converted to S3K tempos
    • Replaced the Original Clone Driver's modified S2 music with stock S2 music

    16/06/2014
    v2.1.3
    • Removed more Special SFX remnants, namely v_special_voice_ptr
    • Freed up a tiny amount of RAM by turning some byte-sized flags to bit-size. They are grouped under the RAM address 'misc_flags'. Flags include:
      • v_gloop_toggle
      • Spindash_LastSound_Flag
      • v_ring_speaker
      • f_updating_dac
      • f_fadein_flag
    • f_updating_dac and f_fadein_flag been changed to a bit, so their 'On' state isn't defined by being set to $80, but to 1
    • Removed f_fastmusic entirely, it's not even used in this version of the Community disasm. It's just v_1up_ram_copy's copy of f_speedup
    • Fixed typo in instruction under PSFX_NotSpinDashRev label
    • Rearranged RAM variables to group all unused RAM in one area ($19-$39)
    • Split music and sound 'include's from main asm file, allowing users to update their s1.sounddriver.asm without overwriting their custom music and sound 'include's
    • Done the above to the music and SFX pointers, also. Said pointers have also been moved to above their respective 'include's, for sake the of ease when updating
    • Added missing equate under Sound_PlaySpecial
    • Modified installation guide to feature a full-speed PAL audio fix, straight from MJ's Moonwalker

    20/04/2014
    v2.1.2
    • Relocated coordination flags from $E0+ to $FE+, as a result, there are now free DAC slots and a total of $7C DAC slots
    • Corrected S3/K/3D DAC order
    • Named all S3/K/3D/C DACs
    • Removed cfStopSpecialFM4

    19/04/2014
    v2.1.1
    • Compressed Mega PCM Z80 code, DAC tables are still uncompressed though
    • Readded Mega PCM .wav compatibility
    • Matched S2 DAC pitches to those in S2's driver, but they're still inaccurate, the snare seems to be BETWEEN 3 and 4
    • Added Crackers DACs
    • Fixed SMPS2ASM's dLowerEchoedClapHit entry

    15/04/2014
    v2.1
    • Relocated sound commands from $F9-$FD to $FB-$FF
    • Fixed priorities list not including the sound commands ($FB-$FF)
    • Adapted Sonic 2's feature of having the priorities system only apply to SFXs
    • Added Sound Flag $FA, StopSFX, now back from Sonic 2, and fully functional
    • Added S3+ PSG instruments
    • Added S3+ DAC samples
    • Added S3+ Universal Voice Bank
    • Modified _smps2asm_inc.asm to have an option for the Clone Driver v2, 'SonicDriverVer = 0'
    • Removed remainder of the Special SFXs ($D0-$DF), freeing up $60 bytes of RAM
    • Rearranged data and indexes:
      • Data (UniVoiceBank, PSG, Music, SFX) at bottom
      • Indexes (PSG, Music, SFX) at top
    • Music and SFXs use absolute (longword) pointers for their Voices, this is to allow UniVoiceBank support
    • Removed all 'Go_Index' nonsense, references are now direct
    • Made Sega PCM ID dynamic
    • Added Flag IDs

    01/04/2014
    v2.0.1
    • Removed unused SoundIndex entry
    • Removed redundant Sega PCM alignment
    • Fixed sound priority
    • Used constants to make sound group changing more accessible
    • Reworded >=$E0 sound bug explanation

    31/03/2014
    v2.0 (Initial release)
    • Ported to AS
    • Replaced local labels with unique labels
    • Added Hivebrain labels
    • Added Mega PCM
    • Applied 'Optimising Z80 Stops' guide
    • Added SMPS2ASM
    • Added S2 priorities
    • Added S2 DACs
    • Added S2 PSGs
    • Added Spin Dash support
    • Added Gloop support
    • Fixed bug causing sounds with an index entry of >=$40 to crash
    • Fixed v_playsnd3 to be fully usable
    • Replaced S1's music with the original Clone Driver's music
    • Replaced S1's sound effects with S2's sound effects
    • Relocated Silence value to $00
    • Extended starting sound slot from $81 to $01
    • Relocated MusicIndex to above music 'BINCLUDE's
    • Removed special SFX-related code
    • Relocated sound commands from $E0-$E4 to $F9-$FD

    Videos


    Credits

    Original Sonic 2 Clone Driver
    Varion Icaria - Puto's sound driver port
    Esrael - Tweaker's sound driver port, plus fixes for Puto's port, including a fix for the Sega sound
    Puto, Tweaker, StephenUK - Numerous fixes
    JMan2050 - Jman's PCM driver
    Valley Bell - $EC sound fix

    Sonic 2 Clone Driver v2
    Contributors to the sound driver disassemblies
    Valley Bell - General help, fixes for some bugs, SMPS Research Pack, inspiration
    Shobiz - Ported Spin Dash rev code
    Puto - Original 68k Sega chant playback code
    MarkeyJester - DAC fade-in fix, along with pointing several other bugs in S1's driver
    Cinossu - S1SMPS2ASM, the basis of SMPS2ASM
    Flamewing - SMPS2ASM core; pointing out S3K's additional PSG frequencies; his perfect-compression koscmp, used to compress Mega PCM
    Vladikcomper - Mega PCM, this fix
    Gardeguey - SH2 code used as the basis of the 'Stub SH2' program
    Clownacy - Go read the changelog =P
     
    Last edited: Jul 2, 2021
  2. Clownacy

    Clownacy

    Tech Member
    1,053
    581
    93
    Update time: Link in main post

    v2.1
    • Fixed Priorities list not including the Sound Flags ($FB-$FF)
    • Adapted Sonic 2's feature of having the priorities system only apply to SFXs
    • Added Sound Flag $FA, StopSFX, now back from Sonic 2, and fully functional
    • Added S3+ PSG instruments
    • Added S3+ DAC samples
    • Added S3+ Universal Voice Bank
    • Modified _smps2asm_inc.asm to have an option for the Clone Driver 2, 'SonicDriverVer = 0'
    • Removed remainder of the Special SFXs ($D0-$DF), freeing up $60 bytes of RAM
    • Rearranged data and indexes:
      • Data (UniVoiceBank, PSG, Music, SFX) at bottom
      • Indexes (PSG, Music, SFX) at top
    • Music and SFXs use absolute (longword) pointers for their Voices, this is to allow UniVoiceBank support
    • Removed all 'Go_Index' nonsense, references are now direct
    • Made Sega PCM ID dynamic
    • Added Flag IDs
     
  3. Caverns 4

    Caverns 4

    Member
    346
    0
    16
    Sonic: Retold
    Did you miss something? I tried the installation guide and now I'm getting a black screen on Regen, leading me to believe that it certainly won't work on real hardware either. Is it just me?

    edit: Yeah, I think it's probably me. I already had the original version of the Clone Driver in my hack, so I think something's being wobbly because of that.
     
  4. Clownacy

    Clownacy

    Tech Member
    1,053
    581
    93
    If it means anything, I primarily test on Regen, with good results. I'm surprised that this is incompatible with hacks that had the original Clone Driver installed, heck, the installation guide is based on the one I posted in your thread all that time ago!

    There is a black-screen bug associated with a certain component of this driver, but I fixed it: Mega PCM's 'Optimising Z80 stops' guide had you remove code that stopped the Z80, but not the code after it that checked if the Z80 had stopped, and, if not, loop back and check again, going in an infinite loop which left you at a black screen.

    EDIT: Tested with a new installation, no blank screen. The Optimised Z80 Stops guide may have to be improvised, though, looks like some of my labels are old. Just clear out the stop/startz80 in V_int.
     
  5. Caverns 4

    Caverns 4

    Member
    346
    0
    16
    Sonic: Retold
    I was able to get the new version of the Clone Driver working in a hack without issue, though now I want to know if it's possible to convert assembled songs into the macro format? If not, then this may provide limited usefulnes, unless it's simple enough to to revert it so that built files can be read.
     
  6. Clownacy

    Clownacy

    Tech Member
    1,053
    581
    93
    Macro format? You mean 'run a built song through smps2asm.exe and have it converted properly'? No, not in its native state. But why would you want to do that? Unless you're stealing a song from a hack, why would you pull a song from an assembled game? In their SMPS2ASM form, all sound files follow stock SMPS2ASM standards, so any other driver using SMPS2ASM can use the songs with no issues, though this will be broken in a later update, where in order to expand the DAC range, I'll need to add a proceeding flag, and I've yet to find a way to effectively "macro-ise" it, so that it'd be handled by _smps2asm_inc.asm without any changes to the individual songs. So far, it looks like you'd have to manually append a flag byte before every DAC entry or duration.

    One epic digression later... In the current version, the Voices pointer is absolute, so you'd need to change that to a word-length pointer relative to its location. You'd also have to restore the Coordination Flag layout of Sonic 1: Currently, their order is almost the same, only they all occupy $FF and $FE. Remove $E0 and slap a $FF before it, and you have the Clone Driver 2 equivalent (for example, "$E2" becomes "$FF,$02"), this somewhat also applys to smpsNoAttack, but, due to a problem with maintaining compatibility with SMPS2ASM-converted files, it is relocated to $FE; the macros don't like smpsNoAttack having the company.

    Of course, there's also the problem with songs that use anything but S1 DACs: smps2asm.exe will label them incorrectly, so you'd have to manually equate them yourself.

    With that all done, you'd still need to correct all of the pointers to accommodate all of the removed bytes.

    Unless I'm a massive idiot and is misreading your post entirely: As I said above, for the moment, this driver's fully compatible with standard SMPS2ASM songs, in the same way that Flamewing's driver is. SMPS2ASM songs do not require any modification to work with the driver, outside of those normally needed for Sonic 1 driver compatibility, such as coordination flag removal/replacement.
     
  7. Caverns 4

    Caverns 4

    Member
    346
    0
    16
    Sonic: Retold
    Maybe it's just me, but it kind of sounded like you were pointing a finger at me. For your imformation, I wanted Sonic 1/2Beta/3K songs in my hacks, and all of those songs are assembled in their respective disassemlies.

    What you're doing now is creating a new music format for the Sonic 1 Sound Driver, and elimating compatibility with the original, making all pre-existing songs incompatable, and while I'm all for moving forward normally, this is one case where I'm not on board unless the the rest of the community is about to embrace this, especially since, from what I understand, you're telling me that porting GHZ's music from Sonic 1 to 2 just went from a copy paste job to writing an entire song in assembly.

    If you intend to move in that direction, then I which you the best of luck, and I'll keep an eye on your sound driver for code reference, but I will not be using your sound driver in my hacks.
     
  8. MainMemory

    MainMemory

    Kate the Wolf Tech Member
    4,735
    334
    63
    SonLVL
    The SMPS2ASM tool can convert binary songs to the macro format, and there is in fact an archive linked in that post containing all of the music and SFX from S1-S3D preconverted. You will have to modify some things, but you won't have to rewrite the entire song in assembly.
     
  9. Clownacy

    Clownacy

    Tech Member
    1,053
    581
    93
    Really? I said "SMPS2ASM" so many times, I thought I needn't point out that the sound files use it.

    So Sonic 2 and 3 can get away with slightly differing formatting but not me? :v:/>

    EDIT: It's worth mentioning that I thought you meant "Can I pull an assembled song from a ROM that uses this driver and have smps2asm.exe process it correctly?"
     
  10. Caverns 4

    Caverns 4

    Member
    346
    0
    16
    Sonic: Retold
    I didn't know about this, thanks for linking it.

    I suppose in fairness, I DID misread your post in a few places. I do understand better now. In that case, I might use this Sound Driver some time in the future, but not for the time being.

    The mean reason modifying the format is a problem for me is simply because of the fact that while label and bug fixing, adding a few macros and so on is fine, the Sonic 1 music format was the most widely accepted one... Or so I thought, prior to learning about SMPS2ASM. Knowing that there is a more or less "community format" now, if what you're working on is an improved variant of that, I probably will get on board with it later, assuming it acquires support.
     
  11. Clownacy

    Clownacy

    Tech Member
    1,053
    581
    93
    The format hasn't been changed yet: it's fully compatible with other drivers and other versions of SMPS2ASM. The internals of the driver have changed, but the songs haven't, as long as they're .asm. Every .asm sound file in that archive MainMemory gave you is compatible with the driver, as are any music files you have smps2asm.exe process.

    But the quickest and easiest way I can imagine my soon-to-be-modified format seeing more widespread support is if the program that converts .bin to .asm, smps2asm.exe, began supporting user-input layout configuration. The reason smpsNoAttack doesn't follow the other coord flag's pattern is because of SMPS2ASM's non-changeable layout, it's currently set so that smpsNoAttack's usage is more strict than other flags'. Yes, one could modify their music files and their _smps2asm_inc.asm, but any files created by smps2asm.exe will require modification. In the future, it will have to be that I will need to leave instructions indicating how to change your music files to a compatible format.

    I know a possible way to "macro-ise" DAC instrument calls so that they have a preceding flag, allowing more DAC samples. But, in other locations, where there are only raw values, manual flag insertion or manual macro-ising of every significant byte of raw data will have to be done. I've had to do this with my personal build of the Clone Driver, it ain't fun.

    I'm not so willing to remove support for SMPS2ASM, but several restrictions regarding macros, brought on by Macro Assembler AS or SMPS2ASM itself restrict me from incorporating features without modifications to them.
     
  12. Caverns 4

    Caverns 4

    Member
    346
    0
    16
    Sonic: Retold
    In that case, I would have no problem using this version of the Sound Driver, except for the fact that I haven't been able to get SMPS2ASM to do anything.
     
  13. Clownacy

    Clownacy

    Tech Member
    1,053
    581
    93
    It's command line, took a while to figure it out completely. The most basic setup you'll want is to get smps2asm.exe in a folder, in the same folder, have GHZ's music in .bin S1 format then hold Shift key and right-click in the Explorer window without anything selected, select "Open command window here", then input the following:

    smps2asm.exe -v 1 "GHZ.bin" "GHZ.asm" GHZ

    If you just enter "smps2asm.exe" you'll get an explanation of what these are: "-v" being driver version, and "1" the variable following it, which matches the driver which the file came from. After that is the input .bin filename, then the output .asm filename, and finally, the name the .asm file uses to identify itself. So labels such as the voices label are "GHZ_Voices".

    There are more settings that are worth using in other situations, like Offset for Z80 driver sound files.
     
  14. redquebec

    redquebec

    Member
    39
    0
    6
    I want to take this opportunity to thank you Clownacy for the great work you've done here! I've been playing with the Clone Driver for some time now, and the cleanup you did is simply short of amazing. The new DAC table open so much possibilities for hacking, and great sound quality too (Mega PCM in Sonic 2? Raaaahh lovely ^^). What do you plans to do next?
     
  15. Clownacy

    Clownacy

    Tech Member
    1,053
    581
    93
    Well, the DAC table still has a way to go: As described above, I intend to roughly double the maximum number of DAC samples. I also plan to implement a less hackish way of supporting S3+ PSGs. You can thank the Community Disasm contributors for the cleanup, all I did was add Hivebrain labels and replace the local ones.

    On the topic of your queries on S3 Complete's thread, what would be the most direct approach of simply adding Mega PCM is hindered by several things, as described here. Though I don't know what upgrading the DAC playback would do: from what I've seen, outside of the PC tracks, S3C doesn't stray from the stock music, so the benefits of additional playback functions would go unnoticed due to lack of use.
     
  16. redquebec

    redquebec

    Member
    39
    0
    6
    The main advantage of Mega PCM is the very cristal-clear clarity of the DAC playing. It is superior-sounding to the original driver. :) Did you noticed that too or is it my ears? ^^
     
  17. Clownacy

    Clownacy

    Tech Member
    1,053
    581
    93
    Vladikcomper mentioned how even the stock DACs play static-ish, but his solution was to optimise the Z80 stops in the H-Interrupt. Not Mega PCM itself. I wouldn't know if that would even work with the Z80 drivers.
     
  18. Clownacy

    Clownacy

    Tech Member
    1,053
    581
    93
    Haven't bothered to write posts on the past couple of update, so I'll group them all here.

    v2.1.1
    • Compressed Mega PCM Z80 code, DAC tables are still uncompressed though
    • Reintroduced Mega PCM .wav compatibility
    • Matched S2 DAC pitches to those in the S2 driver, but they're still inaccurate, the snare seems to be BETWEEN 3 and 4
    • Added Crackers DACs
    • Fixed SMPS2ASM's dLowerEchoedClapHit entry

    v2.1.2
    • Relocated Coord flags from $E0+ to $FE+, as a result, there are now free DAC slots and a total of $7C DAC slots
    • Corrected S3/K/3D DAC order
    • Named all S3/K/3D/C DACs
    • Removed cfStopSpecialFM4

    v2.1.3
    • Removed more Special SFX remnants, namely v_special_voice_ptr
    • Freed up a tiny amount of RAM by turning some byte-sized flags to bit-size. They are grouped under the RAM address 'misc_flags'. Flags include:
      • v_gloop_toggle
      • Spindash_LastSound_Flag
      • v_ring_speaker
      • f_updating_dac
      • f_fadein_flag
    • f_updating_dac and f_fadein_flag been changed to a bit, so their 'On' state isn't defined by being set to $80, but to 1
    • Removed f_fastmusic entirely, it's not even used in this version of the Community disasm. It's just v_1up_ram_copy's copy of f_speedup
    • Fixed typo in instruction under PSFX_NotSpinDashRev label
    • Rearranged RAM variables to group all unused RAM in one area ($19-$39)
    • Split music and sound 'include's from main asm file, allowing users to update their s1.sounddriver.asm without overwriting their custom music and sound 'include's
    • Done the above to the music and SFX pointers, also. Said pointers have also been moved to above their respective 'include's, for sake the of ease when updating
    • Added missing equate under Sound_PlaySpecial
    • Modified installation guide to feature a full-speed PAL audio fix, straight from MJ's Moonwalker

    With the v2.1.3 update, an update-friendly system has been introduced, to make it possible for one to update without losing their custom music and SFX.

    Hopefully, this is the end of my optimisation spree, and I'll finally move on to adding some features...

    ...which I apparently couldn't wait to get to and already added one! That last point, I'm quite happy with; at least something came of that Moonwalker SMPS disassembly. I'll see if I can pick anything from it in the future. It's slightly modified, however: Moonwalker used word operations on PAL_Audio_CountDown despite the highest value written to it being 5. I'm surprised the issue of slowed music on PAL units evaded me until now. I hadn't even thought of it despite me being in a PAL region, myself :P
     
  19. redquebec

    redquebec

    Member
    39
    0
    6
    Looking good Clownacy, thanks a lot for the hard work. :) Will update my build tonight. You know, tracking all the improvement you did on Sonic 1 and 2 is really something. Well done :)
     
  20. Clownacy

    Clownacy

    Tech Member
    1,053
    581
    93
    Two major things here, ported PSG flags and S3K tempo algorithm. The latter is a really welcome addition; even with the modified S2 music of the original Sonic 2 Clone Driver, the tempos were still way off on certain songs, and even worse, the speedup tempos were broken, as the modified music's tempos were already near maximum! With the introduction of S3K's tempo algorithm, I can restore the stock S2 music files and restore the speedup tempos to their former functionality! With this, Sonic 2's driver should be mostly 'cloned' (functionality wise)! Currently, there are some very minor audio differences that I believe to be bugs with the original Sonic 1 driver.

    v2.2
    • Rearranged indexes and data again, now they are all located after the driver's code
    • Reformatted PSGDoVolFX
    • Ported three new PSG flags, two are used by S3K's PSGs, the final is unused, but added for the sake of completion
    • Now using stock S3K PSGs instead of converted-to-S1 equivalents
    • Ported S1 & S2 PSGs
    • Added missing 'even' after the Universal Voice Bank
    • Optimised the unused coordination flags' code
    • Optimised some code under Sound_Play
    • Corrected some comments
    • Ported S3K's TempoWait, allowing full access to S3K-style tempos
    • Added S2 speedup tempos, converted to S3K tempos
    • Replaced the Original Clone Driver's modified S2 music with stock S2 music

    Well, that's it. This now has features and code from at least five different drivers crammed into it. I'm officially dubbing this 'Project Clusterfuck'.

    Updating:
    You must overwrite _smps2asm_inc.asm with the new one. This is to allow usage of S3K tempos.