# Pacman hardware

At the core of Pacman is on a Z80 CPU supported by a 224x288 color video with hardware sprites and a 3-voice wavetable sound generator... a pretty nice setup for 1980!

Here is all the information I know about the Pacman hardware. For the most part it has been extracted by looking at the sources of various emulators, most notably MAME, but I have spent many hours to re-organize and write it down in a single place. If you find wrong or missing information please email me so that I can improve the content of these pages.

### CPU and memory layout

The CPU is a Z80 clocked at 3.072 MHz. The game ROM takes 16K at the beginning of the address space, followed by 2K of video memory and 2K of RAM for game use:

Offset | Length | Description
0000h | 4000h | Game ROM
4000h | 0400h | Video RAM (1K, characters)
4400h | 0400h | Video RAM (1K, color information)
4800h | 07F0h | RAM
4FF0h | 0010h | Sprite data

Several registers that interface with other hardware devices are memory mapped directly in the CPU address space:

* All locations within the specified range replicate the same byte value

Offset | Length | Mode | Description
5000h | 0001h | Write | Interrupt enable (bit 0: 0=disabled, 1=enabled)
5000h | 0040h * | Read | IN0 port (joystick and coin slot)
5001h | 0001h | Write | Sound enable (bit 0: 0=disabled, 1=enabled)
5002h | 0001h | Write | Aux board enable?
5003h | 0001h | Write | Flip screen (bit 0: 0=normal, 1=flipped)
5004h | 0001h | Write | Player 1 start light (bit 0: 1=on, 2=off)
5005h | 0001h | Write | Player 2 start light
5006h | 0001h | Write | Coin lockout (bit 0: 0=unlocked, 1=locked)
5007h | 0001h | Write | Coin counter (trigger by changing the bit 0 from 0 to 1)
5040h | 0020h | Write | Sound registers
5040h | 0040h * | Read | IN1 port (joystick and start buttons)
5040h | 0020h | Write | Sound registers
5060h | 0010h | Write | Sprite coordinates
5080h | 0040h * | Read | DIP switch settings
50C0h | 0040h * | Write | Watchdog reset

From looking at the ROM code I think port 5002h is unused in Pacman and used in Ms. Pacman to enable the auxiliary board (when 01h is written to the port). At least that's how PIE uses it and it seems to work.

In cocktail (table) mode the screen must be flipped for the second player, otherwise he would see the game upside down. This is made in hardware by writing 01h to the port 5003h and only flips the characters, while the sprites are flipped and repositioned by the game engine.

The IN0 port is connected to the joystick and the coin slots:

IN0 port (read-only at address 5000h)

Bit | Description
0 | Joystick up (0=pressed, 1=released)
1 | Joystick left (0=pressed, 1=released)
2 | Joystick right (0=pressed, 1=released)
3 | Joystick down (0=pressed, 1=released)
4 | Rack advance (switch, automatically advance to next game level: 0=on, 1=off)
5 | Coin slot 1 (trigger by changing the bit to 0 then 1)
6 | Coin slot 2 (trigger by changing the bit to 0 then 1)
7 | Credit button (0=pressed, 1=released)

The credit button works like the coin slots but adds a credit without incrementing the coin counter. The IN1 port is connected to the second player joystick (only for cocktail table ) and the start buttons:

IN1 port (read-only at address 5040h)

Bit | Description
0 | Cocktail cabinet: 2nd player joystick up (0=pressed, 1=released)
1 | Cocktail cabinet: 2nd player joystick left (0=pressed, 1=released)
2 | Cocktail cabinet: 2nd player joystick right (0=pressed, 1=released)
3 | Cocktail cabinet: 2nd player joystick down (0=pressed, 1=released)
4 | Board test (switch: 0=on, 1=off)
5 | One player start button (0=pressed, 1=released)
6 | Two players start button (0=pressed, 1=released)
7 | Cabinet mode (0=table, 1=upright)

Some game settings such as for example the number of lives per game or the game difficulty are controlled by DIP (Dual In-line Package) switches that are memory mapped to address 5080h. Each switch is represented by a bit that is 1 if the switch is off and 0 if the switch is on:

DIP switches (read-only at address 5080h)

Bit | Description
0, 1 | Coins per game (0=free play, 1=1 coin per game, 2=1 coin per 2 games, 3=2 coins per game)
2, 3 | Number of lives per game (0=1 life, 1=2 lives, 2=3 lives, 3=5 lives)
4, 5 | Bonus score for extra life (0=10000 points, 1=15000 points, 2=20000 points, 3=none)
6 | Difficulty (jumper pad: 0=hard, 1=normal)
7 | Ghost names (jumper pad: 0=alternate, 1=normal)

I don't have specific information on the watchdog reset port at 50C0h, so I can only guess it is the port that the game uses to reset the watchdog timer, a CPU-independent clock that resets the CPU after a specified timeout elapses. The port is written at costant intervals during the game (three times per frame) mostly with zeroes and every now and then with a decreasing counter: this tells the watchdog that the program is alive and forces the timer to restart from its initial value.

### Video

The display supports a resolution of 224x288 pixels that are actually 8x8 characters arranged in a 28x36 matrix. This allows the video to work with just 2K of RAM, 1K for video information and 1K for color information. The video and color RAM have a very peculiar arrangement with some extra locations that are not visible on the screen.

Colors are defined in a 32-entries palette PROM where each entry contains packed RGB information:

Color palette entry

Bit | Color | Connected to
0 | Red | 1K ohm resistor
1 | Red | 470 ohm resistor
2 | Red | 220 ohm resistor
3 | Green | 1K ohm resistor
4 | Green | 470 ohm resistor
5 | Green | 220 ohm resistor
6 | Blue | 470 ohm resistor
7 | Blue | 220 ohm resistor

The resistor values can be used to compute the weights of each bit. The max current output (i.e. intensity) for a color is V/220 + V/470 + V/1000 and this corresponds to 0xFF, the max palette value for a RGB component. Performing the sum and simplifying, as we're only interested in ratios from now on, we get a total of 7934 and individual weights of 4700, 2200 and 1034 respectively (i.e. the 220 ohm resistor allows more current to pass and thus has a greater weight, i.e. is brighter). Scaling those to 0xFF we get the "typical" weights of 0x97, 0x47 and 0x21 that most emulators use.

Although all useable colors are defined in the above palette, character and sprite colors are defined in terms of a logical 256-entries color map that is also stored in a 4-bit PROM. Because each color entry takes only 4 bits only the first 16 entries in the palette can be used, and in fact in Pacman the remaining entries are all zeroed out.

Character definitions are stored in a 4K ROM. There are 256 8x8 characters and each of them is defined using 2 bits per pixel, so one character takes 16 bytes of ROM space. Note that this approach provides only 4 colors per characters. In order to display a character its code must be written in the proper location in the video memory and also it must be assigned a color by writing in the corresponding color memory location. The character color that is actually displayed is obtained by combining 6 bits from the color memory, which apply to the whole character, with the 2 bits that define each character pixel:

pixel_color(x,y) = (character_color shl 6) or character_pixel_color(x,y)

Pacman supports 8 independent 16x16 color sprites that can be moved anywhere on the screen without interfering with the underlying graphics. Each sprite has its own coordinates, color and display mode. There are 64 different sprite shapes and a sprite can take any one of these. The shapes are defined in a 4K ROM with a format that is practically identical to that of characters. However, according to the display mode, a sprite can also be displayed normally, flipped horizontally, flipped vertically and flipped in both directions.

As usual, sprite registers are memory mapped too:

Sprite registers

Offset | Description
4FF0h | Sprite #0 shape (upper six bits) and mode (lower two bits)
4FF1h | Sprite #0 color
4FF2/3h | Sprite #1 shape/color
4FF4/5h | Sprite #2 shape/color
4FF6/7h | Sprite #3 shape/color
4FF8/9h | Sprite #4 shape/color
4FFA/Bh | Sprite #5 shape/color
4FFC/Dh | Sprite #6 shape/color
4FFE/Fh | Sprite #7 shape/color
5060h | Sprite #0 X coordinate
5061h | Sprite #0 Y coordinate
5062/3h | Sprite #1 X/Y coordinates
5064/5h | Sprite #2 X/Y coordinates
5066/7h | Sprite #3 X/Y coordinates
5068/9h | Sprite #4 X/Y coordinates
506A/Bh | Sprite #5 X/Y coordinates
506C/Dh | Sprite #6 X/Y coordinates
506E/Fh | Sprite #7 X/Y coordinates

Sprites are displayed in reverse order, so if two sprites overlap the one with the higher number can be wholly or partially covered by the one with the lower number.

### Sound

The sound comes from a custom chip made by Namco that is able to play up to 3 simultaneous voices using wavetable synthesis.

Copyright (c) 1997-2004 Alessandro Scotti. All rights reserved.