WORK IN PROGRESS!
Scott Tunstall presents: The Definitive Guide to Robotron: 2084 Source Code.
Reverse Engineering The Ultimate 8-Bit Masterpiece
June 2014 UPDATE: Scotland’s own- Scott Tunstall project to reverse engineer Robotron HERE (SeanRiddle site) “On Sean Riddle’s website there is an ongoing project to reverse engineer Robotron 2084. Thanks to Sean’s info on the hardware I have made great inroads into the way the game works. I aim to reverse engineer the full game, purely for educational purposes. I will try to produce an updated disassembly every week.”
I’ve had a love affair with Robotron for years, probably the only game I play regularly nowadays. It’s an honour to peek into the game and hopefully enable people to create new cheats/change game behaviour in MAME. I’m not a game developer, but am a member of a game dev society for Uni of Abertay Dundee (Scotland) – IMHO each student should pay homage to games like Robotron which are the original adrenaline games.
Scott- If you’re on wave 1 or 2 and you’ve lost lives already, and you have less lives than what you started with, the game adjusts some difficulty settings – presumably to make the game easier. See $2B2F in the code. When a wave starts in Robotron there’s some checking to determine if the player’s “doing badly” (for want of better words from me)
per Larry DeMar June 2014- The Bozo mode was not in the original Robotron code. There were some complaints from the field about how brutal the game was to new players and Scott has discovered the code put in to address these complaints. In that 2nd release the default difficulty was also moved down from 5 to 3. If you are down a man very early in the game then the settings are dialed as low as they can go through the first wave.
20 Tank Bullets: (tanks will run out of bullets after 20 shots if you do not shoot any of their bullets)
I’ve found why 20 tank shells are fired and then no more! At $4E46 (blue label) there’s a function that I have called CREATE_TANK_SHELL. The function (oddly enough) is responsible for creating a tank shell. Among the very first thing the function does is check the current number of tank shells on screen (a value in $98F1) to #$14 (20 decimal) – see line $4E57. If higher than that then the routine exits – no more shells can be created. If there are less than 20 shells active, a shell is created. Shells have a finite lifespan. The line at $4FAF decrements the “lifespan countdown” of the shell and when it hits zero goes to $4FBB which removes the shell from the playfield – the only thing is, it does not decrement the “current number of tank shells on screen” variable! There’s the bug. So when you’ve got 21 tank shells, that’s yer lot. If you want to get them tanks firing like crazy again, you can simply (!) go into MAME debugger and reset $98F1 to 0
I’ve seen code that makes hulks walk up to corners. That’s a bug I’ve found at $010D in the disassembly, where the hulk chases a non-existent object.
1. Hulks do seek out humanoids. At this line of code, to be precise:
01BE: 8D 77 BSR $0237 ; get a family member from the family member list into D 01C0: ED 49 STD $0009,U ; store into target
; An interesting bug: this instruction is supposed to return an active object but there are times when a hulk is created and there’s nothing
; else on screen yet. As a result *(U + 9) computes to WORD 0 (which I call NULL) and the contents of memory addresses $0000 and $0001 are read into Y.
; You get Y=7E 01. Go look at ORG $0000 and see for yourself…
; Now, $7E01 certainly does not point to any real object, so the hulk ends up going on a wild goose chase, chasing an object that does not exist.
; This probably explains why hulks wander off doing their own thing and getting stuck in the corner at times. ;”
Here’s the explanation (at location $1B95 in the disassembly)
On starting wave 5 and inspecting the family member object pointer linear list in $B354 - B3A4, I found that all entries are NULL (WORD 0). As a result, the algorithm that finds the nearest human for the brain always fails, and by default it returns a pointer to the first entry of the list: $B354, Thus, *all* Brains are set up to look at $B354 for their target. There's nothing in the slot (yet). Later on in the wave setup routine when family members are being added to the list, when slot $B354 *is* populated with a pointer to a family member, guess what family member gets the slot? That's right - Mikey! that's why all Brains go for Mikey straight away. After Mikey is killed or rescued, his slot in the family member list is set to NULL. The brains detect this, and then the algorithm to find the nearest family member is called. This time though, the algorithm works as planned because the family member list is fully populated.
Copyright Protection Code
- Was doing some disassembly Sunday evening. I found some code that looks protection related. Did you know that if a certain memory address doesn’t contain a particular value, some code kicks in that subtly (any property) alters object state (like for example the baddies positions, speed or whatnot)
- Larry Jul 2014- The code that you uncovered which makes modifications will eventually crash the program if the value you mention is not present.
- Larry Sep 2014- It wasn’t publicly known before we put it in the Digital Eclipse package. Here is that clip: http://www.youtube.com/watch?v=eAy2f6SUpQU&index=5&list=PL8CAA1599951C5832
Robotron Secret Room / Easter Egg / Copyright Protection
- Larry DeMar shares a Robotron secret (Aug 2012)- Youtube
- steps below per Digital Press Easter Eggs Robotron: 2084 info
- This 3-combo trick must be done during a game, and each combo must be done within ¼ seconds of each other:
- Direction joystick RIGHT + fire joystick UP + 1P button
- Direction joystick UP + fire joystick DOWN + 2P button
- Direction joystick DOWN and hold + fire joystick UP.
- Let go of the fire joystick and the message will appear.
- Update Larry Jul 2014- Comments and things to add. Mark’s sequence is correct except that you hold the “Fire Up” position (Move joystick can be let go once message appears). Let go of Fire Up and game returns to attract mode. We don’t know of a copy of Robotron that was done, but I suspect it was the unknown operation of the LSI custom chips as well as the difficulty of creating that function that was the real roadblock. Also, Robotron was not as successful as Defender. In that regard, in the years since when people have told me about how my game was going to get ripped off, I always reply that “I hope I have that problem to worry about.”
- Update Scott Sept 2014- OK, reverse engineered the Easter Egg!!! The code to show the hidden message is at $D73F. Here’s how to get it in MAME.
Start MAME with the debugger activated then go into the debugger. Type the following: BPSET D75A [press ENTER to execute] and then BPSET D78A. [press ENTER]
After the 2 breakpoints have been set, you then type into the debugger PC = D73F [Press ENTER] . Now press F5 to run to next breakpoint. When you hit a breakpoint type into the debugger A=40 [press Enter] to emulate you pushing the fire stick UP, and again F5 to run to next breakpoint. Keep inputting A=40 [Press ENTER] each time until you see the entire screen of text before you!
I had no joy in doing it in MAME the normal way!!!!!
And here’s the end result….
- Uploaded new disassembly to Sean Riddle’s page with easter egg code (look for the text “EASTER_EGG_PART” and you will find relevant parts) http://seanriddle.com/robomame.asm
Atari 7800 Robotron:
Scott- The way it’s been structured is quite different to the arcade’s code, and the enforcers don’t have their brain-farts. The hulks IIRC don’t consider the player either, unlike the arcade. It’s still good though! One thing in the Atari 7800 version that is not in the arcade is a demo mode which shows an AI mutant fighting the enemy – very well done.
Larry- The 7800 port of Robotron was one of the greatest ports at the time it was written, a period when arcade-to-console usually meant a dramatic watering down of the game. I met the programmer at a trade show of that era. He was so proud of how he nailed the game. The web says his name is David Brown, although I don’t remember the name from that time.
Scott- Having seen the other 8 bit ports I have to agree the 7800 was a great one. The C64 and Spectrum ports were travesties – the C64 could do so much better. His work was indeed good, close enough to satisfy the Robo-groupies . He should be pleased with himself, the 6502 processor has only 3 8-bit registers – its a pig to program! The Atari 7800 hardware is also “unique” with its display list interrupts, which I found hard to get to grips with. So pat on the back to that man
Letter Written By Eugene:
Dear Steve and joe,
You have dug pretty deep into stuff, but I’m still waiting for your
first bug fix! (A guy named Christian Gingras from Quebec actually
spent a year disassembling Robotron and fixed 5 or 6 bugs on the
game, one of which was a fatal crash which Larry and I had fruitlessly
searched months for !!!)
Dealing with your questions point by point:
There are two sets of vectors (EFF8, and FFF8) since our debugging
system normally resided in the F000 block, and the game vectors
were stored in EFF8-EFFF. For production the debugger was replaced
by self-test and diagnostic code, and the game vectors were moved
to FFF8-FFFF, the EFF8 vectors being an appendix of sorts.
The blitter works as you figured (see enclosed I/O map), takes over
the bus, halting the processor, doing a pixel transfer 1D to 2D of
4 bit pixels. (I hate the term blitter… we always called it a DMA)
I’ve always felt systems based on multiple bit planes are bogus, and
that graphics transfers should be done on a pixel basis. It is
much less overhead. The Amiga is a classic example of this nonsense,
vastly increasing overhead, and slugging out an otherwise inspired
machine. Bit-blit systems allow many bizarre pixel operations, very
few actually being useful. 99% of the time all you need is a good
transparency operation. The Williams graphics DMA was inspired
in that it did all it operations (including transparency) in a
single write cycle, with no slow read-modify-write required. Luckily
the world is going to 24 bits/pixel, bit plane systems being assigned
to the technological trash heap. It is ashame that with all the
window systems today, a good blitter is not standard on all PC’s.
You’re talking about a $5-$10 chip that could 10X the graphics
performance. I should have been designing PC’s in ’82…
Top secret C000 data…from raw code vintage 1981
TTL R O B O T W A R
* HARDWARE CONSTANTS
HSTK EQU $BF70
VECTOR EQU $EFF0
CRAM EQU $C000 COLOR RAM ADDR
WDOG EQU $CBFF
WDATA EQU $39
CMOS EQU $CC00
SOUND EQU $C80E
VERTCT EQU $CB00 6-BIT VERTICAL BEAM ADDR
RWCNTL EQU $C900 (BIT 0: 1-ROM READ; 0-RAM READ)
* (BIT 1: 1-INVERT; 0-NORMAL SCREEN)
PIA0 EQU $C80C
*B0 AUTO UP
*B7 SOUND HANDSHAKE
*CA1 IRQ 240 (16 MS) (LINE 240)
PIA1 EQU $C80E
*B6-B7 LED 0,1
*CB1 IRQ 4 MS (0,$40,$80,$C0)
PIA2 EQU $C804
*B0 MOVE UP
*B1 MOVE DOWN
*B2 MOVE LEFT
*B3 MOVE RIGHT
*B4 START 1
*B5 START 2
*B6 FIRE UP
*B7 FIRE DOWN
PIA3 EQU $C806
*B0 FIRE LEFT
*B1 FIRE RIGHT
*B7 INPUT 1=COCKTAIL
*CB2 OUTPUT SWITCH MUX CONTROL 1=PLAYER1,0=PLAYER2
DMACTL EQU $CA00 CONTROL BYTE WRITE INITIATES TRANSFER
*B0:READ FORMAT 0=SERIAL;1=BLOCK
*B1:WRITE FORMAT 0=SERIAL;1=BLOCK
*B2:XSFER RATE 0=ROM-RAM (1MSEC); 1=RAM-RAM (2 MSEC)
*B3:1=ZERO WRITE SUPPRESS
*B6:1=B0-B3 WRITE SUPPRESS
*B7:1=B4-B7 WRITE SUPPRESS
DMACON EQU $CA01 CONSTANT DATA BYTE
DMAORG EQU $CA02 ORIGIN ADDR MSB,LSB
DMADES EQU $CA04 DESTINATION ”
DMASIZ EQU $CA06 HOR,VERT BYTE COUNTS
Trivia note: Robotron was originally called ROBOT WAR, never bothered
to change it in the comments.
The Williams logo and ROBO letters are run-length encoded as you
indicated. The program that runs them is at $77A0, the data is
encoded at the end of that code around $8180 or so.
Robotron was developed on a 64K SS-50 computer system with dual
720K 5 1/4″ floppies. The SS-50 standard was started in about
1976 or 1977 based on a 1Mhz 6800. SWTPC, Gimix, and Smoke Signal
were probably the biggest vendors.
The standard evolved into a 2Mhz 6809 system
which had equivalent power of the first IBM PC. The terminal
RS-232 9600 Baud Televideo 910 with cursor
control giving full screen editing and scrolling capability.
All code written in assembly ( TSC 6809 ). Our Gimixes ran TSC Flex DOS.
OS-9 was written for the SS-50 bus computers, and then later
ported to the 68000 where it survives today. Being the troglodytes
we are we never converted over to it. The ROBOTRON source code
was composed of about 25 modules that were each independently
assembled and orged in a fixed location. All interface between the
modules was through jump vectors at fixed locations. A master
equate file defined all I/O, ram, and jump vector locations. In this way
any module could be modified, assembled, and loaded, without
affecting any of the others. This made for fast turn around time,
since only an assembly and load of the changed module was required.
No linking was necessary!!! The assembler could handle about 3000
global symbols, which is about where my current 386 pc assembler
craps out with 10 times the memory…go figure. The only problem
with the system was that toward the end of a project the modules
would start getting large and sometimes overlapping one another,
necessitating changing the fixed module load points and
reassembling everthing affected….horror show! The assembler could
handle a couple thousand lines a minute. Our text editor was known
as Phred. We wrote it ourselves as there was nothing decent
available at the time. It was a good single-file-at-a-time totally
memory resident system, and worked fine as long as your files
were under 30-40k… 2500 lines if your comments were sparse. Spaces
were compressed. Phred lives on as a set of BRIEF macros.
The proprietary debugging system (code named DCON) consisted of
a parallel port to download code, a serial monitor terminal interface
and rams instead of eproms plugged into the Robo hardware. Monitor
software was loaded at $F000. This system could read/write memory,
set breakpoints, single step, disassemble code, and also had a
nifty hardware halt on address circuit. Very useful in catching
those errant memory writes that so often perplex. The DCON hardware
was designed by my partner Larry DeMar, software by yours truly.
Art tools consisted of a modified Robo system with a 16 color
pixel drawing program installed. (Picasso) This was interfaced
to a Gimix computer and you could save files and animation scripts
to floppy ! A lot of the game was developed with graph paper
drawings before Picasso was up and running. The graph paper
drawings were then hand coded into program data statements pixel
They still make the WICO joysticks and replacment switches. Any
decent distributor should have them. You can also order direct
from WICO part #15-945401. 800-352-4151. You may just have to
adjust your switches. Clean them by squeezing a dollar bill
between the contacts, and make sure the switch is open when
unactuated and closed when joystick direction activated.
Blaster uses a totally unique board. Look for ads in the back
of Play Meter or Replay magazines. Very tough to find.
Joust runs on Robotron boards. Stargate may possibly work. No others.
There are some unused addresses in the C000 range that were reserved
for serial ports in the debugger. I don’t recall exactly which ones.
You can figure it out by looking at a schematic.
JMP’s were used because there faster than JSR’s and RTS’s.
Happy Bit Twiddlin,’
Eugene P. Jarvis
- Christian Gingras’ reverse engineering project from 1987 HERE