Posts Tagged ‘live’

NinBendo (cont’d): Zero-knowledge, realtime music tweaking example

This is a followup to this post.

Quick video example of finding and bending the music data that plays during Super Mario Bros. 3’s World 1 map, using the FCEUX emulator’s advanced 6502 debugging features. Full-screen if you’ve got it – the video did not survive compression well, and I don’t feel like investing hours tweaking around with it…

Video: Using FCEUX features to bend SMB3’s World 1 map music

Once on the screen of interest, go to the Debug menu and open the Trace Logger window. Tick the two ‘Only log new data…’ boxes, choose a filename for ‘Log to file’, and press Start Logging. These options require the Code/Data Logger to also be running, so FCEUX will prompt you to open it (hit Yes). Pay attention to the ‘Bytes logged as data’ count, it is slowly increasing as data is fetched from the cartridge. Most of the game code is running a complete loop every frame, so the ‘Bytes logged as code’ count should max out quickly. Likewise, MOST of the data being accessed here (e.g. sprites, etc.) will go through their entire rotation within a second or so, but the music takes over 20 seconds to do a complete loop (you can see the data byte count roughly keeping time with the music). Thus the last >20 seconds of data in the logfile will consist of music data fetches. Open the log, scroll near the bottom and notice the resulting disassembly, consisting largely of e.g.:

$E47A:B9 71 A7 LDA $A771,Y @ $A7C5 …

In English that is: Cartridge address $E47A onward contains an instruction with data bytes (B9 71 A7). The first byte is a CPU opcode (LDA $xxxx), telling the CPU to load the data at memory address (specified by the next two bytes, $A771) into its A register. Some subsequent code (purposely omitted from your trace log since it runs every time new data is fetched) processes the sound data. Thus corrupting one or more of those address bytes will cause incorrect sound data to be fetched and parsed, causing audible glitching depending on what the fetched data tells the sound loop to do.