5 ms·
I bought one of these recently, and it's amazing how powerful it is given that it's a toy. It sits on the bus between the CPU and the cartridge, so you effectiv
by wzdd 4y ago
I bought one of these recently, and it's amazing how powerful it is given that it's a toy. It sits on the bus between the CPU and the cartridge, so you effectively get to change up to three bytes of program text / rodata* on the fly.
My favourite code is ANTOSA. This is a code for Super Mario Bros. which turns all pipes you can't enter upside-down. SMB1 has been disassembled with commentary, so it's now possible to see how the code works. It turns out there is a table of blocks for the top two layers of both non-warp and warp pipes, that looks like this:
VerticalPipeData
98dd: 11 10 .bulk $11,$10 ;used by pipes that lead somewhere
98df: 15 14 .bulk $15,$14
98e1: 13 12 .bulk $13,$12 ;used by decoration pipes
98e3: 15 14 .bulk $15,$14
The code to draw the pipes gets this address of this table and stores it in the Y register. Then, if the pipe isn't a warp pipe, it executes 4 INY (increment Y) instructions in a row to adjust the offset.
The ANTOSA code just replaces two of the INY instructions with a two-byte BVS (Branch on Overflow Set) instruction. However, the Overflow flag is never set at this point, so effectively this instruction is a two-byte no-op.
The practical upshot is that Y is only incremented by 2, which means it points two bytes inside the "pipes that lead somewhere" data rather than directly at the "used by decoration pipes" data. It turns out that the first two bytes determine the top of the pipe, and the second two bytes determine the second layer, so decoration pipes are effectively drawn (second layer, top layer). And voila -- "upside down" non-warp pipes.
If it was intentional, it was very clever. But I suspect it wasn't -- BVS is an odd choice for a two-byte NOP! An alternative would be change one of the INYs to a DEY (decrement Y), producing the functionally-equivalent codes EETOKX, EETOSX, EETOVX or EETONX, depending on which INY you change. I admit ANTOSA sounds cooler.
The full SMB disassembly (not mine) is here if you're interested: https://6502disassembly.com/nes-smb/SuperMarioBros.html https://6502disassembly.com/nes-smb/SuperMarioBros.html
* Typically. NES cartridges could also contain RAM.
- raldi 4y agoThe Game Genie decoder at https://games.technoplaza.net/ggencoder/js/ https://games.technoplaza.net/ggencoder/js/ claims that ANTOSA means, "Overwrite $18ED with 0x70". 0x70 is indeed BVS, but how does that address (or its endian-corrected $ED18) correspond to any INY instructions in the disassembly?
- wzdd 4y agoIt's the instruction at $98ED which is being substituted, because Game Genie codes use 15-bit addresses with the 16th bit implicitly set.