Y'know what? I think I can make a thread out of this. Let's start off with the following: Files for the Sub CPU code for the ending FMVs have the wrong filenames (GOODEND.BIN is for the bad ending, BADEND.BIN is for the good ending, .MMD and .STM files are correct, though) Level 16x16 blocks are compressed in Nemesis, which is usually only meant for graphics compression, not metadata compression. Level demo files are built from a slightly older version of the level codebase. R11A uses direct addresses for player variables in LevelSizeLoad, and also takes out some leftover Sonic 1 code, while the other level files I've seen pass the player slot into a6 and retain said leftover Sonic 1 code. FMV PCM streaming code has an issue where it'll not write the last 8 bytes in a packet, due to the very last PCM bank having a loop flag set, and them lazily not wanting to overwrite it, resulting in playback quality degradation. Their setup turned out to be unnecessary anyways, but they probably didn't know that, since PCM playback address wrapping back to the start of wave RAM when going past the end isn't officially documented. Speaking of FMV PCM streaming, there's code for setting up a second channel. It's possible that stereo audio was planned, but scrapped. The second channel's registers are set to corrupt data and actually does sound, but its volume is set to 0, so nothing is actually played back from it. Each music track gets their own Sub CPU command entry for playing it. Doubled actually. A set for normal playback, and another for the sound test. Each level gets their own Sub CPU command for loading it. They all point to the same function, but the command ID is used for another table for loading in the appropriate data. The "I'm outta here" and time warp timers are updated every V-BLANK, so even if the game is lagging, they update at a steady 50/60 Hz. This explains why the Taxman version appears to take longer to do a time warp sometimes, even though it really isn't. The Gems Collection of the game has leftover symbol data that can give a glimpse into how files were structured. While levels did use some commonly shared code, they did copy and paste other files for more specific things like scrolling, object lists, data, etc. Even if there are some functions that should also be shared from one common file, they aren't, and this explains some of the weird minute differences between level files. Title screen has 3 unused object functions that are broken. The first sets a "bookmark" that the object manager will jump to in future calls for that object. There's another version that does that and exits the object, and this broken one is meant to set it and then return back to the object. It breaks because it overwrites a0, which was also used for the object slot pointer. The second one is meant to update the object's address manually, but in the title screen, object addresses are stored as words (with the upper word being automatically set to 0x00FF, since it's all loaded in Genesis RAM), and in this function, it writes a longword. The third is meant to delete an object, but it advances a0 as it erases data, so it desyncs the object manager loop. SMPS-PCM issues that aren't really to do with Sonic CD to begin with: The driver is based on the US BIOS' version, where they took out the rhythm channel in a half-assed manner. They didn't remove the slot in the variables region and they didn't take out the channel ID in the assignment array for song tracks. As a result, the proper slot and channel assignment for track 8 are unreferenced. T̶h̶i̶s̶ ̶a̶c̶t̶u̶a̶l̶l̶y̶ ̶c̶a̶u̶s̶e̶s̶ ̶a̶ ̶b̶u̶g̶ ̶w̶i̶t̶h̶ ̶t̶r̶a̶c̶k̶ ̶1̶ ̶a̶n̶d̶ ̶8̶,̶ ̶b̶e̶c̶a̶u̶s̶e̶ ̶t̶h̶e̶ ̶r̶h̶y̶t̶h̶m̶ ̶c̶h̶a̶n̶n̶e̶l̶ ̶w̶a̶s̶ ̶a̶s̶s̶i̶g̶n̶e̶d̶ ̶t̶o̶ ̶u̶s̶e̶ ̶c̶h̶a̶n̶n̶e̶l̶ ̶8̶,̶ ̶w̶i̶t̶h̶ ̶s̶o̶n̶g̶ ̶t̶r̶a̶c̶k̶ ̶7̶ ̶u̶s̶i̶n̶g̶ ̶c̶h̶a̶n̶n̶e̶l̶ ̶8̶ ̶(̶I̶'̶l̶l̶ ̶e̶x̶p̶l̶a̶i̶n̶ ̶w̶h̶y̶ ̶i̶n̶ ̶t̶h̶e̶ ̶n̶e̶x̶t̶ ̶p̶o̶i̶n̶t̶)̶ ̶w̶h̶e̶n̶e̶v̶e̶r̶ ̶r̶h̶y̶t̶h̶m̶ ̶w̶a̶s̶ ̶n̶o̶t̶ ̶b̶e̶i̶n̶g̶ ̶u̶s̶e̶d̶.̶ ̶H̶o̶w̶e̶v̶e̶r̶,̶ ̶s̶i̶n̶c̶e̶ ̶t̶h̶e̶y̶ ̶f̶o̶r̶g̶o̶t̶ ̶t̶o̶ ̶t̶o̶t̶a̶l̶l̶y̶ ̶r̶e̶m̶o̶v̶e̶ ̶t̶h̶e̶ ̶r̶h̶y̶t̶h̶m̶ ̶c̶h̶a̶n̶n̶e̶l̶ ̶d̶a̶t̶a̶,̶ ̶t̶r̶a̶c̶k̶ ̶1̶ ̶u̶s̶e̶s̶ ̶c̶h̶a̶n̶n̶e̶l̶ ̶8̶,̶ ̶w̶h̶i̶l̶e̶ ̶t̶r̶a̶c̶k̶ ̶8̶ ̶a̶l̶s̶o̶ ̶g̶e̶t̶s̶ ̶a̶s̶s̶i̶g̶n̶e̶d̶ ̶t̶h̶a̶t̶ ̶c̶h̶a̶n̶n̶e̶l̶.̶ (EDIT: Disregard, was incorrect) SFX support is very lackluster. Channel overriding does not exist. What they did was allocate SFX to play on channel 7 and try not to have the music use that channel. O̶r̶i̶g̶i̶n̶a̶l̶l̶y̶,̶ ̶w̶i̶t̶h̶ ̶t̶h̶e̶ ̶r̶h̶y̶t̶h̶m̶ ̶c̶h̶a̶n̶n̶e̶l̶ ̶i̶n̶t̶a̶c̶t̶,̶ ̶t̶r̶a̶c̶k̶ ̶8̶ ̶w̶a̶s̶ ̶a̶s̶s̶i̶g̶n̶e̶d̶ ̶t̶o̶ ̶u̶s̶e̶ ̶c̶h̶a̶n̶n̶e̶l̶ ̶7̶ ̶(̶w̶h̶i̶c̶h̶ ̶i̶s̶ ̶w̶h̶y̶ ̶t̶r̶a̶c̶k̶ ̶7̶ ̶w̶a̶s̶ ̶a̶s̶s̶i̶g̶n̶e̶d̶ ̶t̶o̶ ̶u̶s̶e̶ ̶c̶h̶a̶n̶n̶e̶l̶ ̶8̶)̶,̶ ̶s̶o̶ ̶y̶o̶u̶'̶d̶ ̶h̶a̶v̶e̶ ̶t̶o̶ ̶b̶e̶ ̶c̶a̶r̶e̶f̶u̶l̶ ̶t̶o̶ ̶n̶o̶t̶ ̶l̶e̶t̶ ̶S̶F̶X̶ ̶a̶n̶d̶ ̶t̶r̶a̶c̶k̶ ̶8̶ ̶c̶l̶a̶s̶h̶.̶ ̶H̶o̶w̶e̶v̶e̶r̶,̶ ̶h̶e̶r̶e̶ ̶w̶i̶t̶h̶ ̶t̶h̶e̶ ̶r̶h̶y̶t̶h̶m̶ ̶c̶h̶a̶n̶n̶e̶l̶ ̶p̶a̶r̶t̶i̶a̶l̶l̶y̶ ̶r̶e̶m̶o̶v̶e̶d̶,̶ ̶c̶h̶a̶n̶n̶e̶l̶ ̶8̶ ̶n̶o̶ ̶l̶o̶n̶g̶e̶r̶ ̶c̶l̶a̶s̶h̶e̶s̶ ̶w̶i̶t̶h̶ ̶S̶F̶X̶,̶ ̶b̶u̶t̶ ̶l̶i̶k̶e̶ ̶I̶ ̶s̶a̶i̶d̶ ̶i̶n̶ ̶t̶h̶e̶ ̶o̶t̶h̶e̶r̶ ̶p̶o̶i̶n̶t̶,̶ ̶i̶t̶ ̶c̶l̶a̶s̶h̶e̶s̶ ̶w̶i̶t̶h̶ ̶c̶h̶a̶n̶n̶e̶l̶ ̶1̶,̶ ̶i̶n̶s̶t̶e̶a̶d̶,̶ ̶w̶h̶i̶c̶h̶ ̶i̶s̶ ̶a̶r̶g̶u̶a̶b̶l̶y̶ ̶w̶o̶r̶s̶e̶.̶ ̶I̶n̶ ̶t̶h̶e̶ ̶e̶n̶d̶,̶ ̶n̶o̶ ̶m̶a̶t̶t̶e̶r̶ ̶w̶h̶a̶t̶,̶ ̶t̶r̶a̶c̶k̶ ̶8̶ ̶i̶s̶ ̶j̶u̶s̶t̶ ̶n̶o̶t̶ ̶r̶e̶a̶l̶l̶y̶ ̶s̶a̶f̶e̶ ̶t̶o̶ ̶u̶s̶e̶ ̶i̶n̶ ̶g̶a̶m̶e̶p̶l̶a̶y̶.̶ (EDIT: Disregard, was incorrect) The way that samples are being statically loaded into wave RAM if not set to be streamed can be problematic. A sample is defined in a table, and if you don't set it to be streamed, then you must define the location in wave RAM for it to be loaded into. The problem is that for samples that ARE being streamed, its location in wave RAM is automatically assigned based on the channel ID, and static samples do not take that into account. For samples that are being streamed, the stream rate is fixed, in the sense that it fills up a designated wave RAM bank at $200 bytes per driver call, effectively making the maximum supported frequency around the native sample rate of the PCM chip. Playing samples faster than that will cause issues, as the streaming code won't be able to catch up in time. In Wacky Workbench, they used a different codebase for the Sonic object. Most of the changes include handling the stage gimmicks and removing the extended camera. However, the spindash charge speed is also 50 instead of the standard 75. Right now, I have no clue why this is, though I do feel it might have to do with the disabled extended camera. It doesn't cause the charge to require a longer time, since that's based on a timer, and not the charge speed, though.