; CBIOS FOR CP.M VERSION 2.0 ON SBC-100 MSIZE EQU 56 ;SYSTEM SIZE IN KILOBYTES FULLSZ EQU 0 MHZ EQU 25 ;2.5 MEGAHERTZ CLOCK RATE FBASE EQU 0F000H BOOTF EQU FBASE+03H CONST EQU FBASE+06H CONINF EQU FBASE+09H CONOUT EQU FBASE+0CH PUNCH EQU FBASE+12H READER EQU FBASE+15H SETTRK EQU FBASE+1EH SETSEC EQU FBASE+21H SETDMA EQU FBASE+24H READF EQU FBASE+27H WRITEF EQU FBASE+2AH MINI EQU .NOT.FULLSZ.AND.1 NBYTES EQU 128 ;BYTES PER SECTOR 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 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) ERR EQU 0F2D3H ; PRINTER DEFINITIONS OF THE SBC-100 LSPORT EQU 7DH LSMASK EQU 1 LDPORT EQU 7CH ; PORTS USED BY DISK CONTROLLER X EQU 0E0H SELECT EQU X+3 STATUS EQU X+4 TRACK EQU X+5 SECTOR EQU X+6 DATA EQU X+7 CMD EQU X+4 SELEC8 EQU 63H RDACMD EQU 0C4H ;READ ADDRESS COMMAND RDCMD EQU 88H ;READ SECTOR COMMAND WRCMD EQU 0A8H ;WRITE SECTOR COMMAND WRTCMD EQU 0F4H ;WRITE TRACK COMMAND ORG .RES.(MSIZE*1024-600H) JP BOOT JP BOOT JP CONST JP CONIN JP CONOUT JP LIST JP PUNCH JP READER JP HOME JP SELDSK JP SETTRK JP SETSEC JP SETDMA JP READ JP WRITE JP LISTST JP SECTRN ; MINI/FULL SIZE VARIABLES NSCTRS: DEFB 12H*MINI+1AH*FULLSZ ;SECTORS PER TRACK NTRKS: DEFB 23H*MINI+4DH*FULLSZ ;TRACKS PER SIDE RSCMD: DEFB 0BH*MINI+0AH*FULLSZ ;RESTORE COMMAND SKCMD: DEFB 1FH*MINI+1EH*FULLSZ ;SEEK 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 BOOT: LD A,0FH OUT (SELECT),A JP BOOTF CONIN: CALL CONINF CP 1EH ;KEYCODE FOR "HOME" RET NZ LD A,'P'-40H RET HOME: LD C,0 JP SETTRK SELDSK: LD HL,0 ;RETURN 0 IF ERROR LD A,C CP 8 RET NC ;RETURN IF UNIT # IS OUT OF RANGE (>7) LD (DRIVE),A LD L,C LD H,0 ;HL=DISK NUMBER ADD HL,HL ;*2 ADD HL,HL ;*4 ADD HL,HL ;*8 ADD HL,HL ;*16 LD DE,DPBASE ADD HL,DE ;HL=DISK HEADER TABLE ADDRESS RET DRIVE: DEFS 1 LISTST: IN A,(LSPORT) AND LSMASK RET LIST: CALL LISTST JR Z,LIST LD A,C OUT (LDPORT),A RET READ: CALL SETUP JP NZ,READF 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: CALL SETUP JP NZ,WRITEF LD B,10 WRITE1: PUSH BC 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 POP BC RET Z ;RETURN IF NO ERROR CALL RETRY ;RETRY IF ERROR JR WRITE1 SETUP: LD A,(DRIVE) CP 6 JR NC,INCH5 AND 11B LD (UNIT),A LD A,0FH OUT (SELECT),A OR A ;CLEAR ZERO FLAG RET INCH5: AND 1 LD (UNIT),A LD A,0FH OUT (SELEC8),A XOR A ;SET ZERO FLAG RET SECTRN: LD B,0 ;DOUBLE PRECISION SECTOR NUMBER IN BC EX DE,HL ;TRANSLATE TABLE ADDRESS TO HL ADD HL,BC ;TRANSLATE (SECTOR) ADDRESS LD L,(HL) ;RETURN SECTOR NUMBER IN L RET DPBASE: ;DISK PARAMETER HEADERS DEFW TRANS8,0,0,0,DIRBUF,DPBLK2,CHECK0,ALLOC0 DEFW TRANS8,0,0,0,DIRBUF,DPBLK2,CHECK1,ALLOC1 DEFW TRANS8,0,0,0,DIRBUF,DPBLK1,CHECK2,ALLOC2 DEFW TRANS8,0,0,0,DIRBUF,DPBLK1,CHECK3,ALLOC3 DEFW TRANS8,0,0,0,DIRBUF,DPBLK1,CHECK4,ALLOC4 DEFW TRANS8,0,0,0,DIRBUF,DPBLK1,CHECK5,ALLOC5 DEFW TRANS5,0,0,0,DIRBUF,DPBLK5,CHECK6,ALLOC6 DEFW TRANS5,0,0,0,DIRBUF,DPBLK5,CHECK7,ALLOC7 TRANS8: ;SECTOR TRANSLATE VECTOR FOR 8" DISKS DEFB 1,7,13,19,25,5,11,17,23,3,9,15,21,2,8,14 DEFB 20,26,6,12,18,24,4,10,16,22 ;THIS PART IS ONLY USED FOR A DOUBLE SIDED DISK DEFB 27,33,39,45,51,31,37,43,49,29,35,41,47 DEFB 28,34,40,46,52,32,38,44,50,30,36,42,48 TRANS5: ;SECTOR TRANSLATE VECTOR FOR 1S35TRK 5" DISKS DEFB 1,5,9,13,17,3,7,11,15,2,6,10,14,18 DEFB 4,8,12,16 DPBLK2: ;DISK PARAMETER BLOCK, COMMON TO 8" DOUBLE SIDED DISKS DEFW 52 ;SECTORS PER TRACK DEFB 4 ;BLOCK SHIFT FACTOR DEFB 15 ;BLOCK MASK DEFB 0 ;NULL MASK DEFW 246 ;DISK SIZE-1 DEFW 127 ;DIRECTORY MAX DEFB 192 ;ALLOC 0 DEFB 0 ;ALLOC 1 DEFW 32 ;CHECK SIZE DEFW 1 ;TRACK OFFSET DPBLK1: ;DISK PARAMETER BLOCK, COMMON TO 8" SINGLE SIDED DISKS DEFW 26 ;SECTORS PER TRACK DEFB 3 ;BLOCK SHIFT FACTOR DEFB 7 ;BLOCK MASK DEFB 0 ;NULL MASK DEFW 242 ;DISK SIZE-1 DEFW 63 ;DIRECTORY MAX DEFB 192 ;ALLOC 0 DEFB 0 ;ALLOC 1 DEFW 16 ;CHECK SIZE DEFW 2 ;TRACK OFFSET DPBLK5: ;DISK PARAMETER BLOCK, COMMON TO ALL 1S35TRK 5" DISKS DEFW 18 ;SECTORS PER TRACK DEFB 3 ;BLOCK SHIFT FACTOR DEFB 7 ;BLOCK MASK DEFB 0 ;NULL MASK DEFW 71 ;DISK SIZE-1 DEFW 63 ;DIRECTORY MAX DEFB 192 ;ALLOC 0 DEFB 0 ;ALLOC 1 DEFW 16 ;CHECK SIZE DEFW 3 ;TRACK OFFSET RETRY: DJNZ RETRY1 POP AF CALL ERR XOR A INC A ;SET ERROR FLAG RET ;RETURN TO CALLER RETRY1: PUSH BC LD (SPSV),SP LD A,(RSCMD) CALL CMDI XOR A POP BC RET ;TRY AGAIN ;END OF COMMAND END: CALL WAIT CALL DWAIT IN A,(STATUS) LD D,A LD A,(ERMASK) AND D ;CHECK FOR ERRORS RET Z LD A,D END2: LD (ERSTAT),A ;SAVE ERROR BITS OR 1 LD SP,(SPSV) RET ; 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 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 ;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 ;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 ; 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 A,(SCTR) OUT (SECTOR),A ;OUTPUT TO CONTROLLER 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 ; SCRATCH RAM AREA FOR BDOS USE DIRBUF: DEFS 128 ;SCRATCH DIRECTORY AREA ALLOC0: DEFS 31 ;ALLOCATION VECTOR 0 ALLOC1: DEFS 31 ;ALLOCATION VECTOR 1 ALLOC2: DEFS 31 ;ALLOCATION VECTOR 2 ALLOC3: DEFS 31 ;ALLOCATION VECTOR 3 ALLOC4: DEFS 31 ;ALLOCATION VECTOR 4 ALLOC5: DEFS 31 ;ALLOCATION VECTOR 5 ALLOC6: DEFS 9 ;ALLOCATION VECTOR 6 ALLOC7: DEFS 9 ;ALLOCATION VECTOR 7 CHECK0: DEFS 32 ;CHECK VECTOR 0 CHECK1: DEFS 32 ;CHECK VECTOR 1 CHECK2: DEFS 16 ;CHECK VECTOR 2 CHECK3: DEFS 16 ;CHECK VECTOR 3 CHECK4: DEFS 16 ;CHECK VECTOR 4 CHECK5: DEFS 16 ;CHECK VECTOR 5 CHECK6: DEFS 16 ;CHECK VECTOR 6 CHECK7: DEFS 16 ;CHECK VECTOR 7