Subject: TECH: Understanding Early Microprocessor based Solid State Games
From: Clive Jones <[email-masked]>
Date: Mon, 22 Apr 96 08:14:00 PDT
Newsgroups: rec.games.pinball

Well instead of telling/playing pratical jokes all the time I thought I'd   
better put an informative (hopefully) post together.....

Mentioning the words "dead MPU board" or "microprocessor" have alot of   
people running for cover. Microprocessors are not as frightening as they   
are made out to be, you just need to know a little about how they work to   
get rid off that 'techno-fear'.Microprocessors are *extrememly* reliable   
devices, memory - RAM in particular fail much more often than uP's.

Okay, lets make a start. We'll be covering 8 bit uP's from early solid   
state pinball machines here - pre 1984, these are;

Rockwell 6502 (Gottlieb)
Motorola 6800, 6802, 6808 (Williams and Bally)

Just for the record;

Williams - System 3,4 and 6 MPU - 6802 or 6808 uP
Williams - D8223 Sound + Speech - 6802 or 6808 uP
Bally  - AS-2518-17 MPU - 6800 uP
Bally  - AS-2518-35 MPU - 6800 uP
Bally  - AS-2518-51 Sound   - 6802 or 6808 uP
Bally  - AS-2518-61 SQ+TK   - 6802 or 6808 uP
Gottlieb - System 80/A MPU    - 6502 uP
Gottlieb - System 80/A sound  - 6502 uP

All the uP's above have the same basic architecture - 3 busses, a 16 bit   
Address bus, an 8 bit data bus, and, a control bus. They are all NMOS   
devices that output voltages at TTL levels.

The 6802 uP is identical to the 6808 with the exception that it contains   
128 bytes of RAM which must be enabled by strapping the RE (RAM Enable)   
line high with a 4k7 resistor (if your wishing to test your uP - you can   
place a 6808 into a 6802 socket with no I'll effects without strapping RE   
providing remote RAM is available).

*Address Bus*

All 16 lines of the address bus (AO-A15) are omni-directional, meaning   
that the data flows only one way - out of the uP. These lines are used to   
'address' devices on the bus - RAM, ROM, PIA's etcetera.

The number of address lines a uP outputs determines the size of the area   
it can address, for all those listed above this is 64k (65536 bytes).

*Data Bus*

Data flows between the microprocessor and the devices connected to it   
(RAM, ROM etcetera) via this 8 line bi-directional bus (D0-D7). The uP   
accepts data (in) from this bus during a 'read' cycle and writes data to   
devices (out) on the bus during a 'write' cycle.

The size of the data bus actually denotes the size specified of the uP,   
for example - all those uP's listed above are '8 bit', they are however,   
all capable of writing 16 bits of data (they send two 8 bit bytes). 8   
lines are accomodated to cut costs, a uP with 16 data lines would require   
a physically larger PCB and more hardware than as is.

*Control Bus*

There are various signals here associated with each uP, but the specific   
signals we are interested in are;

* - denotes signal is active low

 --Clock--

Not really part of the control bus, but, the most inmportant pin on a any   
microprocessor outside of the power and ground pins, this input usually   
recieves a TTL level clock pulse from an external crystal oscillator   
(Bally use a multivibrator on AS-2518-XX MPU boards) from which *all*   
processing/data transfer timing on the bus is derived.

 --Reset* (active low on all)--

Used as you would expect, to reset the uP. This pin is an *input* and in   
all cases this line must be held low for a defined time period (measured   
in clock cycles*) to allow the internal circuits to stabilze before the   
uP can operate correctly*. Being an input the uP cannot assert reset to   
other devices on the bus itself (the reset line is usually tied to *all*   
devices on that bus that will except it).

[*680x - reset must be low for 8 or more clock cycles, the 6502 must be   
low for 7 or more clock cycles.]

[Reset cicuits* - Williams Level 'n' is all discreet (transistors,   
resistors etcetera) located next to connector 1J2 on MPU board, Bally   
AS-2518-nn, - 'valid power detector' circuit (again discreets, lower l/h   
corner of MPU board), Gottlieb 'System 80/A/B - 3 transistors, a handfull   
of resistors, a blocking diode and a timing capacitor all directly above   
the battery on the MPU board.]

 --R/W*--

Read / Write*. This control signal is output by the microprocessor   
whenever data flows. If the uP is performing a read cycle, it will assert   
this pin high to inform devices on the bus that it requires to read data   
from the memory location specified by the address lines. If the uP wishes   
to write data, it asserts this signal low.

For example; if the 6808 uP wished to write data to a the first address   
of the 6810 RAM at IC16 on a Williams level 6 MPU board, it would place   
the the address $0080 (hex) on the address bus, it would then assert R/W   
low to instruct the 6810 the uP is performing a write cycle and then   
output data on the data lines, which the 6810 would store internally in   
it's byte wide location at $0080.

 --Interrupts; - IRQ* and NMI*--

Interrupts are exceptional conditions - they serve to 'interrupt' the uP   
from it's current task (running the main program) and jump to a unique   
memory location were the uP runs a program or 'service routine'   
associated with each of the two interrupt structures. When these service   
routines are complete, the uP returns to carry on the main program where   
it left off.

Both IRQ* (Interrupt RQuest) and NMI* (Non Maskable Interrupt) are   
*inputs* handled differently by the uP. IRQ is a masked interrupt, this   
simply means that when IRQ is invoked (pulled low from another device on   
the bus), the uP will ingore *all* further IRQ requests until it has   
finished running the IRQ service routine (program).This is dependant on   
setting the interrupt enable bit of the uP's internal 'status register'.

The NMI interrupt (which is also pulled low in the same way) on the other   
hand *cannot* be masked (hence it's name) and another NMI will be   
recognised as valid even if the uP is already running a NMI service   
routine, this effectively interrupts the current interrupt to run   
another, and causes 'nesting', which if uncontrolled, can cause the stack   
to overflow (see later).

To get around this most pinball NMI interrupts are designed to be random   
(asynchronous), for example - depressing the Williams MPU board self-test   
switch. If the designer wishes to run a regular NMI interrupt, lets say -   
 by running a clock onto the NMI pin (synchronous), the software engineer   
must ensure that the time it takes to execute the NMI service routine is   
shorter than the next valid incomming interrupt signal and therefore fits   
into the NMI timing 'window'.

The NMI interrupt is not used on the Gottlieb System 80 MPU board, it is   
used on the System 80 sound board, but it is software controlled (new   
sound select interrupt from game MPU?). On Williams System MPU's it   
invokes the self-test and for Bally it clears the audits.

 --VMA (Valid Memory Address)--

I wasn't going to include this signal, but, considering the number of   
680x's out there in the pinball word I thought I better had. Quite   
simply, anytime a 680x uP places an address onto the address bus,   
regardless of whether it's a read or write cycle this signal is asserted   
high. It's use depends on the hardware design engineer, but commonly, it   
aids selection of devices on the bus (memory address decode logic, bus   
drivers etcetera).

*How it all works*

When any of the uP's above powers up or recieve RESET they go through a   
boot up routine known as 'bootstrapping' (yes - this is where the term   
'boot-up' comes from). The uP's output a fixed address after reset goes   
high   which relects the location or RESET VECTOR which in turn must   
contain the two bytes that form the start address of the main program -   
the RESET vector always reflects an (EP)ROM location on the pinball MPU   
boards we are refering too, this is an automatic/built in function that   
cannot be altered. The uP also asserts R/W* high to indicate a read cycle   
on the bus.

The uP loads the contents of the RESET vector into an internal counter   
known as the 'program counter' (PG) - it then treats the contents of the   
PG as the start address of the main program and makes a jump to that   
address to execute the first instruction, the program is now effectively   
running, for example;

After power up, and reset goes high, the Gottlieb System 80 6502 issues   
the address $FFFC onto the address bus and asserts R/W* high,   
consequently address $FFFC gives up it's contents (it places the contents   
on the data bus), when the 6502 has these it issues the address $FFFD in   
the same manner. Upon retreiving the contents of both memory locations,   
the 6502 places the contents into the PG and begins execution of the   
program at that address;

$FFFC = $FF (low byte), $FFFD = $A0 (high byte), contents placed into   
6502 Program Counter as $A0FF - go to this address and receive your first   
program  instruction.

Notice that the uP obtains the low byte first, the same occurs for the   
680x with the exeption that the vectors are different, for reset they are   
$FFFE and $FFFF respectively.

Exactly the same thing occurs when the uP recieves either an IRQ or NMI   
request - there are unique vectors for each of these too.

(BTW, the Program Counter is just a 16 bit internal counter that keeps   
track of the program address).

The programmer must make sure the vectors are loaded with the correct   
data (in this case $FF and $AO stored in ROM for our example RESET   
vector).

You don't actually need to know the vectors because short of actually   
hacking the ROM's they serve no usefull purpose to a Tech wishing to   
repair the boards (you'd need a data scope to see this in real time,   
which cost like *millions* of pounds, well, maybe not millions but lots   
of money anyway). It is handy however, to know *where* they are located   
if your MPU board only partially boots.

*The Stack*

A area of RAM needs to be reserved for something called the uP 'stack',   
the stack is required by the uP to save the contents of it's internal   
registers onto and temporary storage, especially, when it encounters an   
interrupt.

The 6502 stack *always* resides in RAM at page 1 ($0100) - this cannot be   
changed, on a Gottlieb system 80 MPU board you will not actually see any   
*RAM* at this address - it's hidden inside a 6532 RIOT.

The stack will never reside in 5101 RAM - because the 5101 has only 4   
bits in data width, which is of no use to us (we only get back half the   
data we saved into it!).

The stack - although fixed at $0100 for the 6502 needs to be given a   
length - the programmer defines this length during the initialization*   
routine. If the stack is programmed to be 256 bytes in length ($FF) then   
the stack resides in memory from $0100 - $01FF. The stack builds   
downwards, meaning, the first placement will be at $01FF, the second at   
$01FE and so on pushing down towards $0100. If the stack exceeds it's   
limit of 256 bytes, it 'overflows' and wraps around to $0100 again and   
begins to overwrite itself. Programmers ensure that this doesn't happen   
by carefull use of the stack, overflow is signalled by the uP setting the   
reserved 'stack overflow' bit in the uP's status register.

[*initialization]
Some devices on the bus have to be 'told' how to operate - the 6520/1 PIA   
is a prime example of a device that works in a number of 'modes' and   
during the initialization of devices at start-up by the main program, the   
PIA is told to run in a certain configuration until re-programmed (e.g.   
port A all ouputs, Port B all inputs etcetera). Other routines usually   
ocurr at this time - zeroing out and testing of RAM for example, or, the   
famous Bally 7 flashes indicating device testing.
[end]

The term LIFO is assigned to the stack, meaning 'last in, first out'   
(there *are* others, FIFO - being 'first in first out'). Contents are   
'pushed' onto the stack and then 'popped' (pulled) of the stack again by   
the uP. You may have actually heard the terms 'push' and 'pop' when   
 programmers refer to the stack. The current address of the stack is kept   
in an internal uP register called surprise, surprise - the 'stack   
pointer' (SR).

Pressing the diagnostic switch on the side of a Williams System 'X' MPU   
board is a classic example of stack use;

The pinball machine is either in atract mode or game play, at this time   
the internal computational and status registers of uP contain data   
relating to it's current task. The diagnostic switch is depressed causing   
an NMI interrupt, the microprocessor finishes it's current command   
execution and pushes the program address onto the stack (from the PG)   
with the internal registers and then jumps through the dedicated NMI   
vector at $FFFC/$FFFD to the service routine (all this is automatic with   
Motorola 6800 uP - I'm unsure whether the same can be said for 6802/8,   
but my gut feeling is that Motorola would have made this standard   
architecture - anyone know for sure?). When the routine is over, the   
program control is handed back to the main program when the uP encounters   
the 'RTI' instruction (return from interrupt) which causes the uP to   
automatically 'pop' the stack and re-load the contents into the registers   
from which they were taken. Main program control now continues.

This is not the case however for the 6502, - the programmer must push the   
contents onto the stack (except for the PG address which is automatic)   
and 'pop' them again when the service routine is over. E.g (don't worry   
if you can't read assembley language - it's just an example!!);

The uP recognises an NMI interrupt and jumps through the NMI vector to   
the address which contains the following NMI service routine........

DUMMY INTERRUPT
 PHP  ;push Status register onto stack
 PHA  ;Push accumulator onto stack
 TXA  ;transfer contents of the X register to accumulator
 PHA  ;Push X register contents onto stack
 TYA  ;transfer contents of the Y register to accumulator
 PHA  ;push Y register contents onto stack
 ...
 ...  ;execute NMI service routine
 ...  ;
 ...  ;last NMI service routine instruction execution

 PLA  ;restore the contents
 TAY  ;of the Y register (transfer via accumulator)
 PLA  ;restore the contents
 TAX  ;of the X register (transfer via accumulator)
 PLA  ;restore accumulator
 PLP  ;restore status register
 RTI  ;hand program control back to main program

The 6502 now pulls the PG from the stack and continues where it left off,   
notice that the contents are pulled off in reverse of how they were   
loaded -LIFO.

If the contents of the internal registers were not saved in this way,   
they would contain the data left over from the NMI routine, which, when   
program control was handed back to the main program, would cause the uP   
to become extremely confused and crash.

I have made reference to the internal uP registers here (accumulators,   
status registers etcetera ) but have not explained there use as it would   
make this to complex to understand if your learning - if you really want   
to learn more get yourself a good microprocessor hand book.

As mentioned, the Gottlieb System 80 stack resides in a 6532 RIOT (RAM   
I/O Timer) and in both Williams and Bally, it resides in 6810 RAM. IN   
fact if you look on a Gottlieb System 80 sound board, you won't see *any*   
RAM IC's on it, I can assure you it is there - in U15.

Back onto interrupts - more than one device can be connected to either   
interrupt line - they are 'wire ORed' together, simply, the line is   
pulled high using a pull-up resistor when no interrupts are occuring,   
then grounded by the device requesting an interrupt. The Bally AS-2518-nn   
MPU board does exactly this - both the PIA at U10 and the PIA at U11 can   
signal an interrupt request (IRQ) onto the 6800 (they're IRQ pins are   
wired together) , the 6800 then has to 'poll' (ask) which of the two   
PIA's have requested the interrupt. It does this by examining a special   
register within each PIA which sets a bit (flag) active to indicate an   
interrupt - the uP reads this to determine who made the request and takes   
the relevant action within the IRQ service routine.

Well it seems I've rambled on a bit yet again, and, it's time for dinner   
(which usually comes before *anything* in my home) so - time to sign off.

Just a note - of the uP's used in the late 70's and early 80's pins - the   
6502 has faired better than most, being used by Atari, Apple and others.   
It also has the least number of instructions - 56 as opposed to the   
6800's 72 instructions. It's also interesting to note that of the 4 uP's   
listed, it remains the only one still in production (it's also my   
favourite).

Have fun

Clive

<[email-masked]>