pinball construction kit for bally-35 / bally-17 and stern deutsch


Table of contents
Introduction
Required things
How to do it...
game statments
Testing
Assembling
Tools
faq



Introduction
The pinball construction kit is a new U6 game rom and a toolset to reprogram your existing early bally (1978 - 1983) or stern pinballs. No additional hardware is required expect a pc for programing and an eprom burner...

When you look at a bally-35 mpu, you see two or more game specifc eproms (red circle around the u2 chip and blue circle around the U6 chip, sometimes u1 is filled also). The other chips on this board are not game specific. For using a bally-35 mpu in another game, you must replace these chips.

Pck-bally replaces the existing u6 chip. With the tools availiable from this page you can define new game rules and you can create your own game specific u2 chip. Both chips are 2732 or 2532 eproms.

Required
What is required:
1) A bally / stern pinball
2) some programing skills (preferable motorola 6800 or another 8 bit processor)
3) a good knowledge of the bally hardware
4) some good ideas for new game rules

Pinball
Well I hope you have one with a bally-35 / bally-17 or a stern-100 / stern-200 mpu...

programming skills
The pck-bally is based on 6800 assembler and specific macros. This means you program a mix from pure 6800 assembler code and some predefined macros.

Here are the necessary documents:
Programming the 6800
Datasheet for the 6800 (u9)
Datasheet for the 6821 (u10 and u11)
Be aware that you must have some programing experience...(> 2 years...) and you should be familary with hexadecimal numbers...
Here is the great 6800 assembler (version 1.31) from Frank A. Vorstenbosch.
Read the manual (especially about the macros)...

Bally hardware
Bally wrote an excellent description
This book describes in detail how the bally-35 mpu works
Bally Theory of Operation

New game rules
This is quite a difficult task. Start writing down the existing game rules and think of something new...

How to do it...
To create a new game rom you do the following:
a) Create or modify a game source with a text editor (notepad). You focus only on the game specific things. The general things like scoring, selftest, driving coils, lamps, displays, checking switches, handling up to 4 player are done by the pck-bally u6 rom... Syntax:
Comment everything you do (use separat lines in your sourcefile beginning with ";"). When you use macros, don't add additional blanks or remarks on the right side. Otherwise the assembler may run into problems...
b) assemble it with the 6800 assembler. There use a .bat file you can use.(asspck < filename > )
c) test it with a debug version of pinmame (called pindebug in the further text...)
d) if it is okay burn it on an eprom and test it in your pinball
(You do this at your own risk, you may burn coils if your program does not work well, I'm not responsible for any damage...)

game statments
Coils
First you have to define the coils of the game. In maximum you can define 30 momentary coils. 15 coils are adressed direct, 15 coils are adressed with a solenoid expander board. You can also define 4 permanent coils. During the game momentary coils could be activated.
Momentary coils
The average coil in a pinball is a momentary coil. This coil is triggered a specific time from the game rom.
Fast react or quick coils
Some coils (bumpers and slingshot) must react very quickly during game play. Williams solved this problem with addtional hardware (two switches for one coil). Bally solved this within the software: For every fast react coil one switch is assigned. If this switch is detected closed, the coil is fired from the pck rom (not from the game rom u2).
Permanet coil
You can trigger 4 permanet coils, two are already used: enable flipper k1 (on the solenoid board) and the coin lockout. These two coils are handled by pck. You may use two additional permanet coils (for example a gate)
Example
; Assembler statements
;
; coil definition for mata hari
;
; all solenoids must be defined once with a soldef
; first param (nr) is addr from U2 74ls154 on solenoid board, drives Q...
; if (nr) > 14 then solenoid expander is used...
; second param (type) defines coil usage
; (type) = 100        norm       (rest)
; (type) = 101        perm        (coin lockout=1,flipperenable=4)
; (type) = (swnr)     Quick       (bumper)
; K1 relais
        soldef  4,101
; coin lockout
        soldef  1,101
; saucer          Q2
        soldef  0,100
; chime 10        Q1
        soldef  1,100
; chime 100        Q5
        soldef  2,100
; chime 1000      q6
        soldef  3,100
; extra chime     q7
        soldef  4,100
; knocker         q3
        soldef  5,100
; outhole        q4
        soldef  6,100
; left botton bumper        q8
        soldef  7,38
; left top  bumper        q13
        soldef  8,40
; right top bumper        q14
         soldef  9,39
; right bottom bumper                q9
        soldef  10,37
; left sling        q10
        soldef  11,36
; left drop target reset        q12
        soldef  12,100
; right sling        q11
        soldef  13,35
; right drop target reset        q16
        soldef  14,100
;

Activate a mometary coil:
; all targets down, reset both targets bank
        solon        12,10
        solon        14,10
The solon macro activate the coil (first parameter) a specific time (second parameter). After this time, the coil is released.
Times you should use for specifc coils:
; knocker -> 0c
; kickout ball (outhole) -> 0a
; saucer -> 0c
; targetbank reset -> 10
; chimes -> 00

Activate a quick coil:
No need to activate a quick (or fast react) coil with a solon statement, this coils is triggered by the pck for a specific time.

Activate a permanent coil:
To activate use:
; k1 solenoid board
     sonk1
; coin lockout
     sonco
; permanet coil 2
     sonp2
; permanet coil 3
     sonp3

These coils will be active until your turn them of. To switch this coil off use:
     soffk1
     soffco
     soffp2
     soffp3


Switches
Then you define all used switches the game. In maximum 48 switches are supported.
Behind every switch number you define an entry point in your program. This entry point is called if this switch is closed. A permanent closed switch is detected only once.

Example
; Here you define the 16 first switches (mata hari)
     ; credit button
        swdef        06,swcredit
        ; tilt
        swdef        07,swtilt
        ; outhole switch
        swdef        08,swouthole
        ; coin 2
        swdef        09,swcoin
        ; coin 3
        swdef        10,swcoin
        ; coin 1
        swdef        11,swcoin
        ; slamtilt
        swdef        16,swlam
If the credit button is pressed, the subroutine "swcredit" is called. You have to leave this routine by an rts (return from subroutine) instruction. You can load register a with specific values to influence the pck.
; return code
;
; if reg A = 0, everything okay
; if reg A = 1, ball drained,
;         if no score, serve nextball for this player
;         else if extraball (macro givex) was lit,
;           serve next ball (jsr xball) for this player
;         else next player (stopplayer , player + 1,
;                 startplayer)
; if reg A = 2  ball locked serve next ball
;               for multiball (jsr xball)
; if reg A = 4  add one player if possibile
; if reg A = 5  tilt this ball
; if reg a = 6  slamtilt entire pinball
; if reg a = 7  add credits number of credits in reg b
;                if b = 0 give one freegame with knocker

Here you see the assembler routines for the defined switches:
swouthole:        ; ball in outhole, finish
        ldaa    #$01
        rts
swcredit:        ; add one player
        ldaa    #$04
        rts
swcoin:          ; always two credits with one coin
        jsr     sound3
        ldab    #$02
        ldaa    #$07
        rts
swtilt:          ; pinball is tilted
; trigger upper saucer (maybe the ball is there...)
        solon        00,0A
        ldaa    #$05
        rts
swlam:          ; slamtilt
        ldaa    #$06
        rts

You can check the switches explicitly. For example if you want to check if switch number 12 is closed use the following coding.
     csw    12,open12
close12:
If a switch is permanet close, the entry point is only triggered once. Use the macro rsw to reset the switch 12. If the switch is still closed, the entry point is triggered again after you used this macro.
     rsw    12
Lamps
No need to define lamps explicitly, these are mapped directly to a specific memory area.

The first lamp board is mapped to the memory area
$200 - $20E
The auxilary lamp board (or the second lamp board) is mapped to the memory area:
$20F - $21D

You may adress four lamps at once with a direct memory store to the variable X0200 for example. If a bit is 1 the corrsponding lamp is off, if a specific bit is 0 the lamp is on.
Here is the lamp schema for mata hari.

; mata hari lamp schemas              Connector
; $0200 8765FFFF
;  8 -> bonus 4k           q57        J3 1
;  7 -> bonus 3k           q36        j3 26
;  6 -> bonus 2k           q29        j1 1
;  5 -> bonus 1k           q14        j1 18
; $0201 8765FFFF
;  8 -> bonus 8k           q50        j3 12
;  7 -> bonus 7k           q38        j3 25
;  6 -> bonus 6k           q27        j1 9
;  5 -> bonus 5k           q12        j1 19
; $0202 8765FFFF
;  8 -> drop target spec   q51        j3 15
;  7 -> bonus 20k          q44        j3 19
;  6 -> bonus 10k          q28        j1 8
;  5 -> bonus 9k           q13        j1 17
; $0203 8765FFFF
;  8 -> a target (2)       q54        j3 11
;  7 -> b target (2)       q49        j3 17
;  6 -> n/u                q35        j1 3
;  5 -> n/u                q8         j1 23
; $0204 8765FFFF
;  8 -> n/u                q55        j3 9
;  7 -> n/u                q48        j3 16
;  6 -> n/u                q34        j1 2
;  5 -> n/u                q9         j1 14
; $0205 8765FFFF
;  8 -> ab value 4k        q16        j3 3
;  7 -> ab value 3k        q37        j3 23
;  6 -> ab value 2k        q22        j1 10
;  5 -> ab value 1k        q10        j1 15
; $0206 8765FFFF
;  8 -> n/u                q59        j3 4
;  7 -> ab value spec      q32        j3 27
;  6 -> ab value extra     q26        j1 7
;  5 -> ab value 5k        q11        j1 16
; $0207 8765FFFF
;  8 -> lt outlane 50k     q58        j3 2
;  7 -> rt outlane 50k     q20        j1 13
;  6 -> n/u                q25        j1 6
;  5 -> n/u                q4         j1 28
; $0208 8765FFFF
;  8 -> lt bottom bumpe    q56        j3 10
;  7 -> rt bottom bumpe    q42        j3 21
;  6 -> n/u                q24        j1 5
;  5 -> n/u                q1         j1 24
; $0209 8765FFFF
;  8 -> 2 x potential      q46        j3 18
;  7 -> 3 x potential      q41        j3 20
;  6 -> 5 x potential      q17        j1 11
;  5 -> n/u                q2         j1 25
; $020A 8765FFFF
;  8 -> credit indicator              j3 13
;  7 -> S.P. SHOOT AGAIN              j3 22
;  6 -> MATCH                         j2  8 / j1  4
;  5 -> SHOOT AGAIN                   j1 26 / j2 21
; $020B 8765FFFF
;  8 -> 2 x multi          q30        j3 14
;  7 -> 3 x multi          q39        j3 24
;  6 -> 5 x multi          q21        j1 12 / j2 12
;  5 -> n/u                q7         j1 27 / j2 13
; $020C 8765FFFF
;  8 -> Tilt                          j2 10
;  7 -> Game over                     j2 11
;  6 -> High score to date            j2 23
;  5 -> Ball in play                  j2 22
; $020D 8765FFFF
;  8 -> n player 4         q43        j2 7
;  7 -> n player 3         q30        j2 6
;  6 -> n player 2         q18        j2 20
;  5 -> n player 1          q5        j2 16
; $020E 8765FFFF
;  8 -> player up 4        q45        j2 1
;  7 -> player up 3        q31        j2 2
;  6 -> player up 2        q19        j2 15
;  5 -> player up 1         q6        j2 14

Pck set and reads the lamps at the adress $20A and $20C.
To activate a lamp (for example the 3x multi) use the macro
     lampon 4B
The second half byte specifys the adress (beginning from 200), here 20b. The first half byte specifys the bit position (check the upper table to find the lamp...bit position 4 is number 7)
To switch the same lamp off, use
        lampoff     4B
To check, if the (3x multi) lamp is on use
        laonq        4B,score3x
score1x:
        ...
If this lamp is on, jump to point score3x, otherwise continue at score1x.
To check, if the (3x multi) lamp is off use
        laoffq        4B,sc2off
sc1off:

sc2off:
        ...
If this lamp is off, jump to point sc2off, otherwise continue at sc1off.
For the auxilary (or the second) lamp board use the macros:
     lamponx
     lampofx
     laonqx
     laoffqx
The only difference is that the first adress of the aux board is $20f.
Displays
You only have to define if you use 6 or 7 digit displays. The rest is handled by the pck.
Dip switches
You can read all 32 dip switches into register a.
     dip18
     dip916
     dip1724
     dip2532
If you want to check dip switch 24, use the following coding:
     dip1724
     bita   #$80
     bne    closed24
open24:

Scoring
There are several macros for scoring:
; add 10 to the score
      as100  0010
; add 10'000 to the score
      as10t  0001
; add 1'000'000 to the score (pending)
      as1mp  01
; add 100'000 to the score (pending)
      as100tp 01
; add 5'000 to score (pending)
     as1tp    05
; add 500 to score (pending)
     as100p    05
; add 20 to score (pending)
     as10p    02
Pck will handle the score, check replay levels and show the score in the displays.
Wait
If you want to wait during your game coding (for example during the bonus countdown) use the macro wait
     wait   10
Check game status
If you want to check if the game is tilted or the game over lamp is on use the macro gaoff
     gaoff  gtilt
gameon:
If the game over lamp or the tilt lamp is on, jump to entry point gtilt, otherwise continue at gameon. You could use this marco to disable a bonus coundown if the pinball is tilted.
If you want to check if only the game over lamp is on use the macro gaatt.
     gaatt  attra
gameon:
If the game over lamp is on, jump to entry point attra, otherwise continue at gameon.
Give extra ball
To give an extra ball during game play use the macro givex.
     giveex
Give special
To give a special during game play use the macro givesp.
     givesp
     
Version number
You should define a unique version number.
Callback routines
For specific events (for example when a game starts) a specific routine is called. At this point you may add game specific coding.
With a return code you could signal specifc states back (for example give special...)
The following events are supported:
startpin when pinball is power on
startgame when a game is started
endgame when a game is finished (or cancled..) or after power on
addplayer when one player is added by credit button
startplayer when a ball is served to the player
stopplayer when a ball drains for a player
xball when a ball is served to the player (nromal, extra or multiball)
firstcount when the first points are counted for a ball
zerocross when zero cross routine is activated after timer update, befor lamp update
afterla when zero cross routine is activated after timer update, after lamp update
afterqu when zero cross routine is activated after timer update, after lamp update, after quick solenoid react
afterdisp when display interrupt is activated after display update with one charakter (could be used for 6th display)
befscor befor adding a scoring
addpends add pending score (1 digit )
addscor add the score direct and check freegame
afersco after scoring, do the attract modus here
knock activate knocker
digitup start update digit during scoring
makeso start make sound (hook to sound card)
killso kill running sound
attract if pinball is running in attract mode


Variables
Based on the limited hardware (6810) you may define 19 additional 8 bit variables (value from 0 to 255, or hex 00 to ff)
During the attract modus you may use another 4 additonal 8 bit variables...
You may define 114 additional 4 bit variables (5101). Each variable could hold only 16 different values (hex 0F,1F,2F,3F,4F,5F,6F,7F,8F,9F,aF,bF,cF,dF,EF,FF)

Be aware that you have to define the variables at a specifc place in the source file.

Soundboards S&T
With version 9 (r 2) the s&t board (found in eight ball deluxe, vector and other pinballs) is supported.

If you use want to use this board in your pinball, you have to do the following things:
1) Include the copy pckst.inc in your source file (check file exstt.asm for an example)
2) Include the variable
swsound db        $00
in the 4 bit area.
3) Use the marco ystone once.
;
;    s&T soundboard once
;
        ystone

4) add an additional jsr in the afterqu event (search for zcross3 in the example file)
This jsr is neccessary, because you can define a time where no sound can be played.
This jsr decrease the timer...
;
;    s&T soundboard in the fast react soleonid routine
;
        jsr        ysnddi        ; decrease delay timer of sound board
;
        clra
        rts
4) Every time you want to trigger a sound, use the marco yst.
;
        yst        50,10
;
; first parameter is the value from the s&t board for the specfic sample or the sound
; be aware that sometimes the s&t boards replaces the phrases
; for example SINK THE is sometimes replaced with GO FOR
; Here are some examples from the eigt ball delxue...
; 0f        -> whops to much english...
; 50        -> go for deluxe
; 51        -> eight ball deluxe two ball
; 52        -> eight ball deluxe three ball
;
; second parameter is the delay after the cmd (no other sound played during this time, this value is decreased in a specific event...)
;

Soundboards 32/50
With version 10 (r 2) the soundboard -32 / 50 board (found in harlem, paragon, star trek and other pinballs) is supported.

If you use want to use this board in your pinball, you have to do the following things:
1) Include the copy pckst32.inc in your source file (check file exst32.asm for an example)
2) Use the marco ystone once.
;
;   soundcard 32 / -50  soundboard  once
;
        ystone

3) add an additional jsr in the afterqu event (search for zcross3 in the example file)
This jsr is neccessary, because you can define a table of sounds.
This jsr plays the next sound ...
;
;     soundboard in the fast react soleonid routine
;
        jsr        ysnddi        ; send next sound to sound board (out of soundcmd x) in async mode
;
        clra
        rts
4) Every time you want to trigger a sound, use the marco yst32.
; Load register x with the adress of a soundcmd
        ldx        # SOUN5
        yst32
;
; structure of soundcmd
; $nn $mm $oo $pp
; store first byte in x0030
; if x0030 = 1XXX XXXX sound is played sync, XXX XXX holds wait time between sound
; if x0030 = 0XXX XXXX sound is played in async, XXX XXX holds wait time between sound (decreased by zero cross ysnddi )
; loop
; increase x until contest of xx eq FF -> Sound cmd finished; break
; increase x until contest of xx eq 00 -> refill X0030, go to loop
; otherwise play sound (5 bits relevant)
; if sound should be in sync go to loop until end
; if sound  should be in assync copy x0030 -> X0034 and save X in X0032 / X0033, then routine is called again by zero cross if X0034 reaches zero
; example of soundcmd
SOUN5:                        ; Sound Data Game over guess which pinball
        db        $04, $05, $86, $05
        db        $86, $05, $86, $05
        db        $86, $05, $86, $05
        db        $86, $06, $87, $07
        db        $88, $08, $89, $0A
        db        $8A, $0B, $8B, $0C
        db        $8C, $0D, $8D, $0E
        db        $1F, $0C, $89, $2F
        db        $88, $89, $86, $87
        db        $2F, $86, $87, $81
        db        $84, $82, $00, $01
        db        $11, $1F, $11, $1F
        db        $11, $1F, $12, $1F
        db        $11, $00, $08, $0F
        db        $00, $01, $11, $1F
        db        $11, $1F, $11, $1F
        db        $12, $1F, $11, $1F
        db        $FF

Assembling
You have the asspck.bat file. With this file you can assemble your source. Then the game specific rom is created and the checksum is calculated.
asspck < filename >

Testing
With pindebug you may test your game roms. First you must put your game rom and pck into a zip file. Then you can test
pindebug gamename -d

For example, copy the file matatest to your pinmame rom folder.
use

pindebug matatest -d

Look into your assembler listing to find breakpoints. Relevant commands in the debuger
bp -> set breakpoint at a specifc adress
wp -> when this memory location changes value, execution is halted
tr -> write information into a file

Tools
Unzip this file into a separate directory pck version 10 r2

pck version 7 old version
pck version 9 R 2 old version
pck version 10 old version
You will find the following files:
AS02.EXE      -> 6800 assembler
AS02.MAN      -> 6800 manual
asspck.bat    -> use asspck < filename >
calcbal.exe   -> calculate checksum for u2 rom
copypck.bat   -> create u2 rom
examp.asm     -> example source
exstt.asm     -> example source for soundcard s&t board (eight ball deluxe, with version 9)
exst32.asm    -> example source for soundcard 32/50 board (harkem,paragon, star trek, with version 10 r2)
fsp.exe       -> file splitter
info.txt      -> info
infomata.txt  -> infomata hari
infoexstt.txt -> infomata for the soundcard s&t board
matatest.zip  -> custom game roms for mata hari (version 7)
matat0.asm    -> source for mata hari
matat0N.U2    -> u2 rom for mata hari
pck1.inc      -> include definition for macros
pckst.inc     -> include definition for macros and the soundcard s&t board (with version 9)
pckst32.inc   -> include definition for macros and the soundcard 32/50 board (with version 10 R2)

ptestN.U6     -> u6 rom (pck version 9) <- not longer used since version 10
pck10N.U6     -> u6 rom (pck version 10)

pindebug      -> pinmame linked with -debug option, copy this file in your pinmame directory


Frequently Asked Questions

Well before you ask, the only reason I made this: I want to built a early bally pinball from scratch with the existing bally hardware...


mail me your feedback please


return to mainpage