return to table of content

Modder re-creates Game Boy Advance games using the audio from crash sounds

thewakalix
16 replies
22h53m

The issue with long runs of 0x00 is related to "clock recovery".

Some digital data streams, especially high-speed serial data streams (such as the raw stream of data from the magnetic head of a disk drive and serial communication networks such as Ethernet) are sent without an accompanying clock signal. The receiver generates a clock from an approximate frequency reference, and then phase-aligns the clock to the transitions in the data stream with a phase-locked loop (PLL).

In order for this scheme to work, a data stream must transition frequently enough to correct for any drift in the PLL's oscillator. The limit for how long a clock-recovery unit can operate without a transition is known as its maximum consecutive identical digits (CID) specification.

https://en.wikipedia.org/wiki/Clock_recovery

akira2501
11 replies
21h28m

I love how we used to use a bunch of very clever "code book" systems like 8b/10b which did a lot of careful work with small runs of bits to ensure the clock was recoverable and to avoid line capacitance issues.

Then we just moved to things like 64/66b which takes a giant chunk of bits, adds a short header to guarantee a clock transition, then runs everything through a pseudorandom scrambler.

dwattttt
7 replies
20h43m

A sprinkle of entropy improves everything

jacquesm
5 replies
19h4m

They do a similar thing for GPS data recovery. It is so far below the noise floor that normally speaking the signal is not recoverable. But then you inject some (known) noise and suddenly the noise modulated by the (unknown) signal starts to drown out the noise in the rest of the system and that in turn allows you to recover bits from the signal.

rollcat
2 replies
10h7m
jacquesm
1 replies
5h17m

That's a great article, you should post it separately.

rollcat
0 replies
4h1m
farhanhubble
0 replies
18h2m

This thread brings back fond memories from electronics and digital signal processing.

akira2501
0 replies
18h17m

It's not only below the noise floor, but all satellites transmit the code on the same frequencies, so it's several signals all at once below the noise floor. Which makes the known noise unique to each satellite, and you dredge out the same frequency repeatedly with different sets of known noise to recover multiple signals.

Gold sequences are really neat, which is precisely the same pseudorandom scrambling technique, but where each sequence is selected to have low correlation with all other sequences in use, which is what enables the frequency sharing property of the system.

physicles
0 replies
17h37m

QR codes do this too, as explained by yesterday’s front page post about decoding QR codes by hand.

tux3
1 replies
10h48m

The PCIe standards kept moving to longer codes, and nowadays they're able to do "1b/1b" (no header at all)

phire
0 replies
8h49m

Not really accurate. The switch from NRZ to PAM4 actually massively increased the bit error rate. They switched away from the 8b/10b style line code and replaced it with forwards error correction.

PCIe 6.0 uses 256 Byte frames, with 242 Bytes of data, 8 Bytes or CRC and 3 Bytes of error correction.

So it actually has way more overhead than the older versions and their 128b/130b line coding, It's just at a slightly different layer.

userbinator
0 replies
16h56m

Against adversaries, scrambling schemes can produce some very perplexing behaviour. See the "weak sectors" used for CD copy protection for one infamous example.

hun3
1 replies
8h43m

This is probably irrelevant. The audio is analog (requires DAC to decode into bitstream) and is transmitted with some fixed frequency (44.1kHz or 48kHz), without any particular synchronization.

dtgriscom
0 replies
7h29m

Nope. If you're trying to recover bits from a signal which is either high or low, and the signal stays high for a long time, unless your clocks are perfect (they won't be) you won't be able to tell just how many bits were in that long period of "high"s.

mlyle
0 replies
14h2m

Another concern is if the waveform is AC coupled somewhere and DC can't pass.

Even if you have a perfectly synchronized clock, all-or-mostly-1's will be the same as all-or-mostly-0's in the long run.

andai
0 replies
12h18m

From this page I found a very interesting article: Wireless Set Number 10

https://en.wikipedia.org/wiki/Wireless_Set_Number_10

peddling-brink
11 replies
22h53m

Why would this happen in the first place? Is it common for these games to dump state to audio? Is it a deliberate debugging tool for the game devs?

0xC0ncord
7 replies
22h32m

The author's previous video[1] explains the technical details regarding this behavior.

Basically the way GBA sound works is there is a buffer in RAM that the audio is streamed from, and an interrupt is supposed to signal the hardware to begin reading data from the beginning of the buffer again. However, if the interrupt is never fired (such as when the game crashes), the audio stream will go beyond the buffer and read other parts of memory.

[1] https://www.youtube.com/watch?v=wSWNkpqjtQY&t=361s

jboy55
6 replies
22h27m

Would this be dependent on the audio file that was being played during the crash to start at address 0 of the ROM? It seems like it'd be highly unlikely you'd be able to get 100% of the ROM.

Now if this was a hack where the thought was, "What if we dumped the whole ROM to the audio buffer, could we recover the complete ROM through audio analysis?"

aprilnya
1 replies
18h7m

the sounds aren’t read directly from the rom - the buffer is in a fixed place in ram, and sounds from the rom get copied into there

remember that it’s not like the music is just there as raw audio, the raw audio is just the sounds of the different instruments

jboy55
0 replies
16m

That makes more sense, I thought they would just be pointers to ROM addresses for the samples.

shadowgovt
0 replies
21h53m

The ROM on the GBA is mapped into memory at high memory addresses (0x08000000 and above). The audio "working" buffer is in low memory (I think somewhere near 0x02000000?). An interrupt fires when the audio chip reads to the end of the working buffer that looks something like this:

- run the function to fetch the next batch of audio to audio working RAM

- reset the audio read pointer to the beginning of audio working RAM

When interrupts are disabled (because the game has crashed), that "reset pointer" code never runs and the audio circuit keeps reading way past the end of its buffer, incrementing forever. Eventually it would increment into the 0x08000000 range in which case the sounds it's emitting map directly to the bits in the ROM.

ordu
0 replies
22h19m

I think hardware starts from 0 after reaching 0xfff..ffff address. The article mentions that you need to wait before starting to record, I assume it is a pause needed for hardware to overflow address.

lelandbatey
0 replies
22h19m

That video seems to imply that the audio hardware automatically wraps back to address 0 when it reaches the end of RAM. That may not be true, but it's implied by the animation in that video. And since they were apparently able to dump the entire ROM via audio, I suppose there's some way to get the entire memory contents.

Dwedit
0 replies
16h34m

GBA Memory Map:

  02000000-0203FFFF   EWRAM (256 KBytes)
  03000000-03007FFF   IWRAM (32 KBytes)
  06000000-06017FFF   VRAM - Video RAM (96 KBytes)
  08000000-09FFFFFF   Game Cartridge ROM (max 32MB)
The audio buffer will usually live in EWRAM, then you have to wait until about 100,000,000 audio samples have played before it proceeds from EWRAM to Game Cartridge ROM.

shadowgovt
2 replies
21h38m

It's pretty uncommon and it's not a deliberate debugging tool. In this case, the GBA could, hypothetically, have had a way to "park" the architecture on a game crash, or "watchdog" the system (by tying state update somewhere that should run periodically to a non-maskable interrupt that reboots the machine if that state update stops happening).

Simply because it costs more to do those things, the GBA doesn't (Nintendo instead opting for the time-worn approach of the great game cart manufacturers of old, "if our games don't have bugs we don't have to worry about the behavior of the hardware in undefined state!"). So when a GBA game gets into some crash states (infinite loop with interrupts disabled, for example), the audio chip doesn't know the system is crashed and keeps doing its very simple job: reading sequential bits in RAM and converting them to sounds. Without the housekeeping that normally runs when the game is in good working order shepherding that read operation, it just keeps reading and eventually gets to the bits representing values in the cartridge ROM.

Dwedit
1 replies
16h30m

The GBA does have an interrupt that occurs when cartridge is removed.

krallja
0 replies
4h44m

WOW how did I never know about this?

https://gbadev.net/gbadoc/interrupts.html

It is possible to switch cartridges and have the routine resume execution on a completely different ROM.

That would have been a heck of a game mechanic back in the early 2000s! Maybe I never saw it because game developers were tired of the “please insert disk 2” of the Playstation era. But it feels like a gimmick a Metal Gear Solid game could have used.

Y_Y
9 replies
22h36m

This reminds me of the original iPodLinux hack almost twenty years ago where the fourth-gen firmware was dumped via the piezo speaker - https://web.archive.org/web/20140810083116/http://www.newsci...

Coincidentally one of the things this facilitated was playing GBA games on the iPod, though I was happy enough just to play Doom a with the click wheel and watch monochrome videos.

nathancahill
8 replies
20h27m

Good memories. I still have my iPod Classic, I upgraded the battery and added 4 256GB MicroSD cards. I saw a mod recently for adding Bluetooth but it involves swapping the rear case and I don't think I'll go that far. There's something timeless about the design (and about owning copies of music files).

ace2358
3 replies
14h13m

Given the ‘super compute in your pocket’ thing we say… super computers turned out to be terrible at playing music files without stopping.

My iPhone will regularly forgot what I was listening to moments ago after I press pause. Insane.

tomduncalf
2 replies
11h11m

Yeah this is so annoying! It especially seems to happen with 3rd party music player apps.

mensetmanusman
0 replies
5h21m

I thought everyone enjoyed being forced to watch an Apple Music advert when they just want to play a song stored on device!

ace2358
0 replies
11h2m

Also apps and or websites pausing my music but play no sound… ugh. I want an iPod.app to come along.

Tiny player does nice but the os level issues are getting insane.

Also apps that have their data deleted (Apple tv infuse app, play:sub iOS) because the os said so. I have plenty of space but things get deleted. I want to FILL my 256 phone please.

xyzzy_plugh
2 replies
17h2m

Funny to see this mentioned. I was recently out skiing and was using my phone to listen to music, as I used to do with my 3rd generation iPod. Moments ago I was lamenting to my colleague that while my phone's battery rapidly plummeted in the cold despite being insulated and close to my body (no way even remotely approaching freezing temperatures) my iPod never struggled to play tunes all day. In fact I never recall any noticeable difference in battery performance in cold temperatures despite daily use for years.

And yet my phone gets a bit chilly and gives up the ghost.

I use Bluetooth otherwise I'd have dug out the 3rd gen for the next ski day.

wegfawefgawefg
0 replies
16h54m

Was it a difference in battery chemistry?

speedgoose
0 replies
12h49m

Sample size N=1 too but I remember warming up my iPod to get more battery while my iPhone survives pretty well while streaming my GPS coordinates when I go skiing.

KennyBlanken
0 replies
17h39m

Every music file I have in iTunes and on my iPhone is a DRM-less MP3 or AAC file.

da768
6 replies
23h9m

I imagine the 0xFF might be converted to 0x00 due to DC blocking capacitors/high-pass filtering, audio circuits aren't really suited for non-audible content.

He might get better capture accuracy with a digital oscilloscope hooked directly at the chip's audio outputs if he's lucky, but it's still pretty impressive he got a bootable image out of that.

arcticbull
4 replies
22h40m

I imagine the 0xFF might be converted to 0x00 due to DC blocking capacitors/high-pass filtering, audio circuits aren't really suited for non-audible content.

Yeah, you want to generate a signal with no DC bias, something as simple as Manchester encoding will go a long way. If that's not good enough, there's NRZ or even a convolutional encoding. You also want to make sure you either send a sin wave, or if you can't do that, at least make sure your square wave frequency is high enough that it doesn't get eaten by the AC coupling capacitors.

freeqaz
3 replies
22h36m

Would it be possible to get a higher quality read from using something like an Arduino's I/O pins and some bit-banged C code? I'd be curious to see what would be possible using cheap, off-the-shelf tools since a lot of people don't necessarily have an oscilloscope laying around. :P

fodkodrasz
2 replies
20h54m

Without looking up datasheets, just form the top of my head: the Arduino DAC most likely has 12 bits resolution (as common for cheap uCs), and maybe even slower sampling than a soundcard. A sound card was probably better than that even in the 1990s (say a Sound Blaster).

aidenn0
1 replies
20h45m

The original Sound Blaster could only record at 8-bit resolution at up to 12 kHz. The 2.0 could record at up to 15kHz, still 8-bit.

The second generation of Sound Blaster was the first that could record at 44kHz (mono) sampling rate, but was still only 8-bits of resolution.

It wasn't until the 3rd generation Sound Blaster 16 that 16-bit audio could be recorded.

fodkodrasz
0 replies
19h58m

Hmm, I had (false) memories of better capabilities. Though my first soundcard was an SB Pro clone, later an SB16, both almost capable :)

Frenchgeek
0 replies
22h43m

From what I remember reading in the comments of his youtube video, the point of the exercise was to do it with as basic equipment as possible.Hence the hours of multiples passes to average the error out instead of a proper data-logging oscilloscope.

2024throwaway
6 replies
23h20m

This is insanely impressive. I'm sure many of the techniques used like the "majority vote" algorithm cited are underutilized across many industries.

guyomes
1 replies
19h57m

One interesting application of taking the value appearing in majority, or more generally taking the median, is to remove noise or people from a sequence of several photos taken from the same point of view. This idea is to superimpose all the photos, and for each pixel, you simply keep the median [1].

[1]: https://patdavid.net/2013/05/noise-removal-in-photos-with-me...

astrange
0 replies
10h54m

This will have the effect of smoothing the image even if you didn't want to do that, which is part of the reason people are convinced phone cameras "overprocess" images or try to beautify you even when they aren't.

You have to counteract this by actually putting the noise back when you're done.

epcoa
1 replies
22h3m

If one is interested there is nearly 100 years now of sophisticated noisy signal recovery techniques.

Magnetic storage media operates on the principal of this hack at baseline! https://en.wikipedia.org/wiki/Partial-response_maximum-likel...

The same idea can apply here as GBA ROM material would be highly biased. Majority vote wastes a lot of information.

rob74
0 replies
6h14m

The problem with this signal is that it was never designed to be recovered in the first place (it only came about by chance), that's why it has the issue with long sequences of 0 bytes described in the article.

mikepurvis
0 replies
21h12m

I wondered about it for film scanning, specifically with a fan project like 4K77 where they're dealing with potentially damaged theatre prints rather than pristine masters— having multiple of them and being able to use that to eliminate scratches and so on would potentially save a ton of time on manual fixing in post.

jacquesm
0 replies
19h2m

It's fairly common in data recovery though, just keep on reading disk images and running quora until something passes the checksum and see if it works out. Better still if there are higher level checksums (for instance across a file that has a signature) for further verification. Also used in some aerospace applications.

skeaker
4 replies
22h54m

Glad to see this getting more attention here, it was posted a few days ago but drowned (https://news.ycombinator.com/item?id=39037104). The original video has a lot not mentioned in this brief article, including a custom adapter that the hacker had to cut together manually to get the right audio quality out of the DS.

taftster
3 replies
22h41m
hifikuno
2 replies
21h5m

The video was great. I think my favourite part is where he dumps the Chinese knock off version and finds the random ARM code and reverse engineers it. So much cool stuff in there.

taftster
1 replies
20h56m

Right? This kind of stuff just makes me look silly in what I'm able to achieve. I can only accomplish watching a video of some guy doing bad ass stuff and maybe holding onto a few notional details. People are just super smart sometimes.

runnr_az
0 replies
15h12m

It’s especially fun watching super smart people work on somewhat ridiculous projects.

seabass-labrax
4 replies
20h56m

Does anyone know what's going on when the TheZZAZZGlitch's emulator reports that the game tries to jump to an invalid address? I'm not so familiar with the ARM7 processor used in the GameBoy Advance, but I can't imagine how it would be possible to construct a jump call with an invalid value. Additionally, what would happen if one of TheZZAZZGlitch's incorrectly reconstructed ROMs was run on a real GameBoy?

cosarara
2 replies
20h5m

I can't imagine how it would be possible to construct a jump call with an invalid value

You can use the bx instruction to jump to any address stored in a register.

Additionally, what would happen if one of TheZZAZZGlitch's incorrectly reconstructed ROMs was run on a real GameBoy?

It would crash, and eventually start playing the ROM on the speaker, the whole point of the video :)

seabass-labrax
1 replies
19h7m

Thanks for the explanation! So it sounds like the emulator is detecting the error 'out of band' with the emulated execution flow, and choosing to throw an error message rather than letting the execution continue. If it didn't catch the error, it sounds like it would glitch out in much the same way as the real GameBoy would. Is that right?

immibis
0 replies
3h22m

That's right. This sort of thing is more likely to indicate a discrepancy between the emulator and the real hardware, than actual game behaviour, so emulator developers choose to treat it like a crash. Some emulators have "continue anyway" buttons and some don't.

ehaliewicz2
0 replies
17h27m

It is likely that the emulator only emulates accessing valid parts of the GBA's memory map, and throws that error if invalid parts are accessed. As to what happens on real hardware.. who knows? :)

reactordev
1 replies
23h17m

It’s stories like these that remind me I’m stupid and have a lot still to learn. My goodness this is amazing. Up there with audio key logging and things I read about but could never dream would be a real thing.

I tip my hat sir. Reminded that I’m a mere mortal in the presence of greatness. The absurdity of recreating a game based on audio crashes sounds like something a mental patient would say but no, here we are in 2024.

sunnybeetroot
0 replies
12h22m

You’re not stupid because you don’t know how to reverse engineer a GBA game, unless you work for Nintendo and it’s part of your job description.

Rapzid
1 replies
9h10m

The most impressive part of all this is, IMHO, how the code was modified by the bootleggers to run the game off writable flash vs ROM plus volatile save memory haha.

mmaniac
0 replies
8h11m

This is a very common technique on bootleg Game Boy and Game Boy Advance games which bootleggers use to save a few cents on batteries. And in truth, it's not too difficult to make such a patch.

Bootleggers will write per-game patches which flush the save contents to writeable flash depending on a small amount of reverse engineering work to discover where in the code the game saves. However, since all official GBA games always save data using functions from the Nintendo SDK, it's fairly straightforward to hook those functions and make a generic patch for any GBA game to save on a batteryless bootleg cartridge.

I have written a patcher to do this which you can find here. https://github.com/metroid-maniac/gba-auto-batteryless-patch...

scarecrw
0 replies
10h5m

This reminds me of an attempt made by RGMechEx to retrieve game code for an Atari game where the code itself was used to generate a visual effect similar to TV static on the screen [1].

[1] https://www.youtube.com/watch?v=5HSjJU562e8

maxlin
0 replies
15h44m

The diffing of the real-world cartridge was the most interesting part. Requires a goofy amount of unnecessary knowledge to just jump in to reversing that and figuring out what its meaning is lol

jacquesm
0 replies
19h6m

That is extremely clever. The persistence alone is impressive but to get it to the point where it works well enough that you can actually extract the ROM contents with high fidelity is next level.

goodboyjojo
0 replies
8h53m

this is a good article. very interesting stuff

brokensegue
0 replies
23h17m

Zzazz (the subject of the article) runs a yearly April fools competition/event that usually involves some amount of retro hacking/reverse engineering. I recommend participating. Previous years competitions are on their GitHub

Trekker666
0 replies
19h26m

I've done this using GoldWave opening game files to extract their audio because I like the menu song or something, but nothing this sophisticated and cool.

DerCommodore
0 replies
10h54m

Crazy