Chicken fight like a Robot
authorteamarchive2.fnf.archive.org root <root@teamarchive2.fnf.archive.org>
Sat, 3 Apr 2021 02:21:57 +0000 (02:21 +0000)
committerteamarchive2.fnf.archive.org root <root@teamarchive2.fnf.archive.org>
Sat, 3 Apr 2021 02:21:57 +0000 (02:21 +0000)
35 files changed:
.htaccess [new file with mode: 0644]
README.md [new file with mode: 0644]
align.asm [new file with mode: 0644]
bolts.asm [new file with mode: 0644]
books.asm [new file with mode: 0644]
charset.asm [new file with mode: 0644]
coins.asm [new file with mode: 0644]
color.asm [new file with mode: 0644]
control.asm [new file with mode: 0644]
demo.asm [new file with mode: 0644]
equs.asm [new file with mode: 0644]
factory.asm [new file with mode: 0644]
gameover.asm [new file with mode: 0644]
init.asm [new file with mode: 0644]
init.tel [new file with mode: 0644]
iq.asm [new file with mode: 0644]
job.asm [new file with mode: 0644]
main.asm [new file with mode: 0644]
man.asm [new file with mode: 0644]
nmi.asm [new file with mode: 0644]
pat2.asm [new file with mode: 0644]
pat3.asm [new file with mode: 0644]
pattern.asm [new file with mode: 0644]
play.asm [new file with mode: 0644]
powerup.asm [new file with mode: 0644]
robot.asm [new file with mode: 0644]
room.asm [new file with mode: 0644]
shoot.asm [new file with mode: 0644]
showa.asm [new file with mode: 0644]
skel.asm [new file with mode: 0644]
super.asm [new file with mode: 0644]
talk.asm [new file with mode: 0644]
title.asm [new file with mode: 0644]
uphigh.asm [new file with mode: 0644]
xsum.asm [new file with mode: 0644]

diff --git a/.htaccess b/.htaccess
new file mode 100644 (file)
index 0000000..0e764de
--- /dev/null
+++ b/.htaccess
@@ -0,0 +1,2 @@
+Options +Indexes
+
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..c0e8ddc
--- /dev/null
+++ b/README.md
@@ -0,0 +1 @@
+# frenzy
diff --git a/align.asm b/align.asm
new file mode 100644 (file)
index 0000000..904b627
--- /dev/null
+++ b/align.asm
@@ -0,0 +1,171 @@
+B>type align.asm
+
+.title "CrossHatch and Red Screen"
+.sbttl "FRENZY"
+.ident ALIGN
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Do a cross-hatch display
+;--------------------------------------
+.insert equs
+.extern C.DIPS,W.Fire
+.extern ASHOW,CLEAR,LINE
+; Put up cross-hatch on screen
+ALIGN:: lxi    h,ScreenRAM     ;start vertical lines
+       mov     d,h
+       mov     e,l
+       mvi     M,1             ;turn on one dot
+       inx     h
+       mov     m,e             ;=0
+       inx     h               ;so 1 dot per 16
+       lxi     b,EndScreen-(ScreenRAM+2)
+       xchg
+       ldir                    ;fill screen
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; now screen has vertical lines of dots
+; fill in horizontal lines
+;--------------------------------------
+       lxi     h,ScreenRAM+Hsize*8     ;start 8 lines down
+       mov     d,h
+       mov     e,l
+       mvi     b,Hsize         ;32 bytes across screen
+Hloop: mvi     M,-1            ;fill in line
+       inx     h
+       djnz    Hloop
+       lxi     b,20*Hsize      ;drop down 20 lines
+       dad     b               ;and do it again
+       xchg                    ;by copying top many times
+       lxi     b,(EndScreen-ScreenRAM)-(28*Hsize)
+       ldir
+       call    C.DIPS          ;set color ram to white
+       call    W.Fire          ;wait for fire button
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Make a red screen for purity adj
+;--------------------------------------
+       lxi     h,ScreenRAM     ;fill screen
+       lxi     d,ScreenRAM+1   ;with -1's
+       lxi     b,EndScreen-ScreenRAM   ;to make
+       mvi     M,-1            ;white backgnd
+       ldir
+       lxi     h,ColorRAM      ;fill color ram
+       lxi     d,ColorRAM+1    ;with 11's (RED)
+       lxi     b,EndColor-ColorRAM
+       mvi     M,11H           ;red
+       ldir
+       call    W.Fire          ;wait for fire button
+       jmp     ALIGN           ;jump back in a loop
+.PAGE
+.title "Display ZPU dipsw and VFB switch ports"
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;  Display Switch Status
+;-------------------------------
+Linof  ==      256*16
+
+; Start of Main Test Sequence
+DSPSW::
+       di
+       in      WHATI
+       xra     a
+       out     I.ENAB
+       out     NMIOFF
+       lxi     sp,SPos         ;need a stack pointer
+
+       call    CLEAR           ;clear screen
+       call    C.DIPS          ;color screen
+
+       lxi     h,ZPUSW         ;message for zpu switches
+       lxi     d,Linof*0+32    ;on line 0
+       call    SHOW
+
+;      lxi     h,VFBSW         ;message for vfb switches
+       lxi     d,Linof*8+32    ;on line 8
+       call    SHOW
+
+;      lxi     h,BITS          ;message for bit position
+       lxi     d,Linof*1+8     ;on line 1
+       call    SHOW
+
+;      lxi     h,DEF           ;message for character def
+       lxi     d,Linof*13+16   ;on line 13
+       call    SHOW
+
+       lxi     h,ScreenRAM+16*32*2-96
+       call    LINE
+
+       lxi     h,ScreenRAM+16*32*9-96
+       call    LINE
+..LOOP:
+       lxi     d,Linof*2+8     ;zpu switches line 2 - 6
+
+       in      DIP1            ;top dip
+       call    SWSHOW          ;zpu switches on = 1
+
+       in      DIP2
+       call    SWSHOW
+
+       in      DIP3
+       call    SWSHOW
+
+       in      DIP4
+       call    SWSHOW
+
+       in      DIP5
+       call    SWSHOW
+
+       lxi     d,Linof*9+8     ;vfb switches lines 9 - 11
+       in      I.O1            ;first connector
+       call    SWSHWI          ;vfb switches on = 0
+
+       in      I.O2
+       call    SWSHWI
+
+       in      I.O3
+       call    SWSHWI
+
+       jmp     ..LOOP
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      go show the string
+;-------------------------------
+SHOW:  mvi     B,0             ;magic reg.
+       jmp     ASHOW
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; general show switches routine 1 byte/line
+; input de = crt x,y address for message (next line when done)
+;      a = bit pattern 1 = on
+;-------------------------------
+SWSHWI: cma                    ;now 1 = on
+SWSHOW: mvi    C,8             ;8 bits / byte
+..Loop: rar
+       lxi     h,SWON          ;assume switch on
+       jrc     ..sk1
+       lxi     h,SWOFF         ;switch was off
+..sk1:
+       push    psw             ;save bits
+       push    d               ;save address
+       push    b               ;save bit counter
+       call    SHOW
+       pop     b               ;restore registes
+       pop     d
+       pop     psw
+
+       lxi     h,8*4           ;next position on screen
+       dad     d
+       xchg
+
+       dcr     c               ;all bits displayed?
+       jrnz    ..Loop
+
+       lxi     h,Linof-256     ;point to next line
+       dad     d               ;for writing
+       xchg
+
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;       .asciz Messages
+;--------------------------------------
+ZPUSW: .asciz  "ZPU DIP SWITCHES"
+VFBSW: .asciz  "VFB SWITCHES"
+BITS:  .asciz  "1   2   3   4   5   6   7   8"
+DEF:   .asciz  "0=OFF  1=ON"
+SWON:  .asciz  "1"
+SWOFF: .asciz  "0"
+       .end
diff --git a/bolts.asm b/bolts.asm
new file mode 100644 (file)
index 0000000..7eba0a8
--- /dev/null
+++ b/bolts.asm
@@ -0,0 +1,550 @@
+B>type bolts.asm
+
+.title "PLASMA BOLTS"
+.sbttl "FRENZY"
+.ident BOLTS
+.insert equs
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Bolt Data Structure
+;      bit number
+; +---7-+---6-+---5-+---4-+---3-+---2-+---1-+---0-+
+; |down | up  |right| left|    Length of         |     VX.VY
+; | v  | ^   | >   | <   |     Bolt 1-6          |
+; +-----+-----+-----+-----+-----+-----+-----+-----+
+; BUL1:
+;      ---- VX.VY      [DURL in top,length in bottom]
+;      ---- PX         [position in x]
+;      ---- PY         [ "     in y]
+;       .
+;       :
+;      ---- oldX       [Old positions *6]
+;      ---- oldY
+;------------------------
+;      Equates
+VX.VY  ==      0               ; byte offsets to bolt contents
+PX     ==      1
+PY     ==      2
+LEFT   ==      0               ; direction bit numbers
+RIGHT  ==      1
+UP     ==      2
+DOWN   ==      3
+GREY   ==      77H             ;mirror color
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Do all bolts
+;_______________________________
+BUL.V:: exx
+       push    b               ;set up wall color in alt set
+       lda     Wcolor
+       mov     b,a             ;save
+       ani     0F0H            ;hi nib in C
+       mov     c,a
+       mov     a,b             ;lo nib in b
+       ani     0Fh
+       mov     b,a
+       exx
+       mvi     B,2             ;# man's bolts
+       call    BOLT            ;do 2 bolts
+       mvi     B,2             ;# man's bolts
+       call    BOLT            ;do 2 bolts
+       mvi     b,BOLTS         ;do all bolts
+       call    BOLT
+       exx
+       pop     b
+       exx
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Vector (B) Bolts
+;_______________________________
+BOLT:  lxi     h,BUL1          ;-> at 1st bolt
+B.LOP: push    b               ;save counter
+       push    h               ;save pointer
+       call    VEC.B           ;erase/write a single bolt
+       pop     h               ;restore pointer
+       pop     b               ;restore counter
+       lxi     d,Blength       ;point at next bolt
+       dad     d
+       djnz    B.LOP           ;do for B bolts
+       ret
+.page
+.sbttl /Erase Bolts/
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Vector Bolts
+;_______________________________
+; HL->bolt top
+VEC.B:
+       mov     a,m             ;vx.vy
+       PUSH    PSW             ;save vxy.len
+       ani     0Fh             ;isolate length
+       jrnz    ..cont
+       POP     PSW
+       RET
+; ERASE Oldest position
+..cont:
+       lxi     b,PX
+       dad     b               ;->PX
+       add     a               ;double length
+       mov     c,a             ;bc=length*2
+       dad     b               ;->oldestX
+       mov     e,m             ;oldX
+       inx     h               ;oldestY
+       mov     d,m             ;oldY
+       xchg
+       mov     a,l
+       ora     h               ;no write if 0
+       jrz     ..skip
+;BC=Length, DE->OldestY, HL=YX
+       call    RELX            ;convert to screen coords
+       mvi     M,80h           ;write dot
+..skip:
+       POP     PSW             ;restore vxy.len
+       ani     0F0h            ;check if still writing
+       jrnz    ..ok
+       lxi     h,-1
+       dad     d
+       dsbc    b               ;->vxy.len
+       dcr     M               ;one less in length
+       RET
+; Move array of old positions down
+..ok:  mov     h,d
+       mov     l,e             ;->oldestY
+       dcx     h
+       dcx     h               ;->previous
+       LDDR                    ;move down
+       inx     h               ;->px
+; Update coords & WRITE DOT
+; A=Vxy&F0, BC=0, DE->newest, HL->PX
+       rrc                     ;do table jump
+       rrc
+       rrc
+       mov     c,a             ;bc=offset (DURL*2)
+       xchg                    ;de->px
+       lxi     h,JTable        ;look up vectoring
+       dad     b               ;add offset
+       mov     a,m             ;routine in table
+       inx     h               ;and jump to it
+       mov     h,m
+       mov     l,a
+       xchg
+       mov     c,m
+       inx     h
+       mov     b,m             ;bc=YX
+       xchg
+       pchl                    ;jump
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Update Coords
+;_______________________________
+JTable: .word  Rstop   ;0
+       .word   RLeft   ;1
+       .word   RRight  ;2
+       .word   Rstop   ;3
+       .word   RUp     ;4
+       .word   RUL     ;5
+       .word   RUR     ;6
+       .word   Rstop   ;7
+       .word   RDown   ;8
+       .word   RDL     ;9
+       .word   RDR     ;10
+       .word   Rstop   ;11
+       .word   Rstop   ;12
+       .word   Rstop   ;13
+       .word   Rstop   ;14
+       .word   Rstop   ;15
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; all these routines get as input
+; BC=pYpX, de->pY, hl=label address
+;_______________________________
+Rstop: xchg                    ;hl->py
+Stop:  xra     a               ;0
+       mov     m,a             ;py=0
+       dcx     h               ;->px
+       mov     m,a             ;px=0
+       dcx     h               ;->vxy.len
+       mov     a,m             ;get vxy.len
+       ani     0Fh             ;leave length
+       mov     m,a             ;stop bolt
+       RET
+;set to 4 to protect outer walls
+wallo  ==      0
+.define ULIMIT=[mov    a,b
+       cpi     4+wallo         ;;check limit
+       jrc     STOP
+]
+.define DLIMIT=[mov    a,b
+       cpi     200-wallo
+       jrnc    STOP
+]
+.define RLIMIT=[mov    a,c
+       cpi     252-wallo
+       jrnc    STOP
+]
+.define LLIMIT=[mov    a,c
+       cpi     8+wallo
+       jrc     STOP
+]
+
+RUp:   xchg                    ; hl->py de=YX
+       dcr     b               ;y--
+       ULIMIT
+       jmp     Writ
+
+RDown: xchg
+       inr     b               ;y++
+       DLIMIT
+       jmp     Writ
+
+RRight: xchg
+       inr     c               ;x++
+       RLIMIT
+       jmp     Writ
+
+RLeft: xchg
+       dcr     c               ;x--
+       LLIMIT
+       jmp     Writ
+
+RUL:   xchg
+       dcr     c               ;x--
+       dcr     b               ;y--
+       ULIMIT
+       LLIMIT
+       jmp     Writ
+
+RUR:   xchg
+       inr     c               ;x++
+       dcr     b               ;y--
+       ULIMIT
+       RLIMIT
+       jmp     Writ
+
+RDL:   xchg
+       dcr     c               ;x--
+       inr     b               ;y++
+       DLIMIT
+       LLIMIT
+       jmp     Writ
+
+RDR:   xchg
+       inr     c               ;x++
+       inr     b               ;y++
+       DLIMIT
+       RLIMIT
+       jmp     Writ
+.sbttl /Write Dots/
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Write the Dot
+;_______________________________
+; hl->py,bc=YX
+Writ:  mov     m,b             ;update py
+       dcx     h               ;->px
+       mov     m,c             ;update px
+       xchg                    ;de->px, hl?
+       mov     h,b             ;get pY
+       mov     l,c             ;pX
+       call    RELX            ;convert to screen addr
+       mvi     M,80h           ;write the dot
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Check for intercepts
+;_______________________________
+;BC=yx,DE->px, hl->screen
+       in      WHATI
+       rlc
+       RNC
+; Erase dot
+       mvi     m,80h           ;erase the dot
+       shld    Temp            ;save address for reflect
+       dcx     d               ;->vxy.len
+; Hit Check by looking at the color bolt hit
+       push    b               ;save YX
+       srlr    b               ;index the 4x4 box
+       srlr    b               ;y/2
+       srlr    b               ;YX/8
+       rarr    c
+       srlr    b
+       rarr    c
+       srlr    b
+       rarr    c               ;carry=Low nibble
+       exaf
+       lda     Flip            ;test cocktail
+       ora     a
+       jz      ..norm
+       lxi     h,EndColor
+       dsbc    b               ;subtract box offset
+       pop     b               ;restore YX
+       exaf
+       cmc                     ;complement hi/lo
+       jmp     ..tt
+..norm: lxi    h,ColorScreen   ;base of color area
+       dad     b               ;add box offset
+       pop     b               ;restore YX
+       exaf
+..tt:  jc      LoNib
+; Check hi nibble
+       mov     a,m             ;get 2 color boxes
+       ani     0f0h            ;isolate left one
+       cpi     GREY&0f0h       ;gry=mirror
+       jz      REFLECT
+       exx
+       cmp     c               ;hi nib wall color      
+       exx
+       jz      WALLHIT
+;must have hit another bolt or object
+       jmp     HITCHK
+; Check Lo Nibble
+LoNib:
+       mov     a,m             ;add box offset
+       ani     0fh             ;isolate right one
+       cpi     GREY&0fh        ;gry=mirror
+       jz      REFLECT
+       exx
+       cmp     b               ;lo nib wall color
+       exx
+       jz      WALLHIT
+;must have hit another bolt or object
+       jmp     HITCHK
+.sbttl /Reflect the bolt/
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Reflect the bolt
+;_______________________________
+;BC=yx, DE->vxy.len
+REFLECT:
+       ldax    d               ;get vxy
+       ani     0C0h            ;check for any up/down
+       jrz     ..Ve            ;right/left hit only verticals
+       lhld    Temp            ;get magic address
+       res     5,h             ;convert to normal
+       mov     a,m             ;get pixels of wall
+       mvi     h,90h           ;left nibble test
+       bit     2,C             ;if ((x.mod.8)<4)
+       jrz     ..test          ; then left nibble
+       mvi     h,09h           ;right nibble test
+..test: exaf                   ;save pixels
+       lda     Flip
+       ora     a
+       jz      ..on
+       mvi     a,99h
+       xra     h
+       mov     h,a
+..on:  exaf                    ;restore pixels
+       ana     h               ;look for non 60(vertical)
+       jnz     ..Ho
+..Ve:  lxi     b,VerTab        ;vertical table
+       jmp     ..Go
+..Ho:  lxi     b,HorTab        ;horizontal table
+;bc=table de->vxy,hl->screen
+..Go:  ldax    d               ;get vxy
+       ani     0f0h
+       rrc
+       rrc                     ;vxy*4
+       mov     l,a
+       mvi     h,0
+       dad     b               ;->RefTab[vxy]
+       ldax    d               ;->vxy.length
+       ani     0fh             ;keep length
+       ora     m               ;new vxy
+       stax    d               ;update vxy.len
+       inx     d               ;->px
+       inx     h               ;->offset x
+       ldax    d               ;get px
+       add     m               ;add offset
+       mov     c,a             ;save new x
+       stax    d               ;update px
+       inx     d               ;->py
+       inx     h               ;->offset y
+       ldax    d               ;get py
+       add     m               ;add offset
+       mov     b,a             ;save new y
+       stax    d               ;update py
+;now write the new dot
+       mov     h,b             ;pY
+       mov     l,c             ;pX
+       call    RELX
+       mvi     m,80h           ;write the new head
+       sta     RFSND           ;make ping sound
+       RET
+
+.define RE[vxy,xoffset,yoffset]=
+[      .byte   vxy<4,xoffset,yoffset,0
+]
+VerTab: RE     0,0,0           ;0 stoped
+       RE      2,1,-4          ;1 Left
+       RE      1,-1,-4         ;2 Right
+       RE      0,0,0           ;3
+       RE      8,3,1           ;4 Up-stop
+       RE      6,1,-1          ;5 UL->ur
+       RE      5,-1,-1         ;6 UR->ul
+       RE      0,0,0           ;7
+       RE      4,3,-1          ;8 Down-stop
+       RE      10,1,1          ;9 DL->dr
+       RE      9,-1,1          ;10 DR->dl
+       RE      0,0,0           ;11
+       RE      0,0,0           ;12
+       RE      0,0,0           ;13
+       RE      0,0,0           ;14
+       RE      0,0,0           ;15
+; the horizontal version
+HorTab: RE     0,0,0           ;0 stoped
+       RE      2,1,-4          ;1 Left stop
+       RE      1,-1,-4         ;2 Right stop
+       RE      0,0,0           ;3
+       RE      8,4,1           ;4 Up
+       RE      9,-1,1          ;5 UL->dl
+       RE      10,1,1          ;6 UR->dr
+       RE      0,0,0           ;7
+       RE      4,4,-1          ;8 Down
+       RE      5,-1,-1         ;9 DL->ul
+       RE      6,1,-1          ;10 DR->ur
+       RE      0,0,0           ;11
+       RE      0,0,0           ;12
+       RE      0,0,0           ;13
+       RE      0,0,0           ;14
+       RE      0,0,0           ;15
+.page
+.sbttl /Hit a Wall routine/
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Blast the Wall
+;_______________________________
+;BC=yx, DE->vxy, hl->color
+WallHit:
+       ldax    d               ;get vxy
+       ani     0fh             ;stop the vxy
+       stax    d               ;store 0.len
+       xra     a               ;0
+       inx     d               ;->px
+       stax    d               ;px=0
+       inx     d               ;->py
+       stax    d               ;py=0 (finished with DE)
+; change color box to robot color
+       bit     2,C             ;left/right nibble bit(4)
+       lxi     d,0ff0h         ;left half mask
+       jrz     ..fix
+       lxi     d,#0ff0h        ;right mask
+..fix: lda     Flip
+       ora     a
+       jrz     ..auk
+       mov     a,d             ;swap em
+       mov     d,e
+       mov     e,a
+..auk: mov     a,m             ;get 2 color boxes
+       ana     d               ;mask valid part
+       mov     d,a             ;save
+       lda     Rcolor          ;get robot color
+       ana     e               ;isolate nibble
+       ora     d               ;combine nibbles
+       mov     m,a             ;store new color
+;index the box's pixels = (Y&!3) (X&!3)
+       mov     a,b             ;pY
+       ani     #3              ;move to nearest multiple of 4
+       mov     h,a
+       mov     a,c             ;pX
+       ani     #3
+       mov     l,a
+       call    RELAnd
+       xchg
+       lxi     h,WallPts       ;add 1 pt
+       mov     a,m             ;for hitting wall
+       adi     1
+       daa
+       mov     m,a
+       sta     WLSND           ;make sound
+       lxi     h,Cross
+       jmp     Plot#
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Special Relative to Absolute
+;_______________________________
+;save all but hl,af
+;HL=YX
+RELAnd::
+RELX:  push    b
+       mvi     B,90H           ;xor write
+       call    RtoA#
+       pop     b
+       ret
+.page
+.sbttl /Hit Check for objects/
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Find Out What Got hit
+;_______________________________
+; BC=YX,de->vxy
+HITCHK:
+       ldax    d               ;get vxy
+       ani     0fh             ;stop it
+       stax    d               ;store 0,len
+       mvi     a,MaxVec        ;number of vectors to check
+       lxi     x,Vectors       ;->first vector
+..LOOP:
+       exaf                    ;save count
+       bit     Move,V.Stat(x)  ;check if moving
+       jz      ..next
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Check Vector[ix] Against Bolt
+;_______________________________
+;NOTE: should mans bolt kill him?
+;ix->object, BC=YX, a'=counter
+       mov     a,c             ;bolt X
+       sub     P.X(x)          ;object Y
+       inr     a
+;      mov     c,a             ;save it
+       jm      ..next          ;outside on left?
+       cpi     10              ;max width
+       jrnc    ..next          ;ok in x
+       mov     a,b             ;now do y
+       sub     P.Y(x)
+       inr     a
+       jm      ..next
+       cpi     30
+       jnc     ..next
+;check with real pattern size
+       mov     h,D.P.H(x)      ;get pattern pointer
+       mov     l,D.P.L(x)
+       mov     e,m             ;get address of pattern
+       inx     h
+       mov     d,m
+       xchg                    ;hl->pattern
+       mov     e,m             ;get width in bytes of pattern
+       inx     h
+       mov     d,m             ;get height
+       bit     7,d             ;check for DROP
+       jz      ..ok
+       xchg                    ;special for otto drop
+       dad     h
+       dad     h
+       dad     h               ;drop/32
+       sub     h               ;adjust delta Y
+       xchg
+       inx     h               ;now get real Y height
+       mov     e,m
+       inx     h
+       mov     d,m
+..ok:  inr     d               ;adjust for 1 higher in Y
+       inr     d
+; now check if bolt y is in pattern
+       cmp     d               ;a still y delta
+       jnc     ..next
+;now x NOT NEEDED ALL ARE 8 WIDE
+;      mov     a,c             ;restore delta
+;      sub     P.X(x)
+;      slar    e               ;multiply X.size**NEW
+;      slar    e               ;by 8 cuz of 8 bits to byte
+;      slar    e               ;of pattern
+;      inr     e               ;add one for slop
+;      cmp     e               ;is in past right side?
+;      jrnc    ..next
+; hit this vector, so set his inept bit
+       set     Hit,V.STAT(x)
+       set     INEPT,V.STAT(x) ;cause an explosion
+       RET                     ;leave loop
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      End of Loop
+;_______________________________
+..next: lxi    d,VLEN          ;distance to
+       dadx    d               ;next vector
+..exit: exaf                   ;get counter
+       dcr     a               ;any more vectors left?
+       jrnz    ..LOOP          ;if not,go check this one
+       ret                     ;go do another bolt
+
+; Pattern of wall
+Cross: .byte   1,4
+       .byte   060h,0f0h,0f0h,060h
+
+       .end
diff --git a/books.asm b/books.asm
new file mode 100644 (file)
index 0000000..5ae1e6c
--- /dev/null
+++ b/books.asm
@@ -0,0 +1,305 @@
+B>type books.asm
+
+.title "Show Book-Keeping"
+.sbttl "FRENZY"
+.ident BOOKS
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Book keeping stuff
+;_______________________________
+.insert equs
+.extern MAIN,SHOWC,CLEAR,RtoA,SHOWN,C.BOOKS,Zap
+.extern S.Fire,S.Book
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;       Show book-keeping
+;_______________________________
+BOOKS::
+       xra     a               ;turn off interrupts
+       out     I.ENAB
+       in      WHATI           ;clear any pending interrupts
+       lxi     sp,SPos         ;reset stack pointer
+..T1:  CALL    S.Book
+       jrnz    ..T1
+       call    CLEAR           ;erase screen
+       call    C.BOOKS         ;color it for book-keeping
+       di                      ;re DI cuz CLEAR does EI
+
+       lxi     h,Strings       ;point to book.keeping table
+       mvi     C,-1            ;item number=c
+..loop:
+       inr     c               ;->next item
+       mov     a,c             ;test for end of table
+       cpi     NItems
+       jz      ..exit
+..skip:
+       call    SCROLL          ;scroll up to make room for text
+       push    b
+       mvi     B,0             ;plop write
+       lxi     d,256*207       ;at x=0 y=207
+       call    ASHOW           ;show the text
+       pop     b
+       call    SCROLL          ;make room for number
+..Show:
+       call    ItemShow
+..wait:
+       call    S.Book          ;door switch
+       jrz     ..tst2
+       call    Debounce
+..deb: call    S.Book          ;wait for debounce
+       jrnz    ..deb
+       call    Debounce
+       jmp     ..loop          ;do it again
+..tst2:
+       call    S.Fire
+       jrz     ..wait
+       call    ItemClear       ; clear this book-keeping
+       jmpr    ..Show          ;show it
+
+..exit: call   S.Book
+       jrnz    ..exit
+       call    Debounce
+       jmp     MAIN
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Subroutines for book-keeping
+;-------------------------------
+; Show Item #(C) in hex/BCD
+;_______________________________
+ItemShow:
+       push    b               ;save registers
+       push    h
+       call    ItemPtr
+       xchg
+       lxi     h,0             ;make stack frame
+       push    h
+       push    h
+       push    h
+       dad     sp              ;point hl->stack frame
+       call    MOVEN           ;move number
+       lxi     d,207           ;at x=0,y=207
+       call    SSHON           ;show number
+       pop     h               ;remove stack frame
+       pop     h
+       pop     h
+POPER: pop     h               ;restore registers
+       pop     b
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Clear Item #(C) in hex/BCD
+;_______________________________
+ItemClear:
+       push    b
+       push    h
+       mov     a,c
+       cpi     NItems-1
+       jrnz    ..
+       inr     c               ;special for high scores
+..:    call    ItemPtr
+       dcx     h               ;->xsum
+       inr     b               ;+1 for xsum byte
+ClearLoop:
+       mvi     M,0
+       inx     h
+       djnz    ClearLoop
+       JMPR    POPER
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Increment Item #(C) in BCD nibbles
+;_______________________________
+ItemInc::
+       push    psw
+       push    b
+       push    d
+       push    h
+       call    ItemPtr         ;get hl,b
+       mvi     D,0             ;-> end of BCD
+       mov     e,b
+       dcr     e               ;not beyond end
+       dad     d
+;DE useable now
+;BCD is one digit per byte in upper half of byte
+       mvi     C,10H           ;inc BCD by 1
+       mvi     e,0             ;xsum nibble
+Lip:   mov     a,m             ;get digit
+       ani     0F0H            ;mask garbage
+       add     c               ;add C
+       daa                     ;decimal adjust
+       mov     m,a             ;store back in nibble RAM
+       jrc     ..con           ;if no carry clear C
+       mvi     c,0
+..con: dcx     h               ;point to next msd
+       add     e               ;add in xsum
+       mov     e,a             ;save xsum
+       djnz    Lip             ;one less digit to do
+       mov     m,e             ;store xsum
+       pop     h
+       pop     d
+       pop     b
+       pop     psw
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Get info on Item #(C) in hex/BCD
+; output:hl->item b=# of bytes
+;_______________________________
+ItemPtr::
+       lxi     h,Items         ;->Item[0]
+       mov     e,c
+       mvi     D,0
+       dad     d               ;->Item[b]
+       dad     d               ;->Item[2*b]
+       dad     d               ;->Item[3*b]
+       mov     e,m             ;low address
+       inx     h
+       mov     d,m             ;address of item
+       inx     h
+       mov     b,m             ;number of nibbles in item
+       xchg
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Move @DE,@DE+1 to @HL for B NIBBLES
+;_______________________________
+MOVEN:: push   h               ;save all regs
+       push    d
+       push    b
+       srar    b               ;divive nibbles by 2
+..lp:  ldax    d               ;get a nibble
+       inx     d               ;point to next
+       ani     0F0H            ;isolate battery half
+       mov     c,a             ;save in C
+       ldax    d               ;get next nibble
+       inx     d               ;point at next
+       rlc                     ;isolate battery half into
+       rlc                     ;lower nibble
+       rlc
+       rlc
+       ani     0FH             ;mask off battery ram
+       ora     c               ;or in high nible
+       mov     m,a             ;store at HL
+       inx     h               ;point at next
+       djnz    ..lp            ;two ess nibbles to do
+       pop     b               ;restore
+       pop     d
+       pop     h
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Show # at hl,b digits,e=y position
+;_______________________________
+SSHON: push    b               ;save all
+       push    d
+       push    h
+       mov     d,e             ;move Y position to D
+       mvi     E,0             ;set X to 0
+       call    SHOWN           ;show number
+       pop     h
+       pop     d
+       pop     b
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Scroll Screen and Erase Area for Show
+;_______________________________
+SCROLL:: push  b               ;save all
+       push    d
+       push    h
+       lxi     b,206*Hsize     ;size of area to move
+       lxi     d,ScreenRAM     ;at starting address
+       lxi     h,16*Hsize+ScreenRAM    ;move up 16 lines
+       ldir
+       xchg
+       lxi     b,16*Hsize      ;erase 16 lines at bottom
+       call    Zap
+       pop     h               ;restore all
+       pop     d
+       pop     b
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Show A String
+; hl->string,de=y and x,b=magic
+;_______________________________
+ASHOW:: xchg                   ;relabs take coords in HL
+       call    RtoA            ;convert coordinates
+       xchg
+AS.L:  mov     c,m             ;get character
+       call    SHOWC           ;show it
+       inx     d               ;point to next screen byte
+       inx     h               ;point to next letter
+       mov     b,a             ;save magic/shift
+       mov     a,m             ;test next letter
+       ora     a               ;if 0 leave
+       mov     a,b             ;restore magic/shift
+       jnz     AS.L            ;else loop
+       inx     h               ;skip over 0 byte
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Delay for time here
+;_______________________________
+Debounce:
+       mvi     b,0             ;adjust for best response
+..lop: xtix                    ;long time instr
+       xtix
+       xtix
+       xtix
+       djnz    ..lop
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Check the XSUMs and zap bad ones
+;_______________________________
+CheckBooks::
+       mvi     c,0             ;get 1st item
+..lp1: call    ItemPtr         ;get the pointers
+..do:  dcx     h               ;->xsum
+       mov     a,m             ;get xsum
+       ani     0F0h
+       EXAF
+       mvi     d,0             ;temp xsum
+..lp2: inx     h               ;->next byte
+       mov     a,m             ;get book nibble
+       ani     0F0h            ;isolate nibble
+       add     d               ;add xsum
+       mov     d,a             ;save
+       djnz    ..lp2           ;for b nibbles
+       EXAF                    ;get original xsum
+       cmp     d               ;temp sum the same?
+       cnz     ItemClear       ;no-clear item
+       inr     c               ;goto next item
+       mov     a,c
+       cpi     NItems-1        ;all but high scores
+       jrc     ..lp1
+; do high scores as big number
+       rnz
+       inr     c               ;use special item#10
+       jmpr    ..lp1
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; book-keeping tables
+;
+; macro for setting up book-keeping
+;
+.define ITEM[Address,Length]=[
+       .word   Address
+       .byte   Length
+]
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; pointers and strings for book items
+;_______________________________
+Items:
+       ITEM    CREDITS,2
+       ITEM    Chute1,8
+       ITEM    Chute2,8
+       ITEM    Play1,6
+       ITEM    Play2,6
+       ITEM    Plays,6
+       ITEM    ScoreSum,12
+       ITEM    PlayTime,12
+       ITEM    OnTime,12
+       ITEM    HIGH2,6
+NItems==10     
+       ITEM    HIGH2,12*5      ;special for clearing
+Strings:
+       .asciz  "Credits"
+       .asciz  "Chute 1"
+       .asciz  "Chute 2"
+       .asciz  "1 Player Games"
+       .asciz  "2 Player Games"
+       .asciz  "Total Plays"
+       .asciz  "Total Score"
+       .asciz  "Total Seconds of Play"
+       .asciz  "Total Seconds Game On"
+       .asciz  "High Scores"
+
+       .end
diff --git a/charset.asm b/charset.asm
new file mode 100644 (file)
index 0000000..76728c6
--- /dev/null
@@ -0,0 +1,993 @@
+B>type charset.asm
+
+.TITLE "Standard Charset"
+.sbttl "May 5, 1982"
+;------------------+
+; Standard Charset |
+;------------------+
+; characters are 9 bytes high. For decenders bit 7 of top byte
+; is set then the character is plotted 4 lines lower.
+; Charset starts with value 31 (decimal) the COPYRIGHT character
+.define P[A]=
+[.byte ^B'A
+]
+CHARSET::
+P      0
+P      00111110
+P      01000001
+P      01011101
+P      01010001
+P      01011101
+P      01000001
+P      00111110
+P      0               ;COPYRIGHT
+
+P      0
+P      0
+P      0
+P      0
+P      0
+P      0
+P      0
+P      0
+P      0               ;Space
+
+P      00001000
+P      00011100
+P      00011100
+P      00011100
+P      00011100
+P      00011100
+P      00001000
+P      0
+P      00001000        ;Exclaim
+
+P      00110110
+P      00110110
+P      00010010
+P      00100100
+P      0
+P      0
+P      0
+P      0
+P      0               ;Quote
+
+P      00010100
+P      00010100
+P      00010100
+P      01111111
+P      00010100
+P      01111111
+P      00010100
+P      00010100
+P      00010100        ;pound
+
+P      00010100
+P      00111111
+P      01010100
+P      01010100
+P      00111110
+P      00010101
+P      00010101
+P      01111110
+P      00010100        ;dollar
+
+P      00100000
+P      01010001
+P      00100010
+P      00000100
+P      00001000
+P      00010000
+P      00100010
+P      01000101
+P      00000010        ;%
+
+P      0
+P      00011000
+P      00100100
+P      00101000
+P      00010000
+P      00101001
+P      01000110
+P      01000110
+P      00111001        ;&
+
+P      00011000
+P      00011000
+P      00001000
+P      00010000
+P      0
+P      0
+P      0
+P      0
+P      0               ;tick
+
+P      00000100
+P      00001000
+P      00010000
+P      00010000
+P      00010000
+P      00010000
+P      00010000
+P      00001000
+P      00000100        ;(
+
+P      00010000
+P      00001000
+P      00000100
+P      00000100
+P      00000100
+P      00000100
+P      00000100
+P      00001000
+P      00010000        ;)
+
+P      0
+P      0
+P      00001000
+P      00101010
+P      00011100
+P      00011100
+P      00101010
+P      00001000
+P      0               ;*
+
+P      0
+P      0
+P      00001000
+P      00001000
+P      00111110
+P      00001000
+P      00001000
+P      0
+P      0               ;+
+
+P      10000000
+P      0
+P      0
+P      0
+P      00011000
+P      00011000
+P      00001000
+P      00010000
+P      0               ;,
+
+P      0
+P      0
+P      0
+P      0
+P      00111110
+P      0
+P      0
+P      0
+P      0               ;-
+
+P      0
+P      0
+P      0
+P      0
+P      0
+P      0
+P      0
+P      00011000
+P      00011000        ;.
+
+P      0
+P      0
+P      00000001
+P      00000010
+P      00000100
+P      00001000
+P      00010000
+P      00100000
+P      01000000        ;/
+
+P      00111110
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      00111110        ;0
+
+P      00001100
+P      00011100
+P      00111100
+P      00001100
+P      00001100
+P      00001100
+P      00001100
+P      00001100
+P      00111111        ;1
+
+P      00111110
+P      01100011
+P      01100011
+P      00000110
+P      00001100
+P      00011000
+P      00110000
+P      01100000
+P      01111111        ;2
+
+P      00111110
+P      01100011
+P      00000011
+P      00000011
+P      00011110
+P      00000011
+P      00000011
+P      01100011
+P      00111110        ;3
+
+P      00000110
+P      00001110
+P      00011010
+P      00110010
+P      01100010
+P      01111111
+P      00000110
+P      00000110
+P      00000110        ;4
+
+P      01111111
+P      01100000
+P      01100000
+P      01100000
+P      01111110
+P      00000011
+P      00000011
+P      01100011
+P      00111110        ;5
+
+P      00111110
+P      01100011
+P      01100000
+P      01100000
+P      01111110
+P      01100011
+P      01100011
+P      01100011
+P      00111110        ;6
+
+P      01111111
+P      01100011
+P      00000011
+P      00000110
+P      00001100
+P      00011000
+P      00011000
+P      00011000
+P      00011000        ;7
+
+P      00111110
+P      01100011
+P      01100011
+P      01100011
+P      00111110
+P      01100011
+P      01100011
+P      01100011
+P      00111110        ;8
+
+P      00111110
+P      01100011
+P      01100011
+P      01100011
+P      00111111
+P      00000011
+P      00000011
+P      01100011
+P      00111110        ;9
+
+P      0
+P      0
+P      0
+P      00011000
+P      00011000
+P      0
+P      0
+P      00011000
+P      00011000        ;:
+
+P      10011000
+P      00011000
+P      0
+P      0
+P      00011000
+P      00011000
+P      00001000
+P      00010000
+P      0               ;;
+
+P      00000010
+P      00000100
+P      00001000
+P      00010000
+P      00100000
+P      00010000
+P      00001000
+P      00000100
+P      00000010        ;<
+
+P      0
+P      0
+P      0
+P      00111110
+P      0
+P      00111110
+P      0
+P      0
+P      0               ;=
+
+P      00100000
+P      00010000
+P      00001000
+P      00000100
+P      00000010
+P      00000100
+P      00001000
+P      00010000
+P      00100000        ;>
+
+P      00011100
+P      00100010
+P      00000010
+P      00000010
+P      00000100
+P      00001000
+P      00001000
+P      0
+P      00001000        ;?
+
+P      00111110
+P      01000001
+P      01001111
+P      01001001
+P      01001001
+P      01001111
+P      01000000
+P      01000000
+P      00111111        ;@
+
+P      00111110
+P      01100011
+P      01100011
+P      01100011
+P      01111111
+P      01100011
+P      01100011
+P      01100011
+P      01100011        ;A
+
+P      01111110
+P      01100011
+P      01100011
+P      01100011
+P      01111110
+P      01100011
+P      01100011
+P      01100011
+P      01111110        ;B
+
+P      00111110
+P      01100011
+P      01100000
+P      01100000
+P      01100000
+P      01100000
+P      01100000
+P      01100011
+P      00111110        ;C
+
+P      01111110
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      01111110        ;D
+
+P      01111111
+P      01100000
+P      01100000
+P      01100000
+P      01111100
+P      01100000
+P      01100000
+P      01100000
+P      01111111        ;E
+
+P      01111111
+P      01100000
+P      01100000
+P      01100000
+P      01111100
+P      01100000
+P      01100000
+P      01100000
+P      01100000        ;F
+
+P      00111110
+P      01100011
+P      01100000
+P      01100000
+P      01100111
+P      01100011
+P      01100011
+P      01100011
+P      00111111        ;G
+
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      01111111
+P      01100011
+P      01100011
+P      01100011
+P      01100011        ;H
+
+P      00011110
+P      00001100
+P      00001100
+P      00001100
+P      00001100
+P      00001100
+P      00001100
+P      00001100
+P      00011110        ;I
+
+P      00000011
+P      00000011
+P      00000011
+P      00000011
+P      00000011
+P      00000011
+P      00000011
+P      01100011
+P      00111110        ;J
+
+P      01100011
+P      01100011
+P      01100110
+P      01101100
+P      01111000
+P      01101100
+P      01100110
+P      01100011
+P      01100011        ;K
+
+P      01100000
+P      01100000
+P      01100000
+P      01100000
+P      01100000
+P      01100000
+P      01100000
+P      01100000
+P      01111111        ;L
+
+P      01100011
+P      01110111
+P      01111111
+P      01101011
+P      01101011
+P      01100011
+P      01100011
+P      01100011
+P      01100011        ;M
+
+P      01100011
+P      01110011
+P      01111011
+P      01101111
+P      01100111
+P      01100011
+P      01100011
+P      01100011
+P      01100011        ;N
+
+P      00111110
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      00111110        ;O
+
+P      01111110
+P      01100011
+P      01100011
+P      01100011
+P      01111110
+P      01100000
+P      01100000
+P      01100000
+P      01100000        ;P
+
+P      00111110
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      01101011
+P      01100110
+P      00111101        ;Q
+
+P      01111110
+P      01100011
+P      01100011
+P      01100011
+P      01111110
+P      01101100
+P      01100110
+P      01100011
+P      01100011        ;R
+
+P      00111110
+P      01100011
+P      01100000
+P      01100000
+P      00111110
+P      00000011
+P      00000011
+P      01100011
+P      00111110        ;S
+
+P      01111111
+P      00001100
+P      00001100
+P      00001100
+P      00001100
+P      00001100
+P      00001100
+P      00001100
+P      00001100        ;T
+
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      00111110        ;U
+
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      00110110
+P      00110110
+P      00011100
+P      00001000        ;V
+
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      01101011
+P      01110111
+P      01100011
+P      01000001        ;W
+
+P      01100011
+P      01100011
+P      00110110
+P      00011100
+P      00001000
+P      00011100
+P      00110110
+P      01100011
+P      01100011        ;X
+
+P      00110011
+P      00110011
+P      00110011
+P      00111111
+P      00011110
+P      00001100
+P      00001100
+P      00001100
+P      00001100        ;Y
+
+P      01111111
+P      00000011
+P      00000110
+P      00001100
+P      00011000
+P      00110000
+P      01100000
+P      01100000
+P      01111111        ;Z
+
+P      00111100
+P      00100000
+P      00100000
+P      00100000
+P      00100000
+P      00100000
+P      00100000
+P      00100000
+P      00111100        ;[
+
+P      0
+P      0
+P      01000000
+P      00100000
+P      00010000
+P      00001000
+P      00000100
+P      00000010
+P      00000001        ;\
+
+P      00111100
+P      00000100
+P      00000100
+P      00000100
+P      00000100
+P      00000100
+P      00000100
+P      00000100
+P      00111100        ;]
+
+P      00001000
+P      00010100
+P      00100010
+P      01000001
+P      0
+P      0
+P      0
+P      0
+P      0               ;carot
+
+P      10000000
+P      0
+P      0
+P      0
+P      0
+P      0
+P      11111111
+P      0
+P      0               ;underline
+
+P      00011000
+P      00011000
+P      00010000
+P      00001000
+P      0
+P      0
+P      0
+P      0
+P      0               ;`
+
+P      0
+P      0
+P      0
+P      00111010
+P      01100110
+P      01100110
+P      01100110
+P      01100110
+P      00111010        ;a
+
+P      01100000
+P      01100000
+P      01100000
+P      01111110
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      01111100        ;b
+
+P      0
+P      0
+P      0
+P      00111110
+P      01100011
+P      01100000
+P      01100000
+P      01100011
+P      00111110        ;c
+
+P      00000011
+P      00000011
+P      00000011
+P      00111111
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      00111111        ;d
+
+P      0
+P      0
+P      0
+P      00111110
+P      01100011
+P      01111111
+P      01100000
+P      01100011
+P      00111110        ;e
+
+P      00001110
+P      00011011
+P      00011000
+P      00011000
+P      00111100
+P      00011000
+P      00011000
+P      00011000
+P      00011000        ;f
+
+P      10111110
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      00111111
+P      00000011
+P      01100011
+P      00111110        ;g
+
+P      01100000
+P      01100000
+P      01100000
+P      01111110
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      01100011        ;
+
+P      0
+P      00001100
+P      0
+P      00001100
+P      00001100
+P      00001100
+P      00001100
+P      00001100
+P      00001100        ;i
+
+P      10000110
+P      00000110
+P      00000110
+P      00000110
+P      00000110
+P      00000110
+P      00000110
+P      01100110
+P      00111100        ;j
+
+P      01100000
+P      01100000
+P      01100000
+P      01100110
+P      01101100
+P      01111000
+P      01101100
+P      01100110
+P      01100011        ;k
+
+P      00011000
+P      00011000
+P      00011000
+P      00011000
+P      00011000
+P      00011000
+P      00011000
+P      00011000
+P      00011000        ;l
+
+P      0
+P      0
+P      0
+P      01110110
+P      01101011
+P      01101011
+P      01101011
+P      01101011
+P      01101011        ;m
+
+P      0
+P      0
+P      0
+P      01111110
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      01100011        ;n
+
+P      0
+P      0
+P      0
+P      00111110
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      00111110        ;o
+
+P      11111110
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      01111110
+P      01100000
+P      01100000
+P      01100000        ;p
+
+P      10111111
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      00111111
+P      00000011
+P      00000011
+P      00000011        ;q
+
+P      0
+P      0
+P      0
+P      01011110
+P      01110011
+P      01100000
+P      01100000
+P      01100000
+P      01100000        ;r
+
+P      0
+P      0
+P      0
+P      00111110
+P      01100011
+P      00110000
+P      00001100
+P      01100011
+P      00111110        ;s
+
+P      0
+P      00011000
+P      00011000
+P      01111110
+P      00011000
+P      00011000
+P      00011000
+P      00011000
+P      00001100        ;t
+
+P      0
+P      0
+P      0
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      00111110        ;u
+
+P      0
+P      0
+P      0
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      00110110
+P      00001000        ;v
+
+P      0
+P      0
+P      0
+P      01100011
+P      01100011
+P      01100011
+P      01101011
+P      01101011
+P      00110110        ;w
+
+P      0
+P      0
+P      0
+P      01100011
+P      00110110
+P      00011100
+P      00011100
+P      00110110
+P      01100011        ;x
+
+P      11100011
+P      01100011
+P      01100011
+P      01100011
+P      01100011
+P      00111111
+P      00000011
+P      01100011
+P      00111110        ;y
+
+P      0
+P      0
+P      0
+P      01111111
+P      00000110
+P      00001100
+P      00011000
+P      00110000
+P      01111111        ;z
+
+P      00001100
+P      00010000
+P      00010000
+P      00010000
+P      00100000
+P      00010000
+P      00010000
+P      00010000
+P      00001100        ;{
+
+P      00001000
+P      00001000
+P      00001000
+P      0
+P      0
+P      00001000
+P      00001000
+P      00001000
+P      0               ;|
+
+P      00011000
+P      00000100
+P      00000100
+P      00000100
+P      00000010
+P      00000100
+P      00000100
+P      00000100
+P      00011000        ;}
+
+P      00001000
+P      0
+P      00011100
+P      00101010
+P      00001000
+P      00001000
+P      00010100
+P      00100010
+P      0               ;~man
+
+P      01010101
+P      00101010
+P      01010101
+P      00101010
+P      01010101
+P      00101010
+P      01010101
+P      00101010
+P      01010101        ;delete
+
+P      00001000
+P      0
+P      00011100
+P      00101010
+P      00001000
+P      00001000
+P      00010100
+P      00100010
+P      0               ;man
diff --git a/coins.asm b/coins.asm
new file mode 100644 (file)
index 0000000..a551a4d
--- /dev/null
+++ b/coins.asm
@@ -0,0 +1,175 @@
+B>type coins.asm
+
+.title "Coins and credits"
+.sbttl "FRENZY"
+.ident COINS
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Coins Subroutines
+;_______________________________
+.insert equs
+.intern CREDS,GetC,COINCK
+.intern DECCRD
+.extern SHOWN,GO,ItemInc,S.Free
+ItemOffset     == 0
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Wait for Coins
+;----------------------------
+; B=number of seconds to hang around
+COIN0:: mvi    B,5
+COIN1:: call   GetTimer#       ;returns in HL
+..Coin:
+       mvi     M,30            ;set timer to 30/60's or 1/2 second
+..Fast:
+       push    h               ;save timer
+       call    FreeCred        ;check for service switch
+       call    COINCK          ;check coins
+       jnz     GO              ;if a button down GO play
+       pop     h               ;->timer
+       mov     a,M             ;check if timer still going
+       ora     a
+       jrnz    ..Fast
+       djnz    ..Coin          ;one less second to wait
+       call    FreeTimer#
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;       Display Credits
+;--------------------------------------
+CREDS:
+       push    h               ;create a 2 byte string on the stack
+       lxi     h,0             ;get its address into hl
+       dad     sp
+       call    GetC            ;a:=credits
+       mov     m,a             ;store into 1st byte of stack
+       mvi     B,2             ;# of digits to show
+       lxi     d,213*256+120   ;where to show
+       call    SHOWN           ;show number
+       pop     h               ;remove temp from stack
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Get Credits into A
+;--------------------------------------
+GetC:
+       lda     CREDITS+1       ;load low nibble of credits
+       rrc                     ;which is in high nibble
+       rrc                     ;battery ram
+       rrc                     ;into low nibble of A
+       rrc
+       ani     0FH             ;mask off trash
+       mov     c,a             ;save low nibble
+       lda     CREDITS         ;get high nibble
+       ani     0F0H            ;mask trash
+       ora     c               ;or in low nibble
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Increment Credits by 1
+;--------------------------------------
+IncCred:
+       call    GetC
+       cpi     99H
+       rz      
+       ADI     1
+       daa
+       jmpr    PutCred
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Decrement Credits by 1
+;--------------------------------------
+DECCRD:
+       call    GetC            ;get credits
+       ADI     99H             ;add -1 in 9's complement arithmetic
+       daa                     ;decimal adjust
+       jmpr    PutCred         ;store credits
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Put Credits in A into Battery RAM
+;--------------------------------------
+PutCred:
+       push    b
+       sta     CREDITS         ;store in high nibble battery ram
+       mov     c,a
+       rlc                     ;rotate nibble
+       rlc                     ;note-I dont mask extra bits here
+       rlc                     ;but in getcred I do
+       rlc
+       sta     CREDITS+1       ;store
+       ani     0f0h
+       add     c
+       ani     0f0h
+       sta     CREDITS-1       ;xsum
+       pop     b
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Convert Coin-Clicks to Credits
+;--------------------------------------
+; HL->coins for chute[x]
+; C = i/o port with coin setting dips for chute[x]
+; B = 2,1
+ClickToCredit:
+       in      DIP5            ;credit amount
+       ora     a
+       jrnz    ..pay
+       push    b
+       push    h
+       mvi     b,1             ;give a credit
+       jmpr    ..lp            ;jump into loop
+..pay: mov     a,m             ;check coin clinks
+       ora     a               ;if no clinks
+       rz                      ; leave
+       push    b               ;save i/o port
+       push    h               ;save pointer to clinks thru chute
+       dcr     m               ;do one clink
+       PUSH    B
+       mov     a,b             ;get chute number
+       ADI     ItemOffset      ;add offset
+       mov     c,a             ;pass in C to
+       call    ItemInc         ;do book-keeping
+       POP     B
+       pop     h               ;restore pointer to clinks
+       push    h
+       mvi     b,-1            ;no credits yet(adds one
+       in      DIP5            ;credit amount
+       mov     e,a             ;in E
+       lxi     h,CACKLE        ;move to fractional coins
+       inp     A               ;get dips
+       add     m               ;get fractional
+..cr:  inr     b               ;got enough for a credit
+       mov     m,a             ;store remaining credits
+       sub     e               ;subtract credit amount
+       jrnc    ..cr            ;do another cred
+       mov     a,b             ;check credits
+       ora     a
+       jrz     ..sk            ;no creds-exit
+..lp:  call    IncCred         ;add a credit
+       djnz    ..lp            ;b=number to add
+..sk:  pop     h
+       pop     b
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Check Coins and Show New Credits
+;--------------------------------------
+COINCK: push   b
+       lxi     h,Coins         ;check coins
+       call    GetC            ;get credits
+       push    psw
+       lxi     b,DIP3!(2<8)    ;2 dip banks
+ChuteLoop:
+       call    ClickToCredit   ;clinks to credits
+       inx     h
+       inr     c
+       djnz    ChuteLoop
+       call    GetC            ;if new credits
+       pop     b               ; aren't
+       cmp     b               ;  equal to old
+       cnz     CREDS           ;  then show em
+       pop     b
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Check for Free Credit Button
+;-------------------------------
+FreeCred:
+       call    S.Free
+       rz      
+       call    IncCred
+..lp:  call    S.Free
+       jrnz    ..lp
+       ret
+
+       .end
diff --git a/color.asm b/color.asm
new file mode 100644 (file)
index 0000000..e318b22
--- /dev/null
+++ b/color.asm
@@ -0,0 +1,368 @@
+B>type color.asm
+
+.title "Color Subroutines"
+.sbttl "FRENZY"
+.ident COLOR
+;---------------------------+
+; color related subroutines |
+;---------------------------+
+.insert EQUS
+.intern C.GO,C.L1,C.L2,C.LI,C.DIPS
+.intern C.HIGH,C.WALLS,C.BOOKS
+.intern C.MOVE
+.extern ScorePtr
+.extern J.WAIT
+; equates
+BRIGHT ==      88H
+BLUE   ==      44H
+GREEN  ==      22H
+RED    ==      11H
+WHITE  ==      77H
+PURPLE ==      RED+BLUE
+CYAN   ==      BLUE+GREEN
+YELLOW ==      RED+GREEN
+; macros
+.define LINES[LINE1,LINE2,COLOR]=[
+       call    C.BOX
+       .word   (LINE1*8)
+       .byte   (LINE2-LINE1)/4
+       .byte   32
+       .byte   COLOR
+]
+.define BOX[X,Y,LINE2,WIDTH,COLOR]=[
+       call    C.BOX
+       .word   X+(Y*8)
+       .byte   (LINE2-Y)/4
+       .byte   WIDTH
+       .byte   COLOR
+]
+;
+; setup colors for game over / high scores
+;
+C.GO:  LINES   0,40,BRIGHT+RED
+       LINES   40,56,Yellow
+       LINES   56,60,77H
+       BOX     0,60,184,10,GREEN
+       BOX     10,60,184,8,RED
+       BOX     17,60,184,15,Yellow
+       LINES   184,224,077H
+C.INFO: BOX    0,208,224,10,M1color
+       BOX     22,208,224,10,M2color
+       ret
+; colors for title
+C.TITLE::
+       LINES   0,76,BRIGHT+RED
+       LINES   76,224,BRIGHT+Yellow
+       LINES   188,204,BLUE
+       ret
+; white screen for diag displays
+C.DIPS:
+       LINES   0,224,0FFH
+       ret
+;
+; setup colors for insert coin
+;
+C.LI:  LINES   188,204,Yellow
+       ret
+;
+; setup colors for press 1 or 2 player
+;
+C.L1:
+C.L2:  LINES   188,204,Cyan
+       ret
+;
+; setup colors for congratulations
+;
+C.HIGH: LINES  0,32,BRIGHT+Yellow
+       LINES   32,96,Cyan
+       LINES   96,112,0FFH
+       LINES   112,224,BRIGHT+GREEN
+       jmp     C.INFO
+;
+; setup colors for book-keeping show
+;
+C.BOOKS: LINES 0,188,BRIGHT+BLUE
+       LINES   188,224,BRIGHT+GREEN
+       ret
+; colors for moveing room
+C.MOVE: LINES  0,208,Purple
+       ret
+;-----------------------------
+; fill color ram with a value
+; inline parms:
+; word 1:start address
+; byte 2:number of lines
+; byte 3:width in bytes
+; byte 4:color fill value
+; uses flip to determine direction
+;-----------------------------
+C.BOX: pop     h               ;get parameters address
+       mov     e,m             ;get start address
+       inx     h
+       mov     d,m
+       inx     h
+       push    h
+; convert to offset
+       lda     Flip
+       ora     a
+       jrnz    Up
+Down:  lxi     h,ColorScreen
+       dad     d
+       jmpr    Brk
+Up:    lxi     h,EndColor
+       dsbc    d
+Brk:   xchg
+       pop     h
+       mov     c,m             ;number of lines
+       inx     h
+       exaf
+       mov     a,m             ;get width
+       inx     h
+       exaf
+       ora     a               ;test flipped=nz
+Normal: mov    a,m             ;get color
+       inx     h
+       push    h               ;new return address
+       xchg
+       jrnz    Fli
+       lxi     d,32            ;# of bytes = x width
+..y:   exaf
+       mov     b,a             ;put copy of width in b
+       exaf
+       push    h
+..x:   mov     m,a             ;put color into ram
+       inx     h
+       djnz    ..x
+       pop     h
+       dad     d               ;goto next line down
+       dcr     c
+       jrnz    ..y
+       ret
+Fli: lxi       d,-32           ;# of bytes = x
+..y:   exaf
+       mov     b,a             ;put copy of width in b
+       exaf
+       push    h
+..x:   mov     m,a             ;put color into ram
+       dcx     h
+       djnz    ..x
+       pop     h
+       dad     d               ;goto next line down
+       dcr     c
+       jrnz    ..y
+       ret
+;
+; color walls of room
+;
+C.WALLS:
+       LINES   208,224,077H
+       call    C.INFO
+       lxi     h,R.table       ;percentage table
+       lxi     b,RE.len        ;length of robot table entry
+       lda     RoomCnt         ;total rooms travelled
+       exaf
+R.loop: exaf
+       cmp     m
+       jrc     R.set
+       exaf
+       dad     b
+       mov     a,m
+       ora     a
+       jrnz    R.loop
+; HL -> number of rooms to be travelled before using this mode
+;      # of robot bolts,wait,robot color,wall color
+R.set: inx     h
+       mov     a,m             ;set total number of robot bolts
+       inx     h
+       sta     Rbolts
+       mov     a,m             ;set recharge time
+       inx     h
+       sta     Rwait
+       mov     a,m             ;robot color
+       inx     h
+       mov     c,a
+       sta     Rcolor
+       mov     a,m
+       inx     h
+       sta     Dcolor          ;set Dotted wall color
+       mov     a,m
+       inx     h
+       sta     Wcolor          ;set wall color
+       mov     a,m
+       sta     Wpoint          ;#point for wall hit
+;now go color walls C=robot color
+       lda     Flip
+       ora     a
+       lxi     h,ColorScreen
+       lxi     x,ScreenRAM
+       jrz     Ok
+       lxi     h,ColorScreen+4*32
+       lxi     x,ScreenRAM+16*Hsize
+Ok:    mvi     A,208/4         ;number of lines of room
+..y:   exaf
+       mvi     B,Hsize
+..x:   mov     a,0(x)          ;get screen
+       xra     Hsize(x)
+       ora     Hsize(x)
+;nibble results 0=no wall, 9=cross, others=reflecto
+       mov     d,a             ;save
+       ani     0fh             ;isolate lower nibble
+       jrnz    ..lr
+       mov     a,c
+       jmpr    ..LOW   
+..lr:  cpi     0fh
+       jrnz    ..gry
+       xra     0(x)
+       ani     0fh
+       jrnz    ..c1
+       lda     Dcolor
+       jmpr    ..LOW
+..c1:  cpi     0Fh
+       jrz     ..gry
+       lda     Wcolor          ;get wall color
+       jmpr    ..LOW
+..gry: mvi     a,WHITE
+..LOW: ani     0fh
+       mov     e,a             ;save lower
+       mov     a,d             ;get top nibble
+       ani     0f0h            ;isolate lower nibble
+       jrnz    ..tr
+       mov     a,c
+       jmpr    ..top   
+..tr:  cpi     0f0h
+       jrnz    ..tig
+       xra     0(x)
+       ani     0f0h
+       jrnz    ..c2
+       lda     Dcolor
+       jmpr    ..top
+..c2:  cpi     0F0h
+       jrz     ..tig
+       lda     Wcolor          ;get wall color
+       jmpr    ..top
+..tig: mvi     a,WHITE
+..TOP: ani     0F0h
+       ora     e               ;or in lower
+       mov     m,A             ;write to colorRAM
+       inx     h
+       inx     x
+       djnz    ..x
+       lxi     d,Hsize*3
+       dadx    d
+       exaf
+       dcr     a
+       jrnz    ..y
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; un-color man as he moves
+;___________________________
+UNCMAN::
+       LXI     H,VECTORS
+       bit     BLANK,M
+       rz
+       res     BLANK,M
+;restore old area of man
+       lhld    Caddr
+       lxi     d,Csave         ;save area
+       lxi     b,Hsize-1       ;move to next line
+       mvi     A,5             ;is 5 x 4 high
+..Ylp: exaf
+       ldax    d               ;get old
+       inx     d               ;->next
+       mov     m,a             ;store back to color ram
+       inx     h               ;->next door loc
+       ldax    d               ;get another old one
+       inx     d               ;->next old line
+       mov     m,a             ;store to color ram
+       dad     b               ;->next line down in color ram
+       exaf                    ;get counter
+       dcr     a               ;one less y line to do
+       jnz     ..Ylp
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; color man as he moves
+;_______________________________
+COLMAN::
+       SET     BLANK,M
+       lxi     d,P.X           ;get to px
+       dad     d               ;->p.x.h
+       mov     e,m             ;x position
+       inx     h               ;->v.y
+       inx     h               ;->p.y
+       lda     Flip
+       ora     a               ;test for flip screen
+       mov     a,m             ;y position
+       jrz     ..ok
+       neg
+       ADI     208             ;index screen
+       exaf
+       mvi     A,247
+       sub     e
+       mov     e,a
+       exaf
+..ok:  srlr    A
+       srlr    A
+       mov     h,a
+       mov     l,e
+       srlr    H
+       rarr    L
+       srlr    H
+       rarr    L
+       srlr    H
+       rarr    L
+       lxi     b,ColorScreen
+       dad     b
+; save/write box to screen
+       shld    Caddr           ;save address of box
+       lda     Mcolor          ;get player color
+       mov     c,a             ;save new color
+       lxi     d,Csave
+       mvi     a,5             ;number of bytes high
+..Ylp: exaf
+       mov     a,m             ;get current data
+       stax    d               ;save
+       inx     d
+       mov     m,c             ;write new color
+       inx     h
+       mov     a,m             ;get current data
+       stax    d               ;save
+       inx     d
+       mov     m,c             ;write new color
+       mov     a,c             ;save color
+       lxi     b,Hsize-1
+       dad     b               ;->next line
+       mov     c,a             ;restore color
+       exaf
+       dcr     a
+       jnz     ..Ylp
+       lhld    V.PTR
+       ret
+
+;THIS SHOULD BE IN PLAY
+; Robot Initializer Table
+;              xx99xx,#        ,0 or 1,bolt holdoff,color
+.define RE[Room,Bolts,Wait,RCol,Dcol,Walls,Wp]=[
+       .byte   Room,Bolts,Wait
+       .byte   RCol,Dcol,Walls,Wp
+]
+;
+BR=Bright
+R.table: RE    01,0,90,Yellow,         Blue,   Purple,1
+RE.len == .-R.table
+       RE      03,1,90,BR+Red,         Blue,   Purple, 1
+       RE      05,2,75,Cyan,           Blue,   Purple, 1
+       RE      07,3,60,BR+Green,       Yellow, BR+Red, 2
+       RE      09,4,45,BR+Blue,        Yellow, BR+Red, 2
+       RE      15,5,40,Purple,         Yellow, BR+Red, 2
+       RE      16,3,25,BR+Green,       Purple, Blue,   3
+       RE      17,4,20,Blue,           Yellow, Green,  4
+       RE      21,5,15,Purple,         Yellow, Green,  4
+       RE      23,5,45,BR+PURPLE,      Blue,   White,  4
+       RE      24,2,15,Cyan,           Blue,   Green,  4
+       RE      25,3,10,BR+Green,       Yellow, Blue,   3
+       RE      27,4,05,Blue,           Purple, BR+Red, 2
+       RE      30,5,05,Purple,         Cyan,   BR+Red, 2
+       RE      00,5,05,Yellow,         Blue,   Cyan,   5
+
+       .end
+
diff --git a/control.asm b/control.asm
new file mode 100644 (file)
index 0000000..34eb2a8
--- /dev/null
@@ -0,0 +1,51 @@
+B>type control.asm
+
+.title "Input control routines"
+.sbttl "FRENZY"
+.ident CONTROLS
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Control input routines
+; generally return z if off, nz if on
+;______________________________
+.insert equs
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      wait for fire button
+;______________________________
+W.Fire::call   S.Fire
+       jrnz    W.Fire          ;if up goto loop
+..Loop: call   S.Fire
+       jrz     ..Loop
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Check Fire button
+;________________________________
+S.Fire::
+       call    S.STICK
+       bit     4,A
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Book-Keeping Switch
+;________________________________
+S.Book::in     ZPU
+       bit     7,A
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Free Credit Switch
+;________________________________
+S.Free::in     ZPU
+       bit     0,A
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Control Stick
+;________________________________
+S.STICK::
+       lda     FLIP
+       ora     a
+       in      I.O1
+       jrz     ..fix
+       in      I.O3
+..fix: cma                     ;convert to positive logic
+       ani     1Fh             ;4 direction, 1 shoot
+       ret
+
+       .end
diff --git a/demo.asm b/demo.asm
new file mode 100644 (file)
index 0000000..06a5dc7
--- /dev/null
+++ b/demo.asm
@@ -0,0 +1,120 @@
+B>type demo.asm
+
+.title "Demo Game"
+.sbttl "FRENZY"
+.ident DEMO
+;~~~~~~~~~~~~~~~~~~
+;    Demo Mode
+;------------------
+.insert equs
+.extern PLAY,ScorePtr
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Play Demo Game
+;-----------------------------
+PLAYDEMO::
+       call    ScorePtr        ;point at players score
+       lxi     d,SavedScore
+       call    ScoreMove
+
+       lhld    Seed
+       push    h
+
+       lxi     h,DemoData      ;fake the control
+       shld    DemoPtr         ; inputs data
+
+       mvi     A,-1            ;set to demo mode
+       sta     Demo
+       xra     a
+       sta     WallPts
+
+       lxi     b,Other-Player  ;move demo setup data
+       lxi     d,Player        ; into player data
+       lxi     h,D.DATA
+       ldir
+
+       call    PLAY            ;play one deaths worth
+
+       pop     h               ;restore random number seed
+       push    psw             ;save button status
+       shld    Seed
+       call    RANDOM          ;do another randomize
+
+       call    ScorePtr        ;restore old player score
+       lxi     d,SavedScore
+       xchg
+       call    ScoreMove
+
+       pop     psw             ;restore button status
+       jmp     DemoRet#
+
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Move Score and Zero Source
+;--------------------------------------
+ScoreMove:
+       mvi     B,3             ;score bytes
+ZapLoop:
+       mov     a,m             ; get score byte
+       mvi     M,0             ;zero it
+       inx     h
+       stax    d               ;store in save area
+       inx     d
+       djnz    ZapLoop
+       ret
+
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Random Number Generator
+;--------------------------------------
+RANDOM::
+       push    h
+       lhld    Seed
+       mov     d,h
+       mov     e,l
+       dad     h
+       dad     d
+       dad     h
+       dad     d
+       lxi     d,3153H
+       dad     d
+       shld    Seed
+       mov     a,h
+       pop     h
+       ret
+
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Demo Game Initialization Data
+;--------------------------------------
+; Player Info Area
+;Player         Player # of this player
+;RoomX  room #
+;ManX   mans room-exit position
+;MPY=   ManX+1
+;DEATHS         # of man lives
+;PERCENT %  of robots
+;Rbolts         # of robot bolts
+;Rtime  robot speed
+;Rwait  robot hold off time
+;STIME  time until otto attacks
+;XtraMen=extra man flags
+;--------------------------------------
+D.DATA: .byte  1       ;Player
+       .byte   20,40   ;RoomX
+       .byte   30      ;ManX
+       .byte   116     ;MPY
+       .byte   1       ;DEATHS
+       .byte   8       ;PERCENT
+       .byte   1       ;Rbolts
+       .byte   32      ;Rwait
+       .byte   4       ;STIME
+       .byte   0       ;XtraMen
+       .byte   8       ;RoomCnt
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Fake Control Input Data
+; if bit 7=1 then it is a delay of(X  7fh) 60ths
+;--------------------------------------
+DemoData:
+.byte  01h,8fh,18H,05H,8Fh,1Ah,14h,02h,9Fh,1Ah,02h,94h,16h,0Ah,92h,16h
+.byte  02h,0BFh,14h,8Fh,09h,9Fh,1Ah,8Fh,14h,8Fh,09h,0BFh,02h,0BFh,14h,8Fh
+.byte  14h,8Fh,0Ah,94h,0Ah,9Fh,02h,0CFh,14H,-1,11h,11h,11h,11h,11h,11h
+.byte  11h,11h,11h,11h,11h,9Fh,12h,04h,9fh,16h,9fh,14h,0,-1,-1,-1
+
+       .end
diff --git a/equs.asm b/equs.asm
new file mode 100644 (file)
index 0000000..21352cc
--- /dev/null
+++ b/equs.asm
@@ -0,0 +1,290 @@
+B>type equs.asm
+
+.slist
+.xlist
+;last revision: 18-Jan-82
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Macros
+;_______________________________
+; multiply b*Num hl=0
+.define MULT[Num]=[
+.ifn Num-1,[   MULT    \(Num/2)
+       dad     h
+]
+.ifn Num&1,[   dad     b
+]]
+.define WAIT[Time]=[
+       mvi     a,time
+       call    J.WAIT#
+]
+.define FORK[Addr]=[
+       lxi     b,Addr
+       call    J.FORK#
+]
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      RAM equates
+;_______________________________
+Hsize  ==      32              ; bytes per line
+Vsize  ==      224             ; lines of screen
+BatteryRAM==   0F800H          ; start of battery ram
+Nibbles ==     0FA00H          ; start of non-backed-up nibbles
+VideoRAM==     4000h           ; start of wait stated ram
+ScreenRAM==    4400H           ; beginning of screen ram
+EndScreen==    5FFFH           ; end of screen ram
+MagicScreen==  ScreenRAM+2000H ; magic screen ram
+ColorRAM==     8000H           ; color ram start
+ColorScreen==  8100H           ; start-ram that colors screen
+EndColor==     87FFH           ; end of color ram
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      VFB IO ports
+;_______________________________
+I.O1   ==      48H             ; Switch ports
+I.O2   ==      49H
+I.O3   ==      4AH
+MAGIC  ==      4BH             ; Shifter/flopper/alu control
+NMION  ==      4CH             ; turns NMIs on
+NMIOFF ==      4DH             ; turns NMIs off
+WHATI  ==      4EH             ; middle/bottom screen status
+I.ENAB ==      4FH             ; enable interrupts=-1
+FLOP   ==      3               ; bit number
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      ZPU IO Ports
+;_______________________________
+DIP2   ==      60H             ; DIP switch bank
+DIP1   ==      61H
+DIP3   ==      62H
+DIP4   ==      63H
+DIP5   ==      64H
+ZPU    ==      65H             ; push buttons bits 7&0
+LED.OFF ==     66H             ; turn LED off
+LED.ON ==      67H             ; turn LED on
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Vector Equates
+;_______________________________
+V.STAT ==      0
+SETUP  ==      1
+O.A.L  ==      2
+O.A.H  ==      3
+O.P.L  ==      4
+O.P.H  ==      5
+TPRIME ==      6
+TIME   ==      7
+V.X    ==      8
+P.X    ==      9
+V.Y    ==      10
+P.Y    ==      11
+D.P.L  ==      12
+D.P.H  ==      13
+VLEN   ==      D.P.H+1         ;length of vector
+MaxVec ==      24
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      V_STAT bits
+;_______________________________
+ERASE  ==      0               ;see INT for documentation
+WRITE  ==      1
+MOVE   ==      2
+BLANK  ==      3
+COLOR  ==      4
+INEPT  ==      5               ;for all hits
+HIT    ==      6               ;for bolt hit
+InUse  ==      7
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Bolt Equates
+;_______________________________
+Bolts  ==      7               ;number of bolts
+Blength ==     3+(6*2)         ;length of entrys
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;       Job Equates
+;_______________________________
+; saves AF,BC,DE,HL,IX,IY,PC
+MaxJob ==      25
+JobLength ==   2*(6+2)         ;save 6 word regs+stack
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;       Man Colors
+;_______________________________
+M1color ==     0AAH
+M2color ==     0EEH
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Battery Ram
+;_______________________________
+; 16 Bit Oriented section
+; (in byte section because its the only ram with no wait states)
+
+       .loc    BatteryRAM
+       .blkb   80h
+SPos   ==      .               ;OS (normal) stack
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Sound Chip Phantom Registers
+;_______________________________
+TCR1:  .blkb   1
+TCR2:  .blkb   1
+TCR3:  .blkb   1
+TMR1:  .blkw   1
+TMR2:  .blkw   1
+TMR3:  .blkw   1
+NOISE: .blkb   1
+VOL1:  .blkb   1
+VOL2:  .blkb   1
+VOL3:  .blkb   1
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Sound Interpreter Vars
+;_______________________________
+PC0:   .blkw   1
+PC1:   .blkb   1               ;priority of sound
+WLSND: .blkb   1               ;non0 if a wall hit
+RFSND: .blkb   1               ;non0 if reflected bolt
+AC0:   .blkw   1
+AC1:   .blkw   1
+AC2:   .blkw   1
+AC3:   .blkw   1
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Voice Vars
+;_______________________________
+V.PC:  .blkw   1               ;voice pc
+T.TMR: .blkb   1               ;time until next talk
+CHIKEN: .blkb  1               ;chicken flag
+MemPhs: .blkb  1               ;not used
+PSave: .blkb   1               ;for bonus/percent store
+Man.Alt:.blkb  1               ;man alternator for when to do job
+KWait: .blkb   1               ;time til kill off
+Dcolor: .blkb  1               ;square dot color
+       .blkb   8               ;filler
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      COLOR routines area
+;_______________________________
+Caddr: .blkb   2               ;address of last man write
+Csave: .blkb   2*6             ;save/restore area
+Wpoint: .blkb  1               ;points for a wall hit
+Wcolor: .blkb  1               ;walls color
+Rcolor: .blkb  1               ;color of robots
+Mcolor: .blkb  1               ;man's color
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Vector area
+;_______________________________
+V.Ptr: .blkw   1               ;pointer to next vector
+L.Ptr: .blkw   1               ;pointer to robot vector list
+Old1:  .blkw   1               ;addresses of vectors rewritten
+Old2:  .blkw   1               ; in this 
+Old3:  .blkw   1               ;  interrupt
+IntTyp: .blkb  1               ;alternater (55h)
+T60cnt: .blkb  1               ;second timer
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Book-keeping Data Area
+;_______________________________
+       .blkb   1               ;xsum
+CREDITS:.blkb  2
+       .blkb   1               ;xsum
+Chute1: .blkb  8
+       .blkb   1               ;xsum
+Chute2: .blkb  8
+       .blkb   1               ;xsum
+Play1: .blkb   6
+       .blkb   1               ;xsum
+Play2: .blkb   6
+       .blkb   1               ;xsum
+Plays: .blkb   6
+       .blkb   1               ;xsum
+ScoreSum:.blkb 12
+       .blkb   1               ;xsum
+PlayTime:.blkb 12
+       .blkb   1               ;xsum
+OnTime: .blkb  12
+       .blkb   1               ;xsum
+High2: .blkb   5*12
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Screen RAM Data Area
+;_______________________________
+       .loc    VideoRAM
+Temp:  .blkw   2               ;buffer zone
+NMIflg: .blkb  1               ;used by powerup
+PlayRet:.blkw  1               ;return address for play
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Player Information Area
+;_______________________________
+Player: .blkb  1               ;Player # of this player
+RoomX: .blkb   1               ;room X position
+RoomY: .blkb   1               ;room Y position
+ManX:  .blkb   1               ;copy of man position
+ManY:  .blkb   1
+Deaths: .blkb  1               ;number of lives/deaths for player
+Percent:.blkb  1               ;Percentage factor for game
+Rbolts: .blkb  1               ;# of robot bolts
+Rwait: .blkb   1               ;initial firing holdoff time
+Stime: .blkb   1               ;super robot wait time
+XtraMen:.blkb  1               ;xtra man flags
+RoomCnt:.blkb  1               ;# of rooms exitted
+; Other Player Info Area
+Other: .blkb   Other-Player    ;Non playing persons records
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Misc area
+;_______________________________
+Robots: .blkb  1               ;# of robots
+Rsaved: .blkb  1               ;saved # of robots
+N.Plrs: .blkb  1               ;# of players in this game
+Flip:  .blkb   1               ;flip screen=-1
+IQflg: .blkb   1               ;-1 head toward man
+SSpos: .blkw   1       ;super start position
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Walls Array
+;_______________________________
+Walls: .blkb   4*6             ;array of wall DURL bits by squares
+       .blkb   4*6             ;type array
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Coins Area
+;_______________________________
+StartB: .blkb  1               ;start button tracker
+Coins: .blkb   2               ;number of coins not counted yet
+SWD:   .blkb   2               ;switch trackers
+;only need 1 byte for cackle
+CACKLE: .blkb  3               ;partial credit accumulators
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Demo Area
+;_______________________________
+Demo:  .blkb   1               ;flag =-1 if in demo
+SavedScore:.blkb 3             ;saves player score
+DemoPtr:.blkb  2               ;-> fake control data
+Seed:  .blkb   2               ;random number seed
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Score Area
+;_______________________________
+WallPts: .blkb 1               ;points for wall
+UPDATE: .blkb  1               ;has score been updated
+Score1: .blkb  3               ;player 1's score
+Score2: .blkb  3               ;player 2's score
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Interrupt Area
+;_______________________________
+HIGH1: .blkb   6*10            ;high score to date display
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Interrupt Area
+;_______________________________
+O.I.SP: .blkw  1               ;old stack storage
+M.COLOR:.blkb  1               ;color of man
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Vector area
+;_______________________________
+Vectors:.blkb  MaxVec*VLEN     ;area for vectors
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Job Area
+;_______________________________
+J.Used: .blkb  1               ;# of jobs in use
+J.Index:.blkb  1               ;pointer to current job
+Jobs:  .blkb   MaxJob*JobLength
+VRend  ==      .
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Color Ram Area
+;_______________________________
+       .loc    ColorRam
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Timers Area
+;_______________________________
+MaxTimer==     24
+Talloc: .blkb  MaxTimer/8
+Timer0: .blkb  MaxTimer
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Bolt Vectors
+;_______________________________
+BUL1:  .blkb   Bolts*Blength
+
+       .loc    .PROG.
+.rlist
diff --git a/factory.asm b/factory.asm
new file mode 100644 (file)
index 0000000..cbcd465
--- /dev/null
@@ -0,0 +1,515 @@
+B>type factory.asm
+
+.title "Robot Factory & MaMa Otto"
+.sbttl "FRENZY"
+.ident FACTORY
+.insert equs
+.extern RtoAx,PLOT,V.ZERO
+; MACROS
+RD=8   ;room drop
+XX=120+RD      ;x of left edge
+YY=48+RD       ;y of top corner
+.define START[Pat,Xoff,Yoff]=[
+       lxi     h,Pat#
+       lxi     d,((Yoff+YY)<8)!(Xoff+XX)
+       call    %START
+]
+.define DRAW[Pat,Xoff,Yoff]=[
+       lxi     d,Pat#
+       lxi     h,((Yoff+YY)<8)!(Xoff+XX)
+       call    %DRAW
+]
+.define COLOR[Ctable]=[
+       lxi     h,Ctable
+       call    %Color
+]
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      ROBOT FACTORY
+;_______________________________
+FACTORY::
+       lda     RoomCnt
+       bit     3,a
+       jz      ..8
+       bit     2,a
+       jz      Plant           ;do mama otto 1
+       jmp     Compu           ;2
+..8:   bit     2,a
+       jnz     MaMa            ;2
+; 4-factory is farthest
+       COLOR   FCOLS
+       DRAW    PTA,3,3
+       DRAW    PTB,4,18
+       DRAW    PTC,12,16
+; 4 vectored parts (Conveyor,Handle,WhirlCCW,WhirlCW)
+       START   C.IDLE,8,8
+       START   H.IDLE,28,32
+       START   W.CCW,14,29
+       mvi     TPRIME(x),1
+       START   W.CW,19,36
+       mvi     TPRIME(x),1
+       pop     B               ;wcw save vector pointers
+       pop     B               ;wccw
+       pop     D               ;handle
+       pop     X               ;conveyor
+..n:   call    NEXT.J#
+       lda     Robots
+       ora     a
+       jm      ..go
+       cpi     13
+       jrnc    ..n
+; start one up
+..go:  lxi     h,C.PART#       ;go conveyor
+       call    ChangePat               
+       WAIT    50
+       push    d               ;ex ix,iy
+       xtix
+       pop     d
+       lxi     h,H.GO#
+       call    ChangePat
+       WAIT    60
+       FORK    FROBOT#
+       WAIT    90
+       lxi     h,H.IDLE#
+       Call    ChangePat
+       push    d               ;ex ix,iy
+       xtix
+       pop     d
+       WAIT    30              ;idle
+       jmpr    ..n
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Mother Otto
+;_______________________________
+MaMa:  call    M.TALK#
+       COLOR   MCOLS
+       DRAW    MAL,4,4
+       DRAW    MAR,20,4
+       call    Sleep
+..sl:  call    NEXT.J
+       lda     CACKLE+1        ;ottos hit
+       ora     a
+       jrnz    ..xsl           ;stay asleep
+       lda     Vectors         ;check on man
+       bit     INEPT,a
+       jrz     ..sl
+       call    UnM
+       jmpr    ..xdl
+..xsl: call    Sleep           ;erase old
+       call    Angry
+       lxi     d,(82<8)!110
+       FORK    MSUPER#
+       lxi     d,(82<8)!170
+       FORK    MSUPER
+       lxi     d,(40<8)!148
+       FORK    MSUPER
+       lxi     d,(90<8)!148
+       FORK    MSUPER
+..dl:  call    NEXT.J
+       lda     Vectors         ;check on man
+       bit     INEPT,a
+       jrz     ..dl
+       call    AngryM          ;erase old mouth
+..xdl: call    Smile   
+       jmp     JobDEL#         ;no need for me any more
+;draw smile
+Smile: DRAW    MASML,4,30
+       DRAW    MASMR,20,30
+       RET
+;draw eyes and mouth angry
+Angry: DRAW    MAEL,11,9
+       DRAW    MAER,21,9
+       COLOR   ECOLS
+AngryM: DRAW   MAFL,4,30
+       DRAW    MAFR,20,30
+       ret
+;draw eyes and mouth sleep
+Sleep: DRAW    MASL,4,13
+       DRAW    MASR,20,13
+UnM:   DRAW    MAM,12,30
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Electric Plant
+;_______________________________
+Plant:
+       COLOR   PLCOLS
+       call    UnReflect
+       DRAW    BULB,8,4
+       DRAW    BULB,8,20
+       DRAW    BULB,28,12
+       DRAW    STALK,28,28
+       DRAW    RFILL,3,36
+       DRAW    FILL,16,36
+       DRAW    RFILL,28,36
+; 4 vectored parts (W.CW,W.CCW,TL,BL)
+       START   TL,12,7
+       mvi     TPRIME(x),1
+       START   BL,12,16
+       mvi     TPRIME(x),1
+       START   W.CCW,8,38
+       mvi     TPRIME(x),1
+       START   W.CW,28,38
+       mvi     TPRIME(x),1
+; save vector pointers
+       pop     b
+       pop     d
+       pop     h
+       pop     x
+..loop: call   NEXT.J
+       call    HitChk
+       jrz     ..loop
+..Hit: di
+       ldax    b               ;stop the whirlies
+       res     MOVE,a
+       stax    b
+       ldax    d
+       res     MOVE,a
+       stax    d
+       mov     a,m
+       ani     #((1<MOVE)!(1<WRITE))
+       mov     m,a
+       mov     a,V.STAT(x)
+       ani     #((1<MOVE)!(1<WRITE))
+       mov     V.STAT(x),a
+       ei
+       mvi     a,2
+       sta     IqFlg           ;go for slow moving
+       lxi     b,201h          ;100
+       call    ADDS#
+       jmp     JobDel#
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Computer Control
+;_______________________________
+Compu:
+       COLOR   CPCOLS
+       call    UnReflect
+       DRAW    RTL,4,12
+       DRAW    LTL,24,12
+       DRAW    Nose,18,15
+; 3 vectored parts (CMS,TRCCW,TRCCW)
+       START   CMS,16,2
+       mvi     TPRIME(x),1
+       START   CMouth,12,28
+       START   TRCCW,4,4
+       mvi     TPRIME(x),1
+       START   TRCCW,30,4
+       mvi     TPRIME(x),1
+; save vector pointers
+       pop     x
+       pop     h
+       pop     d               ;mouth
+       pop     b               ;message
+..loop: call   NEXT.J
+       call    HitChk
+       jrz     ..loop
+..Hit: di                      ;stop tape reels
+       ldax    b               ;stop message
+       ani     #(1<MOVE)
+       stax    b
+       mov     a,m
+       ani     #(1<MOVE)
+       mov     m,a
+       mov     a,V.STAT(x)
+       ani     #(1<MOVE)
+       mov     V.STAT(x),a
+;do mouth
+       push    d
+       pop     x
+       lxi     h,CMDIE#
+       mov     D.P.H(x),h
+       mov     D.P.L(x),l
+       ei
+       mvi     a,5             ;no shoot/iq
+       sta     IqFlg           ;go for Crasho
+       lxi     b,201h          ;100
+       call    ADDS#
+       call    C.TALK#
+       jmp     JobDel#
+;~~~~~~~~~~~~~~~~~~~~
+; Check for man bolts
+;____________________
+PX=1
+PY=2
+HitChk: lxi    y,BUL1
+       call    HC
+       lxi     y,BUL1+BLength
+       call    HC
+       xra     a
+       ret
+;
+HC:    mov     a,PX(y)
+       cpi     XX
+       rc
+       cpi     XX+40
+       rnc
+       mov     a,PY(y)
+       cpi     YY
+       rc
+       cpi     YY+46
+       rnc
+       inx     sp      ;drop return address
+       inx     sp
+       ret             ;nz
+;~~~~~~~~~~~~~~~~~~~~
+; Unreflecto the area
+;____________________
+UnReflect:
+       lda     Flip
+       ora     a
+       jrnz    %FUC
+
+       lxi     x,82b0h
+       lxi     d,Hsize
+       call    lin0
+       mvi     b,11
+       call    sid0
+       call    lin0
+; write grapes on wall
+Wallo: di
+       lxi     h,3480h         ;((YY-4)<8)!XX
+       push    h
+       call    HWB#
+       pop     h
+       call    VWB#
+       lxi     h,34a8h         ;((YY-4)<8)!(XX+40)
+       call    VWB
+       lxi     h,6480h         ;((YY+44)<8)!XX
+       call    HWB
+       ei
+       ret
+;flip style
+%FUC:  lxi     x,864fh         ;flip version
+       lxi     d,-Hsize
+       call    lin1
+       mvi     b,11
+       call    sid1
+       call    lin1
+       jmp     wallo
+;
+Lin0:  mvi     b,5
+       push    x
+       pop     h
+       lda     Wcolor
+..loop: mov    m,a
+       inx     h
+       djnz    ..loop
+       mvi     b,1
+;      jmp     Sid0
+;
+Sid0:  lda     Wcolor
+       ani     0F0h
+       mov     c,a
+..loop: mov    a,0(x)
+       ani     0Fh
+       ora     c
+       mov     0(x),a
+       mov     a,5(x)
+       ani     0Fh
+       ora     c
+       mov     5(x),a
+       dadx    d
+       djnz    ..loop
+       ret
+;
+Lin1:  mvi     b,5
+       push    x
+       pop     h
+       lda     Wcolor
+..loop: mov    m,a
+       dcx     h
+       djnz    ..loop
+       mvi     b,1
+;      jmp     sid1
+;
+Sid1:  lda     Wcolor
+       ani     0Fh
+       mov     c,a
+..loop: mov    a,0(x)
+       ani     0F0h
+       ora     c
+       mov     0(x),a
+       mov     a,-5(x)
+       ani     0F0h
+       ora     c
+       mov     -5(x),a
+       dadx    d
+       djnz    ..loop
+       ret
+;~~~~~~~~~~~~~~~~~~~~
+; Color the area
+;____________________
+%Color:                        ;FIX FOR COCKTAIL
+       lda     Flip
+       ora     a
+       jrnz    %FC
+       lxi     x,82B0h
+       lxi     d,Hsize-5
+       mvi     c,12
+..y:   mvi     b,5
+..x:   mov     a,m
+       inx     h
+       mov     0(x),a
+       inx     x
+       djnz    ..x
+       dadx    d
+       dcr     c
+       jrnz    ..y
+       ret
+;
+%FC:   lxi     x,864fh         ;flip version
+       lxi     d,-Hsize+5
+       mvi     c,12
+..y:   mvi     b,5
+..x:   mov     a,m
+       inx     h
+       rlc
+       rlc
+       rlc
+       rlc
+       mov     0(x),a
+       dcx     x
+       djnz    ..x
+       dadx    d
+       dcr     c
+       jrnz    ..y
+       ret
+;~~~~~~~~~~~~~~~~~~~~~
+; Change (ix) pattern
+;_____________________
+ChangePat:
+       di
+       mov     D.P.L(x),l
+       mov     D.P.H(x),h
+       ei
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~
+; Draw does the xor write
+;_________________________
+;de=pattern hl=yx
+%DRAW: di
+       call    RtoAx
+       xchg
+       call    PLOT
+       ei
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Start a sub part
+; push ix on stack on exit
+%START:
+       push    d
+       push    h
+       call    V.ZERO#
+       pop     h
+       pop     d
+       rc
+       mov     P.X(x),e
+       mov     P.Y(x),d
+       mov     D.P.L(x),l
+       mov     D.P.H(x),h
+       mvi     TIME(x),1
+       mvi     TPRIME(x),2
+       mvi     V.STAT(x),(1<InUse)!(1<Move)!(1<Write)  
+       pop     h               ;get return address
+       push    x               ;save vector pointer
+       pchl                    ;return 
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Set up a square around box 9
+;_______________________________
+DOWN=3
+UP=2
+RIGHT=1
+LEFT=0
+S.ROOM::
+       lxi     x,Walls         ;set up walls
+;reflecto
+       set     DOWN,24+9(x)
+       set     UP,24+9(x)
+       set     RIGHT,24+9(x)
+       set     LEFT,24+9(x)
+       set     DOWN,24+3(x)
+       set     UP,24+15(x)
+       set     RIGHT,24+8(x)
+       set     LEFT,24+10(x)
+;set walls
+       set     DOWN,9(x)
+       set     UP,9(x)
+       set     RIGHT,9(x)
+       set     LEFT,9(x)
+       set     DOWN,3(x)
+       set     UP,15(x)
+       set     RIGHT,8(x)
+       set     LEFT,10(x)
+;ocupied
+       set     InUse,9(x)
+       res     DOWN,24+15(x)           ;make sure there is
+       res     UP,24+21(x)             ;a shootable area under
+       res     RIGHT,24+14(x)
+       res     LEFT,24+15(x)
+       res     RIGHT,24+15(x)
+       res     LEFT,24+16(x)
+       ret                             ;the factory
+;----------------------------
+FCOLS: .byte   77h,77h,77h,77h,77h     ;top
+       .byte   77h,77h,77h,77h,77h     ;0
+       .byte   77h,55h,55h,55h,77h     ;1
+       .byte   77h,55h,55h,55h,77h     ;2
+       .byte   77h,55h,55h,55h,77h     ;3
+       .byte   74h,41h,11h,13h,33h     ;4
+       .byte   74h,46h,66h,63h,33h     ;5
+       .byte   74h,46h,66h,63h,33h     ;6
+       .byte   74h,46h,66h,63h,33h     ;7
+       .byte   74h,46h,66h,63h,33h     ;7
+       .byte   74h,46h,66h,63h,33h     ;7
+       .byte   74h,46h,66h,63h,33h     ;7
+
+MCOLS: .byte   77h,77h,77h,77h,77h     ;top
+       .byte   73h,33h,33h,33h,33h     ;0
+       .byte   73h,33h,33h,33h,33h     ;1
+       .byte   73h,33h,33h,33h,33h     ;2
+       .byte   73h,33h,33h,33h,33h     ;3
+       .byte   73h,33h,33h,33h,33h     ;4
+       .byte   73h,33h,33h,33h,33h     ;5
+       .byte   73h,33h,33h,33h,33h     ;6
+       .byte   73h,33h,33h,33h,33h     ;7
+       .byte   73h,33h,33h,33h,33h     ;8
+       .byte   73h,33h,33h,33h,33h     ;9
+       .byte   73h,33h,33h,33h,33h     ;9
+
+ECOLS: .byte   77h,77h,77h,77h,77h     ;top
+       .byte   73h,33h,33h,33h,33h     ;0
+       .byte   73h,33h,33h,33h,33h     ;1
+       .byte   73h,33h,33h,33h,33h     ;2
+       .byte   73h,33h,33h,33h,33h     ;3
+       .byte   73h,31h,33h,13h,33h     ;4
+       .byte   73h,33h,33h,33h,33h     ;5
+       .byte   73h,33h,33h,33h,33h     ;6
+       .byte   73h,33h,33h,33h,33h     ;7
+       .byte   73h,33h,33h,33h,33h     ;8
+       .byte   73h,33h,33h,33h,33h     ;9
+       .byte   73h,33h,33h,33h,33h     ;9
+
+CPCOLS: .byte  77h,77h,77h,77h,77h     ;top
+       .byte   76h,66h,22h,26h,66h     ;0
+       .byte   76h,66h,22h,26h,66h     ;1
+       .byte   76h,66h,22h,26h,66h     ;2
+       .byte   76h,66h,0cch,0c6h,66h   ;3
+       .byte   7ch,3ch,33h,3ch,3ch     ;4
+       .byte   7ch,3ch,33h,3ch,3ch     ;5
+       .byte   7ch,3ch,11h,1ch,3ch     ;6
+       .byte   7ch,3ch,11h,1ch,3ch     ;7
+       .byte   7ch,3ch,11h,1ch,3ch     ;8
+       .byte   7ch,3ch,11h,1ch,3ch     ;9
+       .byte   7ch,0cch,11h,1ch,0cch   ;9
+
+PLCOLS: .byte  77h,77h,77h,77h,77h     ;0
+       .byte   73h,33h,33h,33h,33h     ;1
+       .byte   73h,33h,55h,53h,33h     ;2
+       .byte   73h,33h,55h,53h,33h     ;3
+       .byte   73h,66h,55h,53h,33h     ;4
+       .byte   73h,66h,55h,53h,33h     ;5
+       .byte   73h,33h,55h,56h,63h     ;6
+       .byte   73h,33h,55h,56h,63h     ;7
+       .byte   73h,66h,55h,56h,63h     ;8
+       .byte   73h,66h,55h,56h,63h     ;9
+       .byte   77h,77h,77h,77h,77h     ;10
+       .byte   73h,33h,33h,33h,33h     ;11
+
+       .end
diff --git a/gameover.asm b/gameover.asm
new file mode 100644 (file)
index 0000000..433da39
--- /dev/null
@@ -0,0 +1,277 @@
+B>type gameover.asm
+
+.title "Game Over Show"
+.sbttl "FRENZY"
+.ident GOVER
+;~~~~~~~~~~~~~~~~~~~~~~~
+;      game over
+;_______________________
+.insert equs
+.intern GOVER,CLEAR,INSERT
+.intern LINE,LTABLE
+.extern SHOWN,SHOWO,SHOWA,SHOWC,GETC,CREDS,SHOWS
+.extern C.GO,C.L1,C.L2,C.LI,PH1,NoVoice,Zap
+
+; macros
+.define WROTE[Magic,X,Y,String]=[
+       call    SHOWA
+       .byte   Magic,X,Y
+       .asciz  String
+]
+; language tabled subroutine call
+.define LANG[Name]=[
+       call    LTABLE
+       .word   E.'Name         ;;English
+       .word   G.'Name         ;;German
+       .word   F.'Name         ;;French
+       .word   S.'Name         ;;Spanish
+]
+; equates
+S.END  ==      EndScreen
+LINE1  ==      190
+;---------------------------------+
+; clear screen and show copyright |
+;---------------------------------+
+GOVER: call    CLEAR           ; erase.screen
+       call    C.GO            ; setup color gameover
+       call    CREDS           ;show credits
+       call    SHOWS           ;show scores
+;----------------------------+
+; show high scores and names |
+;----------------------------+
+       call    SmallTitle#     ;FRENZY
+       LANG    High
+       lxi     h,56*Hsize+Screen       ; start position
+       call    LINE
+       lxi     h,HIGH1         ; first high score
+       mvi     A,1
+       sta     TEMP            ; number 1 line
+       lxi     d,63<8!64       ; YX position
+..loop: push   d
+       push    h
+       mov     a,m             ;if score is zero dont show it
+       inx     h
+       ora     m
+       inx     h
+       ora     m
+       pop     h
+       push    h
+       jrnz    ..skip
+       pop     h
+       pop     d
+       jmpr    DRAW
+..skip: lxi    h,TEMP          ; shown line number
+       mvi     B,2             ; 2 digits long
+       call    SHOWN
+       inx     d               ; spc over one byte
+       pop     h
+       mvi     B,6             ; shown high score,6digits
+       call    SHOWO
+       inx     d               ;space over
+       xra     a               ;plop write
+       mov     c,m
+       call    SHOWC
+       inx     d
+       inx     h
+       mov     c,m
+       call    SHOWC
+       inx     d
+       inx     h
+       mov     c,m
+       call    SHOWC
+       inx     h               ; -> next high score
+       pop     d
+       mov     a,d
+       ADI     12
+       mov     d,a
+       lda     TEMP
+       ADI     1
+       daa
+       sta     TEMP
+       cpi     11H
+       jnz     ..loop
+;------------+
+; draw lines
+;------------+
+DRAW:  lxi     h,184*Hsize+Screen
+       call    LINE
+       lxi     h,204*Hsize+Screen
+;      call    line
+;      2
+;------------------+
+; draw line across |
+;------------------+
+LINE:  mvi     A,0FFH
+       mvi     B,64
+L.LOP: mov     m,a
+       inx     h
+       djnz    L.LOP
+       ret
+;--------------+
+; erase screen |
+;--------------+
+CLEAR: lxi     h,ColorScreen
+       lxi     b,700H
+       call    Zap
+       di
+       sspd    Temp
+       lxi     sp,S.END+1
+       mvi     B,Vsize
+       lxi     d,0
+E.L:   push    d
+       push    d
+       push    d
+       push    d
+       push    d
+       push    d
+       push    d
+       push    d
+       push    d
+       push    d
+       push    d
+       push    d
+       push    d
+       push    d
+       push    d
+       push    d
+       djnz    E.L
+       lspd    Temp
+       ei
+; set flip state by player number
+SFLIP: in      I.O3            ;is it a cocktail
+       bit     7,A
+       jrnz    Normal          ;if not cocktail
+       lda     PLAYER          ;is cocktail version
+       cpi     2               ;flip screen? for player2
+       jrnz    Normal
+       mvi     A,8             ;the flip bit
+       sta     FLIP
+       ret
+Normal: xra    a
+       sta     FLIP
+       ret
+; Copyright
+CopyR:: call   SHOWA                   ; @ 1980 stern electronics
+       .byte   90H
+       .byte   12,LINE1,1FH
+       .asciz  "1982 STERN Electronics, Inc."
+       ret
+;---------------------------+
+; insert coin / press start |
+;---------------------------+
+INSERT: CALL   LERASE          ;erase line for text
+       call    GETC            ;get credits
+       jrz     INSSS
+       dcr     a
+       jrz     PRESS1
+       call    C.L2
+       LANG    Pus2
+       ret
+;
+PRESS1: CALL   C.L1
+       LANG    Push1
+       ret
+;
+INSSS: call    C.LI
+       LANG    In
+; coins detected in pocket
+       lxi     h,PH1           ;phrase
+       shld    V.PC            ;into voice pc
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~
+; xtra man level 
+;__________________________
+XMLEV:: call   LERASE
+       in      Dip2
+       ani     15              ;# of k for extra man
+       jrz     ..cheap
+       mov     b,a
+       ani     8
+       mov     c,a
+       mov     a,b
+       ani     7
+       add     c
+       daa                     ;now its in BCD
+       sta     TEMP
+       lxi     d,LINE1<8!88    ; y:x position
+       lxi     h,TEMP          ; number
+       mvi     B,2             ; 2 digits long
+       call    SHOWN           ; show it
+       WROTE   90h,104,LINE1,"000 = ~"
+       ret
+..cheap:
+       WROTE   90H,72,LINE1,"No Extra Lives"
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~
+; erase line for messages
+;__________________________
+LERASE: lxi    h,LINE1*Hsize+Screen
+       lxi     b,2C0H          ;2 lines less than 16
+       xra     a
+LELE:  mov     m,a
+       inx     h
+       dcr     c
+       jnz     LELE
+       djnz    LELE
+       ret
+;---------------------------------+
+; Language tabled subroutine call |
+;---------------------------------+
+LTABLE: pop    h               ;get table address
+       mov     d,h
+       mov     e,l             ;save table address
+       lxi     b,8             ;offset to end of table
+       dad     b               ;calc return address
+       push    h               ;put return address on stack
+       xchg                    ;get table address
+       in      diP2            ;get language bits
+       ani     0C0H
+       rlc                     ;rotate bits into low bits
+       rlc
+       rlc                     ;A=language#*2
+       mov     c,a             ;BC=language#*2
+       dad     b               ;address into table
+       mov     a,m             ;get low address
+       inx     h
+       mov     h,m             ;get high address
+       mov     l,a             ;HL=subroutine address
+       pchl
+;------+
+; Text |
+;------+
+E.High: WROTE  90H,80,42,"High Scores"
+       ret
+F.High: WROTE  90H,68,42,"Meilleur Score"
+       ret
+G.High: WROTE  90H,60,42,"Hoechster Gebnis"
+       ret
+S.High: WROTE  90H,96,42,"Records"
+       ret
+;-------------------------
+E.Push1: WROTE 90H,20,LINE1,"Push 1 Player Start Button"
+       ret
+F.Push1: WROTE 90H,36,LINE1,"Pousser bouton start 1"
+       ret
+;-------------------------
+E.Pus2: WROTE  90H,4,LINE1,"Push 1 or 2 Player Start Button"
+       ret
+F.Pus2: WROTE  90H,16,LINE1,"Pousser bouton start 1 ou 2"
+       ret
+G.Push1:
+G.Pus2: WROTE  90H,32,LINE1,"Startknoepfe druecken"
+       ret
+S.Push1:
+S.Pus2: WROTE  90H,68,LINE1,"Pulsar Start"
+       ret
+;-----------------
+E.In:  WROTE   90H,88,LINE1,"Insert Coin"
+       ret
+F.In:  WROTE   90H,48,LINE1,"Introduire la monnaie"
+       ret
+G.In:  WROTE   90H,72,LINE1,"Munze einwerfen"
+       ret
+S.In:  WROTE   90H,72,LINE1,"Ponga la moneda"
+       ret
+
+       .end
+
diff --git a/init.asm b/init.asm
new file mode 100644 (file)
index 0000000..58dc787
--- /dev/null
+++ b/init.asm
@@ -0,0 +1,450 @@
+B>type init.asm
+
+.title "INTERRUPT ROUTINE"
+.sbttl "FRENZY"
+.ident INT
+;--------------------
+; interrupt routine
+;--------------------
+.insert equs
+.intern INT,PLOT
+.extern RtoA
+;---------------------------------------
+; this routine does writing, erasing,
+; moving, and pattern animation based
+; on the following structure
+;      ---- v.stat     vector status   <- IY points here
+;      ---- setup      last magic value
+;   -------- o.a.l/h   old screen address
+;   -------- o.p.l/h   last pattern addr.
+;      ---- tprime     value to stuff into time
+;      ---- time       time til move
+;      ---- v.x        x velocity
+;      ---- v.y        y velocity
+;      ---- p.x        x position
+;      ---- p.y        y position
+;   -------- d.p.l/h   pattern pointer
+;--------------------------------------
+INT:   out     NMIOFF          ;turn off nmi's
+       di                      ;believe it [cuz of calls]
+       push    psw
+       in      WHATI           ;bottom of screen?
+       rar                     ;test bit 0
+       jrc     BS              ;skip if middle of screen
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;  Middle of Screen Interrupt
+;_______________________________
+; use only AF,BC,HL
+       out     NMION           ;prob get nmi immed'ly
+       push    h               ;save em
+       push    b
+       lxi     h,SWD           ; check coins
+       mov     a,m             ;oldset switch
+       inx     h
+       mov     b,m             ;old sw.
+       xra     b               ;difference in a
+       mov     c,a             ; in c
+       in      I.O2            ;new sw.s
+       cma
+       mov     m,a             ;store new switch
+       dcx     h
+       mov     m,b             ;make old->oldest
+       ana     c               ;check new=1 old=1 oldest=0
+       ani     0c0H
+..lp:  dcx     h               ;->cackle
+       bit     7,a             ; check bit
+       jrz     ..sk
+       inr     m               ;inc coin counter
+..sk:  add     a               ;shift bits
+       jrnz    ..lp
+; update man alternator
+       lxi     h,Man.Alt
+       srlr    m
+;take care of seconds counter
+       lxi     h,T60cnt
+       dcr     m
+       jp      ..ous
+       mvi     m,60            ;reset seconds timer
+       mvi     c,8             ;inc total seconds in backgnd
+       call    ItemInc#        ;pushes all reg used
+       lda     DEMO
+       ora     a
+       mvi     c,7             ;total game time
+       cz      ItemInc
+       lxi     h,KWait         ;adjust kill off
+       mov     a,m
+       ora     a
+       jrz     ..ous
+       dcr     a
+       mov     m,a
+..ous: call    GetC#           ;if no credits
+       mvi     L,0
+       ora     a               ;skip to waiter
+       jrz     I.but
+       cpi     1               ;if only one credit
+       mvi     L,1             ;then check only button1
+       jrz     I.but
+       mvi     L,3
+I.but: in      I.O2            ;check start button[s]
+       cma
+       ana     l
+       mov     l,a             ;save buttons
+       lda     StartB          ;previous buttons
+       ora     l
+       sta     StartB          ;save for main
+       jz      ..exit
+       bit     7,a             ;in play flag
+       jz      GO#             ;go play NOW
+..exit: pop    b
+       pop     h
+       jmp     BYE
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Bottom of Screen Interrupt
+;_______________________________
+BS:    push    y               ;save old jobs
+       push    x
+       push    h
+       push    d
+       push    b
+       exaf
+       push    psw
+;< do color man every 4 int?>
+       lxi     h,0             ;null vector pointer
+       shld    OLD1
+       shld    OLD2
+       shld    OLD3
+       lxi     h,Inttyp        ;test alternator
+       rlcr    m               ;by rotating the bits
+       mvi     b,3             ;do 2 others if no man
+       lhld    L.PTR           ;robot list pointer
+       jc      ..ilp
+       lxi     h,Vectors
+       shld    Old3            ;save for updates
+       call    SECT1           ;rewrite man
+       call    UNCMAN#         ;uncolor man
+       lxi     h,Vectors
+       bit     COLOR,m         ;do color
+       cnz     COLMAN#
+       lhld    L.PTR           ;robot list pointer
+       mvi     b,2             ;# of robots to do
+..ilp: push    b
+       call    SECT1           ;rewrite robot
+       pop     b
+       lhld    V.PTR           ;Get vector pointer
+; save pointer for later update
+       xchg
+       mov     a,b             ;get index
+       add     a               ;double
+       lxi     h,Old1-2        ;save array start
+       add     l               ;add b*2 to hl
+       mov     l,a
+       mov     a,h
+       aci     0
+       mov     h,a
+       mov     m,e             ;store vector address
+       inx     h               ;for later update
+       mov     m,d
+       xchg
+..inc: lxi     d,VLEN          ;delta to next vector
+       dad     d               ;point to next
+       lxi     d,Vectors+(MaxVec*VLEN) ;end of list
+       mov     a,l             ;see if at end
+       cmp     e
+       jnz     ..tst
+       mov     a,h
+       cmp     d
+       jz      ..end
+..tst: mov     a,m             ;see if vector is on
+       ani     (1<INUSE)
+       jrz     ..inc           ;if not look at another
+       djnz    ..ilp
+       jmp     ..done
+..end: lxi     h,Vectors+VLEN  ;first non-man vector
+..done: shld   L.PTR           ;next one to look at
+       call    BUL.V#          ;rewrite & vector bolts
+; now that bolts have done hitting things
+; update Vectors (coordinates)
+       lhld    OLD3            ;first vector written
+       call    SECT3
+       lhld    OLD2
+       call    SECT3
+       lhld    OLD1            ;last vector written
+       call    SECT3           ;update animation and vector
+       call    TIMERS          ;do job timers
+       pop     psw             ;restore all registers
+       exaf
+       pop     b
+       pop     d
+       pop     h
+       pop     x
+       pop     y
+BYE:   mvi     A,1             ;turn on interrupts
+       out     I.ENAB
+       out     NMION           ;prob get nmi immed'ly
+       mvi     A,ITAB/256
+       stai
+       im2
+       pop     psw
+       ei
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; all below assume iy -> vector
+;      and [v.ptr]=iy
+;----------------
+; erase pattern
+;________________
+SECT1: shld    V.PTR
+       liyd    V.PTR
+       bit     ERASE,M         ;hl->v.stat
+       jz      SECT2
+       res     ERASE,M         ;never erase more than once
+       inx     h               ;->setup
+       mov     a,m             ;get old magic value
+       out     MAGIC
+       inx     h               ;->old address
+       mov     e,m
+       inx     h               ;->o.a.h
+       mov     d,m
+       inx     h               ;->old pattern
+       mov     a,m             ;hl:=[hl]
+       inx     h               ;->o.a.h
+       mov     h,m
+       mov     l,a
+       call    PLOT            ;xor write
+       lhld    V.PTR
+;----------------
+; write pattern
+;----------------
+SECT2: bit     WRITE,M         ;check if should write
+       rz
+       res     WRITE,M         ;never write twice either
+       lxi     d,P.X
+       dad     d               ;->p.x
+       mov     e,m             ;x position
+       inx     h               ;->v.y
+       inx     h               ;->p.y
+       mov     d,m             ;y position
+       inx     h
+       mvi     B,90H           ;xor write
+       xchg
+       call    RtoA
+       mov     SETUP(y),A      ;save magic
+; get pattern address := @pattern.pointer
+       xchg
+       mov     a,m             ;->d.p.l
+       inx     h
+       mov     h,m             ;->d.p.h
+       mov     l,a
+       mov     a,m             ;get word in table
+       inx     h               ;which ->pattern
+       mov     h,m
+       mov     l,a
+; check for offset pattern
+       inx     h               ;->y
+       mov     a,m
+       dcx     h
+       bit     7,A
+       jrz     ..noo           ;normal non offset
+       ani     7FH
+       mov     b,a
+       mov     c,m
+       inx     h
+       inx     h
+       xchg
+       lda     FLIP
+       ora     a
+       jz      ..down
+       dsbc    b
+       .byte   (3eh)           ;mvi a,(dad b)
+..down: dad    b
+       xchg
+; store pattern away
+..noo: mov     O.P.L(y),L
+       mov     O.P.H(y),H
+       mov     O.A.L(y),E      ;save screen address
+       mov     O.A.H(y),D
+       call    PLOT
+       lhld    V.PTR
+; check intercept
+       in      WHATI
+       bit     7,A             ;nz means 1 writtn over 1
+       rz
+       set     INEPT,M         ;set intercept bit
+       ret                     ;no point in moving object
+;--------------------------
+; move position, animate
+;--------------------------
+SECT3: shld    V.PTR
+;      bit     Color,m 
+;      cnz     COLMAN#
+       bit     MOVE,M          ;should be moved?
+       rz
+       push    h
+       pop     y               ;iy->vector
+; MOVE bit reset by routine that set it
+       lxi     d,TPRIME
+       dad     d               ;->tprime
+       mov     a,m
+       inx     h               ;->time
+       dcr     m               ;dec time,if0 then
+       rnz
+       mov     m,a             ;time:=tprime
+; vector in x
+       inx     h               ;->V.X
+       mov     a,m
+       inx     h               ;->p.x
+       add     M
+       mov     m,a
+;vector y
+       inx     h               ;->v.y
+       mov     a,m
+       inx     h               ;->p.y
+       add     M
+       mov     m,a
+; update pattern [animate]
+       inx     h               ;->d.p.l
+       mov     e,m
+       inx     h               ;->d.p.h
+       mov     d,m             ;get table address
+       inx     d
+       inx     d               ;point to next entry
+       xchg
+       mov     a,m             ;if0 then
+       inx     h
+       ora     m               ;jump
+       jnz     ..sk
+       inx     h               ;get pointer
+       mov     a,m             ; to value of next word
+       inx     h
+       mov     h,m
+       mov     l,a             ;->head of table
+       .byte   (3eh)           ;mvi a,dcx h (7 T not 12)
+..sk:  dcx     h
+       xchg                    ;de=table address
+       mov     m,d             ;hl->d.p.h
+       dcx     h
+       mov     m,e             ;->d.p.l
+       mvi     A,(1<Write)!(1<Erase)
+       lhld    V.Ptr
+       ora     M               ;or with V.STAT
+       mov     M,A
+       ret
+;-----------------------
+; decrement job timers
+;-----------------------
+TIMERS: lxi    h,Timer0
+       mvi     b,24
+..loop: mov    a,m
+       ora     a
+       jrz     ..dl
+       dcr     m
+..dl:  inx     h
+       djnz    ..loop
+       ret
+;-------------------------------
+; write pattern with intercept
+; 2 byte wide routine  
+;-------------------------------
+;hl->pattern   de->screen data
+PLOT:  mvi     B,0             ; bc=pattern x size
+       mov     a,m
+       inx     h
+       dcr     a
+       jz      X1PLOT          ;if not 1 then 2 bytes only!
+       lda     FLIP
+       ora     a               ;check flip state
+       mov     a,m             ; y size
+       inx     h
+       jnz     XF2PLT
+       lxi     b,Hsize-2
+       xchg                    ;de->pattern byte
+Y.LOOP: exaf                   ;save y size
+       ldax    d               ;get pattern byte
+       inx     d               ;->next pattern byte
+       mov     m,a             ;write to screen
+       inx     h
+       ldax    d               ;repeat for next byte
+       inx     d
+       mov     m,a
+       inx     h
+       mov     m,b             ;flush shifter(b=0)
+       exaf
+       dad     b               ;hl->next line of screen
+       dcr     a               ;--y.size
+       jnz     Y.LOOP
+       ret
+;-----------------------------------------
+; two byte wide upside-down plot routine
+;-----------------------------------------
+XF2PLT: lxi    b,2-Hsize
+       xchg                    ;de->pattern byte
+Y.Lp:  exaf                    ;save y size
+       ldax    d               ;get pattern byte
+       inx     d               ;->next pattern byte
+       mov     m,a             ;write to screen
+       dcx     h
+       ldax    d               ;repeat for next byte
+       inx     d
+       mov     m,a
+       dcx     h
+       mvi     M,0             ;flush shifter(b=0)
+       exaf
+       dad     b               ;hl->next line of screen
+       dcr     a               ;--y.size
+       jnz     Y.Lp
+       ret
+;-----------------------------
+; one byte wide plot routine
+;-----------------------------
+;hl->pattern   de->screen data
+X1PLOT: lda    FLIP            ;hl->y size
+       ora     a               ;check flip state
+       mov     a,m             ;load y size
+       inx     h               ;->first data byte
+       jnz     XF1PLT
+       lxi     b,Hsize-1
+       xchg                    ;de->pattern byte
+..loop: exaf                   ;save y size
+       ldax    d               ;get pattern byte
+       inx     d               ;->next pattern byte
+       mov     m,a             ;write to screen
+       inx     h
+       mov     m,b             ;flush shifter(b=0)
+       exaf
+       dad     b               ;hl->next line of screen
+       dcr     a               ;--y.size
+       jnz     ..loop
+       ret
+;-----------------------------------
+; flipped 1 byte wide plot routine
+;-----------------------------------
+XF1PLT: lxi    b,1-Hsize
+       xchg                    ;de->pattern byte
+..loop: exaf                   ;save y size
+       ldax    d               ;get pattern byte
+       inx     d               ;->next pattern byte
+       mov     m,a             ;write to screen
+       dcx     h               ;backwards writing
+       mvi     M,0             ;flush shifter(b=0)
+       exaf
+       dad     b               ;hl->next line of screen
+       dcr     a               ;--y.size
+       jnz     ..loop
+       ret
+BYTE2:: .byte  0
+;------------------
+; interrupt table
+;------------------
+       .loc    3FFCH
+
+ITAB:  .word   INT             ;video
+BYTE4:: .word  0               ;xsum
+
+       .loc    4000h
+       .word   BYTE1#
+       .word   BYTE2
+       .word   BYTE3#
+       .word   BYTE4
+       .word   BYTE5#
+
+       .end
diff --git a/init.tel b/init.tel
new file mode 100644 (file)
index 0000000..a30e5c7
--- /dev/null
+++ b/init.tel
@@ -0,0 +1,8 @@
+B>type init.tel
+# these were instructions to the linker
+80wl0wn1wt94wy
+j@i/23l23t\e\e
+/j1:p2\e
+j@i/23t\e\e
+/j1:p1@x/ - Space Used /vz-vf=
+1<@s/Version /;@s/./.,.+2:p9ev9w8%8,2\0lt>0,0p9j\e\e
diff --git a/iq.asm b/iq.asm
new file mode 100644 (file)
index 0000000..75397b1
--- /dev/null
+++ b/iq.asm
@@ -0,0 +1,191 @@
+B>type iq.asm
+
+.title "WALL DETECTER AND AVOIDANCE CONTROL"
+.sbttl "FRENZY"
+.ident IQ
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Intelligence
+;_______________________________
+.insert EQUS
+; DURL refered to thru out this program stands for
+; Down,Up,Right,Left bits in directions and wall encoding.
+DOWN   ==      3
+UP     ==      2
+RIGHT  ==      1
+LEFT   ==      0
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;  Check walls and avoid them
+;_______________________________
+;a=new DURL, c=old DURL, ix->vector, iy->mans
+IQ::   push    b               ;save tracker
+       push    d
+       mov     l,D.P.L(x)      ;get height thru
+       mov     h,D.P.H(x)      ;pattern pointer
+       mov     e,m
+       inx     h
+       mov     d,m
+       xchg
+       mov     d,a             ;save DURL      
+       inx     h               ;skip x bytes
+       mov     a,m             ;y lines (height)
+       mov     c,a             ;for down test
+       srlr    a               ;h/2
+       adi     1               ;(h/2)+2
+       mov     e,a             ;number of lines to test
+       mov     h,P.Y(x)        ;get current position
+       mov     l,P.X(x)
+; Regs: HL=YXpos, E=height, c=DURL to test
+; Down tests
+       bit     DOWN,d
+       jz      ..TU
+       push    h
+       mov     a,c             ;height of pattern
+       adi     3               ;margin of error
+       add     h               ;offset to look
+       mov     h,a             ;at for wall color
+       push    d
+       mvi     e,5
+       call    testx           ;check for white below
+       pop     d
+       pop     h
+       jz      ..TR            ;if ok check right,left
+       res     DOWN,d          ;else forget that direction
+       jmp     ..TR
+;up tests
+..TU:  bit     UP,d
+       jz      ..TR
+       push    h
+       mvi     a,-3
+       add     h
+       mov     h,a
+       push    d
+       mvi     e,5
+       call    testx
+       pop     d
+       pop     h
+       jz      ..TR
+       res     UP,d
+;      jmp     ..TR
+;right tests
+..TR:  bit     RIGHT,d
+       jz      ..TL
+       push    h
+       mvi     a,11
+       add     l
+       mov     l,a
+       push    d
+       call    testy
+       pop     d
+       pop     h
+       jz      ..done
+       res     RIGHT,d
+       jmp     ..done
+;left tests
+..TL:  bit     LEFT,d
+       jz      ..done
+       push    h
+       mvi     a,-3
+       add     l
+       mov     l,a
+       push    d
+       call    testy
+       pop     d
+       pop     h
+       jz      ..done
+       res     LEFT,d
+;      jmp     ..done
+..done:
+       mov     a,d             ;final result DURL
+       pop     d
+       pop     b
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Test in X direction
+;_______________________________
+; input: h=Y, l=X, c=DURL
+; output: Z if robot color in that box
+Testx:
+       dcr     l               ;test -1 line
+       inr     e
+..x:   call    CheckBox
+       rnz
+       exaf                    ;save test results
+       mov     a,l             ;get x
+       adi     2               ;add 2
+       mov     l,a
+       exaf                    ;now return test results
+       dcr     e               ;number of times to look
+       jnz     ..x
+       ret                     ;returns Z
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Test in Y direction
+;_______________________________
+; input: h=Y, l=X, c=DURL
+; output: Z if robot color in that box
+Testy: dcr     h
+       inr     e
+..y:   call    CheckBox
+       rnz
+       exaf                    ;save test results
+       mov     a,h             ;get Y
+       adi     2               ;add 2
+       mov     h,a
+       exaf                    ;now return test results
+       dcr     e               ;number of times to look
+       jnz     ..y
+       ret                     ;returns Z
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Check pixel for use
+;_______________________________
+CheckBox:
+       push    h               ;save YX
+       call    RtoAx#          ;in hl out hl,a
+       ani     0fh             ;save shift&flop
+       bit     Flop,a
+       jz      ..fl
+       xri     0Fh             ;flip flop and shift
+..fl:  xri     07h             ;reverse shift
+       di                      ;using magic
+       out     MAGIC
+       res     5,h             ;convert magic->normal addr
+       mov     a,m             ;get normal screen
+       sta     TEMP+(1<13)     ;magic scratch
+       ei
+       lda     TEMP            ;normal scratch
+       ani     1               ;check it
+       pop     h               ;restore YX
+       ret
+;---------------+
+; get durl bits |
+;---------------+
+; input: h=x l=y
+; output: a=durl bits for room xy is in
+; used by man,robot to check for others in square
+WallIndex::
+       mov     a,l             ;get y position
+       sui     8               ;edge of first room
+       mvi     e,0
+       cpi     48              ;1st row
+       jrc     ..sk
+       mvi     e,6             ;2nd row
+       cpi     48*2
+       jrc     ..sk
+       mvi     e,6*2           ;3rd row
+       cpi     48*3
+       jrc     ..sk
+       mvi     e,6*3           ;4th row
+..sk:  mov     a,h             ;x pos
+       sui     8               ;edge of first room
+       dcr     e
+..xlp: sui     40              ;room x width
+       inr     e
+       jrnc    ..xlp
+       xchg
+       lxi     b,WALLS         ;->walls array
+       mvi     H,0             ;add index
+       dad     b
+       mov     a,m             ;get durl for room
+       xchg
+       ret
+
+       .end
diff --git a/job.asm b/job.asm
new file mode 100644 (file)
index 0000000..98a760a
--- /dev/null
+++ b/job.asm
@@ -0,0 +1,261 @@
+B>type job.asm
+
+.title "Job Scheduling"
+.sbttl "FRENZY"
+.ident JOBS
+;~~~~~~~~~~~~~~~~~~~~
+; multi-job System
+;____________________
+.insert EQUS
+.extern Zap
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Job System Initialization
+;____________________________
+JobInit::
+       xra     a               ;reset man alternator
+       sta     Man.Alt
+       lxi     h,J.Used
+       lxi     b,(MaxJob*JobLength)+2
+       jmp     Zap
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Pass Control to next job
+;____________________________
+Next.J::
+       push    y               ;pc is on stack
+       push    x               ;save all registers
+       push    h
+       push    d
+       push    b
+       push    psw             ;->job store area
+       call    JobPtr          ;returns in de
+       lxi     h,0
+       dad     sp              ;hl->top of stack(the register set)
+       lxi     b,JobLength     ;move stack to store
+       LDIR
+       lxi     h,J.Used        ;move to next job
+       mov     b,m             ;# in use
+       inx     h               ;->J.Index
+..loop: mov    a,m
+       inr     m               ;++J.Index
+       cmp     b               ;see if we're last job
+       jrnz    ..ok
+       mvi     m,0
+..ok:  mov     a,m             ;is it man job
+       cpi     1               ;if so skip it
+       jrz     ..loop
+       lxi     h,Man.Alt       ;check if time for man job
+       mov     a,m
+       ora     a
+       jrnz    OK1
+       mvi     m,1b            ;reset alternator
+       lda     J.Used          ;check number of jobs used
+       ora     a
+       jrz     OK1             ;no man job yet so skip
+       call    MJPtr           ;->man job
+       jmpr    GOJ
+OK1:   call    JobPtr
+GOJ:   lxi     h,SPos-JobLength
+       sphl                    ;->stack area
+       xchg
+       lxi     b,JobLength     ;move store to stack
+       LDIR
+       pop     psw             ;get this job's registers
+       pop     b
+       pop     d
+       pop     h
+       pop     x
+       pop     y
+       ret                     ;and pc register too
+;~~~~~~~~~~~~~~~~~~~~~~
+; Return from man job
+;______________________
+Man.Next::
+       push    y               ;pc is on stack
+       push    x               ;save all registers
+       push    h
+       push    d
+       push    b
+       push    psw             ;->job store area
+       call    MJPtr           ;returns -> man job in de
+       lxi     h,0
+       dad     sp              ;hl->top of stack(the register set)
+       lxi     b,JobLength     ;move stack to store
+       LDIR
+       jmp     OK1             ;go do next job
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Split off new job
+;____________________________
+J.FORK::
+       push    b               ;bc=starting PC for new job
+       push    y               ;also get set of input
+       push    x               ;registers for parms
+       push    h
+       push    d
+       push    b
+       push    psw
+; check if possible to start a new job
+       lxi     h,J.Used        ;-># of jobs in use (0 is 1)
+       mov     a,m
+       cpi     MaxJob-1
+       jrc     ..ok
+       lxi     h,7*2           ;sorry no room
+       dad     sp              ;get rid of registers
+       sphl
+       stc                     ;aborto
+       ret
+;ok to add a job
+..ok:  inr     m               ;++J.Used
+       call    JLPtr           ;get pointer to last job in de
+       lxi     h,0
+       dad     sp              ;top ot stack frame
+       lxi     b,JobLength
+       LDIR
+       pop     psw             ;restore mother registers
+       pop     b
+       pop     d
+       pop     h
+       pop     x
+       pop     y
+       pop     b               ;was copy of bc=daughter pc
+       ora     a               ;nc means no problem
+       ret                     ;return to mother
+;~~~~~~~~~~~~~~~~~~~~
+; Delete Current Job
+;____________________
+JobDel::
+       lxi     h,J.Used
+       mov     a,m             ;save
+       dcr     m               ;one less job active
+       inx     h               ;->J.Index
+       sub     m               ;J.Used-J.Index
+       jrnz    ..move          ;if = then this is last job
+       mvi     m,0             ;reset J.Index
+..go:  call    JobPtr          ;de->frame
+       jmpr    GOJ
+..move:                        ;move jobs up j.index stays same
+       call    JobPtr          ;de->frame
+       lxi     h,JobLength
+       dad     d               ;hl->next frame
+       xchg
+       push    h
+       lxi     h,Jobs+(MaxJob*JobLength) ;->end of job area
+       ora     a
+       dsbc    d               ;hl=#of bytes to end of job area
+       mov     b,h
+       mov     c,l
+       pop     h
+       xchg
+       LDIR
+       jmpr    ..go
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Point to Job[J.Index] Storage Area
+;_____________________________________
+MJPtr: mvi     c,1
+       .byte   (3eh)           ;mvi a,(mov c,m)
+JLPtr: mov     c,m
+       lxi     h,Jobs
+       jmpr    JP2
+JobPtr: lxi    h,J.Index
+       mov     c,m             ;current index
+       inx     h               ;->Jobs
+JP2:   mvi     b,0
+       xchg
+       lxi     h,0             ;hl=14*bc (J.Index*JobLength)
+       MULT    JobLength
+       dad     d               ;Jobs[Jindex*JobLength]
+       xchg                    ;return de->job area
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~
+; Initialize the Timers
+;_______________________
+TimerInit::
+       lxi     h,Talloc        ;timer allocation area
+       lxi     b,MaxTimer+(Maxtimer/8)
+       jmp     Zap
+;~~~~~~~~~~~~~~~~~~
+; Allocate a Timer
+;__________________
+; returns hl->a timer byte
+GetTimer::
+       push    d
+       push    b
+       push    psw
+       lxi     h,Talloc
+       lxi     b,(MaxTimer/8)<8 ;#of timers:timer0
+..alp: mov     a,m             ;get alloc bits
+       cpi     -1              ;if not all 1's
+       jrnz    ..get           ;then find a zero bit
+       mvi     a,8             ;move index up 8
+       add     c
+       mov     c,a
+       inx     h               ;->talloc group
+       djnz    ..alp           
+..bad: pop     psw
+       stc                     ;no timer available
+       jmpr    ..ret
+..get: mvi     b,1             ;bit 0 mask
+..blp: mov     d,a             ;save Talloc
+       ana     b               ;check bit
+       mov     a,d             ;restore Talloc
+       jrz     ..ok
+       inr     c               ;up the index
+       rlcr    b               ;move bit left
+       jmpr    ..blp
+..ok:  ora     b               ;set alloc bit
+       mov     m,a             ;set Talloc
+       mvi     b,0             ;bc=timer #
+       lxi     h,Timer0
+       dad     b               ;hl->special timer
+       pop     psw
+       ora     a
+..ret: pop     b
+       pop     d
+       ret
+;~~~~~~~~~~~~~~~
+; Free a Timer
+;_______________
+; input hl->timer byte
+FreeTimer::
+       push    b
+       push    psw
+       mvi     m,0
+       lxi     b,Timer0        ;find the offset
+       ora     a
+       dsbc    b               ;hl=timer number
+       mov     a,l
+       cpi     24
+       jrnc    ..ret
+       lxi     h,Talloc        ;->talloc[0..7]
+..idx: cpi     8               ;check index 0..7
+       jrc     ..ok
+       inx     h               ;->talloc[+8]
+       sui     8               ;index-=8
+       jmpr    ..idx
+..ok:  mvi     b,#1            ;FEh bit 0 negitive mask
+       ora     a               ;index=0?
+       jrz     ..fr
+..blp: rlcr    b               ;move bit mask up
+       dcr     a               ;dec index
+       jrnz    ..blp
+..fr:  mov     a,b
+       ana     m
+       mov     m,a     
+..ret: pop     psw
+       pop     b
+       ret
+;~~~~~~~~~~~~~~~~~~
+; Put job to sleep
+;__________________
+; input A=number of 60ths to wait
+J.WAIT::
+       pop     y
+       call    GetTimer
+       mov     m,a
+..lp:  call    NEXT.J
+       mov     a,m
+       ora     a
+       jrnz    ..lp
+       call    FreeTimer
+       pciy
+
+       .end
diff --git a/main.asm b/main.asm
new file mode 100644 (file)
index 0000000..3013689
--- /dev/null
+++ b/main.asm
@@ -0,0 +1,230 @@
+B>type main.asm
+
+.title "MAIN LOOP"
+.sbttl "FRENZY"
+.ident MAIN
+;----------------------
+;      main loop
+;----------------------
+.insert equs
+.extern GOVER,INSERT,PLAYDEMO,NMI,JobInit
+.extern REST,INT,MOVEN
+.extern UPHIGH,PLAY,SHOWN,RANDOM
+.extern DECCRD,NoVoice,NoSnd,ItemInc
+DEATH2 ==      DEATHS+(OTHER-PLAYER)
+;----------------------
+; start of main module
+;----------------------
+MAIN:: di                      ;initial
+       lxi     sp,SPos         ;set stack
+;zero locations for sounds and battery ram scratch
+       lxi     h,SPos
+       lxi     b,T60cnt-SPos   ;# of bytes
+       call    Zap
+; zero above screen ram
+       lxi     h,VideoRAM
+       lxi     b,ScreenRAM-VideoRam
+       call    Zap
+;start sounds
+       call    66h             ;nmi routine
+;move high scores from backup
+       call    CheckBooks#
+       lxi     h,HIGH1         ;shown
+       lxi     d,HIGH2         ;backed up
+       mvi     B,5*12          ;# of nibbles
+       call    MOVEN
+;setup debouncer coin switches
+       in      I.O2
+       cma
+       lxi     h,SWD           ;switch debouncer
+       mov     m,a
+       inx     h
+       mov     m,a
+; main attract loop
+MLOOP::
+       lxi     sp,SPos         ;reset stack
+       xra     a
+       sta     StartB          ;no start yet
+       call    SET1            ;reset everything
+       call    TITLE#
+       call    CheckBooks
+       mvi     b,8
+       call    COIN1#
+MENTR: xra     a
+       sta     StartB          ;no start yet
+       call    GOVER           ;high score display
+       call    INSERT          ;insert coin/press start
+       mvi     b,3
+       call    COIN1#          ;check coins and wait
+       call    XMLEV#          ;insert coin/press start
+       call    COIN0#          ;check coins and wait
+       jmp     PLAYDEMO        ;play a demo game
+DemoRet::
+       jz      MLOOP
+       jmp     GO              ;play a complete game
+;---------------
+SET1:  di
+       xra     a
+       sta     player          ;forces upside up mode
+       dcr     a               ;-1
+       sta     DEMO            ;is demo mode
+       call    JobInit
+       call    REST            ;stop bolt and vectors
+       mvi     a,55h           ;alternater
+       sta     IntTyp
+       call    INT             ;start interrupts
+       ret
+;-----------------------
+; Play 1 complete game
+;-----------------------
+; take away credits and go play a game
+GO::
+       lxi     sp,SPos         ;reset stack
+       lxi     h,StartB
+       set     7,m             ;no jump while playing
+       call    SET1            ;reset everything
+       lda     StartB
+       mov     l,a
+       call    DECCRD          ;take away 1st player credit
+       bit     1,L             ;test for 2 player button
+       mvi     A,1             ;# of players:=1
+       jrz     ..st            ;0=one player game
+       call    DECCRD          ;take away 2nd player credit
+       mvi     A,2             ;# of players:=2
+..st:  sta     N.PLRS          ;store # of players
+       cpi     2
+       jrz     ..two
+       mvi     c,3             ;1 player plays
+       call    ItemInc
+       jmpr    ..tp
+..two: mvi     c,4             ;2 player games
+       call    ItemInc
+       mvi     c,5             ;total plays
+       call    ItemInc
+..tp:  mvi     c,5             ;total plays
+       call    ItemInc
+       call    ZSCORE          ;zero the score
+       lxi     b,OTHER-PLAYER
+       lxi     d,PLAYER
+       lxi     h,Idata
+       ldir                    ;initial the player
+       lhld    SEED
+       xchg
+       lhld    OnTime+10       ;part of second count
+       dad     d
+       shld    SEED            ;new random room
+       shld    RoomX
+       in      Dip2            ;extra lives
+       ani     15
+       sta     XtraMen
+       xra     a
+       sta     DEMO            ;not a demo
+       sta     CHIKEN          ;not a chicken yet
+       sta     RoomCnt         ;hasn't seen any rooms yet
+       inr     a
+       sta     T.TMR           ;set talk timer for 1 second
+       lxi     h,PLAYER        ; Set 2nd players bank
+       lxi     d,OTHER
+       lxi     b,OTHER-PLAYER
+       ldir
+       mvi     A,2             ;SET AS PLAYER NUMBER 2
+       mov     m,a
+; Turn second player off if 1 player game
+       lda     N.PLRS
+       cpi     2
+       jrz     SLOP
+       xra     a               ;if no deaths
+       sta     DEATH2          ; then no playing either
+SLOP:  ei
+       lhld    Manxi
+       shld    ManX
+       lda     PLAYER
+; Play out one life
+       call    PLAY
+       call    RANDOM
+       WAIT    90              ;pause to show trouble
+       call    REST            ;stop moving stuff on screen
+       lhld    SEED            ;goto a new random room
+       shld    RoomX
+       lxi     h,DEATHS        ;take away a life
+       dcr     m
+       call    SWAP            ;swap to other player
+       jrnz    SLOP            ;if so go play his round
+       call    SWAP            ;do you have any lives left?
+       jrnz    SLOP
+; Update High Scores
+       mvi     a,-1
+       sta     DEMO            ;not playing anymore
+       call    NoSnd
+UPITY: call    UPHIGH          ;Check for high score
+;get other player
+       call    SWAP            ;(in 1 player its score is 0)
+       call    UPHIGH          ;Check for high score
+       lxi     sp,SPos         ;reset stack
+       call    SET1            ;reset everything
+       jmp     MENTR           ;right to high scores
+;---------------------------
+; ZERO both players scores
+; and can the 1/2 credits
+;---------------------------
+ZSCORE: lxi    h,0
+       shld    SCORE1
+       shld    SCORE1+2
+       shld    SCORE2+1
+       shld    CACKLE          ;zero fractional coin
+       lxi     h,NoVoice
+       shld    V.PC
+       jmp     NoSnd
+;----------------------------
+; Swap players banks of ram
+;----------------------------
+SWAP:  push    h
+       lxi     h,PLAYER
+       lxi     d,OTHER
+       mvi     B,OTHER-PLAYER
+..LP:  ldax    d
+       mov     c,m
+       xchg
+       stax    d
+       mov     m,c
+       xchg
+       inx     h
+       inx     d
+       djnz    ..LP
+       pop     h
+       mov     a,m
+       ora     a
+       ret
+;---------------------------
+; zero ram loop
+; hl->start, bc=# of bytes
+;---------------------------
+Zap::  mov     a,c
+       ora     a
+       mov     c,b
+       mov     b,a
+       jrz     ..sk
+       inr     c
+..sk:  xra     a
+..zl:  mov     m,a
+       inx     h
+       djnz    ..zl
+       dcr     c
+       jrnz    ..zl
+       ret
+;---------------------------------------------+
+; Initialization data for players first round |
+;---------------------------------------------+
+Idata: .byte   1       ;PLAYER
+       .byte   0,0     ;RoomX
+Manxi: .byte   30      ;ManX
+       .byte   116     ;MPY
+       .byte   3       ;DEATHS
+       .byte   6       ;PERCENT
+       .byte   0       ;Rbolts
+       .byte   90      ;Rwait
+       .byte   0       ;STIME
+       .byte   0       ;XtraMen
+
+       .end
+
diff --git a/man.asm b/man.asm
new file mode 100644 (file)
index 0000000..6314288
--- /dev/null
+++ b/man.asm
@@ -0,0 +1,304 @@
+B>type man.asm
+
+.title "MOVE MAN"
+.sbttl "FRENZY"
+.ident MAN
+;~~~~~~~~~~~~
+; man mover
+;____________
+.insert EQUS
+.intern V.ZERO,M.INIT,D.TAB
+.extern SETVXY,WallIndex,Man.Next
+ManP   =       6               ;bit number in walls
+SHOOT  ==      4               ;shoot button bit
+DOWN   ==      3
+UP     ==      2
+RIGHT  ==      1
+LEFT   ==      0
+;~~~~~~~~~~~~~
+; initialize
+;_____________
+MAN::  call    M.INIT
+       mvi     V.STAT(x),(1<InUse)!(1<Color)!(1<Move)!(1<Write)
+       lxi     b,-1            ;tracker
+       call    GetTimer#
+       xchg
+;~~~~~~~~~~~~~~~~
+; mans job loop
+;________________
+;bc=tracker
+;de->timer
+;ix->vector
+C.LOOP: call   Man.Next
+       bit     INEPT,V.STAT(x) ; check if alive
+       jnz     DEAD
+       lda     Demo            ;check for demo
+       ora     a
+       jrz     ..real
+;automatic demo mode
+       ldax    d
+       ora     a
+       jrz     ..new
+       mov     a,c
+       jmpr    ARGH
+..new: lhld    DemoPtr
+       mov     a,m
+       inx     h
+       shld    DemoPtr
+       bit     7,A
+       jrz     ..go
+       res     7,A
+       stax    d               ;start timer
+       jmpr    C.LOOP
+..real: call   S.STICK#
+..go:  bit     SHOOT,A         ; if(shoot) fire
+       jrnz    TRY.F
+ARGH:  ani     0FH             ;mask off DURL bits
+       call    IQ#
+       cmp     c               ;compare to tracker
+       cnz     CHANGE          ;if changed update vector
+       jmpr    C.LOOP
+;~~~~~~~~~~~~~~
+; try to fire
+;______________
+TRY.F: mov     b,a             ;save control
+       ldax    d               ;get timer
+       ora     a
+       jrnz    ..0
+       xra     a
+       lxi     y,BUL1          ;bolt one available?
+       ora     0(y)            ;check Vxy.len
+       jrz     FIRE            ;then fire
+       lxi     y,BUL1+Blength  ;bolt 2 available?
+       xra     a
+       ora     0(y)
+       jrz     FIRE
+..0:   mvi     a,0
+       jmpr    ARGH            ;none available=loop
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      shoot plasma bolt
+;_______________________________
+FIRE:  mov     a,b             ;last control
+       ani     0FH             ; look at direction
+       jz      C.LOOP          ;COULD DEFAULT TO LAST DIR
+       push    d               ;save ->timer
+       call    SFIRE#
+       mov     c,a
+       mvi     B,0             ;bc=direction bits DURL
+       mov     d,b             ;zero d too
+       lxi     h,D.TAB         ;->direction table
+       dad     b               ;->offset for direction
+       mov     e,m
+       lxi     h,SR.TAB        ;->shoot table
+       dad     d               ;2 per entry
+       dad     d               ;4
+       dad     d               ;6
+       mvi     V.X(x),0        ;set velocitys to 0
+       mvi     V.Y(x),0
+       mov     a,m             ;get shoot animation table
+       inx     h
+       di
+       mov     D.P.L(x),A
+       mov     a,m
+       inx     h
+       mov     D.P.H(x),A
+       ei
+       mvi     TIME(x),1
+       pop     d               ;restore ->timer
+       xchg
+       mvi     m,2             ;wait for 2 ints
+..wt:  call    Man.Next        ;wait for pattern to be written
+       mov     a,m             ;get the timer
+       ora     a
+       jrnz    ..wt
+       xchg                    ;hl->offsets
+       push    d               ;save ->timer
+       mov     b,m             ;x offset from man
+       inx     h
+       mov     c,m             ;y offset from man
+       inx     h
+       mov     a,m             ;vx.vy for bullet
+       ori     6               ;length of bolt
+       mov     d,a             ;vxy.len
+       mov     a,P.X(x)        ;load mans x position
+       add     b               ;add x offset
+       mov     e,a             ;px
+       mov     a,P.Y(x)        ;load mans y position
+       add     c               ;add y offset
+       mov     c,a             ;py
+       push    Y
+       pop     h
+       mvi     b,BLength
+       xra     a
+..zap: mov     m,a
+       inx     h
+       djnz    ..zap
+       di
+       mov     0(y),D          ;head vx.vy
+       mov     1(y),E          ;set px  py for head
+       mov     2(y),C
+       mov     3(y),E          ;set px  py for tail
+       mov     4(y),C
+       ei
+       mvi     C,00            ;set automatic fire
+       pop     h               ;->timer
+       mvi     m,4             ;wait for exit from gun
+..wlp: call    Man.Next
+       mov     a,m             ;test timer
+       ora     a
+       jrnz    ..wlp
+       mvi     m,13            ;in the timer
+       xchg                    ;put -> back in de
+       jmp     C.LOOP          ;goto control loop
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; change direction of man
+;  a=data, c=tracker [0=stop]
+;_______________________________
+CHANGE: ani    0FH
+;changed direction and moving
+CDIR:  push    d               ;save timer->
+       call    SetVXY          ;updates c:=tracker
+       lxi     h,P.TAB
+       dad     d               ;offset calced in setvxy
+       mov     a,m             ;dpl
+       inx     h
+       mov     h,m
+       di
+       mov     D.P.L(x),A
+       mov     D.P.H(x),H
+       ei
+       pop     d               ;restore timer->
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Kill Man job off
+;_______________________________
+DEAD:  call    SFRY#
+       mvi     A,10H           ;electrocute
+       call    CDIR
+       xchg
+       mvi     m,150           ;electrocution timer
+..wlp: call    Man.Next
+       lda     Mcolor          ;get man color
+       adi     55h             ;change for explosion
+       ori     88h
+       sta     Mcolor
+       mov     a,m
+       ora     a
+       jrnz    ..wlp
+       mvi     V.STAT(x),(1<InUse)!(1<BLANK)!(1<ERASE)
+..lp:  call    Man.Next
+       bit     ERASE,V.STAT(x)
+       jrnz    ..lp
+       mvi     m,30
+..wt:  call    Man.Next
+       mov     a,m
+       ora     a
+       jrnz    ..wt
+       mvi     V.STAT(x),0     ;free the vector
+       xra     a
+       sta     Man.Alt         ;don't do me anymore
+..end: call    Man.Next
+       jmp     ..end           ;just in case
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Start a man vector
+;_______________________________
+M.INIT:
+       call    V.ZERO          ;ix->vector
+; man must be first vector
+       lda     PLAYER
+       cpi     1
+       mvi     a,M1color
+       jrz     ..s
+       mvi     a,M2color
+..s:   sta     Mcolor          ; set color of man
+       lhld    ManX            ;gets x and y position
+       mov     P.X(x),L        ;set x
+       mov     P.Y(x),H        ;set y
+       mov     a,l             ;swap h:l
+       mov     l,h
+       mov     h,a
+       call    WallIndex       ;see what room # im in
+       xchg
+       set     ManP,m          ;warns robots to stay away
+       xra     a               ;stand still
+       call    CHANGE          ;set up vector
+       mvi     TPRIME(x),1
+       mvi     TIME(x),1
+       mvi     a,0aah          ;force man to plot
+       sta     IntTyp
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; find and zero a vector
+;_______________________________
+V.ZERO: lxi    h,Vectors       ;->vector area
+       lxi     d,VLEN          ;vector length
+       mvi     b,MaxVec        ;# of vectors
+..test: bit    InUse,M         ;check if in use
+       jrz     ..ok
+       dad     d
+       djnz    ..test
+       stc                     ;error return
+       ret
+..ok:  push    h               ;->your new vector
+       lxi     b,VLEN          ;# of bytes to zero
+       call    Zap#            ;zero the vector
+       pop     x               ;save vector pointer in x
+       set     InUse,V.STAT(x)
+       ora     a               ;normal return
+       ret
+;~~~~~~~~~~~~~~~~~~
+; direction table
+;__________________
+D.TAB: .byte   0               ;no move
+       .byte   6*2             ;left
+       .byte   2*2             ;right
+       .byte   0
+       .byte   8*2             ;up
+       .byte   7*2             ;up,left
+       .byte   1*2             ;up,right
+       .byte   8*2             ;up default
+       .byte   4*2             ;down
+       .byte   5*2             ;down,left
+       .byte   3*2             ;down,right
+       .byte   4*2             ;down default
+       .byte   0
+       .byte   6*2             ;left default
+       .byte   2*2             ;right default
+       .byte   0
+       .byte   9*2             ;explode
+;~~~~~~~~~~~~
+; move table
+;              x ,y ,animation-table
+.define PAT[ADDR]=[
+.extern ADDR
+       .word   ADDR
+]
+P.TAB: PAT     M.0
+       PAT     M.1
+       PAT     M.2
+       PAT     M.3
+       PAT     M.4
+       PAT     M.5
+       PAT     M.6
+       PAT     M.7
+       PAT     M.8
+       PAT     M.9
+;~~~~~~~~~~~~~~~~~~~~~~
+;      Shoot table
+;______________________
+.define SS[Xo,Yo,Pat,VXY]=[
+.extern Pat
+       .word   Pat
+       .byte   Xo,Yo,VXY<4,0
+]
+SR.TAB: SS     0,0,MS.0,0
+       SS      8,2,MS.1,6
+       SS      8,3,MS.2,2
+       SS      7,7,MS.3,10
+       SS      6,8,MS.4,8
+       SS      -1,7,MS.5,9
+       SS      -1,3,MS.6,1
+       SS      -1,-1,MS.7,5
+       SS      7,1,MS.8,4
+
+       .end
diff --git a/nmi.asm b/nmi.asm
new file mode 100644 (file)
index 0000000..88d4586
--- /dev/null
+++ b/nmi.asm
@@ -0,0 +1,388 @@
+B>type nmi.asm
+
+.title "Non-Maskable Interrupt"
+.sbttl "FRENZY"
+.ident NMI
+;------------------------+
+; Non-Maskable Interrupt |
+;------------------------+
+.insert EQUS
+CR1    ==      40H
+VOICE  ==      44H
+;------------------------+
+; Non-Maskable Interrupt |
+;------------------------+
+NMI::
+;      push    psw             ;done at 66h
+       push    b
+       push    d
+       push    h
+       call    S.BOOK#         ;CHECK CLEAR BUTTON
+       jnz     BOOKS#
+       lda     demo
+       ora     a
+       jrz     ..ok
+       mvi     a,1
+       sta     TCR1
+       jmp     ..no
+..ok:  call    SCPU            ;0=NORMAL
+..no:  call    C.LOAD
+; Do voice if not demo
+       lda     Demo
+       ora     a
+       jrnz    ..stop
+       lhld    V.PC            ;GET VOICE PC
+..lop: mov     a,h             ;IF 0 SKIP
+       ora     l
+       jrz     ..exit
+       in      VOICE           ;IF BUSY SKIP
+       ani     0C0H
+       cpi     40H
+       jrnz    ..exit
+       mov     a,m             ;GET DATA
+       bit     7,A             ;IF NEGATIVE SKIP
+       jrnz    ..stop
+       inx     h
+       out     VOICE           ;OUTPUT THE DATA
+       bit     6,A             ;IF A WORD
+       jrz     ..exit          ; WAIT A 60TH
+       jmp     ..lop           ;DO ANOTHER BYTE
+..stop: lxi    h,0             ;STOP TALKING
+..exit: shld   V.PC            ;STORE POINTER
+       pop     h
+       pop     d
+       pop     b
+       pop     psw
+       out     NMION
+       retn
+;--------------------------------------+
+; OUTPUT DATA TO ALL REGISTERS FROM RAM
+; DO CONTROL REGISTERS
+;
+C.LOAD: lxi    h,TCR1          ;->CR1 TRACKER
+       mov     b,m
+       inx     h
+       mov     d,m
+       inx     h
+       mov     e,m
+       inx     h
+       mvi     c,CR1+1         ;->CR2
+       res     0,B             ;ALL COUNTERS GO
+       set     0,D             ;SELECT CR1
+       OUTP    D               ;2
+       dcr     c               ;->C1:2
+       OUTP    B               ;1
+       inr     c               ;->C2
+       res     0,D             ;SELECT CR3
+       OUTP    D               ;2
+       dcr     c               ;->C1:3
+       OUTP    E               ;3
+;DO TIMERS
+T.LOAD: inr    c
+       inr     c               ;->MSB BUFFER
+       mvi     B,3
+       mov     a,c             ;SAVE MSB PORT ADDRESS
+       inr     c               ;->LSB LATCH #1
+       mov     d,c             ;SAVE LSB PORT ADDRESS
+T.LOOP: mov    e,m             ;GET LSB DATA
+       inx     h
+       mov     c,a
+       mov     a,m
+       inx     h
+       OUTP    A
+       mov     a,c
+       mov     c,d
+       OUTP    E
+       inr     d
+       inr     d               ;->LSB LATCH#N+1
+       djnz    T.LOOP
+;DO NOISE AND VOLUMES
+V.LOAD: dcr    c               ;->NOISE/VOLUME PORT
+       mvi     A,0             ;BITS6,7 FOR SELECT=NOISE
+       mvi     B,4             ;NUMBER OF REGISTERS
+V.LOOP: ora    m               ;OR IN DATA[BETTER BE GOOD]
+       inx     h               ;->NEXT REGISTER DATA
+       OUTP    A               ;OUTPUT
+       ani     0C0H            ;SELECT NEXT REGISTER
+       ADI     40H
+       djnz    V.LOOP
+       ret
+.PAGE
+.title "SOUNDS AND MACROS"
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Sound Process
+;_______________________________
+SCPU:: lda     RFSND
+       ora     a
+       cnz     RSND
+       lda     WLSND
+       ora     a
+       cnz     WSND
+       lhld    PC0             ;get where we left off
+       mov     A,H             ;if 0 don't do anything
+       ora     L
+       rz
+       PCHL                    ;goto routine
+; stop completely
+$STOP: lxi     h,0
+       shld    PC0
+       ret
+; wait for next interrupt
+$TICK: pop     h               ;get where it was
+       shld    PC0             ;save 
+       ret                     ;back to nmi routine
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Sound Macros
+;_______________________________
+.slist
+.xlist
+.define STOP=[ jmp     $STOP
+]
+.define TICK=[ call    $TICK
+]
+.define BR[LABEL]=[    jmp     LABEL
+]
+.define SOB[ByteAdr,Label]=[
+       lxi     h,ByteAdr
+       dcr     m
+       jnz     Label
+]
+.define MVIB[Value,Location]=[
+       mvi     a,Value
+       sta     Location
+]
+.define MVIW[Value,Location]=[
+       lxi     h,Value
+       shld    Location
+]
+.define ADIB[Value,Location]=[
+       lxi     h,Location
+       mov     a,m
+       adi     Value
+       mov     m,a
+]
+.define ADIW[Value,Location]=[
+       lhld    Location
+       lxi     d,Value
+       dad     d
+       shld    Location
+]
+.define MVIBM[Addr,V0,V1,V2,V3,V4,V5,V6,V7]=[
+       lxi     h,Addr
+       mvi     m,V0
+       $XB     V1,V2,V3,V4,V5,V6,V7
+]
+.define $XB[V0,V1,V2,V3,V4,V5,V6]=[
+.ifb   [V0],[.exit]
+       inx     h
+       mvi     m,V0
+       $XB     V1,V2,V3,V4,V5,V6
+]
+.define MVIWM[Addr,V0,V1,V2,V3,V4,V5,V6,V7]=[
+.ifb   [V0],[.exit]
+       lxi     h,V0
+       lhld    Addr
+       MVIWM   \Addr+1,V1,V2,V3,V4,V5,V6,V7
+]
+.define QUIET=[
+       lxi     h,0
+       xra     a
+       shld    TCR1
+       sta     TCR3
+       shld    NOISE
+       shld    VOL2
+]
+.define SETUP[R1,R2,R3,$NOISE,$VOL1,$VOL2,$VOL3]=[
+       lxi     h,TCR1
+       mvi     m,R1
+       inx     h
+       mvi     m,R2
+       inx     h
+       mvi     m,R3
+       lxi     h,NOISE
+       mvi     m,$NOISE
+       inx     h
+       mvi     m,$VOL1
+       inx     h
+       mvi     m,$VOL2
+       inx     h
+       mvi     m,$VOL3
+]
+.define TIMERS[T1,T2,T3]=[
+       lxi     h,T1
+       shld    TMR1
+       lxi     h,T2
+       shld    TMR2
+       lxi     h,T3
+       shld    TMR3
+]
+.define START[Sound,Priority]=[
+Sound:: push   psw
+       lda     PC1             ;now priority
+       cpi     Priority        ;new "
+       jc      ..load
+       jz      ..load
+       pop     psw
+       ret
+..load: mvi    a,Priority
+       sta     PC1
+       push    h
+       lxi     h,$'Sound
+       shld    PC0
+       pop     h
+       pop     psw
+       ret
+$'Sound:
+]
+.rlist
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Sounds
+;_______________________________
+NoSnd:: push   psw
+       push    h
+       QUIET
+       xra     a
+       sta     PC1
+       pop     h
+       pop     psw
+       ret
+
+FAP:   QUIET
+       xra     a               ;zap priority
+       sta     PC1
+       STOP
+
+START  SFIRE,10
+       SETUP   92H,92H,92H,0,5,6,6
+       TIMERS  50,50,50
+       MVIB    50,AC0
+..2:   TICK
+       ADIW    15,TMR1
+       ADIW    17,TMR2
+       ADIW    16,TMR3
+       SOB     AC0,..2
+       MVIB    50,AC0
+..3:   TICK
+       ADIW    10,TMR1
+       ADIW    13,TMR2
+       ADIW    15,TMR3
+       SOB     AC0,..3
+       BR      FAP
+
+START  SFRY,13
+       SETUP   90H,90H,90H,0,6,7,7
+       MVIB    16,AC0
+       MVIW    230,TMR1
+..1:   MVIWM   TMR2,20,10
+       MVIB    20,AC1
+..2:   TICK
+       ADIB    5,TMR2
+       ADIB    30,TMR3
+       SOB     AC1,..2
+       ADIB    -4,TMR1
+       SOB     AC0,..1
+       BR      FAP
+
+START  SBLAM,11
+       SETUP   82H,80H,80H,3,7,7,7
+       TIMERS  1,1,5
+       TICK
+       MVIBM   TCR1,92H,90H,90H
+       MVIB    55,AC1
+..1:   MVIB    6,AC0
+..2:   TICK
+       SOB     AC0,..2
+       ADIW    1,TMR1
+       SOB     AC1,..1
+       BR      FAP
+
+START  SRFIRE,11
+       SETUP   92H,92H,92H,0,6,6,7
+       TIMERS  20,45,90
+       MVIB    4,AC1
+..1:   MVIB    80,AC0
+..2:   TICK
+       ADIW    8,TMR1
+       ADIW    17,TMR2
+       ADIW    47,TMR3
+       SOB     AC0,..2
+       SOB     AC1,..1
+       BR      FAP
+
+START  SXLIFE,12
+       SETUP   92H,92H,92H,0,7,7,7
+       TIMERS  200,60,40
+       MVIB    20,AC1
+..1:   MVIB    20,AC0
+..2:   TICK
+       ADIW    20,TMR1
+       ADIW    6,TMR2
+       ADIW    4,TMR3
+       SOB     AC0,..2
+       MVIB    20,AC0
+..3:   TICK
+       ADIW    -20,TMR1
+       ADIW    -6,TMR2
+       ADIW    -4,TMR3
+       SOB     AC0,..3
+       SOB     AC1,..1
+       BR      FAP
+;rick O'shay sound
+RSND:  xra     a
+       sta     RFSND           ;clear flag
+       sta     WLSND           ;clear flag
+       lda     PC1             ;now priority
+       cpi     11              ;new "
+       jc      ..go
+       jz      ..go
+       ret
+..go:                          ;do the sound
+       mvi     a,11
+       sta     PC1
+       SETUP   92H,92H,92H,0,7,7,7
+       TIMERS  48,56,64
+       ldar                    ;get refresh reg!
+       ani     1fh
+       sta     AC1
+..1:   TICK
+       lda     AC1
+       ani     7
+       jnz     ..on    
+       lxi     h,VOL1
+       mov     a,m             ;v1
+       dcr     a
+       mov     m,a             ;v1
+       inx     h
+       mov     m,a             ;v2
+       inx     h
+       mov     m,a             ;v3
+..on:  ADIB    6,TMR1
+       ADIB    7,TMR2
+       ADIB    8,TMR3
+       SOB     AC1,..1
+       BR      FAP
+
+; Wall sound
+WSND:  xra     a
+       sta     WLSND           ;clear flag
+       lda     PC1             ;now priority
+       cpi     10              ;new "
+       jc      ..go
+       jz      ..go
+       ret
+..go:                          ;do the sound
+       mvi     a,10
+       sta     PC1
+       SETUP   82H,80H,80H,3,7,7,7
+       TIMERS  1,1,2
+       TICK
+       MVIBM   TCR1,92H,90H,90H
+       MVIB    55,AC1
+..1:   TICK
+       ADIB    1,TMR2
+       ADIB    1,TMR3
+       SOB     AC1,..1
+       BR      FAP
+
+       .end
+
diff --git a/pat2.asm b/pat2.asm
new file mode 100644 (file)
index 0000000..0d317dc
--- /dev/null
+++ b/pat2.asm
@@ -0,0 +1,697 @@
+B>type pat2.asm
+
+; MOMMY OTTO
+; LEFT HALF
+MAL::  .BYTE   2,40
+P2     0000000000001111
+P2     0000000000111111
+P2     0000000011111111
+P2     0000000111111111
+P2     0000001111111111
+P2     0000011111111111
+P2     0000111111111111
+P2     0001111111111111
+P2     0001111111111111
+P2     0011111111111111
+P2     0011111111111111
+P2     0111111111111111
+P2     0111111111111111
+P2     0111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     0111111111111111
+P2     0111111111111111
+P2     0111111111111111
+P2     0011111111111111
+P2     0011111111111111
+P2     0001111111111111
+P2     0001111111111111
+P2     0000111111111111
+P2     0000011111111111
+P2     0000001111111111
+P2     0000000111111111
+P2     0000000011111111
+P2     0000000000111111
+P2     0000000000001111
+;right half of mama otto
+MAR::  .BYTE   2,40
+P2     1111000000000000
+P2     1111110000000000
+P2     1111111100000000
+P2     1111111110000000
+P2     1111111111000000
+P2     1111111111100000
+P2     1111111111110000
+P2     1111111111111000
+P2     1111111111111000
+P2     1111111111111100
+P2     1111111111111100
+P2     1111111111111110
+P2     1111111111111110
+P2     1111111111111110
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111110
+P2     1111111111111110
+P2     1111111111111110
+P2     1111111111111100
+P2     1111111111111100
+P2     1111111111111000
+P2     1111111111111000
+P2     1111111111110000
+P2     1111111111100000
+P2     1111111111000000
+P2     1111111110000000
+P2     1111111100000000
+P2     1111110000000000
+P2     1111000000000000
+
+; LEFT EYEBROW-EYE Drop 5 right 5
+MAEL:: .byte   1,12
+P1     00100000
+P1     00110000
+P1     00011000
+P1     00001100
+P1     00000110
+P1     00000011
+P1     01110000
+P1     11111000
+P1     11001000
+P1     11001000
+P1     11111000
+P1     01110000
+; right EYEBROW-EYE
+MAER:: .byte   1,12
+P1     00000100
+P1     00001100
+P1     00011000
+P1     00110000
+P1     01100000
+P1     11000000
+P1     00001110
+P1     00011111
+P1     00010011
+P1     00010011
+P1     00011111
+P1     00001110
+
+; left frown 0,+26
+MAFL:: .byte   2,7
+P2     0000000000000011
+P2     0000000000011111
+P2     0000000000111100
+P2     0000000001100000
+P2     0000000011000000
+P2     0000000110000000
+P2     0000000100000000
+
+; right frown +16,+8
+MAFR:: .byte   2,7
+P2     1100000000000000
+P2     1111100000000000
+P2     0011110000000000
+P2     0000011000000000
+P2     0000001100000000
+P2     0000000110000000
+P2     0000000010000000
+; ma smile
+MASML:: .byte  2,7
+P2     0000000100000000
+P2     0000000110000000
+P2     0000000011000000
+P2     0000000001100000
+P2     0000000000111100
+P2     0000000000011111
+P2     0000000000000011
+MASMR:: .byte  2,7
+P2     0000000010000000
+P2     0000000110000000
+P2     0000001100000000
+P2     0000011000000000
+P2     0011110000000000
+P2     1111100000000000
+P2     1100000000000000
+
+; mouth         down 26 right 8
+MAM::  .byte   2,2
+P2     1111111111111111
+P2     1111111111111111
+; CLOSED EYE Left down 7
+MASL:: .byte   2,8
+P2     0000000000110000
+P2     0000000001111000
+P2     0000000011001100
+P2     0000000110000110
+P2     0000000000000000
+P2     0000000000000000
+P2     0000000000000000
+P2     0000001111110000
+; CLOSED Right EYE 16,7
+MASR:: .byte   2,8
+P2     0000110000000000
+P2     0001111000000000
+P2     0011001100000000
+P2     0110000110000000
+P2     0000000000000000
+P2     0000000000000000
+P2     0000000000000000
+P2     0000111111000000
+;~~~~~~~~~~~~~~~
+; machine shop
+;_______________
+; part A loader +3,+3
+PTA::  .byte   1,11
+P1     11111000
+P1     11111000
+P1     10011000
+P1     01101000
+P1     01101000
+P1     00001000
+P1     01101000
+P1     01101000
+P1     01101000
+P1     11111000
+P1     11111000
+; conveyor patterns +11,+8
+;animate (a,h) idle
+;animate a,b,c,d,e,f,g,(h,a) STOP
+C.A:   .byte   2,6     ;empty
+P2     0000000000000000
+P2     1111111100000000
+P2     0000001010000000
+P2     0000011110000000
+P2     0000001010000000
+P2     1111111100000000
+C.B:   .byte   2,6     ;block start
+P2     0110000000000000
+P2     1111111100000000
+P2     0000010110000000
+P2     0000001010000000
+P2     0000010110000000
+P2     1111111100000000
+C.C:   .byte   2,6
+P2     0000011000000000
+P2     1111111100000000
+P2     0000001010000000
+P2     0000011110000000
+P2     0000001010000000
+P2     1111111100000000
+C.D:   .byte   2,6
+P2     0000000000000000
+P2     1111111101100000
+P2     0000010110110000
+P2     0000001010000000
+P2     0000010110000000
+P2     1111111100000000
+C.E:   .byte   2,6
+P2     0000000000000000
+P2     1111111100000000
+P2     0000001010110000
+P2     0000011110011000
+P2     0000001010000000
+P2     1111111100000000
+C.F:   .byte   2,6
+P2     0000000000000000
+P2     1111111100000000
+P2     0000010110000000
+P2     0000001010000000
+P2     0000010110011000
+P2     1111111100001100
+C.G:   .byte   2,8
+P2     0000000000000000
+P2     1111111100000000
+P2     0000001010000000
+P2     0000011110000000
+P2     0000001010000000
+P2     1111111100000000
+P2     0000000000001100
+P2     0000000000000110
+C.H:   .byte   2,6
+P2     0000000000000000
+P2     1111111100000000
+P2     0000010110000000
+P2     0000001010000000
+P2     0000010110000000
+P2     1111111100000000
+; part B tank +5,+18
+PTB::  .byte   1,23
+P1     00110000
+P1     01111000
+P1     11111100
+P1     11111100
+P1     11111100
+P1     10001100
+P1     10110100
+P1     10110100
+P1     10001100
+P1     10110100
+P1     10110100
+P1     10001100
+P1     11111100
+P1     11111100
+P1     01111000
+P1     00110000
+P1     00110000
+P1     01111000
+P1     00110000
+P1     00110100
+P1     00111111
+P1     00011111
+P1     00000100
+; Central machine +12,+16
+PTC::  .byte   2,29
+P2     0011111111111100
+P2     0001111111111000
+P2     0000111111110000
+P2     0000011111100000
+P2     1111111111111111
+P2     1000000000000001
+P2     1001001100101001
+P2     1010101010111001
+P2     1011101100111001
+P2     1010101010101001
+P2     1010101010101001
+P2     1000000000000001
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+P2     1111111111111111
+; Crank
+H.A:   .byte   1,9
+P1     00000000
+P1     00000000
+P1     00000000
+P1     00000000
+P1     11000000
+P1     01000000
+P1     01000000
+P1     01000000
+P1     01111000
+H.B:   .byte   1,8
+P1     00000000
+P1     00000000
+P1     00000000
+P1     00000000
+P1     11000000
+P1     01000000
+P1     01000000
+P1     01111000
+H.C:   .byte   1,5
+P1     00000000
+P1     00000000
+P1     00000000
+P1     00000000
+P1     11111000
+H.D:   .byte   1,5
+P1     00000000
+P1     01111000
+P1     01000000
+P1     01000000
+P1     11000000
+H.E:   .byte   1,5
+P1     01111000
+P1     01000000
+P1     01000000
+P1     01000000
+P1     11000000
+; whirlies
+W.A:   .byte   1,5
+P1     00000100
+P1     00000100
+P1     11111100
+P1     00000100
+P1     00000100
+W.B:   .byte   1,5
+P1     00000010
+P1     00001100
+P1     01110100
+P1     10000100
+P1     00001000
+W.C:   .byte   1,5
+P1     00000010
+P1     00011010
+P1     00100100
+P1     11001000
+P1     00001000
+W.D:   .byte   1,5
+P1     00001001
+P1     00010010
+P1     00100100
+P1     01001000
+P1     10010000
+W.E:   .byte   1,5
+P1     00010000
+P1     00010011
+P1     00100100
+P1     01011000
+P1     01000000
+W.F:   .byte   1,5
+P1     00010000
+P1     00100001
+P1     00101110
+P1     00110000
+P1     01000000
+W.G:   .byte   1,5
+P1     00100000
+P1     00100000
+P1     00111111
+P1     00100000
+P1     00100000
+W.H:   .byte   1,5
+P1     01000000
+P1     00110000
+P1     00101110
+P1     00100001
+P1     00010000
+W.I:   .byte   1,5
+P1     01000000
+P1     01011000
+P1     00100100
+P1     00010011
+P1     00010000
+W.J:   .byte   1,5
+P1     10010000
+P1     01001000
+P1     00100100
+P1     00010010
+P1     00001001
+W.K:   .byte   1,5
+P1     00001000
+P1     11001000
+P1     00100100
+P1     00011010
+P1     00000010
+W.L:   .byte   1,5
+P1     00001000
+P1     10000100
+P1     01110100
+P1     00001100
+P1     00000010
+; LAY A ROBOT PATTERN
+RL0:   .byte   1,1
+P1     01011010
+RL1:   .byte   1,2
+P1     11111111
+P1     01011010
+RL2:   .byte   1,3
+P1     01111110
+P1     11111111
+P1     01011010
+RL3:   .byte   1,4
+P1     11011011
+P1     01111110
+P1     11111111
+P1     01011010
+RL4:   .bYte   1,5
+P1     00111100
+P1     11011011
+P1     01111110
+P1     11111111
+P1     01011010
+RL5:   .byte   1,6
+P1     01111110
+P1     00111100
+P1     11011011
+P1     01111110
+P1     11111111
+P1     01011010
+RL6:   .byte   1,7
+P1     11111111
+P1     01111110
+P1     00111100
+P1     11011011
+P1     01111110
+P1     11111111
+P1     01011010
+RL7:   .byte   1,8
+P1     11101111
+P1     11111111
+P1     01111110
+P1     00111100
+P1     11011011
+P1     01111110
+P1     11111111
+P1     01011010
+RL8:   .byte   1,9
+P1     11111111
+P1     11101111
+P1     11111111
+P1     01111110
+P1     00111100
+P1     11011011
+P1     01111110
+P1     11111111
+P1     01011010
+RL9:   .byte   1,10
+P1     01111110
+P1     11111111
+P1     11101111
+P1     11111111
+P1     01111110
+P1     00111100
+P1     11011011
+P1     01111110
+P1     11111111
+P1     01011010
+;
+; skeletons
+;
+S.4B:
+S.0A:  .byte   1,16
+P1     00111000
+P1     01010100
+P1     01111100
+P1     00101000
+P1     00111000
+P1     00010000
+P1     01111100
+P1     10010010
+P1     10111010
+P1     10010010
+P1     00111000
+P1     00010000
+P1     00111000
+P1     00101000
+P1     00101000
+P1     01101100
+S.4A:  .byte   1,16
+P1     00111000
+P1     01010100
+P1     01111100
+P1     00101000
+P1     00111000
+P1     00010000
+P1     01111100
+P1     10010010
+P1     10111010
+P1     10010000
+P1     00111000
+P1     00010000
+P1     00111000
+P1     00101000
+P1     01101000
+P1     00001100
+S.4C:  .byte   1,16
+P1     00111000
+P1     01010100
+P1     01111100
+P1     00101000
+P1     00111000
+P1     00010000
+P1     01111100
+P1     10010010
+P1     10111010
+P1     00010010
+P1     00111000
+P1     00010000
+P1     00111000
+P1     00101000
+P1     00101100
+P1     01100000
+S.8A:  .byte   1,16
+P1     00111000
+P1     01111100
+P1     01111100
+P1     00111000
+P1     00111000
+P1     00010000
+P1     01111100
+P1     10010010
+P1     10111010
+P1     10010010
+P1     00111000
+P1     00010000
+P1     00111000
+P1     00101000
+P1     00101000
+P1     01101100
+S.8B:  .byte   1,16
+P1     00111000
+P1     01111100
+P1     01111100
+P1     00111000
+P1     00111000
+P1     00010000
+P1     01111100
+P1     10010010
+P1     10111010
+P1     00010010
+P1     00111000
+P1     00010000
+P1     00111000
+P1     00101000
+P1     00101100
+P1     01100000
+S.8C:  .byte   1,16
+P1     00111000
+P1     01111100
+P1     01111100
+P1     00111000
+P1     00111000
+P1     00010000
+P1     01111100
+P1     10010010
+P1     10111010
+P1     10010000
+P1     00111000
+P1     00010000
+P1     00111000
+P1     00101000
+P1     01101000
+P1     00001100
+S.2Aº .bytå  1,16
+P1     00111000
+P1     01110100
+P1     01111100
+P1     00110000
+P1     00111000
+P1     00010000
+P1     01111100
+P1     10010010
+P1     10111010
+P1     10010010
+P1     00111000
+P1     00010000
+P1     00111000
+P1     00101000
+P1     00101000
+P1     00111100
+S.2B:  .byte   1,16
+P1     00111000
+P1     01110100
+P1     01111100
+P1     00110000
+P1     00111000
+P1     00010000
+P1     01111100
+P1     10010010
+P1     10111010
+P1     10010010
+P1     00111000
+P1     00010000
+P1     01111100
+P1     01000100
+P1     01000100
+P1     01100110
+S.2C:  .byte   1,16
+P1     00111000
+P1     01110100
+P1     01111100
+P1     00110000
+P1     00111000
+P1     00010000
+P1     01111100
+P1     10010010
+P1     10111010
+P1     10010010
+P1     00111000
+P1     00010000
+P1     00010000
+P1     00010000
+P1     00010000
+P1     00011000
+S.6Aº .bytå  1,16
+P1     00111000
+P1     01011100
+P1     01111100
+P1     00011000
+P1     00111000
+P1     00010000
+P1     01111100
+P1     10010010
+P1     10111010
+P1     10010010
+P1     00111000
+P1     00010000
+P1     00111000
+P1     00101000
+P1     00101000
+P1     01111000
+S.6B:  .byte   1,16
+P1     00111000
+P1     01011100
+P1     01111100
+P1     00011000
+P1     00111000
+P1     00010000
+P1     01111100
+P1     10010010
+P1     10111010
+P1     10010010
+P1     00111000
+P1     00010000
+P1     01111100
+P1     01000100
+P1     01000100
+P1     11001100
+S.6C:  .byte   1,16
+P1     00111000
+P1     01011100
+P1     01111100
+P1     00011000
+P1     00111000
+P1     00010000
+P1     01111100
+P1     10010010
+P1     10111010
+P1     10010010
+P1     00111000
+P1     00010000
+P1     00010000
+P1     00010000
+P1     00010000
+P1     00110000
+
diff --git a/pat3.asm b/pat3.asm
new file mode 100644 (file)
index 0000000..801b92e
--- /dev/null
+++ b/pat3.asm
@@ -0,0 +1,417 @@
+B>type pat3.asm
+
+; computer room & power plant patterns
+RTL::
+.byte  2,30
+P2     1000000000000000
+P2     1000000000000000
+P2     1000000000000000
+P2     1000000000000111
+P2     1000000000001000
+P2     1000000000010000
+P2     1000000000100000
+P2     1000000000100000
+P2     1000000000100000
+P2     1000000000100000
+P2     1000000000100000
+P2     1000000000100000
+P2     1000000000100000
+P2     1000000000100000
+P2     1000000000100000
+P2     1000000000100000
+P2     1000000000100000
+P2     1000000000100000
+P2     1000000000100000
+P2     1000000000100000
+P2     1000000000100000
+P2     1000000000100000
+P2     1000000000100000
+P2     1000000000100000
+P2     1000000000100000
+P2     1000000000100000
+P2     0100000001000000
+P2     0100000001000000
+P2     0010000010000000
+P2     0001111100000000
+LTL::
+.byte  2,30
+P2     0000000000000001
+P2     0000000000000001
+P2     0000000000000001
+P2     1110000000000001
+P2     0001000000000001
+P2     0000100000000001
+P2     0000010000000001
+P2     0000010000000001
+P2     0000010000000001
+P2     0000010000000001
+P2     0000010000000001
+P2     0000010000000001
+P2     0000010000000001
+P2     0000010000000001
+P2     0000010000000001
+P2     0000010000000001
+P2     0000010000000001
+P2     0000010000000001
+P2     0000010000000001
+P2     0000010000000001
+P2     0000010000000001
+P2     0000010000000001
+P2     0000010000000001
+P2     0000010000000001
+P2     0000010000000001
+P2     0000010000000001
+P2     0000001000000010
+P2     0000001000000010
+P2     0000000100000100
+P2     0000000011111000
+Nose::
+.byte  1,8
+P1     00111100
+P1     00000000
+P1     11111111
+P1     11111111
+P1     11111111
+P1     01111110
+P1     01111110
+P1     00111100
+CM.A:
+.byte  2,4
+P2     111111111111
+P2     100000000001
+P2     100000000001
+P2     111111111111
+;computer mouth dies
+CM.0:
+.byte  2,4
+P2     111111111111
+P2     100000000001
+P2     100111111001
+P2     111111111111
+CM.1:
+.byte  2,6
+P2     111111111111
+P2     100000000001
+P2     101111111101
+P2     111111111111
+P2     000111111000
+P2     000011110000
+CM.2:
+.byte  2,8
+P2     111111111111
+P2     100000000001
+P2     111110111111
+P2     111110111111
+P2     001111111100
+P2     001111111100
+P2     000111111000
+P2     000011110000
+CM.3:
+.byte  2,10
+P2     111111111111
+P2     100000000001
+P2     111110111111
+P2     111110111111
+P2     011110111110
+P2     011110111110
+P2     001111111100
+P2     001111111100
+P2     000111111000
+P2     000011110000
+CM.4:
+.byte  2,12
+P2     111111111111
+P2     100000000001
+P2     111110111111
+P2     111110111111
+P2     011110111110
+P2     011110111110
+P2     011110111110
+P2     011110111110
+P2     001111111100
+P2     001111111100
+P2     000111111000
+P2     000011110000
+CM.5:
+.byte  2,14
+P2     111111111111
+P2     100000000001
+P2     111110111111
+P2     111110111111
+P2     011110111110
+P2     011110111110
+P2     011110111110
+P2     011110111110
+P2     011110111110
+P2     011110111110
+P2     001111111100
+P2     001111111100
+P2     000111111000
+P2     000011110000
+CM.6:
+.byte  2,15
+P2     111111111111
+P2     100000000001
+P2     111110111111
+P2     111110111111
+P2     011110111110
+P2     011110111110
+P2     011110111110
+P2     011110111110
+P2     011110111110
+P2     011110111110
+P2     011110111110
+P2     001111111100
+P2     001111111100
+P2     000111111000
+P2     000011110000
+; Tape Reels animation
+; TAPE REELS
+TR.1:
+.byte  2,12
+P2     0001111000000000
+P2     0011001100000000
+P2     0111001110000000
+P2     0111001110000000
+P2     1111001111000000
+P2     1111111111000000
+P2     1111111111000000
+P2     1111001111000000
+P2     0111001110000000
+P2     0111001110000000
+P2     0011001100000000
+P2     0001111000000000
+TR.2:
+.byte  2,12
+P2     0001111000000000
+P2     0011111100000000
+P2     0100111110000000
+P2     0110011110000000
+P2     1110011111000000
+P2     1111111111000000
+P2     1111111111000000
+P2     1111100111000000
+P2     0111100110000000
+P2     0111110010000000
+P2     0011111100000000
+P2     0001111000000000
+TR.3:
+.byte  2,12
+P2     0001111000000000
+P2     0011111100000000
+P2     0111111110000000
+P2     0111111110000000
+P2     1111111111000000
+P2     1000110001000000
+P2     1000110001000000
+P2     1111111111000000
+P2     0111111110000000
+P2     0111111110000000
+P2     0011111100000000
+P2     0001111000000000
+TR.4:
+.byte  2,12
+P2     0001111000000000
+P2     0011111100000000
+P2     0111110010000000
+P2     0111100110000000
+P2     1111100111000000
+P2     1111111111000000
+P2     1111111111000000
+P2     1110011111000000
+P2     0110011110000000
+P2     0100111110000000
+P2     0011111100000000
+P2     0001111000000000
+; MESSAGE ANIMATION
+GO:
+.byte  2,8
+P2     1111111111110000
+P2     1100111100110000
+P2     1011011011010000
+P2     1011111011010000
+P2     1010011011010000
+P2     1011011011010000
+P2     1100011100110000
+P2     1111111111110000
+GI:
+.byte  2,8
+P2     1111111111110000
+P2     1100111000110000
+P2     1011011101110000
+P2     1011111101110000
+P2     1010011101110000
+P2     1011011101110000
+P2     1100011000110000
+P2     1111111111110000
+X1:
+.byte  2,8
+P2     1111111111110000
+P2     1011101110110000
+P2     1101011100110000
+P2     1110111110110000
+P2     1110111110110000
+P2     1101011110110000
+P2     1011101100010000
+P2     1111111111110000
+Y5:
+.byte  2,8
+P2     1111111111110000
+P2     1011101000010000
+P2     1101011011110000
+P2     1110111000110000
+P2     1110111111010000
+P2     1110111111010000
+P2     1110111000110000
+P2     1111111111110000
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Power Plant patterns
+;___________________________
+Bulb::
+.byte  1,16
+P1     00111100
+P1     01111110
+P1     11111111
+P1     11111111
+P1     11111111
+P1     11111111
+P1     01111110
+P1     00111100
+P1     00011000
+P1     00011000
+P1     00111100
+P1     00011000
+P1     00011000
+P1     00111100
+P1     00011000
+P1     00011000
+Stalk::
+.byte  1,8
+P1     00111100
+P1     00011000
+P1     00011000
+P1     00111100
+P1     00011000
+P1     00011000
+P1     00111100
+P1     00011000
+; lightning
+TL.0:
+.byte  2,8
+P2     111000000000
+P2     000111000000
+P2     000000110000
+P2     000000100000
+P2     000001000000
+P2     000000110000
+P2     000000001100
+P2     000000000011
+TL.1:
+.byte  2,8
+P2     111000000000
+P2     000111000000
+P2     000000110000
+P2     000001110000
+P2     000011000000
+P2     000000110000
+P2     000000001100
+P2     000000000011
+TL.2:
+.byte  2,8
+P2     000000000000
+P2     111110000000
+P2     000001100000
+P2     000010000000
+P2     000110000000
+P2     000001100000
+P2     000000011000
+P2     000000000111
+TL.3:
+.byte  2,8
+P2     000000000000
+P2     000000000000
+P2     111000000000
+P2     000111000000
+P2     000001100000
+P2     000011100000
+P2     000000011100
+P2     000000000111
+TL.4:
+.byte  2,8
+P2     000000000000
+P2     110000000000
+P2     001110000000
+P2     000001110000
+P2     000000100000
+P2     000001000000
+P2     000000111000
+P2     000000000111
+BL.0:
+.byte  2,8
+P2     000000000000
+P2     000000000001
+P2     000011000110
+P2     000010101000
+P2     000100110000
+P2     001000000000
+P2     010000000000
+P2     100000000000
+BL.1:
+.byte  2,8
+P2     000000000001
+P2     000000000010
+P2     000001100100
+P2     000010011000
+P2     000100000000
+P2     001000000000
+P2     010000000000
+P2     100000000000
+BL.2:
+.byte  2,8
+P2     000000000000
+P2     000000000011
+P2     000000001100
+P2     000000010000
+P2     000011100000
+P2     001100000000
+P2     010000000000
+P2     100000000000
+BL.3:
+.byte  2,8
+P2     000000000011
+P2     000000001100
+P2     000000110000
+P2     000010000000
+P2     000000110000
+P2     000111000000
+P2     111000000000
+P2     000000000000
+BL.4:
+.byte  2,8
+P2     000000000011
+P2     000000001110
+P2     000000011000
+P2     000011010000
+P2     000110110000
+P2     001000000000
+P2     010000000000
+P2     100000000000
+BL.5:
+.byte  2,8
+P2     000000000000
+P2     000000000111
+P2     000010001100
+P2     000011001000
+P2     000110110000
+P2     001000010000
+P2     010000000000
+P2     100000000000
+;
+RFILL::
+.byte  2,2
+.byte  0ffh,0f8h
+.byte  0ffh,0f8h
+FILL::
+.byte  2,2
+.byte  0ffh,0f0h
+.byte  0ffh,0f0h
diff --git a/pattern.asm b/pattern.asm
new file mode 100644 (file)
index 0000000..037feb0
--- /dev/null
@@ -0,0 +1,1006 @@
+B>type pattern.asm
+
+.title "PATTERNS"
+.sbttl "FRENZY"
+.ident PATERN
+;~~~~~~~~~~~~~
+; PATTERNS
+;_____________
+HSIZE  ==      32
+; Macros
+.define ANIMATE[P2]=[
+..Loop: .word  P2
+       .word   0,..Loop
+]
+.define P1[A]=
+[.byte ^B'A
+]
+.define P2[A]=
+[.byte ^B'A>8,^B'A&255
+]
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;   Robot Animation TABLES
+;_______________________________
+R.LAY:: .WORD  RL0,RL1,RL2,RL3,RL4,RL5,RL6,RL7,RL8,RL9
+R.0::  .word   R.0A,R.0B,R.0C,R.0D,R.0E
+       .word   R.0H,R.0H,R.0H,R.0H,R.0H
+       .word   R.0I,R.0J,R.0K
+       .word   0,R.0
+R.1::
+R.3::
+R.2::  ANIMATE (R.2A,R.2B,R.2C)
+R.4::  ANIMATE (R.4A,R.4B,R.4C)
+R.5::
+R.7::
+R.6::  ANIMATE (R.6A,R.6B,R.6C)
+R.8::  ANIMATE (R.8A,R.8B,R.8C)
+; explosion animation
+R.9::  .word   R.9A,R.9B,R.9C
+..Loop: .word  R.9D,00,..Loop
+S.0::  ANIMATE (S.0A,S.0A)
+S.2::  ANIMATE (S.2A,S.2B,S.2A,S.2C)
+S.4::  ANIMATE (S.4A,S.4B,S.4A,S.4C)
+S.6::  ANIMATE (S.6A,S.6B,S.6A,S.6C)
+S.8::  ANIMATE (S.8A,S.8B,S.8A,S.8C)
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;    Man Animation TABLES
+;_______________________________
+MS.0::
+M.0::  ANIMATE (M.0A,M.0A)
+M.2::
+M.3::
+M.4::
+M.8::
+M.1::  ANIMATE (M.1C,M.1C,M.1A,M.1A,M.1B,M.1B)
+M.5::
+M.7::
+M.6::  ANIMATE (M.6C,M.6C,M.6A,M.6A,M.6B,M.6B)
+; Man Electrocution
+M.9::  ANIMATE (M.9B,M.9A,M.9C,M.9D)
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Man Shooting Animation Tables
+;_______________________________
+MS.1:: ANIMATE (MS.1A,MS.1A)
+MS.2:: ANIMATE (MS.2A,MS.2A)
+MS.3:: ANIMATE (MS.3A,MS.3A)
+MS.4:: ANIMATE (MS.4A,MS.4A)
+MS.5:: ANIMATE (MS.5A,MS.5A)
+MS.6:: ANIMATE (MS.6A,MS.6A)
+MS.7:: ANIMATE (MS.7A,MS.7A)
+MS.8:: ANIMATE (MS.8A,MS.8A)
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; "Otto's" Animation Table
+;_______________________________
+; SUPER ROBOT
+SR.0:: .word   SR.0A,SR.0B,SR.0C,SR.0D,SR.0E,SR.0F
+..Loop: .word  SR.0M,SR.0H,SR.0I,SR.0J,SR.0K,SR.0J,SR.0I,SR.0H
+       .word   0,..Loop
+SR.1:: ANIMATE (SR.1M,SR.1H,SR.1I,SR.1J,SR.1K,SR.1J,SR.1I,SR.1H)
+SR.2:: ANIMATE (SR.2M,SR.2H,SR.2I,SR.2J,SR.2K,SR.2J,SR.2I,SR.2H)
+;Death
+SR.3:: .word   SR.2J,SR.2K,SR.2J,SR.2I,SR.2H
+       .word   SR.3A,SR.3B,SR.3C,SR.3D
+..Loop: .word  R.9D
+       .word   0,..Loop
+;~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Robot Factory animations
+;__________________________
+;conveyor
+C.PART:: .word C.A,C.B,C.C,C.D,C.E,C.F,C.G     ;falls into idle
+C.IDLE::ANIMATE (C.H,C.A)
+;Crank Handle
+H.GO:: ANIMATE (H.A,H.B,H.C,H.D,H.E,H.D,H.C,H.B)
+H.IDLE::ANIMATE (H.A,H.A)
+;Whirlies
+W.CW:: ANIMATE (W.A,W.B,W.C,W.D,W.E,W.F,W.G,W.H,W.I,W.J,W.K,W.L)
+W.CCW:: ANIMATE (W.L,W.K,W.J,W.I,W.H,W.G,W.F,W.E,W.D,W.C,W.B,W.A)
+TRCCW:: ANIMATE (TR.1,TR.2,TR.3,TR.4)
+CMS::  ANIMATE (GI,X1,Y5,GO,Y5,GI,X1,GO)
+; computer mouth death animation
+CMDIE:: .WORD  CM.0,CM.1,CM.2,CM.3,CM.4,CM.5
+..Loop: .WORD  CM.6,0,..Loop
+CMouth::ANIMATE (CM.A,CM.0,CM.1,CM.2,CM.1,CM.0)
+TL::   ANIMATE (TL.0,R.9D,R.9D,TL.1,R.9D,TL.2,TL.3,TL.4,R.9D)
+BL::   ANIMATE (R.9D,BL.0,BL.1,BL.2,R.9D,R.9D,R.9D,BL.3,BL.4,BL.5,R.9D)
+; END OF PROGRAM SPACE
+AEND::
+;-------------------------------
+       .LOC    .DATA.
+BYTE5:: .byte  0       ;xsum byte
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Patterns
+; Patterns are encoded as an array, X varying fastest
+; Preceding the array are the 'size bytes' X first then Y.
+;
+;      Robot's Patterns
+;_______________________________
+; ROVING EYE SLOT
+R.0A:  .byte   1,11
+P1     00111100
+P1     01111110
+P1     11000111
+P1     11010111
+P1     11000111
+P1     01111110
+P1     00111100
+P1     11011011
+P1     01111110
+P1     11111111
+P1     01011010
+R.0B:  .byte   1,11
+P1     00111100
+P1     01111110
+P1     11100011
+P1     11101011
+P1     11100011
+P1     01111110
+P1     00111100
+P1     11011011
+P1     01111110
+P1     11111111
+P1     01011010
+R.0C:  .byte   1,11
+P1     00111100
+P1     01111110
+P1     11110001
+P1     11110101
+P1     11110001
+P1     01111110
+P1     00111100
+P1     11011011
+P1     01111110
+P1     11111111
+P1     01011010
+R.0D:  .byte   1,11
+P1     00111100
+P1     01111110
+P1     11111000
+P1     11111010
+P1     11111000
+P1     01111110
+P1     00111100
+P1     11011011
+P1     01111110
+P1     11111111
+P1     01011010
+R.0E:  .byte   1,11
+P1     00111100
+P1     01111110
+P1     11111100
+P1     11111101
+P1     11111100
+P1     01111110
+P1     00111100
+P1     11011011
+P1     01111110
+P1     11111111
+P1     01011010
+R.0H:  .byte   1,11
+P1     00111100
+P1     01111110
+P1     11111111
+P1     11111111
+P1     11111111
+P1     01111110
+P1     00111100
+P1     11011011
+P1     01111110
+P1     11111111
+P1     01011010
+R.0I:  .byte   1,11
+P1     00111100
+P1     01111110
+P1     00111111
+P1     10111111
+P1     00111111
+P1     01111110
+P1     00111100
+P1     11011011
+P1     01111110
+P1     11111111
+P1     01011010
+R.0J:  .byte   1,11
+P1     00111100
+P1     01111110
+P1     00011111
+P1     01011111
+P1     00011111
+P1     01111110
+P1     00111100
+P1     11011011
+P1     01111110
+P1     11111111
+P1     01011010
+R.0K:  .byte   1,11
+P1     00111100
+P1     01111110
+P1     10001111
+P1     10101111
+P1     10001111
+P1     01111110
+P1     00111100
+P1     11011011
+P1     01111110
+P1     11111111
+P1     01011010
+
+;ROBOT moving Right
+R.2A:  .byte   1,11
+P1     00111100
+P1     01111110
+P1     11110001
+P1     11110101
+P1     11110001
+P1     01111110
+P1     00111100
+P1     11011011
+P1     01111110
+P1     11111111
+P1     01011010
+R.2B:  .byte   1,11
+P1     00111100
+P1     01111110
+P1     11110001
+P1     11110101
+P1     11110001
+P1     01111110
+P1     00111100
+P1     01101101
+P1     11111111
+P1     11111110
+P1     00110110
+R.2C:  .byte   1,11
+P1     00111100
+P1     01111110
+P1     11110001
+P1     11110101
+P1     11110001
+P1     01111110
+P1     00111100
+P1     10110110
+P1     11111111
+P1     01111111
+P1     01101100
+;ROBOT MOVING LEFT
+R.6A:  .byte   1,11
+P1     00111100
+P1     01111110
+P1     10001111
+P1     10101111
+P1     10001111
+P1     01111110
+P1     00111100
+P1     11011011
+P1     01111110
+P1     11111111
+P1     01011010
+R.6B:  .byte   1,11
+P1     00111100
+P1     01111110
+P1     10001111
+P1     10101111
+P1     10001111
+P1     01111110
+P1     00111100
+P1     10110110
+P1     11111111
+P1     01111111
+P1     01101100
+R.6C:  .byte   1,11
+P1     00111100
+P1     01111110
+P1     10001111
+P1     10101111
+P1     10001111
+P1     01111110
+P1     00111100
+P1     01101101
+P1     11111111
+P1     11111110
+P1     00110110
+;ROBOT MOVING UP
+R.8A:  .byte   1,11
+P1     00111100
+P1     01111110
+P1     11111111
+P1     11111111
+P1     11111111
+P1     01111110
+P1     00111100
+P1     11111111
+P1     00011111
+P1     11111000
+P1     11100111
+R.8B:  .byte   1,11
+P1     00111100
+P1     01111110
+P1     11111111
+P1     11111111
+P1     11111111
+P1     01111110
+P1     00111100
+P1     00011111
+P1     11111000
+P1     11111111
+P1     00000111
+R.8C:  .byte   1,11
+P1     00111100
+P1     01111110
+P1     11111111
+P1     11111111
+P1     11111111
+P1     01111110
+P1     00111100
+P1     11111000
+P1     11111111
+P1     00011111
+P1     11100000
+;ROBOT MOVING DOWN
+R.4A:  .byte   1,11
+P1     00111100
+P1     01111110
+P1     11111111
+P1     11000111
+P1     11010111
+P1     01000110
+P1     00111100
+P1     11111111
+P1     00011111
+P1     11111000
+P1     11100111
+R.4B:  .byte   1,11
+P1     00111100
+P1     01111110
+P1     11111111
+P1     11000111
+P1     11010111
+P1     01000110
+P1     00111100
+P1     11111000
+P1     11111111
+P1     00011111
+P1     11100000
+R.4C:  .byte   1,11
+P1     00111100
+P1     01111110
+P1     11111111
+P1     11000111
+P1     11010111
+P1     01000110
+P1     00111100
+P1     00011111
+P1     11111000
+P1     11111111
+P1     00000111
+;ROBOT BLOWS UP
+R.9A:  .byte   2,17
+.word  0,0,0,0,0,0
+P2     0000001111000000
+P2     0000011111100000
+P2     0000111101111000
+P2     0001001111001000
+P2     0000101011010000
+P2     0000001101000000
+P2     0011001111001100
+P2     0000100111110000
+P2     0000001001001000
+P2     0001111001111000
+P2     0000011001100000
+
+R.9B:  .byte   2,17
+.word  0,0,0,0
+P2     0000001111000000
+P2     0000011001100000
+P2     0001001001001000
+P2     0000100010010000
+P2     0001000000001000
+P2     0010001001000100
+P2     0010010001001000
+P2     0000101010010000
+P2     0001001101100000
+P2     0000100000011000
+P2     0001010000100000
+P2     0000001001000000
+P2     0000011001100000
+
+R.9C:  .byte   2,19
+.word  0
+P2     0000001000000000
+P2     0000000000100000
+P2     0000000100001000
+P2     0001000000000000
+P2     0000001001000000
+P2     0010000000010010
+P2     0000100000000001
+P2     1000000000100000
+P2     0000100010000010
+P2     0100000000000010
+P2     0000010000010000
+P2     0010000100000000
+P2     0000100000000100
+P2     0010000000000010
+P2     0000010000001000
+P2     0010000000100000
+P2     0001000000001000
+P2     0001100000001100
+
+R.9D:: .byte   1,1
+       .byte   0
+
+;super robot patterns
+.define DROP[Down]=[
+       .word   (Down)+8000H
+]
+
+SR.0A: DROP    16*HSIZE
+       .byte   1,2
+P1     00011000
+P1     00011000
+SR.0B: DROP    16*HSIZE
+       .byte   1,3
+P1     00010000
+P1     00111000
+P1     00010000
+SR.0C: DROP    16*HSIZE
+       .byte   1,4
+P1     00010000
+P1     00111000
+P1     00111000
+P1     00010000
+SR.0D: DROP    16*HSIZE
+       .byte   1,5
+P1     00011000
+P1     00111100
+P1     00111100
+P1     00111100
+P1     00011000
+SR.0E: DROP    16*HSIZE
+       .byte   1,6
+P1     00111000
+P1     01111100
+P1     01111100
+P1     01111100
+P1     01111100
+P1     00111000
+SR.0F: DROP    16*HSIZE
+       .byte   1,7
+P1     00111000
+P1     01111100
+P1     11111110
+P1     11111110
+P1     11111110
+P1     01111100
+P1     00011100
+SR.0G: DROP    16*HSIZE
+       .byte   1,8
+P1     00011000
+P1     01111110
+P1     01011010
+P1     11111111
+P1     11111111
+P1     01111110
+P1     01111110
+P1     00011000
+SR.0H: DROP    8*HSIZE
+       .byte   1,10
+P1     00011000
+P1     01111110
+P1     01111110
+P1     11011011
+P1     11111111
+P1     10111101
+P1     11011011
+P1     01100110
+P1     01111110
+P1     00011000
+SR.0I: DROP    4*HSIZE
+       .byte   1,10
+P1     00011000
+P1     01111110
+P1     01111110
+P1     11011011
+P1     11111111
+P1     10111101
+P1     11011011
+P1     01100110
+P1     01111110
+P1     00011000
+SR.0J: DROP    2*HSIZE
+       .byte   1,10
+P1     00011000
+P1     01111110
+P1     01111110
+P1     11011011
+P1     11111111
+P1     10111101
+P1     11011011
+P1     01100110
+P1     01111110
+P1     00011000
+SR.0K: .byte   1,10
+P1     00011000
+P1     01111110
+P1     01111110
+P1     11011011
+P1     11111111
+P1     10111101
+P1     11011011
+P1     01100110
+P1     01111110
+P1     00011000
+
+SR.1M:
+SR.2M:
+SR.0M: DROP    16*HSIZE
+       .byte   1,9
+       .byte   0,0,0
+P1     00111100
+P1     01011010
+P1     11111111
+P1     11111111
+P1     11000011
+P1     01111110
+SR.1H: DROP    8*HSIZE
+       .byte   1,10
+P1     00011000
+P1     01111110
+P1     01111110
+P1     11011011
+P1     11111111
+P1     11111111
+P1     11000011
+P1     01111110
+P1     01111110
+P1     00011000
+SR.1I: DROP    4*HSIZE
+       .byte   1,10
+P1     00011000
+P1     01111110
+P1     01111110
+P1     11011011
+P1     11111111
+P1     11111111
+P1     11000011
+P1     01111110
+P1     01111110
+P1     00011000
+SR.1J: DROP    2*HSIZE
+       .byte   1,10
+P1     00011000
+P1     01111110
+P1     01111110
+P1     11011011
+P1     11111111
+P1     11111111
+P1     11000011
+P1     01111110
+P1     01111110
+P1     00011000
+SR.1K: .byte   1,10
+P1     00011000
+P1     01111110
+P1     01111110
+P1     11011011
+P1     11111111
+P1     11111111
+P1     11000011
+P1     01111110
+P1     01111110
+P1     00011000
+SR.2H: DROP    8*HSIZE
+       .byte   1,10
+P1     00011000
+P1     01111110
+P1     01111110
+P1     11011011
+P1     11111111
+P1     11111111
+P1     11100111
+P1     01011010
+P1     01111110
+P1     00011000
+SR.2I: DROP    4*HSIZE
+       .byte   1,10
+P1     00011000
+P1     01111110
+P1     01111110
+P1     11011011
+P1     11111111
+P1     11111111
+P1     11100111
+P1     01011010
+P1     01111110
+P1     00011000
+SR.2J: DROP    2*HSIZE
+       .byte   1,10
+P1     00011000
+P1     01111110
+P1     01111110
+P1     11011011
+P1     11111111
+P1     11111111
+P1     11100111
+P1     01011010
+P1     01111110
+P1     00011000
+SR.2K: .byte   1,10
+P1     00011000
+P1     01111110
+P1     01111110
+P1     11011011
+P1     11111111
+P1     11111111
+P1     11100111
+P1     01011010
+P1     01111110
+P1     00011000
+SR.3A: DROP    16*HSIZE
+       .byte   1,9
+       .byte   0,0,0,0,0
+P1     00111100
+P1     01011010
+P1     11000011
+P1     11111111
+SR.3B: DROP    16*HSIZE
+       .byte   1,9
+       .byte   0,0,0,0,0,0
+P1     00111100
+P1     01011010
+P1     11111111
+SR.3C: DROP    16*HSIZE
+       .byte   1,9
+       .byte   0,0,0,0,0,0,0
+P1     00111100
+P1     11111111
+SR.3D: DROP    16*HSIZE
+       .byte   1,9
+       .byte   0,0,0,0,0,0,0,0
+P1     11111111
+
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Man's Patterns
+;_______________________________
+M.0A:  .byte   1,16
+P1     00011000
+P1     00011000
+P1     00000000
+P1     00111100
+P1     01011010
+P1     01011010
+P1     01011010
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011100
+P1     00011000
+
+M.1A:  .byte   1,16
+P1     00011000
+P1     00011000
+P1     00000000
+P1     00111100
+P1     01011010
+P1     10011010
+P1     01011001
+P1     00011000
+P1     00011000
+P1     00100100
+P1     00100010
+P1     01000001
+P1     01000001
+P1     10000001
+P1     10000001
+P1     11000000
+
+M.1B:  .byte   1,16
+P1     00000000
+P1     00011000
+P1     00011000
+P1     00000000
+P1     00111100
+P1     01011100
+P1     01011010
+P1     00111010
+P1     00011000
+P1     00011000
+P1     00010100
+P1     00010010
+P1     11110010
+P1     10000010
+P1     00000010
+P1     00000011
+
+M.1C:  .byte   1,16
+P1     00011000
+P1     00011000
+P1     00000000
+P1     00111100
+P1     00111100
+P1     00111100
+P1     00011010
+P1     00011000
+P1     00011000
+P1     00001100
+P1     00001010
+P1     00001111
+P1     01111000
+P1     01001000
+P1     00001000
+P1     00001100
+
+M.6A:  .byte   1,16
+P1     00011000
+P1     00011000
+P1     00000000
+P1     00111100
+P1     01011010
+P1     01011001
+P1     10011010
+P1     00011000
+P1     00011000
+P1     00100100
+P1     01000100
+P1     10000010
+P1     10000010
+P1     10000001
+P1     10000001
+P1     00000011
+;
+M.6B:  .byte   1,16
+.byte  0
+P1     00011000
+P1     00011000
+P1     00000000
+P1     00111100
+P1     00111010
+P1     00111010
+P1     11011100
+P1     00011000
+P1     00011000
+P1     00101000
+P1     01001000
+P1     01001111
+P1     01000001
+P1     01000000
+P1     10000000
+;
+M.6C:  .byte   1,16
+P1     00011000
+P1     00011000
+.byte  0
+P1     00111100
+P1     00111100
+P1     00111100
+P1     01011000
+P1     00011000
+P1     00011000
+P1     00110000
+P1     01010000
+P1     11110000
+P1     00011110
+P1     00010010
+P1     00010000
+P1     00110000
+
+; NORMAL
+M.9A:  .byte   1,16
+.byte  0
+P1     00011000
+P1     00011000
+P1     00000000
+P1     00111100
+P1     01011010
+P1     01011010
+P1     01011010
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00111100
+; OUTLINE
+M.9B:  .byte   1,17
+P1     00011000
+P1     00100100
+P1     00100100
+P1     01000010
+P1     10000001
+P1     10000001
+P1     10000001
+P1     10000001
+P1     10000001
+P1     01000010
+P1     00100100
+P1     00100100
+P1     00100100
+P1     00100100
+P1     00100100
+P1     01000010
+P1     00111100
+; NEGATIVE
+M.9C:  .byte   1,17
+P1     00011000
+P1     00100100
+P1     00100100
+P1     01111110
+P1     11000011
+P1     10100101
+P1     10100101
+P1     10100101
+P1     11100111
+P1     01100110
+P1     00100100
+P1     00100100
+P1     00100100
+P1     00100100
+P1     01100110
+P1     01000010
+P1     00111100
+; BIG BLOCK
+M.9D:  .byte   1,17
+P1     00111100
+P1     00111100
+P1     00111100
+P1     01111110
+P1     11111111
+P1     11111111
+P1     11111111
+P1     11111111
+P1     11111111
+P1     01111110
+P1     00111100
+P1     00111100
+P1     00111100
+P1     00111100
+P1     01111110
+P1     01111110
+P1     01111110
+; SHOOTING PATTERNS
+MS.1A: .byte   1,15
+P1     00011000
+P1     00011001
+P1     00000010
+P1     00011100
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011100
+
+MS.2A: .byte   1,15
+P1     00011000
+P1     00011000
+P1     00000000
+P1     00011111
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011100
+
+MS.3A: .byte   1,15
+P1     00011000
+P1     00011000
+P1     00000000
+P1     00011000
+P1     00011000
+P1     00011100
+P1     00011010
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011100
+
+MS.4A: .byte   1,15
+P1     00011000
+P1     00011000
+P1     00000000
+P1     00111100
+P1     00111100
+P1     00111010
+P1     00111010
+P1     00111010
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011100
+
+MS.5A: .byte   1,15
+P1     00011000
+P1     00011000
+P1     00000000
+P1     00111100
+P1     00111100
+P1     01011100
+P1     10011100
+P1     00011100
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00111000
+
+MS.6A: .byte   1,15
+P1     00011000
+P1     00011000
+P1     00000000
+P1     11111000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00111000
+
+MS.7A: .byte   1,15
+P1     10011000
+P1     01011000
+P1     00100000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00111000
+
+MS.8A: .byte   1,15
+P1     00011000
+P1     00011000
+P1     00000000
+P1     00011101
+P1     00011011
+P1     00011001
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011000
+P1     00011100
+
+.INSERT CHARSET
+.INSERT PAT2
+.INSERT PAT3
+
+PEND:: 
+       .end
diff --git a/play.asm b/play.asm
new file mode 100644 (file)
index 0000000..6664249
--- /dev/null
+++ b/play.asm
@@ -0,0 +1,424 @@
+B>type play.asm
+
+.title "PLAY A ROUND"
+.sbttl "FRENZY"
+.ident PLAY
+;--------------+
+; PLAY A ROUND |
+;--------------+
+.insert equs
+.intern PLAY,ScorePtr,REST,ADDS,SHOWS
+.extern COINCK,ItemInc,RANDOM,C.MOVE,SHOWN
+;-----------------------
+; PLAY 1 ROUND OF ROBO
+;-----------------------
+PLAY:  pop     h
+       shld    PlayRet
+       call    CLEAR#          ;ERASE Screen
+       call    ROOM#           ;DRAW ROOM
+       lda     Demo            ;IF DEMO DONT FLASH MAN
+       ora     a
+       jrnz    AGAIN
+; FLASH MAN
+       call    M.INIT#
+       lxi     b,(16<8)!(1<COLOR)!(1<WRITE)
+       lda     N.PLRS
+       cpi     2
+       jrz     ..lp
+       mvi     B,6             ;short flashing
+..lp:  mov     V.STAT(x),c     
+       WAIT    10
+       mvi     A,(1<COLOR)!(1<BLANK)!(1<WRITE)!(1<ERASE)
+       xra     c
+       mov     c,a
+       djnz    ..lp
+       call    REST            ;vector initialize
+;PLAY AGAIN LOOP
+AGAIN: ei
+       xra     a
+       sta     IqFlg
+       sta     WallPts
+       mvi     a,90            ;(otto resets it)
+       sta     KWait           ;killoff wait
+       lda     PERCENT         ;figure new percent
+..ad:  adi     6
+..lp:  cpi     22+1
+       jrc     ..ok
+       sui     22
+       cpi     7
+       jrc     ..ad
+       jmpr    ..lp
+..ok:  sta     PERCENT
+       sta     MEMPHS
+       FORK    MAN#
+       FORK    SUPER#
+       lda     RoomCnt
+       ORA     A
+       JRZ     ..NSP
+       ani     3               ;test for special room
+       jrnz    ..nsp
+       FORK    FACTORY#
+..nsp: xra     a
+       sta     Robots
+; start up man,robots,otto
+..rlp: FORK    ROBOT#
+       lxi     h,PERCENT
+       dcr     m
+       jrnz    ..rlp
+       lda     MEMPHS
+       sta     PERCENT
+;--------------------------------
+; TEST FOR MAN DEAD [GAME OVER]
+;--------------------------------
+TLOP:  call    NEXT.J#
+       lxi     x,Vectors       ;man vector
+       bit     MOVE,0(x)       ;if no moving he's dead
+       jz      DEAD
+       mov     a,P.Y(x)        ;STORE LATEST X AND Y
+       sta     ManY            ;INTO INITIAL X,Y
+       mov     b,a
+       mov     a,P.X(x)
+       sta     ManX
+       bit     INEPT,0(x)
+       jnz     NoWAY           ;skip tests if man is hit
+       lxi     D,AGAIN         ;common return address after
+       push    D               ;scrolling
+       cpi     5
+       jc      OLEFT
+       cpi     246
+       jnc     ORIGHT
+       mov     a,b
+       cpi     5
+       jc      OUP
+       cpi     190
+       jnc     ODOWN
+       pop     D
+;not off edges
+NoWAY: call    Awpts           ;award wall pts
+       lda     UPDATE          ;if score hasn't changed
+       ora     a               ;then skip
+       cnz     SHOWS           ;show score
+       lda     Kwait           ;killoff?
+       ora     a
+       jrnz    ..nk
+       dcr     a
+       sta     KWait
+       FORK    KLUTZ#
+..nk:  lda     Demo            ;TEST FOR Demo GAME
+       ora     a
+       jrz     ..sk
+; if in a demo game
+       call    COINCK          ;show new coins
+..sk:
+       jmp     TLOP
+;return to go or main
+DEAD:  call    NoSnd#
+       lhld    PlayRet         ;return to caller
+       pchl
+;-------------------------
+; MOVED OFF EDGE ROUTINES
+;-------------------------
+ODOWN: mvi     A,10
+       sta     ManY
+       lxi     h,RoomX+1
+       inr     m
+       lxi     h,RoomUp#               ;type of room routine
+       push    h                       ;to execute after scroll
+       call    TREST
+       jrz     NorD
+       lxi     d,Screen+223*Hsize-1
+       jmp     S.D
+NorD:  lxi     d,Screen
+;--------------------
+;      SCROLL UP
+;--------------------
+S.U:   mvi     A,27
+..lp:  lxi     h,8*Hsize
+       dad     d
+       lxi     b,200*Hsize
+       push    d
+       ldir                    ;scroll up 8 lines
+       pop     d
+       lxi     b,8*Hsize
+..lp2: dcx     h               ;clear junk under room edge
+       mvi     M,0
+       dcr     c
+       jnz     ..lp2
+       djnz    ..lp2
+       dcr     a
+       jrnz    ..lp
+       ret                     ;will goto RoomXX then AGAIN
+;---------------------
+;      OFF TOP
+;---------------------
+OUP:   mvi     A,178
+       sta     ManY
+       lxi     h,RoomX+1
+       dcr     m
+       lxi     h,RoomDown#             ;type of room routine
+       push    h                       ;to execute after scroll
+       call    TREST
+       jrz     NorU
+       lxi     d,Screen+16*Hsize
+       jmp     S.U
+NorU:  lxi     d,208*Hsize+Screen-1
+;---------------------
+;      SCROLL DOWN
+;---------------------
+S.D:   mvi     A,26
+DL:    lxi     b,200*Hsize
+       lxi     h,-8*Hsize
+       dad     d
+       push    d
+       lddr
+       pop     d
+       lxi     b,8*Hsize
+DL2:   inx     h
+       mvi     M,0
+       dcr     c
+       jnz     DL2
+       djnz    DL2
+       dcr     a
+       jrnz    DL
+       ret                     ;goes to room,again
+;---------------------
+; OFF RIGHT EDGE
+;---------------------
+ORIGHT: mvi    A,19
+       sta     ManX
+       lxi     h,RoomX+0
+       inr     m
+       lxi     h,RoomLeft#             ;type of room routine
+       push    h                       ;to execute after scroll
+       call    TREST
+       jrz     NorR
+       lxi     d,Screen+223*Hsize
+       jmp     S.R
+NorR:  lxi     d,Screen
+;---------------------
+;      SCROLL LEFT
+;---------------------
+S.L:   mvi     a,Hsize
+LL:    lxi     b,Hsize*208-1
+       lxi     h,1
+       dad     d
+       push    d
+       ldir
+       mvi     B,208
+       lxi     d,-Hsize+1
+LL2:   mvi     M,0
+       dcx     h
+       mvi     M,0
+       dad     d
+       djnz    LL2
+       pop     d
+       dcr     a
+       jrnz    LL
+       ret                     ;goes to room,again
+;---------------------
+;      OFF LEFT EDGE
+;---------------------
+OLEFT: mvi     A,228
+       sta     ManX
+       lxi     h,RoomX+0
+       dcr     m
+       lxi     h,RoomRight#            ;type of room routine
+       push    h                       ;to execute after scroll
+       call    TREST
+       jrz     NorL
+       lxi     d,Screen+16*Hsize
+       jmp     S.L
+NorL:  lxi     d,Screen+208*Hsize
+;---------------------
+;      SCROLL RIGHT
+;---------------------
+S.R:   mvi     a,Hsize
+XRL:   lxi     b,Hsize*208
+       lxi     h,-1
+       dad     d
+       push    d
+       lddr
+       lxi     d,Hsize-1
+XRL2:  mvi     M,0
+       inx     h
+       mvi     M,0
+       dad     d
+       djnz    XRL2
+       pop     d
+       dcr     a
+       jrnz    XRL
+       ret                     ;goes to room,again
+;----------------------------
+; STOP TALKING,MOVES & COLOR
+;----------------------------
+TREST: call    C.MOVE
+REST:  di
+       call    STOP.B
+       lxi     h,Vectors+VLEN
+       shld    L.PTR
+       lxi     h,Vectors
+       shld    V.PTR
+       lxi     b,VLEN*MaxVec
+       call    Zap#
+       call    JobInit#
+       call    TimerInit#
+       lda     FLIP
+       ora     a
+       ret
+;---------------------
+; STOP BULLET VECTORS
+;---------------------
+STOP.B: lxi    h,BUL1
+       lxi     b,Blength*Bolts
+       call    Zap
+       ret
+;-------------
+; SHOW SCORE
+;-------------
+SHOWS: xra     a
+       sta     UPDATE
+       lxi     d,213*256+0
+       lxi     h,SCORE1
+       mvi     B,6
+       call    SHOWN
+       lda     N.PLRS
+       cpi     2
+       rnz     
+       lxi     d,213*256+176
+       lxi     h,SCORE2
+       mvi     B,6
+       jmp     SHOWN
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;  ->HL AT PLAYERS SCORE
+;_______________________________
+ScorePtr:
+       lda     PLAYER
+       cpi     2
+       lxi     h,SCORE2
+       rz      
+       lxi     h,SCORE1
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Award wall points
+;_______________________________
+Awpts: lxi     h,WallPts
+       mov     a,m             ;check wall points
+       ora     a
+       rz
+       mov     c,a             ;save score
+       NEG
+       di                      ;points maybe awarded in int by now
+       add     m               ;sub the point awarded
+       mov     m,a             ;update it
+       ei
+       mov     a,c
+       push    psw
+       rrc                     ;get 10's
+       rrc
+       rrc
+       rrc
+       mvi     b,1             ;10's
+       call    ..awd
+       pop     psw
+       mvi     b,0             ;1's
+..awd: ani     0fh             ;isolate score
+       mov     c,a             ;save in c for adds
+       lda     Wpoint          ;multiplier
+..1:   push    psw
+       push    b
+       call    ADDS            ;score 1's
+       pop     b
+       pop     psw
+       dcr     a               ;dec multiplier
+       jrnz    ..1
+       ret
+;------------------------+
+; ADD C X 10**B TO SCORE |
+;------------------------+
+ADDS:  mvi     A,0FFH
+       sta     UPDATE
+       mvi     E,3+1           ;NUMBER OF BYTES
+       call    ScorePtr
+       inx     h
+       inx     h
+       inx     h
+       srlr    B               ;DIVIDE BY 2, REMAINDER TO CARRY
+       exaf                    ;SAVE CARRY
+       inr     b
+..lp:  dcx     h
+       dcr     e               ;ONE LESS BYTE
+       djnz    ..lp
+; HL->SCORE BYTE CARRY FLAG = ODD/EVEN, C=VALUE
+       exaf                    ;RESTORE CARRY
+       jrnc    ..skp
+       slar    C               ;SHIFT SCORE
+       slar    C
+       slar    C
+       slar    C
+..skp: mov     a,e             ;byte number
+       cpi     2               ;checking for thousands
+       jrz     ..td
+       mov     a,c             ;add score
+       add     M
+       daa
+       mov     m,a
+       jrnc    ..done
+..entr: dcx    h
+       mvi     C,1
+       dcr     e               ;ONE LESS BYTE
+       jrnz    ..skp
+..done: ret
+
+; test thousands for extra man award
+..td:  mov     a,m
+       mov     b,a             ;save it
+       add     c               ;add score
+       daa
+       mov     m,a
+       mvi     c,2             ;flag for add 1 to next
+       jrc     ..noc           ;if carry then 2 else 1
+       dcr     c               ;c=1
+..noc: ani     0F0h            ;isolate top nibble
+       exaf
+       mov     a,b             ;do same to b
+       ani     0F0h
+       mov     b,a
+       exaf
+       sub     b               ;check for change
+       daa
+       jrz     ..ext
+       rrc
+       rrc
+       rrc
+       rrc                     ;1-10 bcd
+;now see if time for extra life
+       mov     b,a             ;save change
+       lda     XtraMen
+       ora     a
+       jrz     ..ext
+       sub     b               ;b=#of 1k's
+       jrc     ..give          ;should be Minus?
+       jrz     ..give
+       sta     XtraMen         ;put away extra life accum
+..ext: dcr     c
+       jz      ..done
+       jmp     ..entr
+;award extra life
+..give: mov    b,a             ;save negative or zero remainder
+       in      DIP2            ;get extra life dip
+       ani     15              ;0-15
+       sub     b               ;sub remainder
+       sta     XtraMen
+       push    b
+       push    d
+       push    h
+       lxi     h,DEATHS
+       inr     m               ;inc [deaths]
+       call    SXLIFE#
+       call    SHOWD#
+       pop     h
+       pop     d
+       pop     b
+       jmp     ..ext
+
+       .end
diff --git a/powerup.asm b/powerup.asm
new file mode 100644 (file)
index 0000000..afe7ee0
--- /dev/null
@@ -0,0 +1,766 @@
+B>type powerup.asm
+
+.title "Powerup tests"
+.sbttl "FRENZY"
+.ident POWERUP
+;----------------
+; power up tests
+;----------------
+.insert EQUS
+.extern MAIN,NMI,DSPSW,ALIGN
+; locations NMIflg are scratch flags. they are cleared by the game
+; when it starts up. NMIflg is used to select which nmi routine to run.
+
+%Zero  ==      .
+
+.main.::
+       nop             ;this must be here for the sound processor
+       di              ;this is a good idea.
+       xra     a
+       out     NMIOFF
+       stai
+; test vfb signature analysis dip
+       in      DIP1    ;bottom dip bank
+       bit     0,A
+       jnz     VFBSA   ;do vfb signature analysis if switch one closed
+       bit     2,A
+       jnz     DSPSW
+       bit     3,A
+       jnz     ALIGN
+       lxi     x,ROMTST
+       jmpr    D2
+
+;MACROS
+.define PCALL[ADR]=[
+       lxi     x,.+4+3
+       jmp     ADR
+]
+
+ROMNUM: .byte  4               ;number of roms (not including utility)
+RAMST: .word   BatteryRAM      ;start of battery backup ram
+RAMS12: .word  Credits-BatteryRAM-2    ;length of battery backup ram
+
+; flash LED ring bell
+D0:    lxi     b,00            ;delay
+DEL1:  dcr     c
+       jrnz    DEL1
+       djnz    DEL1
+D1:    in      66H             ;led on
+D2:    mvi     A,1             ;tone on
+       lxi     b,0141H
+       lxi     d,8247H
+D3:    OUTP    B               ; 01 to 41 or 51
+       dcr     c
+       OUTP    D               ; 82 to 40 or 50
+       inr     c
+       inr     c
+       OUTP    B               ; 01 to 42 or 52
+       inr     c
+       OUTP    B               ; 01 to 43 or 53
+       inr     c
+       inr     c
+       inr     c
+       OUTP    E               ; 47 to 46 or 56
+       mvi     C,51H
+       dcr     a
+       jrz     D3
+       lxi     b,00            ;delay
+DEL2:  dcr     c
+       jrnz    DEL2
+       djnz    DEL2
+       in      67H             ;led off
+       xra     a
+       out     40H             ;tone off
+       out     50H             ;tone off
+       pcix
+;-------------------
+; place nmi in here
+;-------------------
+.blkb  66h-(.-%Zero)
+.ifn   (.-%Zero)-66h,[.error /NMI Address/]
+       out     NMIOFF
+       push    psw     ;don't change this without fixing nmi in file main
+       lda     NMIflg
+       ora     a
+       jnz     NMIADD  ; do test nmi
+;      pop     psw     ;done in nmi
+       jmp     NMI
+
+; ROM test
+;this routine reads romnum from the first game rom.
+;it tests the checksum in the first romnum game roms and flags an error
+;if there is one. It checks the remaining game roms to see if they contain
+;any zeros. if a rom does, it tests its checksum and flags an error if
+;there is one. it tests the checksum of the utility rom and flags an error
+;if necessary. If I=1 it goes to scrram if no error and to exclp if an error.
+;e will equal
+;1 error in game rom 6 [C000-Cfff]
+;2             5 [3000-3Fff]
+;3             3 [2000-2Fff]
+;4             1 [1000-1Fff]
+;80 error in utility rom [0-Fff]
+;if i = 0 and there is an error it will halt if no error it will go to romrtn.
+ROMTST:: mvi   E,4
+       lxi     x,1000H
+ROM1:  lxi     b,1000H         ;bc = 4096
+       mvi     H,0             ;h = 0
+       mvi     L,0FFH          ;l = ff
+ROM2:  mov     a,0(x)          ;a = [ix]
+       mov     d,a
+       ana     l
+       mov     l,a             ;l = l and a
+       mov     a,d
+       add     H
+       mov     h,a             ;h = h + a
+       inx     x               ;ix = ix + 1
+       dcr     c
+       jrnz    ROM2
+       djnz    ROM2            ;loop 2048 times
+       lda     ROMNUM
+       cpi     0FFH            ;bad system rom
+       jrz     ROM5
+       mov     a,E
+       CPI     2
+       JNZ     ..
+       LXI     X,0C000H
+..:    ora     a
+       jp      ROM3            ;jmp if testing system rom
+       mov     a,l             ;test for empty socket
+       inr     a
+       jrz     ROM4            ;jmp to rom4 if l = ff
+ROM3:
+;      mvi     A,0FFH
+       mov     a,e             ;get rom number
+       cmp     h               ;xsum = romnum?
+       jrnz    ROM5            ;jmp to rom5 if checksum <> ff
+ROM4:  mov     a,e             ;here if chksm = ff or empty socket
+       rlcr    A               ;contains all zeros
+       jc      ROMRTN          ;to romrtn if e = 80
+       dcr     e               ;e = e - 1
+       jrnz    ROM1            ;to rom1 if e <> 0
+       ldai
+       ana     a
+       jnz     SCRRAM          ;jump to scrram if in sa
+       lxi     x,0             ;ix = 0
+       mvi     E,080H          ;e = 80h
+       jmpr    ROM1            ;to rom1 to start new rom
+ROM5:  ldai                    ;here if checksum error
+       ana     a
+       jnz     EXCLP           ;to exclp if in sa
+CKTRAP::                       ;halt if in powerup (cksum error)
+       jmpr    .               ;hang in the real system
+;
+ROMRTN: PCALL  D0              ;in power up, ring bell & led
+       jmp     SCRRAM
+BYTE1:: .byte  0
+
+; zpu sa loop
+ZPUSA: mvi     A,1
+       stai                    ;i = 1
+       jmp     ROMTST
+
+; you get here by restarting with the sae connector in the test position
+;      .loc    100H
+.blkb  100h-(.-%Zero)
+.ifn   (.-%Zero)-100h,[.error /100 Address/]
+       jmpr    ZPUSA
+
+; sa error execution loop
+; e = one of the following numbers upon entering this routine
+;e = 20 no ram or rom errors - - sa = 0
+;e = 1 rom error 3800-3fff
+;e = 2 rom error 3000-37ff
+;e = 3 "       "       2800-2fff
+;e = 4 "       "       2000-27ff
+;e = 5 "       "       1800-1fff - - sa = 5220 VCC = 8A02
+;e = 6 "       "       1000-17ff
+;e = 10 ram error both nibbles - - sa = 6u6f
+;e = 11 ram error low nibble - - sa = fa6p
+;e = 12 ram error high nibble - - sa = ufp4
+;the routine will loop forever and a signature corresponding
+;to the value of e can be read on a13 with the rising edge of
+; 0 as the clock and a15 as the start/stop signal
+EXCLP: lxi     b,08C0H
+       lxi     h,0H
+       mvi     D,8
+RDLP:  mov     a,m     ;read once from each rom and
+       dad     b       ;ram chip, write to ram chips
+       xra     a
+       star
+       sta     1000H
+       dcr     d
+       jrnz    RDLP
+       mvi     C,7FH   ;c = 7f
+       mvi     D,20H
+INPLP: mov     a,e
+       ani     20H
+       mov     b,a     ;b = e and 20h
+       inp     A       ;input w.bit 5 of e on a13
+       rrcr    E       ;rotate e right
+       dcr     c       ;c = c - 1
+       dcr     d
+       jrnz    INPLP   ;do it for c=7f to 60(ports on zpu board)
+       mvi     A,80H
+       lxi     b,8057H
+OUTLP: OUTP    A
+       dcr     b
+       dcr     c
+       rrcr    A
+       jrnc    OUTLP
+       mvi     C,47H
+OUTLP1: OUTP   A
+       dcr     c
+       rrcr    A
+       jrnc    OUTLP1
+       jmpr    EXCLP
+
+;      scratch ram test
+;
+;this routine tests the scratchpad ram, starting at location ramst,
+;and going to location ramst+rams12-1. ramst and rams12 are read from
+;the first game rom. If I=1 then you are in sa and the routine goes
+;to exclp with e = 20h if no errors, e = 12 if only errors in bits 4-7,
+;e = 11 if only errors in bits 0 - 3, or e=10 if errors in both.
+;if i = 0 then you are in game power up routine and it will halt if
+;there are errors or go to ramt if no errors.
+SCRRAM: lhld   RAMST
+       lbcd    RAMS12
+SCR1:  mvi     M,55H           ;fill ram with 55 s
+       dcx     h
+       cci                     ;bc = bc - 1
+       jpo     SCR2            ;jump if bc=0
+       inx     h               ;hl = hl + 1
+       jmpr    SCR1            ;loop
+SCR2:  mvi     D,0AAH
+       lxi     sp,0FFFFH
+SCR3:  lbcd    RAMS12          ;bc = rams12
+SCR4:  mov     a,d
+       cma                     ;a = invert d
+       xra     m
+       jrnz    SCRERR          ;jump if error
+       mov     m,d             ;[hl] = d
+       dcx     h
+       cci                     ;bc = bc - 1
+       jpe     SCR6            ;jump if bc <> 0
+       mov     a,d
+       cpi     55H
+       jrz     SCR5            ;to scr5 if d = 55h
+       lxi     sp,1H           ;sp = 1
+       mvi     D,55H           ;d = 55
+       jmpr    SCR3
+SCR6:  dad     sp              ;hl = hl + sp
+       jmpr    SCR4
+SCRERR: mov    d,a
+       ldai
+       rrcr    A
+       jrc     SCR7            ;jump if in sa
+       hlt                     ;halt if in power up
+SCR7:  mvi     E,12H
+       mov     a,d
+       ani     0FH             ;test for error in low nibble
+       jz      EXCLP           ;jmp w. e = 12 if no error
+       dcr     e
+       mov     a,d
+       ani     0F0H            ;test for error in high nibble
+       jz      EXCLP           ;jump w. e = 11 if no error
+       dcr     e
+       jmp     EXCLP           ;jump w. e=10 if error in both
+SCR5:  ldai
+       rrcr    A
+       mvi     E,20H
+       jnc     RAMT            ;to ramt if in game powerup
+       jmp     EXCLP
+;---------------------
+; report ram errors Part of RAMTST
+; bc=error bits
+ERROR: lxi     h,TABLE         ;of screen addresses
+       lxi     d,1             ; test bit
+CHECK: mov     a,b             ; bad ram bit?
+       ana     d
+       jnz     PLOT
+       mov     a,c             ; bad ram2 bit
+       ana     e
+       jmp     PLOT
+RET1:  xchg
+       dad     h               ; shift test bit
+       xchg
+       jnc     CHECK
+       lxi     d,4000H         ; wait value
+..wt:  dcr     e
+       mov     a,0(y)          ; waste time
+       jnz     ..wt
+       dcr     d
+       jnz     ..wt
+       jmp     RAMT2
+;---------------+
+; plot bad dips
+;---------------+
+PLOT:  exaf                    ; save whether good or bad
+       mov     a,m             ; get screen address word
+       inx     h
+       exx
+       mov     l,a
+       exx
+       mov     a,m
+       inx     h
+       exx
+       mov     h,a
+       lxi     d,32-1          ; offset to next line
+       mvi     B,3             ; number of notch lines
+       exaf                    ; bad/good flag
+ZORK:  ora     a
+       jrz     GOOD1
+       mvi     M,0FCH          ; half of ic
+       inx     h
+       mvi     M,03FH          ; second half
+       jmpr    ON1
+GOOD1: mvi     M,84H           ; first 1/2
+       inx     h
+       mvi     M,21H           ; second 1/2
+ON1:   dad     d               ; goto next line
+       djnz    ZORK
+       mvi     B,36            ; lines of body of ic
+ZAP:   ora     a
+       jrz     GOOD2
+       mvi     M,0FFH
+       inx     h
+       mvi     M,0FFH
+       jmpr    ON2
+GOOD2: mvi     M,80H
+       inx     h
+       mvi     M,01H
+ON2:   dad     d
+       djnz    ZAP
+       exx
+       jmp     ret1
+
+;vfb signature analysis routine
+;you get here by resetting with switch one of dip switch chip #26 closed
+;      .loc    01fcH
+.blkb  1fch-(.-%Zero)
+.ifn   (.-%Zero)-1fch,[.error /1FC TITAB Address/]
+
+TITAB: .word   INTADD          ;general interupts
+       .word   BADINT          ;general interupts with a bit stuck
+;.=200
+VFBSA: lxi     b,1048H
+       inp     A               ;in from 48
+       inr     c
+       inp     A               ;in from 49
+       inr     c
+       inp     A               ;in from 4a
+       inr     c
+       inr     c
+       inp     A               ;in from 4c
+       inr     c
+       inp     A               ;in from 4d
+       inr     c
+       inp     A               ;in from 4e
+       inr     c
+       mvi     A,1
+       OUTP    A               ;out 01 to 4f
+       lxi     b,0048H
+       inp     A               ;in from 48
+       inr     c
+       inp     A               ;in from 49
+       inr     c
+       inp     A               ;in from 4a
+;this routine fully exercises the shifter,flopper, and intercept logic
+;1.75 msec
+       lxi     h,5000H
+       lxi     d,7000H
+       mvi     B,10H
+VSA2:  mov     a,b
+       dcr     a               ;a = b - 1
+       out     4BH             ;output a to magic reg
+       mvi     A,80H
+VSA3:  mov     m,a             ;write a to 5000h
+       stax    d               ;write a to 7000h
+       mov     c,m
+       rrcr    A
+       jrnc    VSA3            ;loop 8 times
+       xra     a
+       in      4EH             ;input from intercept
+       mvi     A,08H
+       sta     5000H
+       sta     7000H
+       xra     a
+       in      4EH
+       inx     h
+       inx     d
+       djnz    VSA2            ;loop 16 times
+;this routine exercises all address bits to the ram and writes a pattern
+;which can sa'ed at the serial video output
+;228 usec
+       mvi     B,0DH           ;b = 13
+       lxi     d,0A000H
+       lxi     h,05FFEH
+       mvi     A,80H           ;a = 80
+VSA1:  dcr     h
+       mov     m,a             ;[hl] = a write to ram
+       mov     c,m             ;c = [hl] read it back
+       inr     h
+       stc
+       ralr    L
+       ralr    H
+       dad     d
+       rrcr    A               ;rotate a right
+       djnz    VSA1            ;loop 13 times
+; fill bs color ram
+       lxi     h,1111H
+       lxi     d,1111H
+       lxi     sp,8800H
+       mvi     C,16
+BS1:   mvi     B,16
+BS2:   push    h
+       push    h
+       push    h
+       push    h
+       djnz    BS2
+       dad     d
+       pop     psw
+       dcx     sp
+       dcx     sp
+       dcr     c
+       jrnz    BS1
+;----
+       in      4CH     ;turn on nmi
+       xra     a
+       in      4EH     ;input interrupt feedback
+       xra     a
+       in      DIP1
+       BIT     1,A
+VSA6:  jrz     VSA6    ;loop if not to do full test
+;here to do full alu test
+;you get here by closing switches 1,2 of dip switch pack 1
+       lxi     h,5000H
+       lxi     d,7000H
+       mvi     A,0F0H
+       stai                    ;i = f0h
+VSA10: lxi     b,004BH
+       ldai
+       OUTP    A               ;output to magic reg
+       mvi     C,0
+VSA11: mov     a,c
+       mov     m,b             ;write b to 5000h
+       stax    d               ;write c,a to 7000h
+       mov     c,b
+       cma
+       mov     b,m             ;read back from 5000h
+       mov     b,a
+       ora     c
+       jrnz    VSA11
+       ldai
+       sui     10H
+       stai                    ;i = i - 16
+       jrnz    VSA10           ;loop if i >= 0
+VSA12: jmpr    VSA12
+;------------------------
+; official vfb ram test
+;------------------------
+RAMT:  PCALL   D0              ;ring bell & led
+RAMT2: lxi     h,5FFFH
+       lxi     d,0
+       PCALL   UPDN
+       lxi     b,0             ;clear error bits
+       lxi     h,4000H         ;start of ram
+       PCALL   CELL.T          ;test data lines
+;do up down testing for address line problems
+       lxi     h,4000H
+       lxi     d,0055H
+       PCALL   UPDN
+       lxi     h,5FFFH
+       lxi     d,55AAH
+       PCALL   UPDN
+       lxi     h,4000H
+       lxi     d,0AAFFH
+       PCALL   UPDN
+       lxi     h,5FFFH
+       lxi     d,0FF00H
+       PCALL   UPDN
+       mov     a,c
+       ora     b
+       jnz     ERROR
+       PCALL   D0              ;ring bell & led
+;do color ram testing
+       lxi     h,87FFH
+       lxi     d,0
+       PCALL   UPDN
+       lxi     b,0             ;clear error bits
+       lxi     h,8000H         ;start of 1kx4 ram
+       PCALL   CELL.T          ;test data lines
+       lxi     h,8400H         ;start of 1kx4 ram
+       PCALL   CELL.T          ;test data lines
+;do up down testing for address line problems
+       lxi     h,8000H
+       lxi     d,0055H
+       PCALL   UPDN2
+       lxi     h,87FFH
+       lxi     d,55AAH
+       PCALL   UPDN2
+       lxi     h,8000H
+       lxi     d,0AAFFH
+       PCALL   UPDN2
+       lxi     h,87FFH
+       lxi     d,0FF00H
+       PCALL   UPDN2
+       mov     a,c
+       ora     b
+..err: jnz     ..err
+       lxi     x,SHFTST        ;ring bell & led
+       jmp     D0
+;----------------------------------
+; cell test for data line problems
+;----------------------------------
+CELL.T: mvi    D,0             ; test value
+C.LOOP: mov    m,d             ; write test value
+       mov     a,m             ; read back
+       xra     d               ; check for bad bits
+       ora     b               ; add old bad bits
+       mov     b,a             ; save error bits
+       inx     h               ; test bank2
+       mov     m,d
+       mov     a,m
+       xra     d
+       ora     c
+       mov     c,a
+       dcx     h
+       dcr     d               ; new test value
+       jnz     C.LOOP
+       mvi     M,0
+       inx     h
+       mvi     M,0
+       pcix
+;--------------------------------------
+; up down test for addressing problems
+;--------------------------------------
+UPDN2: exx
+       lxi     b,800H
+       jmpr    UPDN3
+;
+UPDN:  exx
+       lxi     b,2000H         ; length of screen
+UPDN3: exx
+D.LOOP: mov    a,m             ; read old value
+       xra     d               ; set error bits
+       ora     b               ; add old errors
+       mov     b,a             ; save errors
+       mov     m,e             ; store new value
+       mov     a,m             ; test now
+       xra     e               ; check
+       ora     b               ; save errors
+       mov     b,a
+       bit     0,E             ; test direction
+       jnz     UP
+       dcx     h
+;      ld a,<dec hl> for timing considerations
+       .byte   3Eh             ; mvi a,next byte
+UP:    inx     h
+       mov     a,b             ; swap b:c
+       mov     b,c
+       mov     c,a
+       exx
+       dcr     c
+       jnz     D.E
+       dcr     b
+       jz      DONE
+D.E:   exx
+       jmp     D.LOOP
+DONE:  exx
+       mov     a,b             ; swap b:c
+       mov     b,c
+       mov     c,a
+       pcix
+;-----------------------+
+; table of ic locations
+; arranged by bit number
+; odd bank first
+;-----------------------+
+.define XY[PAR1,PAR2]=[
+       .word   PAR1+PAR2+4400H
+]
+;
+C1     ==      9               ;column xs
+C2     ==      C1+4
+C3     ==      C2+4
+C4     ==      C3+4
+R1     ==      0               ;row ys
+R2     ==      50*32
+R3     ==      100*32
+R4     ==      150*32
+;
+TABLE: XY      C2,R3           ;o0
+       XY      C2,R2           ;o1
+       XY      C2,R1           ;o2
+       XY      C2,R4           ;o3
+       XY      C4,R1           ;o4
+       XY      C4,R2           ;o5
+       XY      C4,R3           ;o6
+       XY      C4,R4           ;o7
+       XY      C1,R3           ;e0
+       XY      C1,R2           ;e1
+       XY      C1,R1           ;e2
+       XY      C1,R4           ;e3
+       XY      C3,R1           ;e4
+       XY      C3,R2           ;e5
+       XY      C3,R3           ;e6
+       XY      C3,R4           ;e7
+;------------------------------------------------
+;this routine loops forever if there is an
+;error in the shifter or flopper
+;if no error it turns on the led and
+;tone for 1/4 second then turns them off
+;and goes to alutst
+SHFTST: lxi    h,6000H         ;magic ram address
+       mvi     D,01H           ;shift bit pattern
+SHFT6: mov     b,d             ;b=shift bit pattern
+       xra     a
+       mov     c,a             ;c=
+       mov     e,a             ;e=expected value
+       stai                    ;i= magic value
+SHFT5: ldai
+       out     4BH             ;magic register = i
+       mvi     M,0FFH          ;prime HI
+       mov     m,d             ;6000h = d
+       mvi     M,0             ;6000h = 0
+       mov     a,m             ;get result
+       cmp     e               ;compare to expected
+       jrnz    .               ;error-loop forever
+       ldai                    ;get magic value
+       inr     a               ;inc the shift
+       stai                    ;store magic
+       cpi     10H             ;compare to legal range
+       jrnz    SHFT1           ;jump if .ne. 16
+       ralr    D               ;rotate left the bit pattern
+       jrnc    SHFT6           ; so try all patterns of one bit
+       lxi     x,ALUTST        ;go to next test
+       jmp     D0              ;delay, then to alutst
+
+SHFT1: mov     a,c             ;rotate bc right
+       rarr    A
+       rarr    B               ;bit pattern
+       rarr    C
+       mov     e,c             ;e = c
+       ldai                    ;check if floping
+       cpi     8               ;8=flop
+       jrc     SHFT5           ;if i<8 to shft5
+       mvi     A,8             ;this routine sets
+SHFT4: rrcr    B               ;e = b flop
+       ralr    E               ;does not affect b
+       dcr     a
+       jrnz    SHFT4
+       jmpr    SHFT5
+
+;this routine loops forever if there is an
+;error in the alu or interrcept logic
+;if no error it turns on the led and
+;tone for 1/4 second then turns them off
+;and goes to inttst
+
+ALUTST: mvi    E,0
+       lxi     x,ALUSIM        ;ix = alusim
+       lxi     h,6000H         ;hl = 6000
+       lxi     b,0101H         ;bc = 0101
+ALU2:  mov     a,e
+       out     4BH             ;e to magic reg
+       mov     a,b
+       sta     4000H           ;4000h = b
+       mov     m,c             ;6000h = c
+       mov     a,c
+       pcix            ;simulate the alu
+ALURET: xra    m               ;xor simulation with [hl]
+       jrnz    .               ;loop if not equal
+       mov     m,a             ;(6000h) = 0
+       mov     a,b
+       ana     c
+       jrz     ALU1
+       mvi     A,80H
+ALU1:  mov     d,a             ;simulated intercept in bit 7 of d
+       in      4EH
+       xra     d
+       ral
+       jrc     .               ;loop if intercept error
+       rlcr    B               ;rotate b and try again
+       jrnc    ALU2
+       rlcr    C               ;rotate c and try again
+       jrnc    ALU2
+       inx     x
+       inx     x
+       inx     x
+       mvi     A,10H           ;update alu function
+       add     E
+       mov     e,a
+       jrnc    ALU2
+       lxi     x,INTTST
+       jmp     D0              ;delay then to inttst
+;
+ALUSIM: NOP                    ;0,a
+       jmpr    ALURET
+ALUOR: ora     b               ;1,a or b
+       jmpr    ALURET
+       cma                     ;2, (a + not(b)) , not(not(a) and +b)
+       jmpr    ALUANC
+       xra     a               ;3, 1
+       jmpr    ALUCMP
+ALUAN: ana     b               ;4, a and b
+       jmpr    ALURET
+       mov     a,b             ;5, b
+       jmpr    ALURET
+       xra     b               ;6,not(a eor b)
+       jmpr    ALUCMP
+       cma                     ;7, not(a) or b
+       jmpr    ALUOR
+       cma                     ;8, (a and not(b)), not(not(a) or b)
+       jmpr    ALUORC
+       xra     b               ;9, a eor b
+       jmpr    ALURET
+       mov     a,b             ;10, not(b)
+       jmpr    ALUCMP
+ALUANC: ana    b               ;11, not(a and b)
+       jmpr    ALUCMP
+       xra     a               ;12, 0
+       jmpr    ALURET
+       cma                     ;13, not(a) and b
+       jmpr    ALUAN
+ALUORC: ora    b               ;14, not(a or b)
+       jmpr    ALUCMP
+ALUCMP: cma                    ;15, not(a)
+       jmpr    ALURET
+
+;this routine loops forever if interupts or
+;nmi does not work properly. if they are
+;ok it turns the led and tone on for 1/4 second
+;then turns them off and goes to gamst
+
+INTTST ==      .
+       IM2                     ;mode 2
+       mvi     A,01    ;table start
+       stai                    ;point to 7fch
+       lxi     x,MAIN
+       mvi     A,0FFH
+       out     4FH             ;enable interupt
+       mov     b,a
+INTADD: lxi    sp,SCREEN-1     ;give a stack pointer position
+       in      4EH             ;clear int
+       rar
+       ralr    B
+       mov     a,b
+       xri     55H
+       jrz     NMITST
+       ei
+BADINT: jmpr   .
+
+NMITST: out    4FH             ;disable interupts
+       mvi     B,0FFH
+NMIADD: lxi    sp,SCREEN-1     ;give a stack pointer position
+       in      4DH             ;disable nmi
+       in      4EH             ;read center/bottom screen
+       rar
+       ralr    B
+       mov     a,b
+       xri     020H
+       jz      D0              ;to delay if done
+       in      4CH             ;enable nmi
+       jmpr    .
+
+       .end
diff --git a/robot.asm b/robot.asm
new file mode 100644 (file)
index 0000000..e0cd027
--- /dev/null
+++ b/robot.asm
@@ -0,0 +1,325 @@
+B>type robot.asm
+
+.title "MOVE ROBOTS"
+.sbttl "FRENZY"
+.ident ROBOT
+;-------------+
+; robot mover |
+;-------------+
+.insert equs
+.intern SETPAT
+.extern SHOWO,V.ZERO,SHOWA,R.9D,J.WAIT,NEXT.J,ADDS,SETVXY
+.extern R.9,D.TAB,SHOOT,IQ,RANDOM
+;------------+
+; initialize |
+;------------+
+;minwait=      40      ;2/22/82
+MinWait=       30              ;Harder 3/12/82
+FROBOT::call   V.ZERO          ;get vector
+       JC      JobDel#         ;if non leave
+       ldar
+       rrc
+       jrc     ..2
+       call    F1.TALK#
+       jmpr    ..1
+..2:   call    F2.TALK#
+..1:   mvi     P.X(x),146      ;start pos
+       mvi     P.Y(x),104
+       lxi     h,R.LAY#
+       mov     D.P.L(x),l
+       mov     D.P.H(x),h
+       mvi     c,0
+       jmpr    RGO
+ROBOT::
+       call    V.ZERO          ;get vector
+       JC      JobDel#         ;if non leave
+       lxi     h,Robots
+       inr     m               ;inc number of robots
+       mov     a,m
+       sta     Rsaved          ;save number of robots
+       ldar
+       ani     1
+       jnz     SKEL#
+; find a spot to put me
+       call    InitPosition
+       xra     a               ;stop mode
+       mvi     c,-1            ;force on
+       call    SETPAT          ; set up vector
+RGO:   mvi     TPRIME(x),2     ;standard wait time
+       mvi     TIME(x),1       ;update
+       mvi     V.STAT(x),86h   ;write|move
+       call    GetTimer#
+       lda     Rwait           ;initial hold off
+       cpi     MinWait
+       jrnc    ..1             ;safety 1st
+       mvi     A,MinWait       ;minimum wait
+; initial wait period hl->timer
+..1:   mov     b,a
+       call    RANDOM          ;slight randomness in
+       ani     0F8h            ;wake-up time
+       rrc
+       rrc
+       rrc
+       add     b
+       mov     m,a
+..wlp: call    NEXT.J
+       bit     INEPT,V.STAT(x)
+       jrnz    ..blam
+       mov     a,m
+       ora     a
+       jrnz    ..wlp
+..blam:
+       mvi     C,0             ;set tracker=stop
+;-----------------+
+; robots job loop |
+;-----------------+
+; ix->vector
+; hl->timer
+SEEK:  lxi     y,Vectors       ;mans vector
+       push    b               ;save tracker
+; test if anything happened first??
+       mov     a,P.X(y)        ;man x
+       sub     P.X(x)          ;robot x
+       mov     d,a             ;save delta x
+;calc x index
+       lxi     B,0             ;0 velocity in x
+       jrz     ..dx
+       mvi     B,1             ;-      "       in x
+       jrc     ..dx
+       mvi     B,2             ;+      "       in x
+..dx:  mov     a,P.Y(y)        ;man y
+       ADI     2
+       sub     P.Y(x)          ;robot y
+       mov     e,a             ;save delta y
+;calc y index
+       jrz     ..dy
+       mvi     C,4             ;-      "       in y
+       jrc     ..dy
+       mvi     C,8             ;+      "       in y
+..dy:  mov     a,b             ;add offsets
+       add     c               ;to from direction
+       pop     b               ;restore tracker
+       call    SHOOT           ;need hl->timer
+       call    SETPAT          ;does IQ
+       call    NEXT.J
+R.RET:: bit    INEPT,V.STAT(x)
+       jz      SEEK
+       jmpr    BLAM
+;-----------------------------+
+; change direction of robot
+;      a=data, c=tracker [0=stop]
+;-----------------------------+
+SETPAT: push   h
+       lxi     h,IqFlg
+       bit     1,m             ;stop moving
+       jrz     ..1
+       xra     a
+       jmpr    ..2
+..1:   ani     0Fh             ;check for no moving
+       jrz     ..2
+       bit     0,m             ;no iq
+       cz      IQ              ;then check walls returns a
+..2:   cmp     c               ;if tracker and new direction
+       jrz     ..exit          ;are the same then return
+       mov     c,a             ;update tracker
+       call    SETVXY
+       lxi     h,P.TAB         ;index pattern table
+       dad     d               ;returned from setvxy
+       mov     a,m             ;get pattern address
+       inx     h
+       mov     h,m
+       di
+       mov     D.P.L(x),A      ;set pattern
+       mov     D.P.H(x),H
+       ei
+..exit: pop    h
+       ret
+;--------------+
+; blow up time |
+;--------------+
+BLAM:: call    FreeTimer#
+       push    x               ;->vector
+       call    SBLAM#
+       pop     h               ;->vector
+       lxi     d,V.X           ;hl=>v.x
+       dad     d
+       di
+       mov     m,d             ;d=0 v.x
+       inx     h               ;->p.x
+       mov     a,m
+       sui     4               ;offset blast pattern
+       mov     m,a
+       inx     h               ;->v.y
+       mov     m,d             ;d=0
+       inx     h               ;->p.y
+       mov     a,m             ;get position
+       sui     6               ;offset for large blast
+       mov     m,a
+       inx     h               ;->d.p.l
+       lxi     b,R.9           ;blast pattern
+       mov     m,c
+       inx     h
+       mov     m,b
+       ei
+       mvi     TIME(x),1
+       mvi     TPRIME(x),1
+       push    x               ;->vector
+       lxi     b,105H          ;50
+       call    ADDS
+       lxi     h,Robots        ;score bonus
+       mov     a,m
+       ora     a
+       jz      XXX
+       dcr     m               ;one less robot
+       sta     STIME           ;new robot hold off
+       jrnz    XXX             ;if all killed then
+       lda     Rsaved          ;get original number of robots
+SCLOP: push    psw
+       lxi     b,101H          ;score 10 for each killed
+       call    ADDS
+       pop     psw
+       dcr     a
+       jrnz    SCLOP
+; write bonus
+       call    SHOWA
+       .byte   0,96,213
+       .asciz  "BONUS"
+; show how much
+       push    psw
+       lda     Rsaved
+       mov     b,a             ;convert to BCD
+       xra     a               ;0
+..:    ADI     1               ;+1
+       daa                     ;adjust
+       djnz    ..              ;for number of robots
+       rrc
+       rrc
+       rrc
+       rrc
+       mov     l,a
+       ani     0F0H
+       mov     h,a
+       mvi     A,0FH
+       ana     l
+       mov     l,a
+       pop     psw
+       push    h               ;put number on stack
+       lxi     h,0
+       dad     sp              ;->number on stack
+       exaf
+       mvi     B,4
+       call    SHOWO
+       pop     h               ;remove number from stack
+XXX:   pop     x
+       WAIT    30
+..test: lxi    h,R.9D
+       mov     a,O.P.L(x)      ;see if on last pattern
+       cmp     l
+       jrnz    ..no
+       mov     a,O.P.H(x)
+       cmp     h
+       jrz     ..done
+..no:  call    NEXT.J
+       jmpr    ..test
+..done: mvi    V.STAT(x),0     ;free vector
+       jmp     JobDel          ;delete job
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Find a spot for this robot to start
+;___________________________
+InitPosition::
+       call    RANDOM
+..sl:  sui     24
+       jrnc    ..sl
+       adi     24
+       mvi     b,0
+       mov     c,a
+       lxi     h,Walls
+       dad     b               ;->walls array
+       mov     a,m             ;test if in use,exit or man
+       ani     0F0h            ;non wall bits
+       jrz     ..use
+       mov     a,c
+       inr     a
+       jmpr    ..sl
+; fix up faster with linear probe?
+..use: set     InUse,m         ;save our square
+       lxi     h,R.Tab         ;->starting squares
+       dad     b
+       dad     b
+       mov     d,m             ;get x position
+       inx     h
+       mov     e,m
+       call    Rand27
+       add     d
+       mov     P.X(x),a        ;set position
+       call    Rand27
+       add     e
+       mov     P.Y(x),a
+       ret
+Rand27: push   d
+       call    RANDOM
+       pop     d
+..:    sui     26
+       jrnc    ..
+       adi     26
+       ret
+;--------------------------------
+; ROBOT starting position table
+X1     ==      12
+X2     ==      X1+(40*1)
+X3     ==      X1+(40*2)
+X4     ==      X1+(40*3)
+X5     ==      X1+(40*4)
+X6     ==      X1+(40*5)
+Y1     ==      8
+Y2     ==      Y1+(48*1)
+Y3     ==      Y1+(48*2)
+Y4     ==      Y1+(48*3)
+R.TAB: .byte   X1,Y1
+       .byte   X2,Y1
+       .byte   X3,Y1
+       .byte   X4,Y1
+       .byte   X5,Y1
+       .byte   X6,Y1
+
+       .byte   X1,Y2
+       .byte   X2,Y2
+       .byte   X3,Y2
+       .byte   X4,Y2
+       .byte   X5,Y2
+       .byte   X6,Y2
+
+       .byte   X1,Y3
+       .byte   X2,Y3
+       .byte   X3,Y3
+       .byte   X4,Y3
+       .byte   X5,Y3
+       .byte   X6,Y3
+
+       .byte   X1,Y4
+       .byte   X2,Y4
+       .byte   X3,Y4
+       .byte   X4,Y4
+       .byte   X5,Y4
+       .byte   X6,Y4
+;----------------
+; pattern table
+;
+.define PAT[P1]=[
+.extern P1
+       .word   P1]
+
+P.TAB: PAT     R.0
+       PAT     R.1
+       PAT     R.2
+       PAT     R.3
+       PAT     R.4
+       PAT     R.5
+       PAT     R.6
+       PAT     R.7
+       PAT     R.8
+
+BYTE3:: .byte  0
+
+       .end
+
diff --git a/room.asm b/room.asm
new file mode 100644 (file)
index 0000000..88a7ea9
--- /dev/null
+++ b/room.asm
@@ -0,0 +1,605 @@
+B>type room.asm
+
+.title "Draw Room and Set Pointers"
+.sbttl "FRENZY"
+.ident ROOM
+;--------------------+
+; room related stuff |
+;--------------------+
+.insert equs
+.extern SHOWC,SHOWS,SHOWA,SHOWN,RtoA
+.extern CREDS,C.WALLS,PLOT,RANDOM
+; Equates
+BDOWN  ==      3
+BUP    ==      2
+BRIGHT ==      1
+BLEFT  ==      0
+ORWRITE ==     10H
+.define XY[PX,PY]=[
+       lxi     h,PY*256+PX]
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Show room with door on left
+;_______________________________
+RoomLeft::
+       call    RINIT
+       set     BLEFT,0+24(x)
+       set     BLEFT,6+24(x)
+       set     BLEFT,12+24(x)
+       set     BLEFT,18+24(x)
+       lhld    ManX
+       mov     l,h             ;get y
+       mvi     h,240           ;set x
+       call    WallIndex#
+       lxi     h,24
+       dad     d
+       set     BRIGHT,m
+       jmp     DoRo    
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Show room with door on Right
+;_______________________________
+RoomRight::
+       call    RINIT
+       set     BRIGHT,5+24(x)
+       set     BRIGHT,11+24(x)
+       set     BRIGHT,17+24(x)
+       set     BRIGHT,23+24(x)
+       lhld    ManX
+       mov     l,h             ;get y
+       mvi     h,16            ;set x
+       call    WallIndex#
+       lxi     h,24
+       dad     d
+       set     BLEFT,m
+       jmp     DoRo    
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Show room with door on Down
+;_______________________________
+RoomDown::
+       call    RINIT
+       set     BDOWN,18+24(x)
+       set     BDOWN,19+24(x)
+       set     BDOWN,20+24(x)
+       set     BDOWN,21+24(x)
+       set     BDOWN,22+24(x)
+       set     BDOWN,23+24(x)
+       lhld    ManX
+       mov     h,l             ;get x
+       mvi     l,16            ;set y
+       call    WallIndex#
+       lxi     h,24
+       dad     d
+       set     BUP,m
+       jmp     DoRo    
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Show room with door on Up
+;_______________________________
+RoomUp::
+       call    RINIT
+       set     BUP,0+24(x)
+       set     BUP,1+24(x)
+       set     BUP,2+24(x)
+       set     BUP,3+24(x)
+       set     BUP,4+24(x)
+       set     BUP,5+24(x)
+       lhld    ManX
+       mov     h,l             ;get x
+       mvi     l,180           ;set y
+       call    WallIndex#
+       lxi     h,24
+       dad     d
+       set     BDOWN,m
+       jmp     DoRo    
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; Show outline of room
+;_______________________________
+ROOM:: lxi     h,RoomCnt
+       dcr     m
+       call    RINIT
+; generate walls bits
+DoRo:  lxi     x,WALLS
+       call    ROW
+       call    ROW
+       call    ROW
+; draw walls
+       call    RoomDraw
+       call    C.WALLS         ; color walls
+       call    Wdot            ;add white dots
+       call    SHOWS
+; show number of deaths left
+SHOWD:: lda    PLAYER
+       cpi     2
+       XY      56,213
+       jrnz    DPI
+       mvi     L,232
+DPI:   mvi     B,0
+       call    RtoA
+       xchg
+       exaf
+       lda     DEATHS
+       mov     b,a
+       exaf
+       dcr     b
+       jrz     SSE
+DLP:   push    b
+       mvi     C,80H           ;man
+       call    SHOWC
+       inx     d
+       exaf
+       lda     Flip
+       ora     a
+       jrz     ..
+       dcx     d
+       dcx     d
+..:    exaf
+       pop     b
+       djnz    DLP
+SSE:   lda     Demo            ;if demo,show credits
+       ora     a
+       cnz     CREDS
+       ret
+;---------------------------+
+; Generate 0-4 random walls |
+;---------------------------+
+ROW:   mvi     b,5
+..lp:  push    b
+       call    RANDOM
+       lxi     b,..ret         ;return address for all
+       push    b               ;do table call sort of
+       ani     3
+       jz      UP
+       dcr     a
+       jz      DOWN
+       dcr     a
+       jz      RIGHT
+       jmp     LEFT
+..ret: pop     b               ;move to next column
+       inx     x
+       djnz    ..lp
+       inx     x
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;  Wall setting routines
+;_______________________________
+DOWN:  set     BRIGHT,6(x)
+       set     BLEFT,7(x)
+       lda     SEED            ;reflecto wall?
+       rlc
+       rnc
+       set     BRIGHT,24+6(x)  ;set reflecto
+       set     BLEFT,24+7(x)
+       ret
+;
+UP:    set     BRIGHT,0(x)
+       set     BLEFT,1(x)
+       lda     SEED
+       rlc
+       rnc
+       set     BRIGHT,24+0(x)
+       set     BLEFT,24+1(x)
+       ret
+;
+RIGHT: set     BDOWN,1(x)
+       set     BUP,7(x)
+       lda     SEED
+       rlc
+       rnc
+       set     BDOWN,24+1(x)
+       set     BUP,24+7(x)
+       ret
+;
+LEFT:  set     BDOWN,0(x)
+       set     BUP,6(x)
+       lda     SEED
+       rlc
+       rnc
+       set     BDOWN,24+0(x)
+       set     BUP,24+6(x)
+       ret
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+;      Draw a Room
+;_______________________________
+RoomDraw:
+       mvi     h,4