Thursday, April 24, 2014

Fixing Pac-Man - Attract mode with less burn-in


One of the problems with Pac-Man, especially for home use, is that once a coin is dropped in, or you have it in Free Play mode, it will sit on the "Press Start" button screen forever, until all of the credits are depleated... which can take a long time, especially in Free Play mode. ;)

After being inspired by the ET bugfix project (a great read, btw), I decided to attempt to fix this myself. I should note that there are other versions of this fix on the net, and I have no idea if any of those are better or worse than mine.  Mine is a total of 30 bytes changed in the ROM.


My first thought is that it switches into the "Press Start" screen after it has some credits in it.  So the first thing to look for in the Ms. Pac-Man documented disassembly is the RAM location for number of credits in the machine.


At the top of the disassembly, are a bunch of RAM locations that have been decoded by contributors. As you can see, 0x4e6e contains the number of credits in the system.  Next thing to do is to search for "4e6e" in the file, and sooner or later, I figured I'd find the right location.  There's got to be a section of code that reads a value in from this, and compares it with 0 to determine if it should stay in attract mode or show the "Press Start" screen.  Sure enough...


Here we see a snippet of code.  This is in the main attract sequence.  This block of code above draws the number of credits on the screen (at 03fe), then checks the number of credits against zero (0401-0405).  If it's still 0, it goes to 0x0413, where it continues through the attract sequences.  Otherwise, it falls through, to some code (0407-0412) that advances the game mode to the dreaded "Press Start" screen that we want to eliminate.  Jackpot!

All that I need to do now, is to patch off of this code to my own routine.  The basic thought (which did work out) is that the only way that it will switch to the "Press Start" screen is if the user is pressing start.  Once it changes to that screen, the start button will still be pressed, and the game will just start.

This means that the only way that the code from 0407-0412 will get run here is if there is not zero credits AND a start button is being pressed.  On top of this, we don't want to run that code when the user is pressing 2P start unless there's at least 2 credits.



And that is the entire patch.  30 bytes of code.

The original code will check if there's credits in the machine.  If there are, it falls through to 0407, which is where my code takes over.

It simply jumps to some unused space in the ROM, starting at 0f3c.  "attStTest" checks to see if the user is pressing P1 or P2 start.  If they're not, we jump on over to 0413, as before, to continue with the attract sequence.  If they are pressing P2 start, it does the extra check in "credChk2" to make sure that there's at least 2 credits in the machine.  If there's not, it again will jump over to 0413.  Finally, we know that we can switch the game mode to the "Press Start" screen, where our button press will promptly get gobbled up, and the game will start.

The code in "startIt" should look a little familiar.  The first two opcodes are the opcodes we overwrote in 0407 where we jumped over here to this mess.  Then we jump back to "startItR" return location, and the original code resumes at 040b, performing the game mode switch.  For clarity, I could have dropped the remaining 4 opcodes which start at 040b in here, but I decided to save space and do it this way.

30 bytes different, and the game is the way it should be... especially if your friends come over to your basement arcade, and press the credit button 12 times, or you have it set on Free Play. ;)

1 comment:

  1. This took me longer to write up than it did to code. heh.

    ReplyDelete