Posts

Timers, Events and State Machines

The code for Pacman is a series of event-driven state machines.  The basic unit of measurement is the video interrupt which occurs at 60Hz (every 16.667 milliseconds).  After game initialisation and self test the interrupt vector is set to #008d and this interrupt service routine (ISR) drives various events and timers. Interrupt Service Routine The video timer inerrupt performs the following functions in sequence: Disables interrupts Copies the audio frequency data to the hardware registers Updates the audio wave form registers Copies sprite attribute and location data to the hardware registers Reorders sprites if necessary A ghost that has just been eaten is the highest priority so the points are not hidden by other sprites Pacman is higher priority than the ghosts if he is powered up Updates counters Dispatches ISR tasks Drives the main state machine Mutes the sound if in demo mode Calls the sound effect update state machine Calls the songs state machine Re-enables interrupts and ret

Characters, sprites and colours

Image
Screen characters and colours The Pacman video system consists of a 1024 (#400) byte screen 8x8 character array at CPU location #4000, a 1024 (#400) byte colour array at location #4400 and 8 sprites.  Each of the sprites has 2 memory-mapped attribute bytes and 2 memory-mapped position bytes.  The attribute bytes are a 16-byte array at #4ff0 and the position bytes are at #5060. The screen layout is unusual in that the top 2 rows and the bottom 2 rows have a different geometry to the central maze part of the screen.  There is a good explanation of the layout on Alessandro Scotti's page  here .  Each byte in the character array represents a tile.    There is a "flipscreen" register that inverts the whole display for two-player cocktail mode.  This register does not invert the orientation or position of the sprites though and these are changed by the code when play changes. Colour Palette A byte in the colour array, corresponding to the screen array location, contains the col

Movement patterns

Image
Tiles, pixels and vectors The pacman screen consists of 28 x 36 "tiles" which are 8 x 8 characters.  The number of pixels is then 224 x 288.  Each character has a 2-byte XY value for their current and next tile as well as a pixel XY position.  The tiles are used primarily when it comes to deciding in what direction a character moves. Each character also has a current and next vector.  This is an XY pair which is determines the direction of movement.  The "origin" is the top right corner. Finally each character has a "target" tile which is the tile they are trying to get to. A table at location #32ff contains two copies of the vectors as follows: direction X vector Y vector Right -1 0 Down 0 1 Left 1 0 Up 0 -1 A current and next orientation flag is maintained for each character. Adding 1 to the orientation flag rotates the character orientation clockwi
Image
Pacman Audio The distinctive audio sound in pacman is a major part of the game and in translating the Z80 ROM code into C, I got a better understanding of how it works.  This post captures my findings so far. Hardware The hardware is very simple.  It seems to have been simply an 8-bit DAC that plays samples at 96KHz.  A 32-byte memory mapped set of registers is used by the game ROM to play sounds.  It is organised as 3 channels each with a unique waveform, volume and frequency.  Channel 1 has a 20-bit frequency and frequency counter while channels 2 and 3 both have 16-bit frequencies. Each of the registers appears as 8-bits wide to the Z80 CPU but is actually only 4-bits wide.  (I haven't found the sound chip / ROM on the schematic but it may well have been only 4-bits). The highest 4-bits of each register are therefore ignored.  This means setting a 16-bit frequency is done by setting values across 4 registers.  Volume and waveform values are also limited to 4-bits only.

Translating pacman into C

Image
Translating Midway/Namco Pacman into C  Lots of emulators exist, such as mame, that faithfully recreate the original pacman/puckman gameplay. Additionally, many clones have been created in various programming languages.  But running the original ROM code in an emulator can be done with no understanding of how the original Z80 ROM code actually works. I decided a couple of months ago to translate the Z80 assembly code into C so that I could build the code and run it on my Linux desktop. The result is on github . This blog is intended to be a record of my findings through the translation journey and hopefully might add to the knowledge base that already exists. Code conventions The C code in pacman.c contains the original disassembled Z80 code as comments just before it.  In many cases, there is redundancy in the code but I've left these in as a literal translation.  There are about 10,000 lines of disassembled Z80 code and about 5,000 lines of C code.  These 5,000 lines could eas