The PPU registers from $3f00 to $3f1f (mirrored from $3f00 to $3fff) holds the 16 currently selected colors for the background and the 16 currently selected colors for the sprites. Each byte represents a color number. Their meaning differs between different PPU. eg: Color $1a on a 2c05 is blue while on a 2c02 it's green!
To correct this problem, I created a rom patch to make sure the right colors are sent to the PPU. Here is how I did:
- I converted the Unisystem ROM files to a .NES in order to be able to use them with NES emulators and debuggers. (Note: Use mapper 99)
I used No$NES
(a NES debuger) to find the subroutine which transfers the palette to the PPU. The
subroutine starts at address $914a. It expects a pointer (located at $0000)
to a transfer structure. This copy structure containts the destination PPU address,
the length of the copy and the data.
The copy subroutine works like this:
- Send the destination address to the PPU.
- Send all the data to the PPU.
- I found what I think is an empty space in the ROM (all $FF during 148 bytes) big enough to hold my code and a color conversion table. I used a conversion table from the AdvanceMame. emulator source code.
- In the copy subroutine, I inserted a jump (JMP) to my code just before the copy loop. Since the copy subroutine is not only used for palette data, my code checks the destination address. If the destination address is not in the palette range, I jump back to the normal copy loop. If the destination address is in the palette range, my copy loop is executed. All the data is then copied and corrected on-the-fly using the conversion table.
How to apply the patch:
Here is a file which you must be placed at address $159C in the file mds-sm4.1d: fix_palette.bin
Next, in mds-sm4.1d, replace the 3 bytes $4A $4A $AA (lsr A, lsr A, txa) at address $116B by $4C $9C $95 (jmp $959c).
Here is the source code. I use wla dx since I can use it under Linux:
NOTE: Dont bother asking me for the ROMS or where to get them, I wont reply.