.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