home *** CD-ROM | disk | FTP | other *** search
- ;
- ; TARBELL CASSETTE BASIC I/O SYSTEM
- ; LAST CHANGED 8-23-78
- ;
- ; THIS INPUT/OUTPUT SOURCE USES CONDITIONAL
- ; ASSEMBLIES TO ACTIVATE DIFFERENT PARTS OF
- ; THE CODE FOR DIFFERENT PURPOSES. NOTE THAT
- ; SEVERAL EQU'S BELOW ARE SET EITHER TO TRUE
- ; (-1) OR FALSE (0). THESE VALUES ARE THEN
- ; USED WITH THE PSUEDO-OPS "IF" AND "ENDIF"
- ; TO INHIBIT THE ASSEMBLY OF SECTIONS OF CODE.
- ; THIS IS A FEATURE OF THE CP/M ASSEMBLER.
- ;
- TRUE EQU 0FFFFH ;FOR CONDITIONAL ASSEMBLIES.
- FALSE EQU NOT TRUE
- ;
- CPM EQU TRUE ;TRUE FOR CP/M DISK SYSTEMS.
- DISK EQU TRUE ;TRUE FOR DISK VERSION.
- STD EQU FALSE ;TRUE FOR STANDARD CONSOLE.
-
- ; PORTS FOR STANDARD I/O SYSTEM.
- CONSP EQU 0 ;CONSOLE STATUS PORT.
- CONDP EQU 1 ;CONSOLE DATA PORT.
- CONIM EQU 01H ;CONSOLE INPUT MASK.
- CONOM EQU 80H ;CONSOLE OUTPUT MASK.
- LSTSP EQU 2 ;LISTER STATUS PORT.
- LSTDP EQU 3 ;LISTER DATA PORT.
- LSTOM EQU 080H ;LISTER OUTPUT MASK.
-
- ; PORTS FOR TARBELL CASSETTE I/O.
- CASC EQU 6EH ;CASSETTE STATUS PORT.
- CASD EQU 6FH ;CASSETTE DATA PORT.
-
- ; CP/M BIOS JUMP VECTOR OFFSETS.
- CONST EQU 3 ;CONSOLE STATUS OFFSET.
- CONIN EQU 6 ;CONSOLE INPUT OFFSET.
- CONOT EQU 9 ;CONSOLE OUTPUT OFFSET.
- LIST EQU 12 ;LIST OUTPUT OFFSET.
-
- ; CP/M COMMON LOCATIONS.
- BDOS EQU 5 ;MAIN ENTRY POINT TO BDOS.
- FCB EQU 5CH ;DEFAULT FILE CONTROL BLOCK.
- TBUFF EQU 80H ;DEFAULT BUFFER LOCATION.
-
- ; ENTRY POINTS INTO TARBELL BASIC INTERPRETER.
- BASIC EQU 0500H ;START OF TBASIC INTERPRETER.
- CHANL EQU BASIC+3 ;ADR OF ADR OF CHANNEL TABLE.
- TRMNL EQU BASIC+5 ;ADR OF ADR OF TERMINAL TABLE.
- SSSS EQU BASIC+7 ;ADR OF ADR OF END OF MEMORY.
- CNVRA EQU BASIC+9 ;ADR OF ADR OF NO. OF DIGITS.
- FPRA6 EQU BASIC+11 ;ADR OF ADR OF USR ROUTINE.
- MODES EQU BASIC+13 ;ADR OF ADR OF MODES TABLE.
- FSRC EQU BASIC+15 ;ADR OF ADR OF START OF PROGRAM.
- ESRC EQU BASIC+17 ;ADR OF ADR OF END OF PROGRAM.
- ;
- ;
- ORG 100H ;NORMAL LOAD ADDRESS.
- JMP INIT ;GO TO INITIALIZATION.
- CONI: JMP CONINP ;CONSOLE INPUT ROUTINE.
- CONO: JMP CONOUT ;CONSOLE OUTPUT ROUTINE.
- SPAR: NOP!NOP!RET ;FOR SPARE I/O ROUTINE.
- LSTO: JMP LSTOUT ;LISTING OUTPUT ROUTINE.
- RDRI: NOP!NOP!RET ;FOR READER INPUT ROUTINE.
- PUNO: NOP!NOP!RET ;FOR PUNCH OUTPUT ROUTINE.
- DSKI: JMP DSKINP ;DISK INPUT ROUTINE.
- DSKO: JMP DSKOUT ;DISK OUTPUT ROUTINE.
- CASI: JMP CASINP ;CASSETTE INPUT ROUTINE.
- CASO: JMP CASOUT ;CASSETTE OUTPUT ROUTINE.
- USR: JMP USRSUB ;HOP TO USER SUBROUTINE.
- ;
- INIT:
-
- IF NOT CPM ;IF NOT CPM, LET BASIC
- LXI H,1 ;FIGURE END OF MEMORY.
- ENDIF
-
- IF CPM AND NOT DISK ;IF NOT DISK VERSION,
- LHLD 1 ;GET START OF BIOS.
- ENDIF
-
- IF CPM AND DISK ;IF DISK VERSION,
- XRA A ;SET DISK I/O FLAG = 0.
- STA DSKFLG
- LHLD 6 ;GET START OF CP/M.
- ENDIF
-
- DCX H ;DECREMENT BELOW IT.
- XCHG ;PUT IN D&E.
- LHLD SSSS ;SET TOP OF MEMORY.
- MOV M,E ;PUT TOP ADR
- INX H ;AT SSSS.
- MOV M,D
- LHLD CNVRA ;GET ADR OF NO. OF DIGITIS.
- MVI M,10 ;MAKE IT TEN.
- LXI H,USR ;GET ADR OF USER SUBROUTINE.
- XCHG ;PUT INTO D&E.
- LHLD FPRA6 ;GET LINKING ADDRESS.
- MOV M,E ;PUT ADR OF USER ROUTINE
- INX H
- MOV M,D ;AT FPRAA+6 IN BASIC.
- LHLD CHANL ;GET ADR OF CHANNEL TABLE.
- LXI D,JADR ;GET ADR OF JMP ADR TABLE.
- MVI B,20 ;MOVE ADDRESS FROM THERE
- CALL MOVE ;TO BASIC'S CHANNEL TABLE.
- LXI D,IMODES ;GET ADR OF INITIAL MODES.
- LHLD MODES ;GET ADR OF MODES TABLE.
- MVI B,10 ;BYTE COUNT = 10.
- CALL MOVE ;INITIALIZE THE MODES TABLE.
- LHLD TRMNL ;GET ADR OF TERMINAL TABLE.
- INX H!INX H!INX H ;H&L = H&L+3
- MVI M,72 ;SET CONSOLE TERM WIDTH.
- INX H!INX H ;H&L = H&L+2.
- MVI M,7FH ;SET CONSOLE RUBOUT.
- LXI D,10 ;SET D&E = 10.
- DAD D ;H&L = H&L+10.
- MVI M,72 ;SET LISTING WIDTH.
- INX H ;GET LIST LOC #2.
- MVI M,0 ;PUT ZERO IN IT.
- INX H ;GET LIST LOC #3.
- MVI M,0BH ;PUT 0B INTO IT.
- JMP BASIC ;HOP INTO TARBELL BASIC.
- ;
- ; JADR - I/O JUMP ADDRESS TABLE, GETS MOVED
- ; INTO BASIC'S CHANNEL TABLE AT INITIALIZATION.
- ;
- JADR: DW CONI ;CONSOLE INPUT ADDRESS.
- DW CONO ;CONSOLE OUTPUT ADDRESS.
- DW CASI ;CASSETTE INPUT ADDRESS.
- DW CASO ;CASSETTE OUTPUT ADDRESS.
- DW SPAR ;SPARE I/O ADDRESS.
- DW LSTO ;LISTING OUTPUT ADDRESS.
- DW RDRI ;READER INPUT ADDRESS.
- DW PUNO ;PUNCH OUTPUT ADDRESS.
- DW DSKI ;DISK INPUT ADDRESS.
- DW DSKO ;DISK OUTPUT ADDRESS.
- ;
- ; MOVE - MOVE THE NUMBER OF BYTES SPECIFIED BY
- ; REGISTER B, FROM THE ADDRESS IN D&E TO THE
- ; ADDRESS IN H&L.
- ;
- MOVE: LDAX D ;GET A BYTE.
- MOV M,A ;PUT A BYTE.
- INX H ;INCREMENT H&L.
- INX D ;INCREMENT D&E.
- DCR B ;DECREMENT COUNTER.
- JNZ MOVE ;GO TILL COUNTER=0.
- RET ;RETURN FROM MOVE.
- ;
- ; IMODES - INITIAL MODES TABLE FOR I/O DEVICES.
- ; THIS GETS TRANSFERRED FROM HERE TO BASIC'S
- ; MODES TABLE UPON INITIALIZATION. AFTER THAT,
- ; BASIC'S MODES TABLE MAY BE CHANGED FROM A
- ; RUNNING BASIC PROGRAM BY USING THE ASSIGN
- ; AND DROP STATEMENTS TO SET & RESET BITS.
- ;
-
- ;LOG. DEV. # 76543210 ;PHYSICAL DEVICE.
-
- IMODES: DB 00000001B ;KEYBOARD INPUT.
- DB 00000010B ;CONSOLE PRINTER.
-
- IF NOT DISK ;IF NOT DISK VERSION.
- DB 00010100B ;CASSETTE INPUT.
- DB 00101000B ;CASSETTE OUTPUT.
- ENDIF
-
- IF DISK ;IF DISK VERSION,
- DB 00000000B ;CASSETTE INPUT.
- DB 00000000B ;CASSETTE OUTPUT.
- ENDIF
-
- DB 00000000B ;SPARE INPUT/OUTPUT.
- DB 00000000B ;LISTING OUTPUT.
- DB 00000000B ;READER INPUT.
- DB 00000000B ;PUNCH OUTPUT.
-
- IF DISK ;IF DISK VERSION,
- DB 00010100B ;DISK INPUT.
- DB 00101000B ;DISK OUTPUT.
- ENDIF
-
- IF NOT DISK ;IF NOT DISK VERSION,
- DB 00000000B ;DISK INPUT.
- DB 00000000B ;DISK OUTPUT.
- ENDIF
-
- ;
- ; CONOUT - PRINT THE CHARACTER IN REGISTER A
- ; ONTO THE CONSOLE OUTPUT DEVICE, USUALLY A
- ; TELETYPEWRITER OR CRT TERMINAL. IF THE
- ; CHARACTER IS A CARRIAGE-RETURN, ADD A
- ; LINE-FEED. IF THE CHARACTER IS A RUBOUT,
- ; ECHO A BACKSPACE.
- ;
- CONOUT: PUSH H ;SAVE H&L.
- PUSH D ;SAVE D&E.
- PUSH B ;SAVE B&C.
- PUSH PSW ;SAVE A&PSW.
- CPI 7FH ;IS IT RUBOUT?
- JNZ ECHO ;IF NOT, ECHO.
- MVI A,08H ;IF SO, GET BACKSPACE.
-
- IF CPM ;IF CP/M I/O,
- CALL IO ;PRINT CHARACTER IN A.
- DB CONOT
- MVI A,20H ;PRINT SPACE.
- CALL IO
- DB CONOT
- MVI A,08H ;PRINT BACKSPACE.
- ECHO: CALL IO
- DB CONOT
- ENDIF
-
- IF STD ;IF STANDARD I/O,
- CALL CONOTS ;PRINT CHARACTER IN A.
- MVI A,20H ;PRINT SPACE.
- CALL CONOTS
- MVI A,08H ;PRINT BACKSPACE AGAIN.
- ECHO: CALL CONOTS
- ENDIF
-
- POP PSW ;RESTORE A&PSW.
- POP B ;RESTORE B&C.
- POP D ;RESTORE D&E.
- POP H ;RESTORE H&L.
- RET ;RETURN FROM CONOUT.
-
- IF STD ;IF STANDARD I/O,
- CONOTS: PUSH PSW ;SAVE REGISTER A & STATUS.
- CONOTL: IN CONSP ;READ CONSOLE STATUS.
- ANI CONOM ;LOOK AT OUTPUT STATUS BIT.
- JNZ CONOTL ;WAIT UNTIL READY.
- POP PSW ;GET CHARACTER.
- OUT CONDP ;PRINT IT.
- RET ;RETURN FROM CONOT.
- ENDIF
-
- ;
- ; CONINP - READ A BYTE FROM THE CONSOLE KEYBOARD INTO
- ; REGISTER A. IF THIS ROUTINE IS ENTERED WITH THE
- ; 8080 ZERO FLAG SET, IT IS A CHECK FOR CONTROL-C.
- ; IN THIS CASE, A CHECK IS MADE TO SEE IF A CONTROL-C
- ; KEY HAS BEEN PUSHED. IF IT HASN'T, A RETURN IS
- ; MADE WITH THE ZERO FLAG CLEARED. IF IT HAS, A
- ; RETURN IS MADE WITH THE ZERO FLAG SET.
- ;
- CONINP: JZ CHKST ;IF ZERO, MUST BE STATUS CHECK.
-
- IF CPM ;IF CP/M I/O,
- CALL IO ;READ KEYBOARD.
- DB CONIN
- ENDIF
-
- IF STD ;IF STANDARD I/O,
- CALL CONINS ;READ KEYBOARD.
- ENDIF
-
- RET ;RETURN FROM CONINP.
- CHKST: PUSH H ;SAVE H&L.
- PUSH D ;SAVE D&E.
- PUSH B ;SAVE B&C.
-
- IF CPM ;IF CP/M I/O,
- CALL IO ;CHECK KEYBOARD STATUS.
- DB CONST
- ENDIF
-
- IF STD ;IF STANDARD I/O,
- CALL CHKSTS ;CHECK KEYBOARD STATUS.
- ENDIF
-
- POP B ;RESTORE B&C.
- POP D ;RESTORE D&E.
- POP H ;RESTORE H&L.
- CMA ;COMPLEMENT RESULT.
- ORA A ;SET FLAGS.
- RNZ ;RETURN IF NO KEY PUSH.
- CHKST1:
- IF CPM ;IF CP/M I/O,
- CALL IO ;READ KEYBOARD.
- DB CONIN
- ENDIF
-
- IF STD ;IF STANDARD I/O,
- CALL CONINS ;READ KEYBOARD.
- ENDIF
-
- CPI 3 ;SET ZERO FLAG IF CTL-C.
- RZ ;RETURN IF CTL-C.
- CPI 13H ;IS IT A CTL-S?
- JZ CHKST1 ;IF SO, READ KB AGAIN.
- RET ;RETURN FROM CONINP.
-
- IF STD ;IF STANDARD I/O,
- ;
- ; CONINS - STANDARD READ FROM KEYBOARD.
- ;
- CONINS: IN CONSP ;READ CONSOLE STATUS.
- ANI CONIM ;LOOK AT INPUT STATUS BIT.
- JNZ CONINS ;LOOP UNTIL READY.
- IN CONDP ;READ THE CHARCTER.
- ANI 7FH ;STRIP PARITY BIT OFF.
- RET ;RETURN FROM CONINS.
- ;
- ; CHKSTS - STANDARD CONSOLE STATUS ROUTINE.
- ;
- CHKSTS: IN CONSP ;READ CONSOLE STATUS.
- ANI CONIM ;LOOK AT KB READY BIT.
- MVI A,0 ;SET A=0 FOR RETURN.
- RNZ ;NOT READY WHEN NOT ZERO.
- CMA ;IF READY, A=FF.
- RET ;RETURN FROM CHKSTS.
- ENDIF
-
- IF CPM ;IF CP/M INPUT/OUTPUT,
- ;
- ; IO - PERFORM AN INPUT OR OUTPUT OPERATION USING
- ; CP/M'S BIOS (BASIC INPUT/OUTPUT SYSTEM). THE
- ; BYTE FOLLOWING THE CALL TO THIS ROUTINE IS AN
- ; OFFSET WHICH IS ADDED TO THE BIOS JUMP VECTOR
- ; ADDRESS TO DETERMINE THE CORRECT ENTRY POINT
- ; TO BIOS.
- ;
- IO: XTHL ;GET ADDRESS OF OFFSET.
- MOV E,M ;PUT OFFSET IN D&E.
- MVI D,0
- INX H ;MAKE RETURN ADDRESS RIGHT.
- XTHL ;PUT BACK ONTO STACK.
- LHLD 1 ;GET ADDRESS OF IO VECTOR.
- DAD D ;ADD OFFSET.
- MOV C,A ;OUTPUT GOES IN C.
- PCHL ;JUMP TO IO ROUTINE.
- ENDIF
-
- ;
- ; LSTOUT - PRINT THE CHARACTER IN REGISTER A ON THE
- ; LISTING DEVICE. IF IT'S A CARRIAGE-RETURN, ADD
- ; A LINE-FEED.
- ;
- LSTOUT: PUSH PSW ;SAVE REG A AND PSW.
- PUSH B ;SAVE B&C.
-
- IF CPM ;IF CP/M I/O,
- CALL IO ;PRINT CHARACTER.
- DB LIST
- ENDIF
-
- IF STD ;IF STANDARD I/O,
- CALL LSTOUS ;PRINT CHARACTER.
- ENDIF
-
- POP B ;RESTORE B&C.
- POP PSW ;RESTORE REG A AND PSW.
- RET ;RETURN FROM LSTOUT.
-
- IF STD ;IF STANDARD I/O,
- ;
- ; LSTOUS - STANDARD LISTING DEVICE ROUTINE.
- ;
- LSTOUS: PUSH PSW ;SAVE CHARACTER.
- LSTOUL: IN LSTSP ;READ STATUS.
- ANI LSTOM ;LOOK AT STATUS BIT.
- JNZ LSTOUL ;WAIT TILL READY.
- POP PSW ;GET CHARACTER BACK.
- PUSH PSW ;BACK AGAIN.
- CPI 7FH ;IS IT BACKSPACE?
- JNZ LSTECH ;HOP IF NOT.
- MVI A,'\' ;PRINT BACKSLASH INSTEAD.
- LSTECH: OUT LSTDP ;PRINT CHARACTER.
- POP PSW ;RECOVER ORIG. CHAR.
- RET ;RETURN FROM LSTOUS.
- ENDIF
-
- ;
- ; CASINP - READ A BYTE FROM CASSETTE RECORDER.
- ; BYTE RETURNS IN REGISTER A. IF THE CARRY
- ; FLAG IS SET UPON RETURN FROM THIS ROUTINE,
- ; A TAPE READ ERROR HAS OCCURED.
- ;
- CASINP: RZ ;RETURN IF EITHER FLAG SET.
- JNC CASINC ;IF CARRY,
- ORA A ;CLEAR IT AND QUIT.
- RET
- CASINC: PUSH H ;SAVE H&L.
- PUSH D ;SAVE D&E.
- PUSH B ;SAVE B&C.
- LDA CASIB ;GET BYTE COUNT.
- ORA A ;IF IT'S NOT ZERO,
- JNZ CASIM ;MOVE BYTE FROM BUFFER.
- CALL CTRD ;READ FROM CASSETTE.
- CASIR: JZ CASINE ;NO ERROR IF ZERO SET.
- STC ;OTHERWISE, SET CARRY,
- JMP CASIRT ;RETURN WITH ERROR.
- CASINE: MOV A,B ;GET BYTE COUNT.
- LXI H,IBUF ;INITIALIZE BUFFER POINTER.
- SHLD CASIHL
- CASIM: LHLD CASIHL ;LOAD BUFFER POINTER.
- CASIL1: MOV C,M ;GET BYTE FROM BUFFER.
- INX H ;INCREMENT POINTER.
- SHLD CASIHL ;SAVE THE POINTER.
- DCR A ;DECREMENT BYTE COUNT.
- STA CASIB ;SAVE IT.
- MOV A,C ;GET DATA BYTE.
- ORA A ;CLEAR CARRY.
- CASIRT: POP B ;RESTORE B&C.
- POP D ;RESTORE D&E.
- POP H ;RESTORE H&L.
- RET
- ;
- ; CASOUT - OUTPUT ONE BYTE TO CASSETTE RECORDER.
- ; ON ENTRY, IF REG A=1, INITIALIZE.
- ; IF CARRY SET, END OF TRANSFER.
- ; DATA BYTE IS IN REGISTER A.
- ;
- CASOUT: PUSH H ;SAVE ALL REGISTERS.
- PUSH D
- PUSH B
- PUSH PSW
- JZ CASOST ;IF Z=1, MUST BE START.
- CASONS: LHLD CASOHL ;GET BUFFER POINTER.
- LDA CASOB ;GET BYTE COUNT.
- MOV B,A ;PUT INTO REG B.
- POP PSW ;RESTORE REG A AND PSW.
- PUSH PSW ;SAVE IT BACK.
- JC CASOEN ;IF CARRY, MUST BE END.
- CASOL1: MOV M,A ;PUT BYTE INTO BUFFER.
- INX H ;INCREMENT POINTER.
- SHLD CASOHL ;SAVE THE POINTER.
- INR B ;INCREMENT BYTE COUNT.
- MOV A,B ;SAVE NEW BYTE COUNT.
- STA CASOB
- CPI 128 ;128 BYTES YET?
- JNZ REGRES ;RETURN IF NOT.
- CASOEN: MOV A,B ;GET BYTE COUNT.
- ORA A ;IF IT'S ZERO,
- JZ REGRES ;RETURN.
- LXI H,OBUF ;GET ADDRESS OF BUFFER.
- CALL CTWT ;IF SO, WRITE BUFFER.
- CASOST: LXI H,OBUF ;GET ADDRESS OF OUTPUT BUFFER.
- SHLD CASOHL ;INITIALIZE POINTER WITH IT.
- XRA A ;SET BYTE COUNT=0.
- STA CASOB
- REGRES: POP PSW ;RESTORE PSW&A.
- POP B ;RESTORE B&C.
- POP D ;RESTORE D&E.
- POP H ;RESTORE H&L.
- RET ;RETURN FROM REGRES.
- ;
- ; DSKINP - READ A BYTE FROM THE CURRENT DISK FILE.
- ; BYTE RETURNS IN REGISTER A. IF THE CARRY FLAG
- ; IS SET UPON RETURN FROM THIS ROUTINE, A DISK
- ; READ ERROR HAS OCCURED.
- ;
- DSKINP:
- IF DISK ;IF DISK VERSION,
- RZ ;RETURN IF EITHER FLAG SET.
- JNC DSKINC ;IF CARRY,
- ORA A ;CLEAR IT AND QUIT.
- RET
- DSKINC: PUSH H ;SAVE H&L.
- PUSH D ;SAVE D&E.
- PUSH B ;SAVE B&C.
- LXI H,DSKFLG ;GET ADR OF DISK FLAG.
- XRA A ;SET A = ZERO.
- CMP M ;IS DISK FLAG = 0?
- JNZ DSKIRB ;HOP AROUND READ IF NOT.
- MVI M,0FFH ; SET DISK FLAG = READ MODE.
- CALL DSKRD ;READ FIRST BLOCK FROM DISK.
- JC CASIRT ;RETURN IF CARRY (ERROR).
- DSKIRB: LHLD DSKHL ;GET BUFFER POINTER.
- MOV A,M ;GET BYTE FROM BUFFER.
- INX H ;INCREMENT POINTER.
- SHLD DSKHL ;SAVE IT.
- LXI H,DSKCTR ;GET ADR OF BYTE COUNT.
- ORA A ;CLEAR CARRY FLAG!!!!
- INR M ;INCREMENT IT.
- JP CASIRT ;RETURN IF NOT 128 YET.
- PUSH A ;SAVE DATA BYTE ON STACK.
- CALL DSKRD ;READ FROM DISK.
- POP B ;GET DATA BYTE BACK FROM
- MOV A,B ;STACK WITHOUT CHANGING PSW.
- JMP CASIRT ;RESTORE REGISTERS & RETURN.
- ENDIF
-
- ;
- ; DSKOUT - OUTPUT ONE BYTE TO CURRENT DISK FILE.
- ; ON ENTRY, IF REG A=1, INITIALIZE.
- ; IF CARRY SET, END OF TRANSFER.
- ; DATA BYTE IS IN REGISTER A.
- ;
- DSKOUT:
- IF DISK ;IF DISK VERSION,
- RZ ;RETURN IF START FLAG.
- RC ;RETURN IF END FLAG.
- PUSH H ;SAVE ALL REGISTERS.
- PUSH D
- PUSH B
- PUSH PSW
- DSKPUT: LHLD DSKHL ;GET BUFFER POINTER.
- MOV M,A ;PUT BYTE INTO BUFFER.
- INX H ;INCREMENT POINTER.
- SHLD DSKHL ;UPDATE POINTER.
- MVI A,1 ;SET DISK WRITE MODE.
- STA DSKFLG
- LXI H,DSKCTR ;GET ADR OF BYTE COUNT.
- INR M ;INCREMENT BYTE COUNT.
- CM DSKWT ;IF 128, WRITE TO DISK.
- JMP REGRES ;RESTORE & RETURN.
- ENDIF
-
-
- IF DISK ;IF DISK VERSION,
- ;
- ; USRSUB - THIS IS THE SUBROUTINE THAT GETS
- ; CALLED BY THE USR FUNCTION IN TARBELL BASIC.
- ; THE ARGUMENT OF THE FUNCTION COMES IN D&E.
- ; IF D&E = ZERO, IT MEANS TO CLOSE A FILE.
- ; IF D&E = ONE, IT MEANS TO OPEN CURRENT FILE.
- ; IF D&E FROM 128 TO 255, GOTO ZERO.
- ; IF D&E => 256, D&E CONTAINS THE ADDRESS OF A
- ; STRING WHICH IS THE NAME OF THE FILE TO OPEN.
- ;
- USRSUB: MOV A,D ;CHECK TO SEE IF
- ORA A ;IS D=0?
- JNZ USRS2 ;IF NOT, MUST BE NAME.
- MOV A,E ;IS E=0 TOO?
- ORA A ;IF SO,
- JZ DSKCL ;JUST CLOSE FILE.
- JM 0 ;IF MSB = 1 GOTOT 0.
- DCR A ;IF E WAS 1,
- JZ DSKOP ;OPEN WITH PRESENT NAME.
- USRS2: PUSH D ;SAVE D&E.
- LXI D,BFCB ;GET ADR OF BLANK FCB.
- LXI H,FCB ;GET ADR OF FCB.
- MVI B,16 ;GET LENGTH OF AREA.
- CALL MOVE ;SET FCB TO BLANK.
- POP D ;RESTORE D&E.
- LXI H,FCB+1 ;GET ADR OF FCB+1.
- MVI C,11 ;MAXIMUM OF 11 CHARS.
- USRS1: LDAX D ;GET CHAR FROM STRING.
- ANI 7FH ;CLEAR MSB.
- MOV M,A ;PUT INTO FCB.
- INX H ;INCREMENT POINTERS.
- LDAX D ;GET CHAR AGAIN.
- INX D ;INCREMENT D&E.
- DCR C ;DECREMENT COUNTER.
- JZ DSKOP ;IF 11 CHARS, OPEN.
- ORA A ;IS MSB SET?
- JP USRS1 ;IF NOT MSB, GET ANOTHER.
- ;
- ; DSKOP - OPEN THE DISK FILE WHOSE NAME IS IN
- ; THE DEFAULT FILE CONTROL BLOCK.
- ;
- DSKOP: LDA DSKFLG ;GET DISK MODE FLAG.
- ORA A ;WAS FILE OPEN?
- CNZ DSKCL ;CLOSE IF FILE OPEN.
- CALL DSKRS ;RESET DISK PTR & CTR.
- MVI C,15 ;OPEN FILE.
- LXI D,FCB ;DEFAULT FCB ADR.
- CALL BDOS ;DO IT.
- INR A ;WAS FILE FOUND?
- MVI A,0 ;SET NR = 0.
- STA FCB+32
- RNZ ;RETURN IF FILE FOUND.
- MVI C,22 ;OTHERWISE MAKE FILE.
- LXI D,FCB ;FILE CTL BLOCK ADR.
- CALL BDOS ;DO IT.
- MVI D,0 ;PUT A INTO D&E.
- MOV E,A
- INR A ;WAS THERE ROOM?
- JNZ DSKOP ;OPEN IF SO.
- RET ;RETURN IF NOT.
- ;
- ; BFCB - BLANK FILE CONTROL BLOCK.
- ;
- BFCB: DB 0,' ',0,0,0,0
- ;
- ; DSKCL - CLOSE THE DISK FILE WHOSE NAME IS IN
- ; THE DEFAULT FILE CONTROL BLOCK.
- ;
- DSKCL: LDA DSKFLG ;GET DISK FLAG.
- INR A ;IF IT WAS = FF,
- JZ DSKCLR ;MUST HAVE BEEN READING.
- LHLD DSKHL ;GET DISK BUFFER PTR.
- MVI M,1AH ;PUT IN END-OF-FILE.
- CALL DSKWT ;WRITE LAST RECORD.
- XRA A ;SET DISK MODE INACTIVE.
- DSKCLR: STA DSKFLG
- MVI C,16 ;CLOSE FILE CODE.
- LXI D,FCB ;DEFAULT FCB ADR.
- CALL BDOS ;CLOSE IT.
- RET
- ;
- ; DSKRD - READ A SECTOR FROM THE CURRENT DISK
- ; FILE INTO MEMORY AT ADDRESS 0080H.
- ;
- DSKRD: CALL DSKRS ;RESET POINTER & COUNTER.
- MVI C,20 ;READ NEXT RECORD.
- LXI D,FCB ;GET ADR OF FCB.
- CALL BDOS
- ORA A ;SET FLAGS.
- RZ ;RETURN IF NO ERRORS.
- STC ;SET CARRY IF ERROR.
- RET ;RETURN FROM DSKRD.
- ;
- ; DSKWT - WRITE A SECTOR FROM THE BUFFER AT
- ; ADDRESS 0080H TO THE CURRENT DISK FILE.
- ; ALSO RESET DISK BUFFER POINTER & COUNTER.
- ;
- DSKWT: MVI C,21 ;WRITE NEXT RECORD.
- LXI D,FCB ;GET ADR OF FCB.
- CALL BDOS
- DSKRS: LXI H,TBUFF ;GET DISK BUFFER ADR.
- SHLD DSKHL ;INITIALIZE POINTER.
- XRA A ;SET BYTE COUNT = 0.
- STA DSKCTR
- RET
- ENDIF
-
- IF NOT DISK ;IF NOT DISK VERSION,
- USRSUB: JMP 0 ;JUST HOP TO ZERO.
- ENDIF
-
- ;
- ; CTWT - WRITE A BLOCK TO CASSETTE.
- ;
- CTWT: LXI D,187*2 ;GET COUNT FOR 2 SECONDS.
- DELAY: MVI A,3CH ;WRITE START BYTE.
- CALL CASW
- DCX D ;DECREMENT COUNT.
- MOV A,D ;IF D&E ARE
- ORA E ;NOT YET ZERO,
- JNZ DELAY ;KEEP COUNTING DOWN.
- MVI A,0E6H ;WRITE SYNC BYTE.
- CALL CASW
- MVI C,0 ;CLEAR CHECKSUM.
- MVI A,90H ;WRITE TYPE BYTE.
- CALL CASW
- MOV A,B ;WRITE LENGTH BYTE.
- CALL CASW
- MOV A,B ;GET LENGTH BYTE.
- ORA A ;IF IT'S ZERO,
- RZ ;RETURN FROM CTWT.
- CTLP: MOV A,M ;WRITE DATA BYTE.
- CALL CASW
- INX H ;INCREMENT POINTER.
- DCR B ;DECREMENT COUNTER.
- JNZ CTLP ;REPEAT.
- MOV A,C ;WRITE CHECKSUM.
- CASW: PUSH PSW ;SAVE DATA ON STACK.
- CALP: IN CASC ;READ CASSETTE STATUS.
- ANI 20H ;LOOK AT BIT 5.
- JNZ CALP ;WAIT UNTIL READY.
- POP PSW ;RECOVER DATA.
- OUT CASD ;WRITE A BYTE.
- ADD C ;ADD TO CHECKSUM.
- MOV C,A
- RET ;RETURN FROM CASW.
- ;
- ; CTRD - READ A RECORD FROM CASSETTE.
- ;
- CTRD: LXI H,IBUF ;GET BUFFER ADDRESS.
- CALL CASW ;DELAY TO ALLOW LAST
- CALL CASW ;BYTE TO PASS THROUGH.
- MVI E,0 ;SET CHECKSUM=0.
- MVI A,10H ;SET BIT 4=1.
- OUT CASC ;RESET RECEIVER.
- CALL CASR ;READ TYPE BYTE.
- CALL CASR ;READ LENGTH BYTE.
- MOV B,A ;PUT LENGTH BYTE IN B.
- RZ ;RETURN IF LENGTH 0.
- MOV C,A ;PUT LENGTH IN C TOO.
- CRLOP: CALL CASR ;READ DATA BYTE.
- MOV M,A ;PUT INTO MEMORY.
- INX H ;INCREMENT POINTER.
- DCR C ;DECREMENT COUNTER.
- JNZ CRLOP ;READ ANOTHER BYTE.
- MOV C,E ;PUT CHECKSUM IN C.
- CALL CASR ;READ CHECKSUM.
- SUB C ;SUBTRACT FROM A.
- RET ;RETURN FROM CRLOP.
- ;
- CASR: IN CASC ;READ CASS. STATUS.
- ANI 10H ;CHECK BIT 4.
- JNZ CASR ;WAIT TILL READY.
- IN CASD ;READ DATA.
- PUSH PSW ;SAVE REG A.
- ADD E ;ADD TO CHECKSUM.
- MOV E,A
- POP PSW ;RESTORE A.
- ORA A ;SET FLAGS.
- RET ;RETURN FROM CASR.
- ;
- ;
- ; THIS PART SHOULD BE IN RAM.
- ;
- DSKFLG: DS 1 ;0=NONE, 1=WRITE, FF=READ.
- DSKHL: DS 2 ;DISK BUFFER POINTER.
- DSKCTR: DB 0 ;DISK BYTE COUNTER.
- CASOHL: DS 2 ;OUTPUT BUFFER POINTER.
- CASOB: DB 0 ;CASS. OUTPUT BYTE COUNT.
- OBUF: DS 128 ;CASS. OUTPUT BUFFER.
- CASIHL: DS 2 ;INPUT BUFFER POINTER.
- CASIB: DB 0 ;INPUT BYTE COUNT.
- IBUF: DS 128 ;INPUT BUFFER.
- END
-