Reactor on GG-III hardware

Reactor is a fantastically fun game. However, it didn’t do very well in the arcades and that caused a (large) number of the games to be converted or trashed. As a result, the CPU boards got tossed either (i) on a shelf to corrode, or (ii) tossed in the trash. If you’ve read this far, you probably know how hard it is to locate a Reactor boardset – let alone a working Reactor boardset!

In late 1999, I acquired an empty Reactor cabinet, and was having very little luck getting the boards. Looking at a Reactor board, it seemed very similar to a Q*Bert or Mad Planets board. There was even a short note about converting a Q*Bert board to run Reactor code, but no one had actually done it. Until now.

I had previously worked with Fabrice Frances on implementing speech in the Reactor and Q*Bert MAME drivers. Fabrice lives and works in France and missed the funny speech that Q*Bert spouts during the game. That speech is generated from the Votrax SC-01a voice synthesis chip. Very hard to find, and *almost* impossible to emulate. Samples were taken from a Q*Bert sound board and incorporated into MAME. During this process, I asked Fabrice if he could just make the Reactor code *work* on a Q*Bert board. Not being a programmer, I didn’t understand the complexity this task involved.

To begin with, the Reactor (GG-2) board uses a completely different memory map than the later revisions of the Gottlieb board.

Gottlieb GG-2 memory map: Reactor

Main processor (8088 minimum mode)
0000-1fff RAM (NOT battery backed unlike all the others)
2000-2fff sprites
3000-37ff video ram
4000-4fff char generator ram
6000-67ff palette ram (palette of 16 colors)
7000-77ff i/o ports
8000-ffff ROM

Gottlieb GG-III memory map: Q*Bert, Mad Planets, Krull

Main processor (8088 minimum mode)
0000-0fff RAM (battery backed)
1000-1fff RAM or ROM (selected with jumpers on the board)
2000-2fff RAM or ROM (selected with jumpers on the board)
3000-37ff sprites
3800-3fff video RAM
4000-4fff char generator RAM
5000-57ff palette ram (palette of 16 colors)
5800-5fff i/o ports
6000-ffff ROM (not necessarily fully populated)

In addition, the Reactor code was compiled to fit on eight 2716 EPROMs, while the Q*Bert GG-III board uses three 2732 EPROMs. Some of you might be saying "if it is simply a matter of changing the memory pointers in the Reactor code to work with the GG-III hardware, why didn’t you just do that??" That is certainly what I was thinking. Fabrice had already decrypted all the Gottlieb ROMs in order to write the MAME driver. He effectively had the source code!

Well, not exactly. With limited context information, it is not always possible to decide if an address in a sub-routine should be changed or not. Tim Skelly had his source code and Tim took the liberty of describing it.

"The Reactor listing is a whopping 397 pages long of 11"x15" tractor feed paper weighing in at 8lbs, signed and dated 5/5/81 with corrections made in 1982. Produced by an 8086/8087/8088 macro assembler, it is divided into the following sections: RAM structure, Cross Reference (values and addresses of all labels), Data Tables and their structures, Code including in this order, primary and control routines, sub-routines that call other sub-routines and stand-alone sub-routines. Sub-routines are preceded by documentation of the following items: What conditions the routine assumes, which processor registers the routine will use, what the routine returns, what variables will be used, which data tables will be directly required and which other routines are called. In addition to human-readable Assembler Code and occasional Programmer Comments, each line is accompanied by the HEX value of its memory location and the object code contained at that location. Woof!

There are no electronic versions of this in existence. Jim [Weisz] had not yet built our PC-based development system, and I was working with and Intel processor emulator system. Our storage was a trash-compactor sized outboard hard drive that used removable, birthday-cake sized platters that held a whopping FIVE MEGABYTES of storage. I doubt the machine itself, much less the disks, remains."

Tim was able to get a copy of his source code to Fabrice (with about only a dozen comment lines in a total of 13000) whereupon Fabrice made all the address changes. Here are a couple of pages from the Reactor source code listing.

During the alteration of the Reactor source code, Tim Skelly responsed to Fabrice’s question of why there's a data section in the Reactor source code starting at $F0D0 and a code section (with data interleaved) starting at $F69E, which is dead code.

"Well, I think the reason actual code ends at about F0D0 (F08B, going by the listing, not the actual code) is that that's where the program ends.

For some reason, its clear that when initialized the processor may begin execution at (actual) address FFF0. From there the program executes a jump to the relative start of the program. So:

(Hex addresses not adjusted for later corrections)
Location 0000: Beginning of RAM storage
Location 8000: Power-Up Initialization jump to Code Start, skipping Data
Location 8005: Beginning of Data
Location B865: End of Data
Location B866: Code Start
Location F08B: End of Code
Location FFF0: Power-Up Initialization jump to Code Start

This sort of oddity was not unusual when writing assembler for what were essentially "embedded" processors. Processors were quirky about where they started executing code on power-up, and oddities like this one were not unusual. Sometimes it was just superstition, but hey, it didn't cost anything. No matter where the program ended, the code space ended at FFF0."

Fabrice also had this to say about the Reactor source code:
"I only found one bug/feature in the code - initialization of the character generator ram data is done 6 characters at once (because it uses a temporary buffer in workram that is only 192 bytes), and it is done 22 times, so a total of 132 characters are transferred while the character ram has only room for 128. On the reactor board, this overflows to an unmapped area. With the port to the Q*bert board, this translates to an overflow on the color palette ram. But once again, it doesn't seem to be a problem, because this initialization is done once, and the palette is redefined after. Tim's source code shows that very little workram is used (a little more than 2KB), so in fact only the 0000-0FFF range needs to be RAM.

One important thing to note, though... I didn't have the diagnostic source code when porting the code to the Q*bert board, so this part (code from F063 to FFEF) is not guaranteed to work!! This means of course you shouldn't start in diagnostic mode because if a routine in this range is called from the main program it will crash."

As an aside, Tim Skelly got interested in this project because the colors in Reactor were being incorrectly emulated in MAME. After many discussions and examination of the current set of ROMs out on the net, it was discovered that MAME was loading the video ROMs in the incorrect order – effectively putting the bottom colors on top, and the top colors (primarily white) on the bottom. A rather easy fix once it was discovered :)

If you are interested in receiving the "reactor2" ROM images that will run on a GGIII board, please e-mail me. ** Note, these ROM images may not be sold, and I better not find someone selling a ‘hacked’ board on eBay!**