;******************************************************** ;* Xerox 820 * ;* -- CUSTOM BIOS FOR CP/M VERSION 2.2 -- * ;* * ;* Russell Smith 7-October-1980 * ;* * ;******************************************************** ; ; MSIZE EQU 60 ;MEMORY CAPACITY IN KBYTES MONITR EQU 0F000H ;BASE OF SYSTEM MONITOR BAUD EQU 0CH ;CHANNEL B BAUD RATE GEN ; ; CP/M REFERENCE CONSTANTS ; BIAS EQU .RES.(MSIZE-20)*1024 CCP EQU .RES.3400H+BIAS BDOS EQU .RES.CCP+806H CBIOS EQU .RES.CCP+1600H ; ; ; ORG CBIOS ; JP BOOT ;STANDARD JUMP TABLE TO BVECTR: JP WBOOT ;THE SUBROUTINES OF CBIOS SVECTR: JP CONST IVECTR: JP CONIN OVECTR: JP CONOUT JP LSTOUT ;LIST DEVICE VECTOR JP CONOUT ;PUNCH DEVICE VECTOR JP MODMIN ;INPUT DEVICE VECTOR JP HOME JP SELECT JP SEEK JP SETSEC JP SETPTR JP READ JP WRITE JP LSTST ;LIST DEVICE STATUS VECTOR JP TRANS ; ; ; BOOT: XOR A LD (0003H),A ;RESET IOBYTE TO ZEROS LD HL,SIGNON CALL PMSG ;PRINT SIGNON MESSAGE JR GOCPM-$ ; ; WBOOT: LD SP,STACK LD C,0 CALL SELECT ;SELECT UNIT 0 CALL HOME ;SEEK TRACK ZERO LD HL,.RES.3400H+BIAS LD BC,0D02H CALL RDLOOP ;READ EVEN SECTORS ON TRK 0 LD HL,.RES.3480H+BIAS LD BC,0C03H CALL RDLOOP ;READ ODD SECTORS ON TRK 0 LD C,1 CALL SEEK ;SEEK TO TRACK 1 JR NZ,BOMB-$ LD HL,.RES.4080H+BIAS LD BC,0A01H CALL RDLOOP ;READ ODD SECTORS ON TRK 1 LD HL,.RES.4100H+BIAS LD BC,0902H CALL RDLOOP ;READ EVEN SECTORS ON TRK 1 GOCPM: LD A,0C3H ;STORE JUMP VECTORS IN RAM LD (00H),A LD HL,CBIOS+3 ;JUMP TO CBIOS WARM BOOT AT 00H LD (01H),HL LD (05H),A LD HL,BDOS ;JUMP TO BDOS GOES AT 05H LD (06H),HL LD (38H),A LD HL,MONITR ;JUMP TO MONTR GOES AT 38H LD (39H),HL LD BC,0080H CALL SETPTR ;MAKE DISK BUFFER=0080H LD C,0 JP CCP ; ; RDLOOP: LD (POINTR),HL ;STORE ADDR. PASSED IN HL LD A,C LD (SECTOR),A ;STORE SECT# PASSED IN C PUSH HL PUSH BC CALL READ ;READ THE SPECIFIED SECTOR POP BC POP HL JR NZ,BOMB-$ INC H ;BUMP LOAD ADDRESS BY 256 INC C INC C ;BUMP SECTOR# BY 2 DJNZ RDLOOP-$ RET ; ; BOMB: LD HL,DEAD CALL PMSG LOOP: JP LOOP DEAD: DEFB CR,LF DEFM 'cannot boot CP/M $' ; ; ; CONST: JP MONITR+6 ;MONITOR CONSOLE STATUS RTN. ; ; CONIN: JP MONITR+9 ;MONITOR CONSOLE INPUT RTN. ; ; CONOUT: LD A,C JP MONITR+12 ;MONITOR CONSOLE OUTPUT RTN. ; ; LSTOUT: LD A,C JP MONITR+15 ;MONITOR PTR(SIO) RETURN. ; ; LSTST: JP MONITR+18 ;MONITOR LIST STATUS RETURN ; ; MODMIN: JP MONITR+21 ;MONITOR SIOB INPUT RETURN. ; ;******************************************************** ;* * ;* DISK I/O SUBROUTINES FOR CP/M CBIOS * ;* * ;******************************************************** ; ; ; SECTOR TRANSLATE TABLE FOR STANDARD ; 1 IN 6 INTERLEAVE FACTOR ; SECTAB: DEFB 1,7,13,19 DEFB 25,5,11,17 DEFB 23,3,9,15 DEFB 21,2,8,14 DEFB 20,26,6,12 DEFB 18,24,4,10 DEFB 16,22 ; ; ; DISK PARAMETER BLOCK FOR STANDARD 8" FLOPPY ; DPBLK: DEFW 26 ;SECTORS PER TRACK DEFB 3 ;BLOCK SHIFT CONST. DEFB 7 ;BLOCK MASK CONST. DEFB 0 ;EXTENT MASK CONST. DEFW 242 ;MAX BLOCK# DEFW 63 ;MAX DIRECTORY ENTRY# DEFB 11000000B ;ALLOCATION MASK MSB DEFB 00000000B ;' ' LSB DEFW 16 ;CHECK SIZE DEFW 2 ;RESERVED TRACKS ; ; ; DISK PARAMETER HEADERS FOR A 4 DISK SYSTEM ; DPHTAB: DEFW SECTAB,0000H ;DPH FOR UNIT 0 DEFW 0000H,0000H DEFW DIRBUF,DPBLK DEFW CHK0,ALL0 DEFW SECTAB,0000H ;DPH FOR UNIT 1 DEFW 0000H,0000H DEFW DIRBUF,DPBLK DEFW CHK1,ALL1 DEFW SECTAB,0000H ;DPH FOR UNIT 2 DEFW 0000H,0000H DEFW DIRBUF,DPBLK DEFW CHK2,ALL2 DEFW SECTAB,0000H ;DPH FOR UNIT 3 DEFW 0000H,0000H DEFW DIRBUF,DPBLK DEFW CHK3,ALL3 ; ; ; ; SETSEC: LD A,C LD (SECTOR),A ;STORE SECTOR NUMBER PASSED RET ; VIA BC ; ; TRANS: EX DE,HL ;ADD TRANSLATION TABLE ADDRESS ADD HL,BC ; PASSED IN DE TO SECTOR# IN BC LD L,(HL) LD H,0 ;LOOKUP PHYSICAL SECTOR NUMBER RET ; AND RETURN IT IN HL ; ; SETPTR: LD (POINTR),BC ;STORE DATA POINTER PASSED RET ; VIA BC ; ; ; SELECT: LD HL,0 ;PREP TO CHECK FOR MAX UNIT# LD A,C CP 4 RET NC ;RETURN WITH HL=0 IF C > 3 LD (UNIT),A ;STORE C AS NEW DRIVE UNIT# LD L,A ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,HL ;MULTIPLY UNIT# BY 16 LD DE,DPHTAB ADD HL,DE ;ADD START ADDRESS OF DHP BLOCK PUSH HL LD C,A ;LOAD C WITH DISK DRIVE NUMBER LD B,0 ;LOAD B WITH SEEK SPEED FOR THIS DRIVE CALL MONITR+27 ;CALL SELECT ROUTINE IN MONITOR POP HL RET Z ;EXIT IF SELECTED SUCCESSFULY LD C,1 CALL REPORT JR NZ,SEL2-$ ;JUMP IF COMMAND ABORT INDICATED LD A,(UNIT) ;ELSE TRY TO SELECT THE DRIVE AGAIN LD C,A JR SELECT-$ SEL2: LD HL,0 ;DISABLE FURTHER BIOS CALLS BY RET ; INDICATING SELECT ERROR TO BDOS ; ; ; HOME: CALL MONITR+30 ;CALL HOME ROUTINE IN MONITOR RET Z ;RETURN IF ALL WENT WELL LD C,2 CALL REPORT JR Z,HOME-$ ;RE-TRY HOME IF ERROR INDICATED RET ; ; SEEK: LD A,C ;GET TRACK # FROM C LD (TRACK),A CALL MONITR+33 ;CALL SEEK ROUTINE IN MONITOR RET Z ;EXIT IF NO ERRORS INDICATED LD C,2 CALL REPORT ;REPORT SEEK ERROR TO CONSOLE RET NZ ;RETURN PERMANENT ERROR UNLESS LD A,(TRACK) ; RE-TRY REQUEST IS INDICATED LD C,A JR SEEK-$ ; ; ; READ: LD HL,(POINTR) LD A,(SECTOR) LD C,A CALL MONITR+36 ;CALL READ ROUTINE IN MONITOR RET Z ;RETURN IF NO ERRORS LD C,3 ;INDICATE READ ERROR TO HANDLER CALL REPORT ;REPORT DISK ERROR TO CONSOLE JR Z,READ-$ ;RE-TRY READ IF INDICATED RET ; ; ; WRITE: LD HL,(POINTR) LD A,(SECTOR) LD C,A CALL MONITR+39 ;CALL WRITE ROUTINE IN MONITOR RET Z ;RETURN IF NO ERRORS LD C,4 ;INDICATE WRITE ERROR TO HANDLER CALL REPORT ;REPORT DISK ERROR TO CONSOLE JR Z,WRITE-$ ;RE-TRY WRITE IF INDICATED RET ;ELSE RETURN PERMANENT ERROR ; ; REPORT: LD (FLAGS),A ;STORE 1771 I/O STATUS FLAGS LD A,C LD (CLASS),A ;STORE COMMAND CLASS OF ERROR LD HL,DSKMSG CALL PMSG ;PRINT OUT START OF MESSAGE DEC HL LD A,(CLASS) LD B,A REP1: CALL SKIP ;SKIP TO NEXT '$' IN STRING @ HL DJNZ REP1-$ CALL PMSG ;PRINT STRING NOW POINTED TO BY HL LD HL,ERRMSG CALL PMSG ;PRINT 'error ' AFTER TYPE LD A,(FLAGS) RLA ;TEST FIRST FOR DRIVE-NOT-READY ERROR JR C,REP8-$ ; AND JUMP IF THAT IS THE PROBLEM LD E,A ;GET REMAINING 1771 ERROR BITS INTO E LD HL,RWERRS LD A,(CLASS) CP 3 ;DETERMINE IF SELECT/SEEK OF R/W ERROR JR NC,REP2-$ LD HL,SKERRS ;POINT HL TO PROPER SET OF MESSAGES REP2: LD B,5 RES 0,D REP4: SLA E ;SHIFT OUT A 1771 STATUS REG BIT JR NC,REP5-$ LD C,',' BIT 0,D CALL NZ,OVECTR ;PRINT COMMA BETWEEN STRINGS IF D=1 CALL PMSG ;THEN PRINT ERROR MESSAGE @ HL SET 0,D ;FLAG THAT A STRING WAS PRINTED JR REP6-$ REP5: CALL SKIP ;SKIP TO NEXT STRING @ HL RES 0,D ;FLAG THAT A STRING WAS SKIPPED REP6: DJNZ REP4-$ ;REPEAT FOR ALL 5 POSSIBLE ERRORS LD HL,TSMSG CALL PMSG ;PRINT TRACK/SECTOR# HEADER LD A,(TRACK) CALL PUT2HX ;PRINT TRACK# IN HEX LD C,'/' CALL OVECTR LD A,(SECTOR) CALL PUT2HX REP7: LD A,1 OR A ;RETURN PERM ERROR INDICATION IN A RET ; REP8: LD HL,RDYMSG CALL PMSG ;PRINT DISK-NOT-READY MESSAGE CALL IVECTR ; AND WAIT FOR CONSOLE INPUT CP 'C'-64 JR Z,REP7-$ XOR A ;RETURN A=0 IF SOMETHING OTHER THAN RET ; CONTROL-C WAS TYPED AT THE CONSOLE ; SKIP: PUSH BC ;SAVE BC LD B,255 LD A,'$' CPIR ;SCAN MEMORY LOOKING FOR '$' POP BC RET ; ; ; ; CHARACTER STRING OUTPUT ROUTINE. PRINTS ASCII DATA ; POINTED TO BY HL UNTIL A DOLLAR SIGN IS ENCOUNTERED PMSG: LD A,(HL) ;HL POINTS TO ASCII STRING CP '$' INC HL RET Z LD C,A ;PRINT CHARACTER IF NOT DOLLAR SIGN CALL OVECTR JR PMSG-$ ; ; PUT2HX: PUSH AF RRA RRA RRA RRA CALL PUTNIB POP AF PUTNIB: AND 00001111B ADD A,90H DAA ADC A,40H DAA LD C,A CALL OVECTR ;PRINT A HEX-ASCII CHARACTER RET ; ; ; LF EQU 0AH ;LINE FEED CR EQU 0DH ;CARRIAGE RETURN DSKMSG: DEFB CR,LF DEFM 'bios $' DEFM 'select $' DEFM 'seek $' DEFM 'read $' DEFM 'write $' ERRMSG: DEFM 'error $' SKERRS: DEFM '$' DEFM '$' DEFM 'cannot seek$' DEFM 'bad crc$' DEFM 'cannot restore$' RDYMSG: DEFM 'drive not ready -$' RWERRS: DEFM 'write protected$' DEFM 'write fault$' DEFM 'record not found$' DEFM 'bad crc$' DEFM 'data overrun$' TSMSG: DEFM ' trk/sect = $' SIGNON: DEFB CR,LF DEFM '60k CP/M version 2.2' DEFB CR,LF DEFM 'CUSTOM VERSION FOR XEROX 820' DEFB CR,LF DEFM 'ON LINE BULLETIN BOARD' DEFB CR,LF DEFM 'MARK RICHEY, APR.1986' DEFB CR,LF DEFB CR,LF DEFM 'SERIAL CHANNEL B BAUD = 1200 ' CRLF: DEFB CR,LF DEFB '$' ; ; UNIT: DEFS 1 TRACK: DEFS 1 SECTOR: DEFS 1 POINTR: DEFS 1 FLAGS: DEFS 1 CLASS: DEFS 1 DEFS 32 STACK: DEFS 1 ;LOCAL STACK FOR WARM BOOT ; ;******************************************************** ;* * ;* DISK I/O BUFFERS FOR BDOS FILE HANDLER * ;* * ;******************************************************** ; ; ; DIRBUF: DEFS 128 ;SCRATCH DIRECTORY BUFFER ; ALL0: DEFS 32 ;UNIT 0 ALLOCATION BUFFER CHK0: DEFS 16 ;UNIT 0 CHECK VECTOR ALL1: DEFS 32 ;UNIT 1 ALLOCATION VECTOR CHK1: DEFS 16 ;UNIT 1 CHECK VECTOR ALL2: DEFS 32 ;UNIT 2 ALLOCATION VECTOR CHK2: DEFS 16 ;UNIT 2 CHECK VECTOR ALL3: DEFS 32 ;UNIT 3 ALLOCATION VECTOR CHK3: DEFS 16 ;UNIT 3 CHECK VECTOR ; ; DEFB 1,BAUD DEFB 0111B ;1200 BAUD ; END