The game
Bratz: Rock Angelz Guitar Game is a plug-and-play TV game that MGA Entertainment released in 2005. You plug a toy guitar into the TV, pick one of the Bratz girls and one of ten songs, then hit the coloured buttons when the falling notes reach the bottom of the screen. Think of it as a children's Guitar Hero.
Inside is the usual plug-and-play recipe: an Elan EU3A13 system-on-chip (6502 CPU, video and I/O on one die) and memory under black blobs of epoxy ("globs").
Half a ROM
I read the external ROM (u1, 1 MB) months ago. A short analysis was enough to see that it couldn't be the whole game. It only held graphics plus a tiny boot module that shows the MGA logo and the copyright screen. The actual game code had to sit in a second, internal ROM. It can't be assigned to any position on the board; the Elan addresses it directly.
The usual trick is to look for extra address lines and read the rest through them, but there were none. The internal ROM simply has no pins we can reach. We were stuck.
The trojan ROM idea
Then we had a different idea. If we can't read the internal ROM from outside, the console can read it and show it to us on screen.
The console boots from u1, so I disabled the original u1 glob (chip enable tied high) and soldered a flash chip in its place. We patched the boot module in a copy of u1 without changing its checksum. After the copyright screen, it now jumps into our own code instead of the game.
That code uses the Elan's bank switching to walk through the whole internal ROM (and, as a cross-check, u1). It draws the data on screen as fat black-and-white blocks:
- Encoding: every byte becomes one 16×16 pixel tile, and each bit is a large 8×4-pixel block. That survives a cheap capture card, analog blur and scaling.
- Page layout: each screen ("page") carries 208 data bytes and a header row. The header holds a magic marker, the address and its complement, a page number, and a CRC32 of the page.
- Calibration: checkerboard screens at the start let the decoder find the grid automatically.
- Summary: a final page shows a SUM16 checksum of the whole ROM, calculated by the console itself.
The console then plays the ROM like a slideshow. I recorded about 40 minutes of video: 6,302 pages. A Python/OpenCV decoder finds each page, reads the blocks back into bytes, sorts them by page number and checks every CRC32. Every page decoded cleanly, and the overall SUM16 matched what the console had calculated.
That is 1 MB of ROM dumped purely through the video output. Not a single wire was attached to the internal ROM.
Complete, but silent
With u1 and the internal ROM together, the game runs in MAME: logos, title screen, character select, song select, the stage, falling notes and the final score. Graphics and program code are complete.
But there was no music in the ROMs. The Elan data contains just one tiny sound sample, which the game never even uses. The music lives in a third glob on the board, labelled TP1, which has its own 4 MHz crystal. TP1 is a dedicated sound chip with its songs built in, and there is no way to read its contents.
Analysing the game code showed how the two chips talk:
- Commands: the Elan sends 6-bit commands to TP1 on a GPIO port.
$31–$3Astart songs 1–10,$3Bstarts the menu music, and$00stops. - Note interrupts: while a song plays, TP1 fires an interrupt for every note of the guitar chart. The game spawns a falling note each time. The note chart is therefore inside the sound chip too.
- Status line: TP1 holds an input line high while it is playing. The game ends a song (and shows Final Score) when that line drops. In the menu, the game restarts the music whenever the line is low.
So for a correct emulation we needed three things from TP1: the audio, the exact time of every note, and the exact length of every song.
Trojan number two: a sound test
The same flash-chip trick gave us a second trojan ROM: a sound test. It goes through every TP1 command one after another, exactly the way the game sends them, and shows live on screen:
- CMD: the command currently playing;
- BEATS: the number of note interrupts so far;
- BEAT TICKS / BEAT FRAMES: the time between the last two notes, in Elan timer ticks (1/1309 s) and in video frames;
- END FRAMES: how long the song ran until TP1 dropped its status line;
- PORT0 / TIME FRAMES: the raw status port and the elapsed time.
When a song ends, the trojan waits two seconds and moves on to the next command.
We recorded the console's audio output and the screen at the same time, then let the computer do the rest:
- Reading the screen: every video frame was read automatically by matching the digits against templates. The interval of every single note was measured in timer ticks, so it is exact to under a millisecond.
- Cutting the audio: each song was cut from the recording, starting at the audible click of the command. That gives a sample-exact start point for both the music and the notes.
- Finding the structure: every song turned out to be a short lead-in followed by exactly two passes of the song body, after which TP1 simply stops. Waveform correlation finds the loop length to the sample. The menu music is an endless loop of 51.9 seconds.
- Cross-checking: the song end shown on screen and the end in the audio agree within a few hundredths of a second for all ten songs. Two independent recording sessions gave identical note counts.
All ten songs: two passes each, plus the note interrupts
The ten songs, as named in the game: These Girls, Beach Bums, I Will, Alive And Kicking, Looking Good, Summertime Girl, Bulletproof, Who I Am, Holiday and Glad You're Here.
Back into MAME
The MAME driver now has a small simulated TP1 that works like this:
- when the game sends a command, it plays the matching sample;
- it fires the note interrupts at the measured times;
- it holds the status line high while a song plays and drops it at the measured end;
- it loops the menu music seamlessly.
The measurements also exposed a bug in the existing emulation. MAME ran the Elan's periodic timer at 2048 Hz, but the real hardware runs it at 1309 Hz. That is fixed as well.
The best test was running our own sound-test trojan inside MAME. It shows the same values as the real console.
The result: the game boots in MAME and plays every song with the original music. The notes fall in time, and when the song ends the game moves on to the final score, just like the real toy.
What's preserved
- Both Elan ROMs: u1 read directly, the internal ROM read through the video output.
- TP1 audio: every song complete, exactly as the hardware plays it, plus seamless endless loops of every song and the menu music. All of it is lossless FLAC.
- Song data: the timing of every note interrupt and the length of every song, as JSON and CSV.
- Tools: both trojan ROMs, the decoders and the MAME patch.
The sound chip itself remains a black box. We may never know what's inside TP1, but everything it does is now captured.




