Chicken fight like a Robot

master
teamarchive2.fnf.archive.org root 2021-04-03 02:21:57 +00:00
commit dece43002f
35 changed files with 11521 additions and 0 deletions

2
.htaccess Normal file
View File

@ -0,0 +1,2 @@
Options +Indexes

1
README.md Normal file
View File

@ -0,0 +1 @@
# frenzy

171
align.asm Normal file
View File

@ -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

550
bolts.asm Normal file
View File

@ -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

305
books.asm Normal file
View File

@ -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

993
charset.asm Normal file
View File

@ -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

175
coins.asm Normal file
View File

@ -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

368
color.asm Normal file
View File

@ -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

51
control.asm Normal file
View File

@ -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

120
demo.asm Normal file
View File

@ -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

290
equs.asm Normal file
View File

@ -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

515
factory.asm Normal file
View File

@ -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

277
gameover.asm Normal file
View File

@ -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

450
init.asm Normal file
View File

@ -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

8
init.tel Normal file
View File

@ -0,0 +1,8 @@
B>type init.tel
# these were instructions to the linker
80wl0wn1wt94wy
j@i/23l23t
/j1:p2
j@i/23t
/j1:p1@x/ - Space Used /vz-vf=
1<@s/Version /;@s/./.,.+2:p9ev9w8%8,2\0lt>0,0p9j

191
iq.asm Normal file
View File

@ -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

261
job.asm Normal file
View File

@ -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

230
main.asm Normal file
View File

@ -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

304
man.asm Normal file
View File

@ -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

388
nmi.asm Normal file
View File

@ -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

697
pat2.asm Normal file
View File

@ -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

417
pat3.asm Normal file
View File

@ -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

1006
pattern.asm Normal file

File diff suppressed because it is too large Load Diff

424
play.asm Normal file
View File

@ -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

766
powerup.asm Normal file
View File

@ -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

325
robot.asm Normal file
View File

@ -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

605
room.asm Normal file
View File

@ -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
lxi x,walls
lxi b,(4<8)!(1<BUP)
..lp: call HORIZ
mvi a,48
add h
mov h,a
djnz ..lp
lxi x,walls+(3*6) ; do last wall
mvi c,1<BDOWN
call HORIZ
lxi x,walls ; do verticals
lxi b,(6<8)!(1<BLEFT)
mvi L,8
..kp: call VERT
mvi a,40
add l
mov l,a
djnz ..kp
dcx x ;do last vert wall
mvi c,1<BRight
call VERT
ret
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Draw complete horizontal
;_______________________________
HORIZ: push b
mvi l,8
mvi b,6
..lp: push h
push b
mov a,24(x) ;check reflecto wall
ana c
jrz ..nor ;0=non reflecto
mov a,0(x)
ana c
jrz ..sq
call HWR
jmpr ..open
..sq: call HWS
jmpr ..open
..nor: mov a,0(x)
ana c
jrz ..open
call HWB
..open: pop b
pop h
inx x
mvi a,40
add l
mov l,a
djnz ..lp
pop b
ret
;~~~~~~~~~~~~~~~~~~~~~~~~~~
; Draw complete Vertical
;__________________________
VERT: push b
mvi h,4
mvi b,4
..lp: push h
push b
mov a,24(x) ;check reflecto wall
ana c
jrz ..nor ;0=non reflecto
mov a,0(x)
ana c
jrz ..sq
call VWR
jmpr ..open
..sq: call VWS
jmpr ..open
..nor: mov a,0(x)
ana c
jrz ..open
call VWB
..open: pop b
pop h
lxi d,6
dadx d
mvi a,48
add h
mov h,a
djnz ..lp
lxi d,-(6*4)+1
dadx d
pop b
ret
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Horizontal wall of Crosses
;_______________________________
HWB:: mvi B,11
Hlp: push b ;number of bricks to write
push h ;x and y relative addr
call RELOR ;convert coordinates
lxi h,CROSS ;brick pattern
call PLOT ;plot a brick
pop h
pop b
mvi A,4 ;move to end of brick in x
add l ;to lay next one
mov l,a
djnz Hlp ;do another brick
ret
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Horizontal wall of Squares
;_______________________________
HWS: mvi B,11
..Hlp: push b ;number of bricks to write
push h ;x and y relative addr
call RELOR ;convert coordinates
lxi h,CUBE ;brick pattern
call PLOT ;plot a brick
pop h
pop b
mvi A,4 ;move to end of brick in x
add l ;to lay next one
mov l,a
djnz ..Hlp ;do another brick
ret
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Horizontal wall of Reflecto
;_______________________________
HWR: push h
call RELOR
lxi h,HSTART
call PLOT
pop h
mvi A,4 ;move to end of brick in x
add l ;to lay next one
mov l,a
mvi B,9
..lp: push b ;number of bricks to write
push h ;x and y relative addr
call RELOR ;convert coordinates
lxi h,HBLOCK ;brick pattern
call PLOT ;plot a brick
pop h
pop b
mvi A,4 ;move to end of brick in x
add l ;to lay next one
mov l,a
djnz ..lp ;do another brick
call RELOR ;convert coordinates
lxi h,HEND
jmp PLOT
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Vertical wall of Crosses
;_______________________________
VWB:: mvi B,13
Vlp: push b ;number of bricks to write
push h ;x and y relative addr
call RELOR ;convert coordinates
lxi h,CROSS
call PLOT
pop h
pop b
mvi A,4 ;move to end of brick in y
add h ;to lay next one
mov h,a
djnz Vlp ;do another brick
ret
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Vertical wall of Squares
;_______________________________
VWS: mvi B,13
..Vlp: push b ;number of bricks to write
push h ;x and y relative addr
call RELOR ;convert coordinates
lxi h,CUBE
call PLOT
pop h
pop b
mvi A,4 ;move to end of brick in y
add h ;to lay next one
mov h,a
djnz ..Vlp ;do another brick
ret
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Vertical wall of Crosses
;_______________________________
VWR: push h
call RELOR
lxi h,VSTART
call PLOT
pop h
mvi A,4 ;move to end of brick in y
add h ;to lay next one
mov h,a
mvi B,11
..lp: push b ;number of bricks to write
push h ;x and y relative addr
call RELOR ;convert coordinates
lxi h,VBLOCK
call PLOT
pop h
pop b
mvi A,4 ;move to end of brick in y
add h ;to lay next one
mov h,a
djnz ..lp ;do another brick
call RELOR
lxi h,VEND
jmp PLOT
;----------------------+
; relative to absolute |
;----------------------+
RELOR: mvi B,ORWRITE
call RtoA
xchg
ret
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Initialize walls arrays etc
;_______________________________
RINIT: lhld RoomX ;put room number
shld SEED ;in seed
;erase message area
lda FLIP
ora a
jrnz ..flp
lxi h,10+211*Hsize+Screen ;modify for upside down??
jmpr ..Nor
..flp: lxi h,Screen+10+2*Hsize
..Nor: lxi d,Hsize-12
xra a
mvi C,12 ;for 12 lines
..JEL: mvi B,12 ;erase 12 bytes
..MEL: mov m,a
inx h
djnz ..MEL
dad d
dcr c
jrnz ..JEL
; initialize walls array
lxi b,4*6*2
lxi d,WALLS
lxi h,R.DATA
ldir
;generate doors - TOP
lxi x,Walls
lhld RoomX ;get coords
mov a,l ;get y
ani 3
mov e,a
mvi d,0
mov h,d
mov l,e ;1
dad h ;2
dad d ;3
dad h
xchg
dadx d ;6*
RES BLEFT,0(x) ;set door bit
;right
lxi x,Walls
lhld RoomX ;get coords
mov a,l ;get x
inr a
ani 3
mov e,a
mvi d,0
mov h,d
mov l,e ;1
dad h ;2
dad d ;3
dad h
xchg
dadx d ;6*
RES BRIGHT,5(x) ;set door bit
;top
lxi x,Walls
lhld RoomX ;get coords
mov a,h ;get y
ani 3
inr a
mov e,a
mvi d,0
dadx d
RES BUP,0(x) ;set door bit
;bottom
lxi x,Walls
lhld RoomX ;get coords
mov a,h ;get y
inr a
ani 3
inr a
mov e,a
mvi d,0
dadx d
RES BDOWN,18(x) ;set door bit
;inc number of rooms seen
lxi h,RoomCnt
inr m ;inc room count
mov a,m
cpi 32+1
jrc ..rm
cpi -1
jrz ..rm
mvi m,19 ;3 rooms of white hell
..rm: mov a,m
ora a
jrz ..skw
ani 3 ;test for special room
cz S.ROOM#
..skw: lxi x,Walls ;everyone needs this
ret
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Put white dot around edge
;_______________________________
Wdot: lxi h,D.Table ;dot table
..loop: mov a,m ;x
ora a
rz
mov c,a ;set X
inx h
mov b,m ;set Y
inx h
push h
call Cdot
pop h
jmp ..loop
; change dot at bc to white
Cdot: 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:
; change color box to grey
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 Dcolor ;get dot color
ana e ;isolate nibble
ora d ;combine nibbles
mov m,a ;store new color
ret
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; initial room data
;__________ d.u.r.l
R.DATA: .byte 5,4,4,4,4,6
.byte 1,0,0,0,0,2
.byte 1,0,0,0,0,2
.byte 9,8,8,8,8,10
.byte 0,0,0,0,0,0
.byte 0,0,0,0,0,0
.byte 0,0,0,0,0,0
.byte 0,0,0,0,0,0
; table of dot positions
D.Table:
.byte 8,4,8,52,8,100,8,148,8,196
.byte 248,4,248,52,248,100,248,148,248,196
.byte 48,4,88,4,128,4,168,4,208,4
.byte 48,196,88,196,128,196,168,196,208,196
.byte 0
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; patterns for walls
;__________________________________
CUBE: .byte 1,4
.byte 0F0h,090h,090h,0F0h
CROSS: .byte 1,4
.byte 060h,0F0h,0F0h,060h
Vblock: .byte 1,4
.byte 060h,060h,060h,060h
VSTART: .byte 1,4
.byte 000h,060h,060h,060h
VEND: .byte 1,4
.byte 060h,060h,060h,000h
HBLOCK: .byte 1,4
.byte 000h,0F0h,0F0h,000h
HSTART: .byte 1,4
.byte 000h,070h,070h,000h
HEND: .byte 1,4
.byte 000h,0E0h,0E0h,000h
.end

189
shoot.asm Normal file
View File

@ -0,0 +1,189 @@
B>type shoot.asm
.title "SHOOT AT MAN"
.sbttl "FRENZY"
.ident SHOOT
;---------------------------------------
; if (a bolt is available) then
; if (it is possible to shoot at the man)
; Shoot;
;---------------------------------------
.insert equs
.extern D.TAB,SETPAT,NEXT.J
; a=DURL to man
; hl->timer
SHOOT::
push h ;timer
push b ;tracker
push psw ;DURL
mov c,a ;save DURL
mov a,m ;check timer
ora a
jrnz ..exit
lda IqFlg
bit 2,a
jrnz ..exit
; check if bolt available
lda Rbolts ;check if shooting
ora a
jrz ..exit
mov b,a ;number of bolts useable
lxi h,BUL1+(2*Blength) ;check 3rd bolt on
push d
lxi d,Blength ;delta to next bolt
..lp: mov a,m ;check vx.vy=0
ora a
jrz ..OK ;have a bolt
dad d
djnz ..lp
pop d
..exit: pop psw
pop b
pop h ;timer
ret ;no bolt
; Have Bolt Will Shoot
..OK: pop d
;HL now points at bullet to use
;now check if man is up or down from you
mov a,d ;d=delta x
cpi -2
jnc FIREY ;out of range
cpi 8
jrc FIREY
;check for a left or right shot
mov a,e ;e=delta y
cpi -10
jrnc FIREX
cpi 5
jrc FIREX
;check for a diagonal shot
mov a,d ;abs[delta x]
bit 0,C ;bit left
jrz ..dox
neg
mov d,a
..dox: mov a,e ;abs[delta y]
bit 2,C ;bit up
jrz ..doy
neg
mov e,a
..doy: sub d ;if (|dX|-|dY|)
cpi -10 ;is in range then shoot
jrnc FIRE
cpi 6
jrnc ..exit
jmpr FIRE
;make shot go horizontal
FIREX: mov a,c
ani 3
mov c,a
jmpr FIRE
;make vertical shot
FIREY: mov a,c
ani 0CH
mov c,a
jmpr FIRE
;---------------------------------------
; set up robot and bolt
;---------------------------------------
;hl->bolt,c=direction(DURL)
FIRE:
push h ;save bolt pointer
; zero the whole bolt
mvi b,Blength
xra a
..zap: mov m,a
inx h
djnz ..zap ;b=0
call SRFIRE# ;make noise
lxi h,D.TAB ;translate DURL to clock
dad b ;b=0,c=durl
mov c,m ;direction offset
lxi h,S.TAB
dad b ;entry 2
dad b ;4
dad b ;6
mov V.X(x),B ;b=0
mov V.Y(x),B ;robot stops moving
mov a,m ;get pattern address
inx h
di
mov D.P.L(x),A
mov a,m
mov D.P.H(x),A
ei
inx h
mvi TIME(x),1 ;make it write
mov b,m ;xoffset
inx h
mov c,m ;yoffset
inx h
mov d,m ;vx.vy
mov a,P.X(x) ;calc offset from robot
add B
mov b,a
mov a,P.Y(x) ;same for y
add C
mov c,a
pop h ;-> bolt
mov a,d
ori 3 ;length of bolt
di
mov m,a ;vx.vy
inx h
mov m,b ;xposition
inx h
mov m,c ;yposition
inx h ;repeat for tail
mov m,b ;xposition
inx h
mov m,c ;yposition
ei
pop psw ;durl
pop b ;tracker
pop h ;timer
mvi m,10
..wlp: call NEXT.J
bit INEPT,V.STAT(x)
jrnz ..sk
mov a,m
ora a
jrnz ..wlp
..sk:
; wait is lesser of (Robots*4)+5 or (Rwait/2)
; RWait comes into play later in the game
lda Robots ;bolt hold off
add a
add a
adi 5 ;was 10
mov c,a ;save this delay
lda Rwait
srlr a
cmp c ;compare and use
jrc ..t ;lesser delay
mov a,c
..t: mov m,a
mvi C,10H ;force new setpat
jmp R.ret#
;
.define SS[Xoffset,Yoffset,Pat,Dir]=[
.word Pat
.byte Xoffset
.byte Yoffset
.byte Dir<4
.byte 0
]
;
; shoot table
;
.extern R.0
S.TAB: SS 0,0,R.0,0 ;0
SS 7,1,R.0,6 ;1ur
SS 8,2,R.0,2 ;2r
SS 8,4,R.0,10 ;3dr
SS 6,11,R.0,8 ;4d
SS -1,4,R.0,9 ;5dl
SS -1,2,R.0,1 ;6l
SS 0,1,R.0,5 ;7ul
SS 6,0,R.0,4 ;8u
.end

218
showa.asm Normal file
View File

@ -0,0 +1,218 @@
B>type showa.asm
.title "SHOW ALPHABETIC"
.sbttl "FRENZY"
.ident SHOWA
;-----------------
; string display
;-----------------
.insert EQUS
.extern CHARSET
;-----------------------------------
; show a string
; inline parms: x,y bytes
; followed by a string ending in 0
;-----------------------------------
SHOWA:: pop h ; hl -> inline parms
mov b,m ; magic value
inx h
mov e,m ; load x
inx h
mov d,m ; load y
inx h
xchg
call RtoA
xchg
..lp: mov c,m ; get char
res 7,C ; clear end of string indicator
call SHOWC ; show char
mov b,a ; save magic
lda FLIP
ora a
jrnz ..1
inx d ; point to next char position
jmpr ..2
..1: dcx d
..2: inx h ; point to next character
mov a,m ; test next character
ora a ; if zero
mov a,b
jnz ..lp ; then loop
inx h ;return past
pchl ; data bytes
;-------------------------------
; relative to absolute
; in: b=magic ,h=y,l=x
; out:a=magic+shift,hl=address
;-------------------------------
RtoAx:: mvi B,90H ;xor write
RtoA:: lda FLIP
ora a
mvi A,7
jrnz ..flp
ana l
ora b
out MAGIC ; set magic register
srlr H
rarr L
srlr H
rarr L
srlr H
rarr L
lxi b,MagicScreen
dad b
ret
;flipped version
..flp: ana l
ora b
set FLOP,A
out MAGIC ; set magic register
srlr H
rarr L
srlr H
rarr L
srlr H
rarr L
mov b,h
mov c,l
lxi h,Hsize*224+MagicScreen-1
ora a
dsbc b
ret
;-------------------
; show a character
; in: a=magic trash
; c=char
; hl->string
; de->mscreen
;-------------------
VOFSET == 3
CHARV == 9
;
SHOWC:: push h ; savestring pointer
lxi h,0
mvi B,0
dad b
dad h ; calc char offset
dad h
dad h
dad b
lxi b,CHARSET-(1FH*CHARV)
dad b ;hl->char data
push d
push psw
xchg ;hl->screen
lda FLIP ;check for flipped state
ora a
ldax d ;test for lower case
jrnz FLIPD
ora a
jp ..no
lxi b,Hsize*VOFSET
dad b ;decender offset
..no: mvi a,CHARV ;number of bytes high
lxi b,Hsize-1 ; offset to next line
..lp: exaf
pop psw
push psw
di
out MAGIC
ldax d ;get data
ani 7FH ;clear shift bit
inx d
mov m,a ;write to screen
inx h
mvi M,0 ;flush magic register
ei
dad b ;move down a line
exaf
dcr a
jnz ..lp
pop psw
pop d
pop h
ret
;flipped version
FLIPD: ora a
jp ..no
lxi b,-Hsize*VOFSET
dad b ;decender offset
..no: mvi a,CHARV ;number of bytes high
lxi b,-Hsize+1 ; offset to next line
..lp: exaf
pop psw
push psw
di
out MAGIC
ldax d ;get data
ani 7FH ;clear shift bit
inx d
mov m,a ;write to screen
dcx h
mvi M,0 ;flush magic register
ei
dad b ;move down a line
exaf
dcr a
jnz ..lp
pop psw
pop d
pop h
ret
;-------------------------------
; show a number
; i: b = number of digits
; de= y and x postition
; hl= address of bcd string
; does a plop write
;-------------------------------
SHOWN:: push b ;save number of digits
mvi B,0 ;plop write
xchg
call RtoA ;convert xy to address
xchg
exaf ;save magic reg
pop b
SHOWO:: res 0,C ;zero suppress on
..loop: mov a,b ;get count
dcr a ;if last digit-
jrnz ..skip ; dont suppress it
set 0,C ;dont zero suppress
..skip: mov a,m ;get 2 bcd digits
bit 0,B ;odd or even digit?
jrnz ..no ;shift
srlr A ;top digit
srlr A ;into bottom
srlr A
srlr A
dcx h
..no: inx h
ani 0FH ;isolate digit
jrnz ..SUP ;if 0 check-
bit 0,C ; for suppress
jrnz ..2
mvi A," " ;suppress it
jmpr ..dec
..SUP: SET 0,C ;no more suppress
..2: adi 90h ;hex to ascii trick
daa
adi 40h
daa
..dec: push h
push b
mov c,a ;char into c
exaf ;restore magic reg
call SHOWC ;display one digit
exaf ;save magic
pop b
pop h
lda FLIP
ora a
jrnz ..ss
inx d ; point to next char position
jmpr ..xx
..ss: dcx d
..xx: djnz ..loop
ret
.end

319
skel.asm Normal file
View File

@ -0,0 +1,319 @@
B>type skel.asm
.title "Skeletons"
.sbttl "FRENZY"
.ident SKEL
;-------------+
; robot mover |
;-------------+
.insert equs
.extern SHOWO,V.ZERO,SHOWA,R.9D,J.WAIT,NEXT.J,ADDS,SETVXY
.extern R.9,D.TAB,IQ,RANDOM
;------------+
; initialize |
;------------+
;MinWait= 45
MinWait= 35 ;harder 3/12/82
SKEL::
; lxi h,Robots ;NOW DONE IN ROBOT-3/12/82
; inr m ;inc number of robots
; mov a,m
; sta Rsaved ;save number of robots
; call V.ZERO ;get vector
; JC JobDel# ;if non leave
; 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
;------------------
; Skel 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
SUI 1
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
push h
ani 0FH ;if tracker non-0
jrz ..ud
lxi h,IqFlg
bit 1,m ;stop moving
jrz ..1
xra a
jmpr ..ud
..1: bit 0,m ;no iq
cz IQ ;then check walls returns a
bit 0,a
jrnz ..go
bit 1,a
jrz ..ud
..go: ani 3 ;go rl first
..ud: cmp c ;if tracker and new direction
pop h
jrz ..sl ;are the same then return
mov c,a ;update tracker
call SETPAT ;does IQ
..sl: call NEXT.J
R.RET: bit INEPT,V.STAT(x)
jz SEEK
jmp BLAM#
;-----------------------------+
; change direction of robot
; a=data, c=tracker [0=stop]
;-----------------------------+
SETPAT: push h
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
;----------------
; pattern table
;
P.TAB: .word S.0#
.word S.2#
.word S.2
.word S.2
.word S.4#
.word S.6#
.word S.6
.word S.6
.word S.8#
;---------------------------------------
; if (a bolt is available) then
; if (it is possible to shoot at the man)
; Shoot;
;---------------------------------------
; a=DURL to man
; hl->timer
SHOOT:
push h ;timer
push b ;tracker
push psw ;DURL
mov c,a ;save DURL
mov a,m ;check timer
ora a
jrnz ..exit
lda IqFlg
bit 2,a
jrnz ..exit
; check if bolt available
lda Rbolts ;check if shooting
ora a
jrz ..exit
mov b,a ;number of bolts useable
lxi h,BUL1+(2*Blength) ;check 3rd bolt on
push d
lxi d,Blength ;delta to next bolt
..lp: mov a,m ;check vx.vy=0
ora a
jrz ..OK ;have a bolt
dad d
djnz ..lp
pop d
..exit: pop psw
pop b
pop h ;timer
ret ;no bolt
; Have Bolt Will Shoot
..OK: pop d
;HL now points at bullet to use
;now check if man is up or down from you
mov a,d ;d=delta x
cpi -2
jnc FIREY ;out of range
cpi 6
jrc FIREY
;check for a left or right shot
mov a,e ;e=delta y
cpi -10
jrnc FIREX
cpi 2
jrc FIREX
;check for a diagonal shot
mov a,d ;abs[delta x]
bit 0,C ;bit left
jrz ..dox
neg
mov d,a
..dox: mov a,e ;abs[delta y]
bit 2,C ;bit up
jrz ..doy
neg
mov e,a
..doy: sub d ;if (|dX|-|dY|)
cpi -10 ;is in range then shoot
jrnc FIRE
cpi 6
jrnc ..exit
jmpr FIRE
;make shot go horizontal
FIREX: mov a,c
ani 3
mov c,a
jmpr FIRE
;make vertical shot
FIREY: mov a,c
ani 0CH
mov c,a
jmpr FIRE
;---------------------------------------
; set up robot and bolt
;---------------------------------------
;hl->bolt,c=direction(DURL)
FIRE:
push h ;save bolt pointer
; zero the whole bolt
mvi b,Blength
xra a
..zap: mov m,a
inx h
djnz ..zap ;b=0
call SRFIRE# ;make noise
lxi h,D.TAB ;translate DURL to clock
dad b ;b=0,c=durl
mov c,m ;direction offset
lxi h,S.TAB
dad b ;entry 2
dad b ;4
dad b ;6
mov V.X(x),B ;b=0
mov V.Y(x),B ;robot stops moving
mov a,m ;get pattern address
inx h
di
mov D.P.L(x),A
mov a,m
mov D.P.H(x),A
ei
inx h
mvi TIME(x),1 ;make it write
mov b,m ;xoffset
inx h
mov c,m ;yoffset
inx h
mov d,m ;vx.vy
mov a,P.X(x) ;calc offset from robot
add B
mov b,a
mov a,P.Y(x) ;same for y
add C
mov c,a
pop h ;-> bolt
mov a,d
ori 3 ;length of bolt
di
mov m,a ;vx.vy
inx h
mov m,b ;xposition
inx h
mov m,c ;yposition
inx h ;repeat for tail
mov m,b ;xposition
inx h
mov m,c ;yposition
ei
pop psw ;durl
pop b ;tracker
pop h ;timer
mvi m,10
..wlp: call NEXT.J
bit INEPT,V.STAT(x)
jrnz ..sk
mov a,m
ora a
jrnz ..wlp
..sk:
; wait is lesser of (Robots*4)+5 or (Rwait/2)
; RWait comes into play later in the game
lda Robots ;bolt hold off
add a
add a
adi 5 ;was 10
mov c,a ;save this delay
lda Rwait
srlr a
cmp c ;compare and use
jrc ..t ;lesser delay
mov a,c
..t: mov m,a
mvi C,10H ;force new setpat
jmp R.ret
;
.define SS[Xoffset,Yoffset,Pat,Dir]=[
.word Pat
.byte Xoffset
.byte Yoffset
.byte Dir<4
.byte 0
]
; shoot table
;
S.TAB: SS 0,0,S.0,0 ;0
SS 5,0,S.0,6 ;1ur
SS 6,1,S.0,2 ;2r
SS 6,2,S.0,10 ;3dr
SS 6,10,S.0,8 ;4d
SS 0,2,S.0,9 ;5dl
SS 0,1,S.0,1 ;6l
SS 0,0,S.0,5 ;7ul
SS 5,0,S.0,4 ;8u
.end

270
super.asm Normal file
View File

@ -0,0 +1,270 @@
B>type super.asm
.title "SUPER-ROBOT"
.sbttl "FRENZY"
.ident SUPER
;-------------+
; super robot |
;-------------+
.insert EQUS
.intern SETVXY
.extern NEXT.J,J.WAIT,D.TAB,V.ZERO,SR.0
Down= 3
Up= 2
Right= 1
Left= 0
;-------------
; Initialize
;-------------
SUPER::
xra a
sta CACKLE+1 ;otto death flag
lhld ManX ;set position
mov a,l
cpi 32
jrnc ..r
mvi L,2
jmpr ..y
..r: cpi 240
jrc ..y
mvi L,248
..y: mov a,h
cpi 180
jrc ..t
mvi H,160
..T: shld SSpos
lda Rsaved ; calc time til start
mov b,a
lda Rwait
rrc
rrc
ani 7
add B
sta STIME
mvi e,0 ;speed=1
; wait for stime seconds
..LOOP: WAIT 40
lxi h,STIME
dcr m
jrnz ..LOOP
lhld SSpos ;super start pos
mvi a,30
sta KWait
jmpr INIT
;~~~~~~~~~~~~~~~~~~~~~~~
; Moms own SUPER Ottos
;_______________________
;de=yx to start
Klutz:: lxi d,(84<8)!128
MSUPER::
xchg ;get hl=YX
lxi d,1 ;sportingly fast ottos
; initialize, e=speed
INIT: push d
PUSH H
call V.ZERO ; zap vector
POP H
pop d
jc JobDel# ;if none available forget it
mov a,e ;if faster speed no talk
ora a
jrnz REDO ;go fast
PUSH D
PUSH H
call S.TALK#
POP B
POP D
WAIT 60
mov h,b
mov l,c ;start position
REDO: mov P.X(x),L ;set pos
mov P.Y(x),H
xra a
mov V.X(x),a
mov V.Y(x),a
lxi h,SR.0
mov D.P.L(x),L
mov D.P.H(x),H
mvi TIME(x),1
mvi TPRIME(x),2 ;slower than normal
mvi d,0 ;number of hits taken
mvi V.STAT(x),(1<InUse)!(1<Move)!(1<Write)
xra a
call SETDIR
WAIT 60
res HIT,V.STAT(x)
;------------------------+
; super robot's job loop |
;------------------------+
SEEK: lxi y,Vectors ; mans vector
push D
;calc delta x => e
mov a,P.X(y) ;man x
sub P.X(x) ;robot x
;calc x index
mvi B,0 ;0 velocity in x
jrz X.D
mvi B,1<RIGHT ;+ vel in x
jrnc X.D
mvi B,1<LEFT ;- vel in x
neg
;calc delta y => d
X.D: mov d,a ;save |delta X|
mov a,P.Y(y) ;mans Y
add e ;drift down with speed
mov e,d ;save delta in right place
sui 1
cpi 175+1
jc ..ok ;adjust mans x
mvi a,175
..ok: sub P.Y(x)
;calc y index
mvi C,0 ;0 velocity in y
jrz Y.D
mvi C,1<DOWN ;+ vel in y
jrnc Y.D
mvi C,1<UP ;- vel in y
neg
Y.D: mov d,a ;save abs(delta Y)
mov a,b ;add offsets
add c ;to from direction
mov b,d ;bc=de
mov c,e
pop D ;speed
call SETDIR
bit HIT,V.STAT(x) ;check for hits
jrz ..wait
res HIT,V.STAT(x) ;reset hit bit
call SBLAM# ;hit sound
inr d ;number of hits taken
push d
; set new pattern
lxi h,SR.1#
dcr d
jz ..stdp
lxi h,SR.2#
..stdp: mov D.P.L(x),L
mov D.P.H(x),H
mvi TIME(x),1
lxi b,102h ;50pts
call ADDS#
pop d
mov a,d ;check hits
cpi 3 ;if 3 then DIE sucker
jrz DIE
..wait: call NEXT.J
jmpr SEEK
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Otto Deflates
;_______________________________
DIE: xra a
mov V.X(x),a
mov V.Y(x),a
cma
sta CACKLE+1 ;otto death flag
call SD.TALK#
lxi h,SR.3#
mov D.P.L(x),L
mov D.P.H(x),H
mvi TPRIME(x),4 ;real slow
WAIT 60
mvi V.STAT(x),(1<InUse)!(1<Erase)
WAIT 10
; start a new otto
mov a,e
cpi 7
jrnc ..n
inr e ;up the speed
..n: lhld SSpos
jmp REDO
;-----------------------------
; change direction of robot
; a=durl, e=speed
;-----------------------------
SETDIR: ani 0FH ; SUPER ROBOTS VERSION
jnz ..nor
lxi b,0
jmp SETV
..nor: PUSH B ;save deltas
EXAF ;save durl
;get speed numbers
lxi h,SpeedTab
mvi B,0
mov c,e
dad b
dad b
mov a,m
mov TPRIME(x),a
inx h
mov a,m ;speed
; now set vel
POP B ;delta yx
cmp b ;is vy<|delta|
jrnc ..sy
mov b,a ;save smaller
..sy: cmp c ;is vx<delta
jrnc ..sx
mov c,a ;save smaller
..sx: EXAF ;get durl
bit up,a
jrz ..dx
EXAF
mov a,b
neg ;vel=-vel
mov b,a
EXAF
..dx: bit left,a
jrz ..sv
EXAF
mov a,c
neg ;vel=-vel
mov c,a
EXAF
..sv:
SETV: mov V.X(x),c
mov V.Y(x),b
ret
; normal robot version
SETVXY: mov c,a ;update tracker
mvi B,0
lxi h,D.TAB ;convert direction to offset
dad b
mov e,m ;load offset
mov d,b
lxi h,M.TAB ;index move table
dad d
mov a,m ;get vx
mov V.X(x),a
inx h
mov A,m ;get vy
mov V.Y(x),a
ret
;----------------------
; move table
; x,y
M.TAB: .byte 0,0
.byte 1,-1
.byte 1,0
.byte 1,1
.byte 0,1
.byte -1,1
.byte -1,0
.byte -1,-1
.byte 0,-1
.byte 0,0
.define ST[Tprime,Vel]=
[ .byte Tprime,Vel
]
SpeedTab:
ST 3,1
ST 1,1
ST 1,3
ST 1,4
ST 1,6
ST 1,8
ST 1,10
ST 1,12
.end

72
talk.asm Normal file
View File

@ -0,0 +1,72 @@
B>type talk.asm
.title "Talking"
.sbttl "FRENZY"
.ident TALK
;--------------------------------
; voice synthesiser subroutines
;--------------------------------
.insert EQUS
; macros
; equates
XKILL == 1
XATTACK == 2
XCHARGE == 3
XGOT == 4
XSHOOT == 5
XGET == 6
XIS == 7
XALERT == 8
XDETECTED== 9
XTHE == 10
XIN == 11
XIT == 12
XTHERE == 13
XWHERE == 14
XHUMANOID== 15
XCOINS == 16
XPOCKET == 17
XINTRUDER== 18
XNO == 19
XESCAPE == 20
XDESTROY== 21
XMUST == 22
XNOT == 23
XCHICKEN== 24
XFIGHT == 25
XLIKE == 26
XA == 27
XROBOT == 28
xp1 ==29
xp2 ==30
xp3 ==31
;--------------------
; Talk Routines
;--------------------
Talk: pop h ;return points at talk
SHLD V.PC
ret
S.TALK::
call talk
.byte 175Q,XROBOT,XATTACK,107Q,-1
SD.TALK::
call talk
.byte 176Q,XCHARGE,XATTACK,XSHOOT,XKILL,XDESTROY,107q,-1
F1.TALK::
call talk
.byte 174q,XA,Xrobot,Xis,Xnot,Xa,Xchicken,107q,-1
F2.TALK::
call talk
.byte 174q,Xa,Xrobot,Xmust,Xget,Xthe,Xhumanoid,107q,-1
M.TALK::
call talk
.byte 176q,Xthe,Xhumanoid,Xmust,Xnot,Xdestroy,Xthe,Xrobot,107q,-1
C.TALK::
call talk
.byte 173q,Xwhere,Xis,Xthe,Xhumanoid,107q,-1
;
PH1:: .byte 175Q,XCOINS,XDETECTED,XIN,XPOCKET
NoVoice::
.byte 105Q,-1
.end

203
title.asm Normal file
View File

@ -0,0 +1,203 @@
B>type title.asm
.title "TITLE PAGE"
.sbttl "FRENZY"
.ident TITLE
;~~~~~~~~~~~~~~~~~~~~~~~
; TITLE PAGE
;_______________________
.insert equs
.define P[A]=[
.byte ^b'A
]
TITLE:: call CLEAR#
call C.TITLE# ;for now
call CopyR# ;display copyright
; display STERN
lxi y,CROSS
lxi x,STERN
lxi h,12<8!16 ;start pos
lxi d,5<8!4 ;offsets
call PLOTER
; display FRENZY
lxi y,SQUARE
lxi x,FRENZY
lxi h,84<8!16 ;start pos
lxi d,8<8!5 ;offsets
call PLOTER ;**was plotes
ret
; gamevoer frenzy
SmallTitle::
lxi y,Little
lxi x,FRENZY
lxi h,2<8!61 ;start pos
lxi d,4<8!3 ;offsets
call PLOTER
ret
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; PLOTER
; Purpose: Diplays pattern using big patterns as pixel
; Inputs:
; DE = Yoffset,Xoffset
; HL = Y start pos,X start pos
; IX-> Display Data String (i.e. STERN)(*CharArray)
; IY-> Object to use as dots
; additional Regs:
; C = one bit mask
; B = DELAY on each dot
PLOTES: mvi b,-1
jmpr Pl2
PLOTER: mvi b,0
Pl2: mvi c,1 ;first bit mask
..lop1: push h ;save YX
push x ;save *CharArray
..lop2: mov a,0(x) ;check bit for write
ana c ;is bit=1
jz ..inc ;else skip
; plot *iy at H,L
push b ;save all
push d
push h
call RtoAx# ;convert hl
xchg
push y ;get ob pointer
pop h ;to hl
call PLOT#
pop h ;restore all
pop d
pop b
mov a,b
ora a
jz ..inc
mvi b,0
..l: xtix
xtix
xtix
xtix
djnz ..l ;delay slightly
mov b,a
..inc: mov a,l ;x
add e ;xoffset
mov l,a ;x +=offset
inx x ;++CArray
mov a,0(x) ;test if at end of array
ora -1(x) ;both 0 means end
jnz ..lop2 ;go do next dot
pop x ;*CA=&start of array
pop h ;restore X to begin of line
mov a,h ;y
add d ;Yoffset
mov h,a ;y+=Yoffset
slar c ;maskbit=maskbit<<1
jnz ..lop1 ;if still a bit left do it
ret
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Data for display
; organized as strips
;-------------------------------
STERN:
P 11001110
P 11011011
P 11011011
P 11111011
P 01110011
P 00000000
P 00000011
P 00000011
P 11111111
P 11111111
P 00000011
P 00000011
P 00000000
P 11111111
P 11111111
P 11011011
P 11011011
P 11000011
P 00000000
P 11111111
P 11111111
P 00011011
P 00011011
P 11111111
P 11101110
P 00000000
P 11111111
P 11111111
P 00001110
P 00011100
P 00111000
P 11111111
P 11111111
P 00000000
P 00000000
FRENZY:
P 11111111
P 11111111
P 00011011
P 00011011
P 00000011
P 00000011
P 00000000
P 11111111
P 11111111
P 00011011
P 00011011
P 11111111
P 11101110
P 00000000
P 11111111
P 11111111
P 11011011
P 11011011
P 11000011
P 11000011
P 00000000
P 11111111
P 11111111
P 00001110
P 00011100
P 00111000
P 11111111
P 11111111
P 00000000
P 11100011
P 11110011
P 11111011
P 11011111
P 11001111
P 11000111
P 00000000
P 00000111
P 00001111
P 11111100
P 11111100
P 00001111
P 00000111
.byte 0,0
CROSS: .byte 1,4
P 01000000
P 11100000
P 11100000
P 01000000
SQUARE: .byte 1,9
P 01111100
P 10000100
P 10000100
P 10000100
P 11111100
P 10000100
P 10000100
P 10000100
P 11111000
Little: .byte 1,4
P 11000000
P 11000000
P 11000000
P 00000000
.end

328
uphigh.asm Normal file
View File

@ -0,0 +1,328 @@
B>type uphigh.asm
.title "Update High Scores"
.sbttl "FRENZY"
.ident UPHIGH
;-------------------+
; High Score Update |
;-------------------+
.insert EQUS
.extern CLEAR,ScorePtr,SHOWA,RtoA,SHOWC,SHOWO
.extern C.HIGH,J.WAIT,LTABLE,S.STICK,NEXT.J
.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
]
UPHIGH::
CALL ScorePtr
B.BOP: push h
; hl->players score
inx h
inx h ;->last byte
; add score to total
mvi c,6
xchg ;->de score
push d
call ItemPtr# ;->hl at books
mov e,b ;->end
mvi d,0 ; by adding offset
dcr e ; -1
dad d
pop d
; b=# bytes hl->books end de->score end
mvi c,0 ;no carry flag
ldax d ;get score 2 digits
dcx d
call AdBtoN
ldax d ;get score 2 digits
dcx d
call AdBtoN
ldax d ;get score 2 digits
dcx d
call AdBtoN ;done with player score
mvi b,3 ;the rest of the score area
..loop: xra a
call AdBtoN
djnz ..loop
; now xsum it
mvi c,6 ;scum #
call ItemPtr
push h
mvi c,0 ;put xsum in c
..xsum: mov a,m ;add nibble to xsum
ani 0F0h
add c
mov c,a
inx h
djnz ..xsum
pop h
dcx h ;->xsum byte
mov m,c
;check for high score
mvi C,10 ;number of high scores
lxi d,HIGH1 ;-> highest high
pop h
..HLP: push h
push d ;save pointer to high score
mvi B,3 ;number of bytes in high
..test: ldax d ;get high
cmp m ;compare to score
jrc NEW.HI ;high exceeded?
jrnz ..SKIP ;equal maybe new high
inx d
inx h
djnz ..test
..SKIP: pop d ;restore high pointer
lxi h,6 ;length of high entry
dad d ;point to next entry
xchg ;put in de
pop h
dcr c ;one less entry to look at
jrnz ..HLP ;out of entries?
ret
;------------------------+
; new high score to date |
;------------------------+
; enter new score by pushing down old ones
NEW.HI: pop d ;get pointer to high score beaten
push d
mvi B,0 ; c=number of entries left
dcr c
jrz ..SK
lxi h,0 ;hl=bc*6
dad b
dad h
dad b
dad h
push h ;save for later
dad d ;point at end
dcx h
mov d,h
mov e,l
lxi b,+6
dad b
xchg
pop b
lddr
..SK: pop d ;new high
pop h ;->score
mvi B,3
..LP: mov a,m
inx h
stax d
inx d
djnz ..LP
xchg
;~~~~~~~~~~~~~~~~~~~~~
; get player initials
;_____________________
push h
call CLEAR
call C.HIGH
call SHOWS#
LANG Line1
exaf
mvi B,1
lxi h,PLAYER ;show player number
call SHOWO
LANG Line2
WROTE 90H,120,98,("___")
LANG Line3
call GetTimer#
push h
pop y ;iy->timer
;get letters
mvi B,0
lxi h,96*256+120 ;start char
call RtoA ;a=magic
xchg
pop h ;restore pointer to letters
push h
mvi B,3
..fill: mvi M,' '
inx h
djnz ..fill
pop h
mvi A,30 ;# of seconds to wait
sta DEATHS ; for initials
mvi B,3 ;number of chars
mvi C,'A'
S.L: push b
lda FLIP ;0 or 8=flop
call SHOWC
pop b
mvi 0(y),15
..wlp: call NEXT.J
mov a,0(y)
ora a
jrnz ..wlp
T.L: mvi 0(y),60 ;sixty ticks to a second
I.L: mov a,0(y) ;if a second is up
ora a
jrnz I.S
lda DEATHS ;then if[[--wait.time]==0]
dcr a
sta DEATHS
jrz BUP ;leave else goto t.l
jmpr T.L
I.S: call S.STICK
bit 4,A ;fire:lock in letter?
jrz ROTA
mov m,c ;store
push b ;save number of letters
lda FLIP
ora a
lxi b,64 ;shift down 2 lines
jrz ..up
lxi b,-64
..up: push d
xchg
dad b
xchg
lda FLIP ;0 or 8=flop
ori 90H ;xor
mvi C,'_' ;erase underline
call SHOWC
pop d
pop b
inx h ;point to next letter
lda FLIP
ora a
inx d ;move screen position
jrz ..dl
dcx d ;backwards writing
dcx d
..dl: call S.STICK
bit 4,A
jrnz ..dl
djnz S.L ;dec chars left
; update battery backed up score
BUP: lxi h,HIGH1
lxi d,HIGH2
lxi B,(5*6<8)!0
BHLP: mov a,m
ani 0F0h
stax d
inx d
add c ;check sum it on fly
mov c,a
mov a,m
inx h
rlc
rlc
rlc
rlc
ani 0F0h
stax d
inx d
add c ;check sum it on fly
mov c,a
djnz BHLP
mov a,c ;get xsum
sta HIGH2-1 ;store it
ret
; change letter?
ROTA: bit 0,A ;down,left=less
jrnz ..su
bit 3,A
jrnz ..su
bit 1,A ;up/right=more
jrnz ..ad
bit 2,a
jrnz ..ad
jmp I.L
..su: mvi a,-1
jmpr ..adj
..ad: mvi a,1
..ADJ: add c ;change char
cpi 'A'-1 ;check in range a-z
jrnz ..2
mvi A,'Z'
..2: cpi 'Z'+1
jrnz ..3
mvi A,'A'
..3: mov c,a ;store new char
jmp S.L
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Add A to 2 nibble in books
; c=carry status
;______________________________
AdBtoN: push psw
rlc
rlc
rlc
rlc
call Nib
pop psw
; call Nib
Nib: ani 0f0h
exaf
mov a,m
ani 0f0h
add c
daa
mov m,a
exaf
add m
daa
mov m,a ;store the books
dcx h
mvi c,0
rnc
mvi c,10h ;carry
ret
;---------------
ELine1: WROTE 90H,32,08,("Congratulations Player ")
ret
FLine1: WROTE 90H,16,08,("Felicitations au joueur ")
ret
GLine1: WROTE 90H,32,08,("Gratuliere, Spieler ")
ret
SLine1: WROTE 90H,32,08,("Felicitaciones jugador ")
ret
;---------------
ELine2: WROTE 90H,08,32,("You have joined the immortals")
WROTE 90H,16,48,("in the FRENZY hall of fame")
WROTE 90H,24,80,("Enter your initials:")
ret
FLine2: WROTE 90H,08,32,("Vous avez joint les immortels")
WROTE 90H,24,48,("du pantheon FRENZY.")
WROTE 90H,08,80,("Inscrire vos initiales:")
ret
; ---------------------- 123456789012345678901234567890
GLine2: WROTE 90H,08,32,("Das War ein Ruhmvoller Sieg!")
WROTE 90H,08,64,("Trag Deinen Namen in die")
WROTE 90H,16,80,("Heldenliste ein!")
ret
SLine2: WROTE 90H,04,32,("Se puntaje esta entre los diez")
WROTE 90H,08,48,("mejores.")
WROTE 90H,24,80,("Entre sus iniciales:")
ret
;---------------
GLine3 == .
ELine3: WROTE 90H,8,128,("Move stick to change letter")
WROTE 90H,8,144,("then press FIRE to store it.")
ret
FLine3: WROTE 90H,4,128,("Poussez batonnet pour vos")
WROTE 90H,4,144,("initiales. Poussez FIRE quand")
WROTE 90H,4,160,("lettre correcte")
ret
;
SLine3: WROTE 90H,4,128,("Moviendo la palanca para")
WROTE 90H,4,144,("cambiar las letras, luego")
WROTE 90H,4,160,("aplaste el boton de disparo")
WROTE 90H,4,176,("para retenerlas.")
ret
.end

32
xsum.asm Normal file
View File

@ -0,0 +1,32 @@
B>type xsum.asm
.title "Xsums"
.sbttl "FRENZY"
.ident xsum
;----------------------------------------------------------------
;
; CKSUM BYTE #1
;
;----------------------------------------------------------------
;
.intern BYTE1,PRMNBR
.extern BYTE2,BYTE3,BYTE4,BYTE5,BYTE6
;
BYTE1: .byte 0 ;SUM BYTE
;
;
; NUMBER OF PROMS IN SYSTEM, DEFINES HERE IN POWERUP
;
PRMNBR == 6
;
;
.loc 4000H ;DATA TABLE FOR CKSUM GENERATING PROGRAM
.byte PRMNBR ;5 ROM SYSTEM
.word BYTE1
.word BYTE2
.word BYTE3
.word BYTE4
.word BYTE5
.word BYTE6
;
.end