Sound Hacking/Sega Consoles
Sega MegaDrive/Genesis sound hacks
Simple Triggers
These are simple memory triggers. Setting the respective bytes in 68000 or Z80 RAM will cause the game to immediately play a song or sound effect.
See BlastEm's page for instructions on how to use these in that emulator.
Game | Sound Driver | Music Trigger + Comments |
---|---|---|
Bill's Tomato Game | Krisalis/Shaun Hollingworth | maincpu.w@FF900E = xxxx
|
Chuck Rock | Krisalis/Shaun Hollingworth | maincpu.w@FF0014 = xxxx
|
Sonic The Hedgehog | SMPS 68k | maincpu.b@FFF009 = xx
|
Sonic The Hedgehog 2 | SMPS Z80 | genesis_snd_z80.b@1B88 = xx
|
Sonic The Hedgehog 3 | SMPS Z80 | genesis_snd_z80.b@1C0A = xx
|
Spider-Man vs. The Kingpin | unknown custom | play SFX: maincpu.b@FFE6EC = xx , values 00~31 pause music: |
Verytex | Terpsichorean | genesis_snd_z80.b@0107 = 0xXX; genesis_snd_z80.b@0108 = 0x02
|
Advanced Hacks
This section contains ROM patches for playing songs/SFX, as well as hacking information like ROM/RAM offsets and sound driver RAM layouts.
Adventures of Rocky and Bullwinkle and Friends, The
Offset | ROM's Hex | Replace with | Description |
---|---|---|---|
03C29E | 05 A4 | 00 02 | ignore bad ROM checksum |
04C0F7 | 03 | xx | where xx = sound ID |
068B9C | 6A | 60 | Make it freeze on the SEGA screen |
The PlaySong
function is located at ROM offset 05618A
.
Baby's Day Out
Offset | Hex bytes | ASM code | Description |
---|---|---|---|
019FC4 | 41F9 00FF 0408 | LEA $FF0408.L, A0 |
|
019FCA | 4210 | CLR.B (A0) |
|
019FCC | 4A10 | TST.B (A0) |
|
019FCE | 67FC | BEQ $019FCC |
Wait for Vertical Interrupt |
019FD0 | 4EB8 1612 | JSR $001612.W |
Call Play Music (skipping the "stop" part) |
019FD4 | xxxx | DC.W #id |
"song ID" (xxxx) parameter for PlayMusic |
019FD6 | 60FE | BRA * |
Freeze game |
PlayMusic routine | 001608 (stops music, waits for frame to finish, then starts music) |
---|---|
GemsStart routine | 005CC4 (start GEMS sequence) |
GemsStop routine | 005D06 (stop all GEMS sequences) |
GEMS command area | A01B40~A01B7F |
Bass Masters Classic / Bass Masters Classic: Pro Edition
For Bass Masters Classic, these codes will freeze the game and allow you to play any of the GEMS sequences in place of the title track:
15EF3C:01FC 15EF1C:00??
The Pro Edition release has a different set of patch codes:
001DF4:44FC 001E1E:70??
Bill's Tomato Game
Hacking information:
Note: Almost every value is a 2-byte word. (Big Endian) Sound RAM: FF9000 NTSC/PAL Mode: FF9006/07 (01 - NTSC, enables extra delay, 00 - PAL) NTSC Delay Cntr:FF9008/09 (counts 0..5 in NTSC mode, unused in PAL mode) Pause Enable: FF900A/0B (01 - pause sound driver) PlayMusic Slot: FF900E/0F (value is 01+) Tempo Countdown:FF9010/11 Cur. Pattern: FF9012/13 Cur. Row: FF9014/15 Tempo: FF902C/2D Playing State: FF902E -> 00 - playing -> FF - paused Track RAM: FF903A (0C bytes per track, 6 tracks) Total Frames: FF90B0/B1 Frames in Sec.: FF90B2/B3 Total Seconds: FF90B4/B5 Sound Driver Init routine: 0F91AA Sound Driver Update routine: 0F928A Track RAM --------- 00/01 - some Tick Counter 02/03 - Ticks until next event 04 - Event Type?? 05 - Event Data 06 - ?? 07-0B - unused (00)
Bugs Bunny in Double Trouble
The Options menu uses the demo timer, similar to #The Death and Return of Superman. The way to eliminate the timer isn't known yet, but you can extend it.
68000 RAM address 0xFA76
extends the timer when set to a large number below hexadecimal 80/decimal 128. (Set to those numbers, it makes the demo start at once.) At 0x7F, it lasts a little longer than two loops' worth of some of the longer songs, like BULLYBUG.
To work in Blastem, it must be specified as a byte:
set [$FFFA76].b $7F
Song pointers are known from the sound test of the hidden cheat menu, and by observing 68000 RAM address 0x0416
. It contains the currently playing song/sfx, but isn't a trigger: setting the number directly doesn't change it.
The sound slots in the cheat menu stop at 76 (0x59). Although it plays music at high enough numbers, they sound different from the options menu's music test.
Hex number | Description |
---|---|
00 | Title Screen |
02 | CAMEOS |
03 | LEVCOMP |
04 | LEVFAIL |
05 | BUGSPACE |
06 | BULLYBUG |
07 | BONUSLEV |
08 | GAMECOMP |
0B | MRVANGRY |
0C | BUGSCONT |
0D | INVULNER |
0E | running |
0F | boom |
10 | stopped running |
11 | running alt? |
12 | whiff |
13 | lion |
14 | thump? |
15-29 | |
2A | pause |
2B | |
2C | cage |
2D-31 | |
32 | menu sound |
37 | nyah nyah nyah-nyah nyah |
38 | took hit |
39-3A | |
3B | ARENABUG |
3C | BUGHAUNT |
3D | DUCKRABB |
3E | ARABIAN |
3F | KNIGHTY |
40-59 |
ClayFighter
ROM patches to play GEMS sequence data on the Interplay logo:
offset hex bytes description 000B36 4475 ;freezes game on Interplay logo 000B2C 00xx ;plays music or sound effect
The Death and Return of Superman
This game has a timer used for every screen, which will force the game to either start the demo (on the title screen), or boot you out of the options menu. This patch will disable the timer, allowing the sound test to be used properly.
003FD6 536D -> 382D ; disable timer 012BDF 32 -> 00 ; skip the copyright screen (which can't be skipped otherwise)
Doom
Use these ROM patch codes to access the GEMS sequences used in the game.
0013B8:00BC 0013B0:00??
The above code freezes the game; the question marks are where the song/SFX IDs go.
Dragon's Lair: The Adventure Continues
0003B6:70xx replaces the song that plays during the attract mode, with xx being a song ID. 00 is silence. 0003BE:60FE causes the game to freeze just before the title screen, allowing the song to play uninterrupted.
Most SFX are PCM samples and are played with a different routine.
Dynamite Headdy (April beta)
Song | ROM Hex Address | Listed At |
---|---|---|
Beat It | 061ACE | Unreferenced |
Unused Track | 062334 | Unreferenced |
Escape Hero (Section B) | 064270 | Unreferenced |
Escape Hero (Short Version) | 064EC6 | Unreferenced |
Foreman for Real
The word at $1D185A is the song ID of the title screen track, which plays in an uninterrupted loop indefinitely throughout the attract mode (without any sound effects). $0081 is the title screen song itself.
Head-On Soccer
Apply the code 01390C:60FE, which will cause the title screen to freeze on a white screen.
Change the two bytes at $008926 to change which song is played at that point. By default it is 0001, for the title screen music.
The Lost World: Jurassic Park
Apply the following codes:
- 3FA118:4E75: bypass the region check
- 0003BC:4E71 and 0003BE:4E71: bypass the checksum check
- 3B75BC:4E71: disable the options screen idle timer
After that, 3B7728:70xx changes the song played when switching the Music option to On, with xx being the song ID. 00 is silence (and is what is played when you switch Music back to Off). Codes from 0A on seem to be invalid and do nothing, though the game plays 0A at some point (ROM $3B9914; could this be a bug? feel free to try yourself and correct me). Other sounds are played by other routines.
Mario Lemieux Hockey
FF9458 offset to Track RAM for current song Note: Each song has its own (!) track RAM. FFD406 decompressed song data sound calls: 022086 Sound Driver Update 022452 play title music 022512 stop music 022536 play menu music 022548 play ?? 0225F2 play fight music 022604 play ?? 022698 play shoot out music 0226F8 play ??
It's worth mentioning that the sound system in this game is a total mess. Each song is in a separate "sound bank" and each sound bank has its own work RAM. The pointer stored at FF9458 in 68k RAM tells the sound driver, which part of the sound bank RAM it has to update. This also has the interesting effect, that the menu SFX stop working when you play e.g. the title theme on the menu screen. In order to play a song, the game calls one of the "play XX" routines, which has all hardcoded offsets for track RAM and song data.
sound test patch: 000498 4EB9 -> 601A skip title screen 0004CE 4EB9 0002 2452 -> 4EB9 0002 2512 don't play music at SEGA screen 000556 6600 -> 6000 cut SEGA logo short 0009A8 4EB9 0002 2536 -> 4EB9 00xx xxxx insert address of "play XX" routine at xx
Math Blaster: Episode 1
To choose a song to play, write its ID to the word at $FF0EAC. I (andlabs) think that this will be picked up during the next vertical blank? unless the code to start song playback is buried deep within the plumbing of the code.
For something more practical for ripping: the word at $00000632 is the ID of the song played on the title screen. Change the byte at $00068A to $60 to stop the demo from starting (causing the game to wait for you to press start on the title screen forever and preventing any sound effects from playing). Don't press start, as the process of loading the main menu pauses the sound temporarily.
ID $0005 is the title screen song. ID $0004 is silence, and is explicitly played on the Sega screen.
Mickey's Ultimate Challenge
007A57 song ID for title screen (default: 09h)
This code allows the game stay on the title screen forever (overwrite existing bytes):
offset byte code ASM code comment ------ --------- -------- ------- 007B8C 4EB8 05A6 JSR $0005A6.w ; wait for VSync 007B90 60FA BRA.S *-4 ; and do that forever
Additional patches for quick screen fading (i.e. less annoyance when booting the ROM)
00712A 6A00 -> 6000 ; SEGA screen 00786C 6A00 -> 6000 ; Copyright screen 007926 6A00 -> 6000 ; Hi Tech Expressions screen 007A02 6A00 -> 6000 ; Designer Software screen
Newman/Haas IndyCar featuring Nigel Mansell
ROM patch to play a song on the title screen:
offset hex bytes ASM code description 1C8C72 4E71 NOP ; skip SEGA screen 1CA4B6 4E71 NOP ; skip license screen 1C8A8E 4E71 NOP ; skip Aklaim screen 1C018E 303C 00xx MOVE.W #xx, D0 ; set song ID to play (0..5) 1C01A0 60FE BRA * ; freeze game after starting the song (to prevent screen changes etc.)
General ROM locations:
StopMusic: 070000 PlayMusic: 070004 (Register D0 = sound ID) UpdateMusic: 070008 LoadZ80Driver: 07000C SilencePSG: 070014 UpdateSFX: 07001C StopSFX: 070028 DoCarEngineSFX: 070030 Music Pointer Lists: 07173C (20h bytes per song, 6 songs) Sound RAM: FF8400
Sound IDs:
00 - Main Theme 01 - Racing BGM 02 - Qualified 03 - Hard Luck 04 - Race Results 05 - Ending
Top Gear 2
ROM patch code 0251EA:00?? allows you to access any song in the game. The "??" is the ID for each song.
01 - Title screen (Used) 02 - Canterbury Plains 03 - Ayers Rock 04 - Unused Jingle? 05 - Title Screen (Unused) 06 - Auckland
True Lies
ROM patches:
disable fade in: 00BAD7: 08 -> FF ; set fade in speed from "slow" to "fast" modify title screen song: 000871: 13 -> ## ; set song playing on title screen (possible song IDs are 00~19) prevent title screen timeout: 17C1DD: 01 -> 00 ; prevent countdown on title screen skip various screens (replacing JSR instruciton with NOPs): 01225C: 4EB9 0000 0700 -> 4E71 4E71 4E71 ; skip SEGA screen 000C9C: 4EB9 0000 A3E2 -> 4E71 4E71 4E71 ; skip Copyright screen 000CA2: 4EB9 0000 A30C -> 4E71 4E71 4E71 ; skip Aklaim screen 000CA8: 4EB9 0000 A06E -> 4E71 4E71 4E71 ; skip Beam Software screen
Note: The music seems to lag a bit when loading the title screen the first time. There is no lag when the music restarts when exiting the options screen.
Hacking information:
Sound Driver Functions ---------------------- Update Sound: 0134BC Load Z80 Driver: 013AB4 Play SFX: 0136E2 reg D0: ID (00 = play SFX, 08 = stop music?, 80 = fade music) reg D1: SFX channel? / destination volume (00 = min, FF = max) reg D2: SFX ID / fade speed (00 = slow, FF = fast) Play Music 1: 01385C reg D0: song ID reg D1: ?? reg D2: ?? reg D3: ?? Play Music 2: 013942 (song ID is read from 68k RAM F6BC) Music Pointer List: 197718 Main Music List: 001868 (1Ah entries, 2 bytes each, all are multiples of 2, used with 19699A) Some Music List: 19699A (0Dh entries, 2 bytes each) Bank Pointer List?: 1969B4 Game Sound APIs --------------- PlayBGM: 001792 reg D0: song ID (00h~19h) SetBank?: 00BA28 reg D0: bank ID (00h~19h) sets RAM FB21 and RAM FB25 PlayBGM_A: 00BA42 -> 01385C, reg D0 = RAM FB21, reg D1 = RAM FB25, reg D2 = 1, reg D3 = 0 PlayBGM_B: 00BA70 -> 01385C, reg D0 = 0, reg D1 = RAM FB25, reg D2 = 1, reg D3 = 0 StartLevelBGM: 00BA90 -> 01385C, reg D0 = 0, reg D1 = word from (19699A+18) -> value 0, reg D2 = 1, reg D3 = 0 Fade Out Music: 00BAB8 -> 0136E2, reg D0 = 80, reg D1 = 00, reg D2 = 8 Fade In Music: 00BACC -> 0136E2, reg D0 = 80, reg D1 = RAM FB29, reg D2 = 8 Note: The sound driver defaults to volume 0, so this call is *REQUIRED* after starting a BGM. PlaySFX: 00BAE4 -> 0136E2, reg D0 = 4, reg D1 = RAM FB15, reg D2 = 0 -> 0136E2, reg D0 = 2, reg D1 = [parameter reg D1], reg D2 = 0 -> 0136E2, reg D0 = 0, reg D1 = 6, reg D2 = [from tables pointed to from 1969E8] ???: 00BB40 -> 0136E2, reg D0 = 4, reg D1 = ??, reg D2 = 0 -> 00BAE4 -> 0136E2, reg D0 = 4, reg D1 = RAM FB15, reg D2 = 0 ???: 00BB82 -> 0136E2, reg D0 = 4, reg D1 = [parameter reg D1], reg D2 = 0 -> 00BAE4 -> 0136E2, reg D0 = 4, reg D1 = RAM FB15, reg D2 = 0
Ultraman
sound driver calls: 038000 - Sound Driver Update [no parameters] 038004 - Stop All Sound [no parameters] 038008 - Play PCM SFX [register D0 = SFX ID] 03800C - Play Sound [register D0 = sound ID, register D1 = number of channels] 038010 - ?? (unused?) 038014 - ?? (unused?) 038018 - Fade Out [register D0 = fade speed?] 03801C - Load Z80 Driver [no parameters] 038020 - ?? [register D0 = some ID] 038024 - ?? [register D0 = some ID] General Music List: 007172 (2 bytes for entry, list contains 14h entries = 28h bytes total) for each entry: 1 byte - ID [reg D0], 1 byte - channel count [reg D1] Level BGM List: 007178 (part of the General Music List)
The sound driver has a huge pointer list 039D88. These are pointers to "track headers". In order to load a song, it specifies the ID of the first track header (register D0) and the number of channels/track headers (register D1) to be loaded. Then it calls "PlaySound". So if it loads "reg D0 = 45h, reg D1 = 3", it loads the track headers for with IDs 45h, 46h and 47h. The list contains SFX as well as songs and the game code has the "first track ID" and "channel count" values hardcoded.
playing the "Stage Select" music is done using the following code: 006C7C 70 4F MOVEQ #$4F, D0 ; reg D0: sound ID 006C7E 72 06 MOVEQ #$06, D1 ; reg D1: channel count 006C80 4EB9 0003 800C JSR $03800C ; call PlaySound a search pattern for "Play Sound" routine: 70## 72## 4EB9 0003 800C You can make a simple "sound test" patch by modifying the ROM this way: 000328 4E71 -> 6048 skip checksum check 000430 4EB9 0000 -> 4EF8 21C0 skip to "stage 1" screen [we use it for playing songs] 006C7C 704F -> 70xx set xx = sound ID 006C7E 7206 -> 72xx set xx = channel count