Modder re-creates Game Boy Advance games using the audio from crash sounds
arstechnica.com
arstechnica.com
> 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.
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.
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.
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.
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.
I was talking about if long period of "high" can be distinguished from long period of "low"--DC offsets.
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.
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.
My iPhone will regularly forgot what I was listening to moments ago after I press pause. Insane.
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.
The original NES had a sample generator that could do arbitrary waveforms and could be driven in two modes: one mode is you gave it a memory address and it'd start reading the bits in and treat them as an incredibly simple waveform (1 means 'go up one value', 0 means 'go down one value'... So to do a flat wave you'd do a run of 10101010etc.).
But you could also direct-drive the chip by continuously feeding it an "initial value" directly from the CPU, which was actually faster than the audio driver would read the bits from RAM itself... Problem is that doing so ate up all your CPU cycles, so you could only do it if you weren't doing anything else.
There were some games that took advantage of that: Battletoads had higher-fidelity drum-hits that they could play when action was paused, and they used it for the title screen, the extra-"crunchy" final hits on enemies (where all the action paused for a moment for dramatic effect), and the memorable pause music.
Here's a demo of the game switching between direct-drive and let-chip-read-samples mode to demonstrate (credit to Retro Game Audio for uploading the emulator-doctored video to show when the game is in the direct-drive subroutine). https://www.youtube.com/watch?v=JGT0FM3yh-w
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.
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?"
- 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.
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
Here's what's going on:
- reading from ROM is slow, relative to working RAM; the ROM is mapped to the same memory address space as the RAM, but reading a ROM address takes (I think 8?) clock ticks.
- so to do audio playback, the GBA "stripes" a chunk of data into RAM, sets a pointer to the beginning of that stripe, and then lets the audio chip pull data and update that pointer. When the pointer reaches the end of the stripe, an interrupt triggers that is supposed to pull in the next chunk of audio into the stripe (overwriting the current stripe contents) and reset the pointer.
... but if interrupts are disabled, then that doesn't happen, and the simpler logic in the audio chip just keeps incrementing the pointer forever and reading more data. It'll eventually get to the ROM addresses and pull directly from those (it's slow, but fast enough that it doesn't starve the chip; you just wouldn't run your audio this way in the game normally because you'd have 1/8th the amount of time to do everything else every frame of animation if the audio system were reading directly from ROM all the time. Also, reading from RAM lets you edit the samples to do audio effects).
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.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.
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.
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.
[1]: https://patdavid.net/2013/05/noise-removal-in-photos-with-me...
You have to counteract this by actually putting the noise back when you're done.
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.
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.
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.
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...
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 :)
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.