NAME DBIOSV VDB EQU 1 FULLSZ EQU 1 MHZ EQU 25 ;2 MHZ CLOCK RATE ; I/O DRIVERS FOR CP/M ; VERSION 2.0 12/28/78 ; RUNS ON SBC-100 ; THE 2.0 VERSION OF DBIOS CONTAINS THE FORMAT WHICH ; IS COMPATIBLE WITH BOTH THE 1771 AND THE 1791. ORG 0F000H RS232 EQU VDB-1 MINI EQU .NOT.FULLSZ.AND.1 NBYTES EQU 128 ;BYTES PER SECTOR UL EQU 5FH ;UNDERLINE BS EQU 8 ;BACKSPACE RO EQU 127 ;RUBOUT SPACE EQU 20H ;SPACE RBASE EQU 0000H ;START OF RAM TADDR EQU RBASE+40H ;TRANSFER ADDRESS UNIT EQU RBASE+42H ;DRIVE # SCTR EQU RBASE+43H ;SECTOR TRK EQU RBASE+44H ;TRACK NREC EQU RBASE+45H ;# OF SECTORS ERMASK EQU RBASE+46H ;ERROR MASK ERSTAT EQU RBASE+47H ;ERROR STATUS IDSV EQU RBASE+48H ;4 BYTES CMDSV EQU RBASE+4CH ;COMMAND SAVE SPSV EQU RBASE+4DH ;SP SAVE (2 BYTES) CICHR EQU RBASE+4FH ;USED FOR BACKSPACE SSTACK EQU RBASE+80H ;SYSTEM STACK COLD EQU RBASE+80H ;COLD START ADDRESS UDATA EQU 7CH ;USART DATA PORT USTAT EQU 7DH ;USART STATUS/CONTROL PORT ; PORTS USED BY DISK CONTROLLER X EQU 60H SELECT EQU X+3 STATUS EQU X+4 TRACK EQU X+5 SECTOR EQU X+6 DATA EQU X+7 CMD EQU X+4 ; SERIAL I/O PORTS IF RS232 SDATA DEFL 07CH ;SERIAL DATA PORT SSTAT DEFL 07DH ;SERIAL STATUS PORT RXRMSK DEFL 02H ;RX READY MASK TXRMSK DEFL 01H ;TX READY MASK ENDIF IF VDB SDATA DEFL 01H ;VIDEO DATA PORT SSTAT DEFL 00H ;VIDEO STATUS PORT RXRMSK DEFL 02H ;RX READY MASK TXRMSK DEFL 04H ;TX READY MASK ENDIF CTC0 EQU 78H ;CTC PORT X000 EQU 7FH PDATA EQU 7EH ;PARALLEL DATA PSTAT EQU 7FH ;PARALLEL STATUS/CONTROL ;DISK ERROR STATUS BITS (ERSTAT) ;BIT 7 - DRIVE NOT READY ;BIT 6 - WRITE PROTECTED ;BIT 5 - TRACK SEEK ERROR ;BIT 4 - SECTOR NOT FOUND ;BIT 3 - CYCLIC REDUNDANCY CHECK ERROR ;BIT 2 - DATA LOST ;BIT 1 - DRQ BIT ;BIT 0 - WRITE DELETED SECTOR READ ;DISK CONTROLLER COMMAND CODES RDACMD EQU 0C4H ;READ ADDRESS COMMAND RDCMD EQU 88H ;READ SECTOR COMMAND WRCMD EQU 0A8H ;WRITE SECTOR COMMAND WRTCMD EQU 0F4H ;WRITE TRACK COMMAND PAGE ; CP/M SYSTEM LINKAGES BIOS: JP INIT ;RESET ENTRY WBOOTE: JP BOOT ;WARM START ENTRY CSE: JP CONST ;CONSOLE STATUS CIE: JP CONIN ;READ CONSOLE COE: JP CONOUT ;WRITE CONSOLE LSTE: JP LIST ;WRITE PRINTER PCHE: JP PUNCH ;WRITE PUNCH RDRE: JP READER ;READ READER HME: JP HOME ;MOVE DISK TO TRK 00 SDSKE: JP SELDSK ;SELECT DISK DRIVE STRKE: JP SETTRK ;SET DISK TRACK SSECE: JP SETSEC ;SET DISK SECTOR SDMAE: JP SETDMA ;SET MEMORY ADDRESS FOR READ/WRITE RDE: JP READ ;READ A SECTOR WRE: JP WRITE ;WRITE A SECTOR LDE: JP LOADER ;LOAD "N" SECTORS SVE: JP SAVER ;SAVE "N" SECTORS FMATE: JP FMAT ;FORMAT A TRACK PTXTE: JP PTXT ;PRINT TEXT PACCE: JP PACC ;PRINT ACCUMULATOR PAGE ; MINI/FULL SIZE VARIABLES DEFB 0,3AH,0 NSCTRS: DEFB 12H*MINI+1AH*FULLSZ ;SECTORS PER TRACK NTRKS: DEFB 23H*MINI+4DH*FULLSZ ;TRACKS PER SIDE GAP1: DEFB 14H*MINI+4CH*FULLSZ ;FORMAT GAP 1 GAP2: DEFB 6 ;FORMAT GAP 2 GAP3: DEFB 8*MINI+1BH*FULLSZ ;FORMAT GAP 3 RSCMD: DEFB 0BH*MINI+0AH*FULLSZ ;RESTORE COMMAND SKCMD: DEFB 1FH*MINI+1EH*FULLSZ ;SEEK COMMAND SKNCMD: DEFB 1BH*MINI+1AH*FULLSZ ;SEEK WITH NO VERIFY COMMAND HLDLY: DEFB 4BH*MINI+23H*FULLSZ ;HEAD LOAD DELAY ; DELAY CONSTANT DLYCON: IF MHZ=20 DEFB 8EH ENDIF IF MHZ=25 DEFB 0B2H ENDIF IF MHZ=30 DEFB 0D8H ENDIF IF MHZ=40 DEFB 0 ENDIF PAGE ; ENTER HERE FROM RESET ; COMPUTE BAUD RATE, THEN BOOT INIT: IN A,(X000) ;CLEAR HARDWARE LD A,4EH OUT (USTAT),A ;USART MODE LD A,37H OUT (USTAT),A ;USART COMMAND LD A,5 OUT (CTC0),A ;CTC MODE IF VDB LD A,1 OUT (CTC0),A ENDIF IF RS232 LD C,USTAT ;USART STATUS PORT LD DE,1 L1: IN A,(C) JP P,L1 ;WAIT FOR START BIT L2: INC DE IN A,(C) JP M,L2 ;WAIT FOR END OF BIT LD SP,BTAB-1 L3: INC SP POP HL SCF SBC HL,DE JR C,L3 DEC SP POP AF OUT (CTC0),A ;BAUD RATE CONSTANT LD A,100 DEL1: LD B,200 ;DELAY UNTIL END OF CHARACTER DEL2: DJNZ DEL2 DEC A JR NZ,DEL1 ENDIF IN A,(UDATA) ;CLEAR RX READY ;STEP ALL HEADS AWAY FROM TRACK 00 BOOT: LD SP,SSTACK LD A,10H ;UP TO 4 BYTES BOOT1: SRL A LD (UNIT),A CPL OUT (SELECT),A JR Z,BOOT3 LD HL,SSTACK-2 LD (SPSV),HL CALL HLCHK ;FORCE STATUS TYPE 1 IN A,(STATUS) AND 4 ;CHECK FOR TRACK 00 JR Z,BOOT2 LD A,42H ;STEP IN COMMAND CALL CMDI ;STEP HEAD IN BOOT2: LD A,(UNIT) JR BOOT1 BOOT3: LD (CICHR),A INC A OUT (PSTAT),A ;CLEAR PARALLEL OUT IN A,(PSTAT) ;CLEAR PARALLEL IN LD HL,COLD LD (TADDR),HL LD A,1 LD (NREC),A LD (SCTR),A XOR A LD (UNIT),A LD (TRK),A CALL LOADER ;BOOT IN COLD SECTOR JP Z,COLD ;JUMP TO COLD START HALT ;IF BAD DISK, HALT IF RS232 ; BAUD RATE TABLE BTAB: DEFW 0DH ;9600 DEFB 1 DEFW 1AH ;4800 DEFB 2 DEFW 34H ;2400 DEFB 4 DEFW 68H ;1200 DEFB 8 DEFW 0D0H ;600 DEFB 16 DEFW 1A0H ;300 DEFB 32 DEFW 7FFFH ;110 DEFB 57H ENDIF PAGE ; NON-DISK I/O DRIVERS CONST: IN A,(SSTAT) AND RXRMSK RET Z LD A,0FFH RET ;CONSOLE INPUT CONIN: CALL CONST JR Z,CONIN IN A,(SDATA) AND 7FH LD (CICHR),A CP UL RET NZ LD A,RO RET ;CONSOLE OUTPUT CONOUT: LD A,C CP RO RET Z LD A,(CICHR) CP UL JR NZ,CO LD C,BS CALL CO LD C,SPACE CALL CO LD C,BS CO: IN A,(SSTAT) AND TXRMSK ;TX BUFFER EMPTY JR Z,CO LD A,C OUT (SDATA),A RET ;READER INPUT READER EQU CONIN ;LISTING OUTPUT ; THIS IS A DRIVER FOR THE CENTRONICS PRINTERS ; UTILIZING THE PARALLEL OUTPUT INTERFACE ; THE OSTB OUTPUT (J3-21) SHOULD BE CONNECTED TO ; THE DATA STROBE LINE ON THE PRINTER ; THE ORPLY INPUT (J3-19) SHOULD BE CONNECTED TO THE ; BUSY LINE ON THE PRINTER ; THE DATA LINES ON THE PRINTER SHOULD BE CONNECTED ; TO THE PO0-PO7 OUTPUTS (J3-3,5,7,9,11,13,15,17) ; CONNECT THE PRINTER GROUND TO J3-1 ; INSTALL THE FOLLOWING JUMPERS ON THE SBC-100: ; X4-4 TO X4-5, X4-7 TO X4-8 LIST: IN A,(PSTAT) ;PARALLEL OUT STATUS AND 1 JR Z,LIST ;WAIT FOR PRINTER READY LD A,C OUT (PDATA),A ;OUTPUT DATA XOR A OUT (PSTAT),A ;TURN ON STROBE INC A OUT (PSTAT),A ;TURN OFF STROBE LD A,C RET ;PUNCH OUTPUT PUNCH EQU CONOUT PAGE ; DISK CONTROLLER LINKAGES HOME: LD (SPSV),SP CALL DRVSET ;SELECT DRIVE HOME1: LD (SPSV),SP LD A,(RSCMD) CALL CMDI XOR A RET ; SELECT DISK DRIVE SELDSK: LD A,C LD (UNIT),A RET ; SET TRACK NUMBER SETTRK: LD A,C LD (TRK),A RET ; SET SECTOR NUMBER SETSEC: LD A,C LD (SCTR),A RET ; SET MEMORY TRANSFER ADDRESS FOR DISK READ/WRITE SETDMA: LD (TADDR),BC RET ; READ A SECTOR READ: LD B,10 READ1: PUSH BC CALL RDSC ;READ A SECTOR POP BC RET Z ;RETURN IF NO ERROR CALL RETRY ;RETRY IF ERROR JR READ1 ; WRITE A SECTOR WRITE: LD B,10 WRITE1: PUSH BC CALL WRSC ;WRITE A SECTOR POP BC RET Z ;RETURN IF NO ERROR CALL RETRY ;RETRY IF ERROR JR WRITE1 RETRY: DJNZ RETRY1 POP AF CALL ERR XOR A INC A ;SET ERROR FLAG RET ;RETURN TO CALLER RETRY1: PUSH BC CALL HOME1 ;RESTORE DRIVE POP BC RET ;TRY AGAIN ; PAGE ;END OF COMMAND END: CALL WAIT CALL DWAIT IN A,(STATUS) LD D,A LD A,(ERMASK) AND D ;CHECK FOR ERRORS RET Z END1: LD A,D END2: LD (ERSTAT),A ;SAVE ERROR BITS OR 1 LD SP,(SPSV) RET PAGE ; SELECT SIDE AND SEEK TRACK SEEK: CALL RDYCK LD A,(NTRKS) LD C,A LD A,(TRK) CP C JR C,SEEK1 LD A,0FH JR END2 ;INVALID TRACK SEEK1: LD C,A ;SAVE NEW TRACK # IN A,(TRACK) ;PRESENT TRACK CP C RET Z ;IF SAME TRACK, RETURN SEEK2: LD A,C ;TRACK # OUT (DATA),A LD A,(SKCMD) ;SEEK COMMAND CALL CMDI IN A,(STATUS) AND 10H ;TEST FOR SEEK ERROR RET Z ;IF NO ERROR, RETURN LD A,20H JR END2 PAGE ;CHECK DRIVE SELECT AND CHANGE IF DIFFERENT DRVSET: IN A,(SELECT) CPL AND 0FH JR Z,DRSEL ;IF NONE, JUMP LD C,0FFH DRVS0: INC C ;CONVERT TO DRIVE NUMBER RRA JR NC,DRVS0 LD A,(UNIT) AND 3 CP C RET Z ;SELECT DRIVE DRSEL: LD A,(UNIT) AND 3 OR A ;CHECK FOR ZERO LD C,A LD A,1 JR Z,DRSEL3 ;NO SHIFTING DRSEL2: RLCA ;SHIFT LEFT DEC C JR NZ,DRSEL2 DRSEL3:CPL OUT (SELECT),A LD A,(HLDLY) CALL MSEC ;DELAY 35 MILLISECONDS CALL RDYCK ;READ PRESENT DISK ADDRESS (TRACK AND SECTOR) IDRD: LD HL,IDSV LD BC,400H+DATA LD A,0F8H LD (ERMASK),A CALL SWEB LD A,RDACMD ;"READ ADDRESS" COMMAND CALL RDSC0 ;READ ID LD A,(IDSV) OUT (TRACK),A RET PAGE ;READ SECTOR COMMAND RDSC: LD (SPSV),SP CALL DRVSET CALL SEEK ;SEEK TRACK LD A,0FEH LD (ERMASK),A CALL TRINT LD A,RDCMD ;READ COMMAND CALL HLCHK ;SET UP HEAD LOAD BIT RDSC0: LD (CMDSV),A OUT (CMD),A ;OUTPUT COMMAND INIR ;INPUT A SECTOR CALL END XOR A RET PAGE ;WRITE SECTOR COMMAND WRSC: LD (SPSV),SP CALL DRVSET CALL SEEK ;SEEK TRACK LD A,0FCH LD (ERMASK),A CALL TRINT LD A,WRCMD ;WRITE COMMAND CALL HLCHK ;SET UP HEAD LOAD BIT LD (CMDSV),A OUT (CMD),A ;OUTPUT COMMAND OTIR ;OUTPUT A SECTOR CALL END XOR A RET PAGE ; TYPE 1 COMMANDS CMDI: LD (CMDSV),A ;SAVE COMMAND LD A,080H LD (ERMASK),A CALL WAIT CALL DWAIT LD A,(CMDSV) OUT (CMD),A ;OUTPUT COMMAND LD A,1 CALL MSEC ;WAIT FOR STATUS JP END WAIT: IN A,(STATUS) AND 1 JR NZ,WAIT RET ;DISABLE WAIT STATES DWAIT: IN A,(SELECT) OR 0E0H ;NEGATIVE TRUE .AND. OUT (SELECT),A RET ;ENABLE WAIT STATES SWEB: IN A,(SELECT) AND 1FH OUT (SELECT),A RET ;DELAY (A REGISTER)*1 MILLISECOND MSEC: LD B,A MSEC0: LD A,(DLYCON) MSEC1: DEC A JR NZ,MSEC1 DJNZ MSEC0 RET RDYCK: IN A,(STATUS) AND 80H JP NZ,END2 RET ;INITIALIZE FOR DISK TRANSFER TRINT: LD HL,(TADDR) LD B,0 LD A,(NSCTRS) INC A LD C,A LD A,(SCTR) CP C ;CHECK FOR SIDE JR C,TRINT1 LD B,10H DEC C SUB C ;IF SIDE 2, SUBTRACT TRINT1: OUT (SECTOR),A ;OUTPUT TO CONTROLLER IN A,(SELECT) CPL LD E,A AND 10H CP B JR Z,TRINT2 ;IF SAME SIDE, JUMP LD A,E AND 0FH OR B CPL OUT (SELECT),A ;SELECT NEW SIDE LD A,1 CALL MSEC TRINT2: LD BC,.RES.(NBYTES*100H+DATA) JR SWEB ;CHECK FOR HEAD LOADED, IF NOT SET ;"H" BIT IN COMMAND. HLCHK: LD D,A ;SAVE COMMAND IN D LD A,0D0H OUT (CMD),A ;"FORCE INTERRUPT" COMMAND LD A,4 HLCHK0: DEC A JR NZ,HLCHK0 IN A,(STATUS) AND 20H LD A,D ;RESTORE COMMAND RET NZ ;IF HEAD LOADED, RETURN OR 4 ;SET "H" BIT RET PAGE ;LOAD # OF SECTORS IN (NREC) LOADER: CALL READ ;READ A SECTOR RET NZ CALL INCP ;INCREMENT TRACK/SECTOR JR NZ,LOADER RET ;SAVE # OF SECTORS IN (NREC) SAVER: CALL WRITE RET NZ CALL INCP JR NZ,SAVER RET ;INCREMENT SECTOR AND TRACK INCP: LD HL,(TADDR) LD DE,NBYTES ADD HL,DE LD (TADDR),HL LD HL,NREC ;POINT TO NREC DEC (HL) RET Z DEC HL DEC HL ;POINT TO SECTOR INC (HL) ;INCREMENT SECTOR # IN A,(SELECT) AND 20H ;CHECK DOUBLE SIDED JUMPER LD A,(NSCTRS) JR Z,INCP1 OR A RLCA ;IF DOUBLE SIDED, SHIFT LEFT INCP1: INC A CP (HL) ;LAST SECTOR ON TRACK? RET NZ ;IF NOT, RETURN LD (HL),1 ;SET TO SECTOR 1 INC HL ;POINT TO TRACK INC (HL) ;INCREMENT TRACK # OR A RET ;ERROR MESSAGE "CMD ER D T S: " ERR: LD HL,ERMSG CALL PTXT LD A,(CMDSV) CALL PACSP LD A,(ERSTAT) CALL PACSP LD A,(UNIT) CALL PACSP LD A,(TRK) CALL PACSP LD A,(SCTR) CALL PACC LD C,0AH CALL COE LD C,0DH JP COE RET ERMSG: DEFW 0D0AH DEFM 'CMD ER D T S: ' DEFB 3 ;PRINT TEXT PTXT: LD A,(HL) ;FETCH A BYTE CP 3 RET Z LD C,A CALL COE INC HL JR PTXT ;PRINT ACCUMULATOR PACC: PUSH AF RRCA RRCA RRCA RRCA CALL PRVAL POP AF PRVAL: AND 0FH ADD A,90H DAA ADC A,40H DAA PRVAL1: LD C,A JP COE ;PRINT IT PACSP: CALL PACC LD A,' ' JR PRVAL1 PAGE ; FORMAT A TRACK FMAT: CALL FMAT1 RET Z JR ERR FMAT1: LD (SPSV),SP LD A,(TRK) OUT (DATA),A OR A CALL Z,DRVSET LD A,(SKNCMD) CALL CMDI LD L,1 LD A,(NSCTRS) LD H,A LD A,(GAP1) LD B,A LD A,0C0H LD (ERMASK),A CALL SWEB LD A,WRTCMD LD (CMDSV),A OUT (CMD),A ;OUTPUT COMMAND LD A,0FFH FMAT2: OUT (DATA),A ;GAP1 DJNZ FMAT2 FMAT4: LD A,(GAP2) LD B,A XOR A FMAT5: OUT (DATA),A DJNZ FMAT5 LD A,0FEH ;ID ADDRESS MARK OUT (DATA),A IN A,(TRACK) OUT (DATA),A ;TRACK # XOR A OUT (DATA),A ;0 GAP LD A,L OUT (DATA),A ;SECTOR # XOR A OUT (DATA),A ;SECTOR LENGTH=128 LD A,0F7H ;SEND CRC (2 BYTES) OUT (DATA),A LD B,11 LD A,0FFH FMATA: OUT (DATA),A DJNZ FMATA LD B,6 XOR A FMAT6: OUT (DATA),A DJNZ FMAT6 LD A,0FBH ;DATA ADDRESS MARK OUT (DATA),A LD A,0E5H LD B,128 FMAT7: OUT (DATA),A ;128 E5'S IN DATA FIELD DJNZ FMAT7 LD A,0F7H OUT (DATA),A ;CRC (2 BYTES) LD A,(GAP3) LD B,A XOR A FMAT8: OUT (DATA),A ;GAP3 DJNZ FMAT8 INC L ;INCREMENT SECTOR # DEC H ;CHECK FOR LAST SECTOR JP NZ,FMAT4 ;WRITE ALL SECTORS CALL END LD A,60 CALL MSEC XOR A RET END