	.PREL
	.IDENT	MAIN
	.INSERT	HVG.LIB
	.INSERT	MACRO.LIB
	.INSERT	MUSIC.LIB
	.INSERT	BBEQU.ASM
	.LOC	BOTSCR
; TAPE INPUT GOODIES
CONPRO	==:	.	; TAG TO NAIL BOTH
PROPTR:: .BLKB	1	; PRODUCERS POINTER
CONPTR:: .BLKB	1	; CONSUMERS POINTER
TAPBUF:: .BLKB	48	; ROTATING BUFFER
TBFEND	==:	.	; 1 PAST END OF BUFFER
BBRND:: .BLKB	4	; RANDOM NUMBER SEED REGISTER
KBBPC::
KBPRO:: .BLKB	1	; KEYBOARD PRODUCER POINTER
KBCON:: .BLKB	1	; KEYBOARD CONSUMER POINTER
KEYBUF:: .BLKB	KEYBSZ	; KEYBOARD TYPEAHEAD BUFFER
OLDKEY:: .BLKB	1	; LAST KEY CODE FROM CHROMERICS
HLTFLG:: .BLKB	1	; HALT KEY HIT FLAG
TXTUNF:: .BLKB	2
CURFLG:: .BLKB	1	; CURSOR FLAG
KEYTMR:: .BLKB	1	; KEYBOARD SCAN TIMER
MUZTMR:: .BLKB	1	; MUSIC NOTE TIMER
NEWTMR:: .BLKB	1	; NEW MUSIC TIMER VALUE
MUZMO:: .BLKB	1	; MASTER OSCILLATOR
MUZTON:: .BLKB	1	; TONE VALUE
SHARPF:: .BLKB	1	; SHARP-FLAT FLAG
;
WINPTR:: .BLKB	2	; WINDOW TABLE POINTER
;
INCRO:: .BLKB	2	; GRAPHICS
MNMX:: .BLKB	2
PIXVAL:: .BLKB	1
WRMODE:: .BLKB	1
EDFLG:: .BLKB	1	; EDITOR FLAG
EDPTR:: .BLKB	2	; EDITOR POINTER
;
CIRXA:: .BLKB	2
CIRYA:: .BLKB	2
CIRDEL:: .BLKB	2
;
NLLNLN:: .BLKB	2	; LINE NUMBER BEING TYPED
NLLNCT:: .BLKB	1	; AUTO LINE # FLAG-COUNTER
NLLNZS:: .BLKB	1	; AUTO LINE NUMBER ZERO SURPRESS FLAG
OLDLN:: .BLKB	2	; PREVIOUS LINE # TYPED
;
LRGFNT:: .BLKB	7	; LARGE FONT TABLE
KEYTRK:: .BLKB	1	; KEYBOARD TRACKER
VARBGN:: .BLKB	2*26
DEVVAR::	; DEVICE VARIABLES::	
DEVCL0:: .BLKB	2	; BACKGROUND COLOR
DEVCL1:: .BLKB	2	; FOREGROUND COLOR
DEVCL2:: .BLKB	2	; COLOR 2
DEVCL3:: .BLKB	2	; COLOR 3
DEVXR:: .BLKB	2	; X RIGHT
DEVXL:: .BLKB	2	; X LEFT
DEVYT:: .BLKB	2	; Y TOP
DEVYB:: .BLKB	2	; Y BOTTOM
DEVTEM:: .BLKB	2	; TEMPO
VDMX:: .BLKB	2	; VDM X COORDINATE
VDMY:: .BLKB	2	; VDM Y COORDINATE
VDMCC:: .BLKB	2	; COLOR OF CHARS
VDMLC:: .BLKB	2	; LAST CHAR DISPLAYED
VDMCF:: .BLKB	2	; POINTER TO FONT DESCRIPTOR
VDMCR:: .BLKB	2	; VDM WINDOW RIGHT LIMIT
VDMCL:: .BLKB	2	; LEFT LIMIT
VDMCT:: .BLKB	2	; TOP LIMIT
VDMCB:: .BLKB	2	; BOTTOM LIMIT
DEVNB:: .BLKB	2	; NUMBER PRINT BASE
OLDXY:: .BLKB	2	; PREVIOUS COORDINATES FROM VECTOR DRAW
REMAIN:: .BLKB	2	; REMAINDER FROM LAST DIVIDE
BCDA1:: .BLKB	9	; FIRST	ARG AREA
BCDA2:: .BLKB	9	; SECOND ARG AREA
TAPEST:: .BLKB	1	; TAPE STATUS
CURRNT:: .BLKB	2
STKGOS:: .BLKB	2
VARNXT	==:	.
STKINP:: .BLKB	2
LOPVAR:: .BLKB	2
LOPINC:: .BLKB	2
LOPLMT:: .BLKB	2
LOPLN:: .BLKB	2
LOPPT:: .BLKB	2
	.BLKB	1
BUFFER:: .BLKB	160
BUFEND	==:	.
	.BLKB	32
STKLMT	==:	.
	.LOC	TOPSCR
STACK	==:	.
	.LOC	BOTRAM
TEXT:: .BLKB	2
	.LOC	BOTROM
.MAIN.:: JMP	HKRST0#	; ** AUTOSTART CASSETTE **
	.ASCIZ	'(C) 81 BALLY'
JTAB:	.WORD	SIDINT
ITAB:	.WORD	TBIINT
; ** TINY BASIC EXECUTION STARTS HERE **
BEGIN::
	DI
	XRA	A
	OUT	INMOD
; CLEAR WHOLE KIT AND KABOODLE
	MVI	A,13H
	OUT	0F8H
	MVI	A,00H
	OUT	0F9H
	MVI	A,0CFH
	OUT	0FAH
	MVI	A,00H
	OUT	0FBH
	XRA	A
	OUT	MAGIC
	STA	0FFFH	; FLUSH OUT THE SHIFTER
	LXI	H,4000H	; CLEAR SCREEN AND PGM AREA
	MOV	B,A
BEGIN1:	MOV	M,B
	INX	H
	MOV	A,H
	CPI	50H
	JRNZ	BEGIN1
	LXI	H,8000H
..FRG2:	MVI	M,0
	INX	H
	MOV	A,H
	CPI	90H
	JRNZ	..FRG2
	LXI	SP,STACK
	ENTER
	SETOUT	1
	.BYTE	204
	.BYTE	44
	.BYTE	8
	EMUSIC	1	; SHUT DOWN MUSIC
	SETB	1
	.BYTE	OA2	; SET INITIAL MASTER OSCILATOR
	.WORD	MUZMO
; INITIALIZE DEVICE VARIABLES
	MOVE	1
	.WORD	DEVVAR
	.WORD	38
	.WORD	INIDEV#
	MOVE	1
	.WORD	LRGFNT
	.WORD	5
	.WORD	INILFD
	SETW	1
	.WORD	DEVXR
	.WORD	WINPTR
	EXIT
	LHLD	20BH
	SHLD	LRGFNT+5	; COPY FONT TABLE OVER
	LXI	H,'JF'
	SHLD	BBRND
	LXI	H,'ZM'
	SHLD	BBRND+2
	CALL	RESCXY#
ZAPALL:: LHLD	HVTEXT#
	INX	H
	MVI	M,0FFH
	INX	H
	INX	H
	INX	H
	SHLD	TXTUNF
	MVI	A,0FFH
	CALL	TBIEST	; FIRST TIME THRU
	LXI	D,UPMSG
	CALL	PRTSTG#
	JMP	TELL#
INIT0::	CALL	TBIEST
INIT::	CALL	UNCURSE#	; DINK THE CURSOR IF ITS THERE
	XRA	A		; CLEAR HALT FLAG
	STA	HLTFLG
	CALL	HKHLT#
	CALL	CRLF#
	JMP	TELL#
INILFD:	.BYTE	20H,5,7,6,8	; INITIAL LARGE FONT DESCRIPTOR
UPMSG:	.ASCII	'HOT ROD BALLY BASIC'
	.BYTE	CR
; TINY BASIC INTERRUPT ROUTINE
TBIINT:	PUSH	PSW	; SAVE REGISTERS
	PUSH	B
	PUSH	D
	PUSH	H
; DEAL WITH KEYBOARD SCAN TIMER
	LXI	H,KEYTMR
	MOV	A,M
	ANA	A
	JRZ	TBIN0
	DCR	M
TBIN0:	INX	H
; HAS MUSIC TIMER COUNTED DOWN?
	MOV	A,M
	ANA	A
	JRZ	TBIN1	; YEP - PLAY NEXT NOTE
	DCR	M	; ELSE DECREMENT IT
	JRNZ	TBIN3	; JUMP IF NOT NOW ZERO
	XRA	A
	OUT	TONEA	; ELSE SILENCE
	JMPR	TBIN2
; MUSIC TIMER IS AT ZERO - ARE NEW PARAMETERS READY?
TBIN1:	INX	H	; STEP TO NEW TIMER VALUE
	ORA	M	; IS IT NON ZERO?
	JRZ	TBIN3	; JUMP IF NOT
	DCX	H	; ELSE SET OFFICIAL TIMER
	MOV	M,A
	INX	H
	MVI	M,0	; ZERO NEW TIMER VALUE AS FLAG
	INX	H
	MOV	A,M	; GET NEW M.O.
	OUT	TONMO
	MVI	M,OA2	; RESET DEFAULT MASTER OSC
	INX	H
	MOV	A,M	; AND NEW TONE
	OUT	TONEA
	ANA	A	; REST WANTED?
	JRZ	TBIN3	; YES - JUMP AROUND VOLUME UPDATE
	MVI	A,15
TBIN2:	OUT	VOLAB
; SET COLOR REGISTERS TO VALUES IN PARAMETER VARS %0 AND %1
TBIN3:	LDA	DEVCL0
	OUT	COL0L
	LDA	DEVCL1
	OUT	COL1L
	LDA	DEVCL2
	OUT	COL2L
	LDA	DEVCL3
	OUT	COL3L
; DONE - RESTORE REGISTERS AND GO BACK
INTDON:	CALL	HKSINT#
	POP	H
	POP	D
	POP	B
	JMPR	ZRONK
; SERIAL INPUT DRIVER INTERRUPT ROUTINE
; THIS ROUTINE SAMPLES THE SERIAL INPUT BIT
; AND FORMS CHARACTERS WHICH ARE PLACED IN THE
; CIRCULAR INPUT BUFFER FOR CONSUMPTION BY BACKGROUND LEVEL
;
; THIS ROUTINE USES THE ALTERNATE REGISTER SET
; WHERE B=STATE VARIABLE, C=CHARACTER ACCUMULATOR
; IF STATE VAR < 0 => WE ARE AWAITING -N STOP BITS BEFORE
;       WE BELIEVE ANYTHING
; IF STATE VAR = 0 => WE ARE LOOKING FOR A START BIT
; IF STATE VAR > 0 => WE ARE GETTING DATA BITS
SIDINT:	PUSH	PSW
	EXX
; SAMPLE THE INPUT BIT
GETBIT:	IN	TAPEIO
	RAR	
	MOV	A,C	; SHIFT INTO ACCUMULATOR
	RAR	
	MOV	C,A
	MOV	A,B	; WHAT STATE ARE WE IN?
	ANA	A
	JM	SIDIN0	; 1 COUNTING STATE?
	JRNZ	SIDIN1	; JUMP IF IN MIDDLE OF CHAR
; WE ARE WAITING FOR A START BIT
	BIT	7,C	; DID WE GET ONE?
	JRNZ	SIDIN3	; JUMP IF RIGHT
	MVI	B,8	; SET WAITING FOR 8 BITS
	JMPR	SIDIN3	; AND GO GONZO
; TAPE INPUT WAS RECENTLY TURNED ON, AND WE ARE WAITING FOR
; SEVERAL SEARCH WINDOWS IN A ROW TO EACH SHOW A 1 BIT
; IMPLYING THAT THIS BEASTIE IS REALLY WORKING
SIDIN0:	INR	B	; ASSUME WE GOT IT
	BIT	7,C
	JRNZ	SIDIN3	; JUMP IF GOOD ASSUMPTION
; NO - RESET COUNTER AND WAIT SOME MORE
	MVI	B,STPBCT
	JMPR	SIDIN3
; IN THE MIDDLE OF A CHARACTER...
; WAS THIS THE LAST BIT?
SIDIN1:	DJNZ	SIDIN3	; JUMP IF NOT
; WELCOME TO LAST BITSVILLE
	LHLD	CONPRO	; GET POINTERS
	MOV	A,L
	CALL	BUMPTR	; A=P+1
	CMP	H	; IS C = P+1?
	JRZ	SIDIN3	; YEP - FULL - IGNORE
	STA	PROPTR
	MVI	H,TAPBUF>8
	MOV	M,C
SIDIN3:	EXX
	CALL	HKLPIN#
ZRONK:	POP	PSW
	EI
	RET
; SUBROUTINE TO INCREMENT 1 BYTE POINTER TO CIRCULAR BUFFER
BUMPTR::	INR	A	; BUMP IT
	CPI	TBFEND&0FFH
	RNZ		; QUIT IF NOT AT END
	MVI	A,TAPBUF&0FFH
	RET
; COMMAND TO RESTORE TINY BASIC INTERRUPT ROUTINE
TRETUR:: CALL	TBIEST
BBRET:	RSTFIN	; GO HOME
TBIEST::	IN	TAPEIO	; INITIALIZE TAPE INTERFACE
	ANI	2
	JRNZ	TBIEST	; WAIT FOR THANG TO GO TO ZERO
	STA	TAPEST
	MVI	A,3
	STA	DEVTEM
; ACTIVATE TINY BASIC INTERRUPT ROUTINE
	DI
	IM2	
	MVI	A,ITAB>8
	STAI	
	MVI	A,8
	OUT	INMOD
	MVI	A,200
	OUT	INLIN
	MVI	A,ITAB&0FFH
	OUT	INFBK
	EI
	RET
; SUBROUTINE TO ESTABLISH TAPE UNIT AS INPUT DEVICE
TINPES:: DI
	LXI	H,((TAPBUF&0FFH)<8)+(TAPBUF&0FFH)
	SHLD	CONPRO
	EXX
	XRA	A
	STA	DEVTEM
	INR	A
	STA	TAPEST
	MVI	B,STPBCT
	EXX
	MVI	A,18H
	OUT	INMOD
	EI
	RET
	.END
                                                                                            