;******************************************************** ;* * ;* -- CUSTOM BIOS FOR CP/M VERSION 2.2 -- * ;* 8-INCH DISK VERSION * ;* * ;* APRIL 1981 * ;* * ;* CBIOS FOR XEROX WORD PROCESSING DISK * ;* COMBINED VERSION FOR 5.25" AND 8" - JUNE 1981 * ;* * ;******************************************************** ; PSECT ABS ; MSIZE EQU 60 ;MEMORY CAPACITY IN KBYTES MONITR EQU 0F000H ;BASE OF SYSTEM MONITOR EXTRA EQU MSIZE-20 BASE EQU .RES.EXTRA*1024 CCP EQU .RES.3400H+BASE ;CONSOLE COMMAND PROCESSOR BDOS EQU .RES.3C06H+BASE ;OPERATING SYSTEM ENTRY POINT CBIOS EQU .RES.4A00H+BASE ;BASE OF CUSTOM BIOS ; ; ; EQUATES TO SELECT THE CONDITIONAL ASSEMBLY ; FOR 5.25 OR 8 INCH DISKS ; ; THE EQUATES DSKTY5 OR DSKTY8 ARE USED FOR ; CONDITIONAL ASSEMBLY CONTROL ; ; ONE CONDITIONAL ASSEMBLY FLAG SHOULD BE ON ; AND THE OTHER SHOULD BE OFF AT ALL TIMES. ; DSKTY5 EQU 1 ;5.25 INCH DISK TYPE FLAG DSKTY8 EQU 0 ;8 INCH DISK TYPE FLAG ; ; 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 CONIN ;READER DEVICE VECTOR JP HOME JP SELECT JP SEEK JP SETSEC JP SETPTR JP READ JP WRITE JP CONST ;LIST DEVICE STATUS VECTOR JP TRANS ; ; JUMP VECTORS TO DIRECT PRINTER DRIVERS ; JP POBUSY ;LIST DEVICE STATUS JP POSEND ;LIST DEVICE OUTPUT JP POINP ;LIST DEVICE INPUT ; ; ; BOOT: XOR A LD (0003H),A ;RESET IOBYTE TO ZEROS LD (WUNIT),A ;ZERO SAVE AREA FOR LOGGED DRIVE ; ; MOVE XEROX ID TO THE SIGN ON MESSAGE ; LD HL,00F7H ;ADRS OF XEROX ID AFTER BOOT LD DE,XEROXID ;ADRS OF XEROX ID IN BIOS LD BC,09D ;NUMBER OF BYTES TO MOVE IN DECIMAL LDIR ;MOVE THEM ; LD HL,SIGNON CALL PMSG ;PRINT SIGNON MESSAGE JR GOCPM-$ ; ; IF DSKTY5 ;5.25 INCH DISK WBOOT: LD SP,STACK LD A,(UNIT) ;SAVE LOGGED DRIVE FOR LD (WUNIT),A ;* LATER USE LD C,0 CALL SELECT ;SELECT UNIT 0 CALL HOME ;SEEK TRACK ZERO JP NZ,BOMB LD HL,.RES.3480H+BASE LD BC,0803H CALL RDLOOP ;READ EVEN SECTORS ON TRK 0 LD HL,.RES.3400H+BASE LD BC,0902H CALL RDLOOP ;READ ODD SECTORS ON TRK 0 LD C,1 CALL SEEK ;SEEK TO TRACK 1 JP NZ,BOMB LD HL,.RES.3C80H+BASE LD BC,0901H CALL RDLOOP ;READ ODD SECTORS ON TRK 1 LD HL,.RES.3D00H+BASE LD BC,0902H CALL RDLOOP ;READ EVEN SECTORS ON TRK 1 LD C,2 CALL SEEK ;SEEK TRACK #2 JR NZ,BOMB-$ LD HL,.RES.4580H+BASE LD BC,0501H CALL RDLOOP ;READ ODD SECTORS ON TRK 2 LD HL,.RES.4600H+BASE LD BC,0402H CALL RDLOOP ;READ EVEN SECTORS ON TRK 2 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 ENDIF ;END OF 5.25 INCH SECTION IF DSKTY8 ;8 INCH DISK WBOOT: LD SP,STACK LD A,(UNIT) ;SAVE LOGGED DRIVE FOR LD (WUNIT),A ;* LATER USE LD C,0 CALL SELECT ;SELECT UNIT 0 CALL HOME ;SEEK TRACK ZERO LD HL,.RES.3400H+BASE LD BC,0D02H CALL RDLOOP ;READ EVEN SECTORS ON TRK 0 LD HL,.RES.3480H+BASE LD BC,0C03H CALL RDLOOP ;READ ODD SECTORS ON TRK 0 LD C,1 CALL SEEK ;SEEK TO TRACK 1 JP NZ,BOMB-$ LD HL,.RES.4080H+BASE LD BC,0A01H CALL RDLOOP ;READ ODD SECTORS ON TRK 1 LD HL,.RES.4100H+BASE 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 ENDIF ; ; ; SET UP 'XWS' TO EXECUTE ON COLD AND WARM BOOT' ; ; LD DE,0D407H ;ADRS OF CCP COMMAND BUFFER LD HL,AUTOTXT ;ADRS OF COMMAND TO MOVE LD BC,5 ;NUMBER OF BYTES TO MOVE LDIR ;MOVE THEM ; ; INITIALIZE THE PRINTER ; LD A,07 ;LOAD BAUD RATE OUT (0CH),A ;SEND TO SIO CH. B ; ; SEND A 'RESET' SEQUENCE TO THE PRINTER ; LD B,03D ;NUMBER OF BYTES IN SEQUENCE LD HL,INPR2 ;ADRS OF 'RESET' TABLE INPR1: CALL POBUSY ;IS PRINTER READY? JR C,INPR1-$ ;* REPEAT TILL READY LD A,(HL) ;GET THE BYTE OUT (05H),A ;SEND IT INC HL ;POINT TO NEXT BYTE DJNZ INPR1-$ ;REPEAT TILL DONE ; ; LD A,(WUNIT) ;SELECT SAVED DRIVE LD C,A ;* JP CCP ;* JUMP TO COMMAND CONSOLE PROCESSOR ; ; 'RESET' SEQUENCE TABLE FOR PRINTER ; INPR2: DEFB 1BH ; 'ESC' DEFB 0DH ; 'CR' DEFB 50H ; 'P' ; ; 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 WAS CHANGED TO LOOP UNTIL GET CTRL+C ; ; CONIN: CALL MONITR+9 ;MONITOR CONSOLE INPUT RTN. ; ; RESET THE HIGH ORDER BIT IF THE ABOVE INSTRUCTION ; IS A 'CALL MONITR+9'. IF A 'JP MONITR+9' THIS CODE ; IS NOT EXECUTED AND THE 'RETURN' IS DONE FROM THE MONITOR. ; RES 7,A ;RESET THE HIGH ORDER BIT RET ; ; CONOUT: LD A,C JP MONITR+12 ;MONITOR CONSOLE OUTPUT RTN. ; ; ;******************************************** ;* * ;* LIST OUTPUT DEVICE DRIVER * ;* * ;******************************************** ; LSTOUT: CALL POINP ;CHECK IF PRINTER HAS DATA JR NC,LSTOUT-$ ;REPEAT TILL CLEAR CPBSY: CALL POBUSY ;CHECK IF PRINTER BUSY JR C,CPBSY-$ ;REPEAT TILL READY LD A,C ;GET CHAR FROM C CALL POSEND ;PRINT THE CHARACTER CP 0AH ;WAS IT A LINE FEED? RET NZ ;RETURN IF NOT CPBSY2: CALL POBUSY ;IF SO GET PRINTER READY JR C,CPBSY2-$ ;* LD A,03 ;LOAD A 'ETX' CALL POSEND ;AND PRINT IT WAIT: CALL POINP ;LOOP TILL RECEIVE JR C,WAIT-$ ;* AN 'ACT' RET ;THEN RETURN ; ; ; PRINTER BUSY ROUTINE ; POBUSY: IN A,(07) ;READ SIO PORT CH. B AND 04 ;MASK OUT BITS OF INTEREST XOR 04 ;* TO CHECK PRINTER STATUS SCF ;SET CARRY RET NZ ;RET WITH PRINTER NOT READY OR A ;* ELSE RESET CARRY RET ;* AND RET WITH PRINTER READY ; ; ; PRINTER OUTPUT ROUTINE ; POSEND: OUT (05),A ;SEND THE BYTE RET ;* AND RETURN ; ; ; PRINTER INPUT STATUS ROUTINE ; POINP: IN A,(07) ;READ SIO PORT CH. B AND 01 ;CHECK FOR RECEIVE XOR 01 ;* CHARACTER AVAILABLE SCF ;SET CARRY RET NZ ;RET WITH NO CHARA AVAIL. IN A,(05) ;* ELSE GET CHARACTER OR A ;* RESET CARRY RET ;* AND RETURN ; ; ; ;******************************************************** ;* * ;* DISK I/O SUBROUTINES FOR CP/M CBIOS * ;* * ;******************************************************** ; ; IF DSKTY5 ;5.25 INCH DISK ; ; ; SECTOR TRANSLATE TABLE FOR STANDARD ; 1 IN 5 INTERLEAVE FACTOR ; SECTAB: DEFB 1,6,11,16 DEFB 3,8,13,18 DEFB 5,10,15,2 DEFB 7,12,17,4 DEFB 9,14 ; ; ; DISK PARAMETER BLOCK FOR STANDARD 5.25" MINI FLOPPY ; DPBLK: DEFW 18 ;SECTORS PER TRACK DEFB 3 ;BLOCK SHIFT CONST. DEFB 7 ;BLOCK MASK CONST. DEFB 0 ;EXTENT MASK CONST. DEFW 81 ;MAX BLOCK# DEFW 31 ;MAX DIRECTORY ENTRY# DEFB 10000000B ;ALLOCATION MASK MSB DEFB 00000000B ;' ' LSB DEFW 16 ;CHECK SIZE DEFW 3 ;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 ENDIF ;END OF 5.25 INCH SECTION IF DSKTY8 ;8 INCH DISK ; ; ; 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 2 DISK SYSTEM ; THE LAST TWO REMOVED FOR SPACE. ; 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 ENDIF ;END OF 8 INCH SECTION ; ; ; ; 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 ; ; IF DSKTY5 ;5.25" SYSTEM CP 4 ;IS ALLOWED TO HAVE 4 DRIVES ENDIF ; ; IF DSKTY8 ;8" SYSTEM CP 2 ;IS ALLOWED TO HAVE 2 DRIVES ENDIF ; ; 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 RET ;DO NOT ACTUALLY SELECT THE DRIVE SELEX: PUSH BC ;SAVE REGISTERS VALUES PUSH HL LD A,(UNIT) LD C,A ;LOAD C WITH DISK DRIVE NUMBER LD A,(PUNIT) ;LOAD PREVIOUSLY SELECTED DRIVE CP C ;COMPARE WITH CURRENTLY SELECTED DRIVE JR Z,SELEX1-$ ;DO NOT SELECT IF SAME DRIVE SELEX2: LD B,0 ;LOAD B WITH SEEK SPEED FOR THIS DRIVE CALL MONITR+27 ;CALL SELECT ROUTINE IN MONITOR JR Z,SELEX1-$ CALL REPORT ;CALL ERROR ROUTINE JR NZ,SELEX3-$ LD A,(UNIT) ;SAVE AS NEXT DRIVE LD C,A ;LOAD DRIVE TO BE SELECTED IN C JR SELEX2-$ ; SELEX1: LD A,(UNIT) ;LOAD DRIVE JUST SELECTED LD (PUNIT),A ;STOR IT AS A PREVIOUS DRIVE POP HL POP BC ;RESTORE REGISTERS RET ;EXIT IF SELECTED SUCCESSFULY SELEX3: XOR A LD (UNIT),A JP 0H ;DISABLE FURTHER BIOS CALLS BY ; RET ; INDICATING SELECT ERROR TO BDOS ; ; ; HOME: CALL SELEX ;FIND OUT IF DRIVE IS SELECTED CALL MONITR+30 ;CALL HOME ROUTINE IN MONITOR RET Z ;RETURN IF ALL WENT WELL CALL REPORT JR Z,HOME-$ ;RE-TRY HOME IF ERROR INDICATED RET ; ; SEEK: CALL SELEX ;FIND OUT IF DRIVE IS SELECTED 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 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: CALL SELEX ;FIND OUT IF DRIVE IS SELECTED LD HL,(POINTR) LD A,(SECTOR) LD C,A CALL MONITR+36 ;CALL READ ROUTINE IN MONITOR RET Z ;RETURN IF NO ERRORS CALL REPORT ;REPORT DISK ERROR TO CONSOLE JR Z,READ-$ ;RE-TRY READ IF INDICATED RET ; ; ; WRITE: CALL SELEX ;FIND OUT IF DRIVE IS SELECTED LD HL,(POINTR) LD A,(SECTOR) LD C,A CALL MONITR+39 ;CALL WRITE ROUTINE IN MONITOR RET Z ;RETURN IF NO ERRORS LD E,A ;SAVE 1771 I/O STATUS FLAG RLA RLA ;CRY CONTAINS WRITE PROTECT STATUS JR NC,WRIT1-$ ;CONTINUE IF NOT WRITE PROTECTED LD HL,DSKMSG CALL PMSG ;PRINT 'disk' LD HL,WRTERR CALL PMSG ;PRINT 'write protected' CALL REP3 ;WAIT FOR CONSOLE INPUT JR Z,WRITE-$ ;RETRY IF INDICATED RET WRIT1: LD A,E ;RETRIEVE SAVED 1771 STATUS CALL REPORT ;REPORT DISK ERROR TO CONSOLE JR Z,WRITE-$ ;RE-TRY WRITE IF INDICATED RET ;ELSE RETURN PERMANENT ERROR ; ; ; ON ENTRY (A) = 1771 I/O STATUS FLAG ; ; REPORT: PUSH AF ;SAVE 1771 I/O STATUS LD HL,DSKMSG CALL PMSG ;PRINT 'disk ' POP AF ;RETRIEVE SAVED STATUS RLA ;TEST FIRST FOR DRIVE-NOT-READY ERROR JR C,REP2-$ ;JUMP IF THAT IS THE PROBLEM LD HL,ERRMSG ;OTHER TYPE OF ERROR SO --- CALL PMSG ;PRINT 'error ' REP1: LD A,1 ;SET UP A NZERO CONDITION FOR RETURN OR A ;RETURN PERM ERROR INDICATION IN A RET ; REP2: LD HL,RDYMSG CALL PMSG ;PRINT DISK-NOT-READY MESSAGE REP3: CALL IVECTR ;AND WAIT FOR CONSOLE INPUT CP 'C'-64 JR Z,REP1-$ XOR A ;RETURN A=0 IF SOMETHING OTHER THAN RET ;CONTROL-C WAS TYPED AT THE CONSOLE ; ; ; ; 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-$ ; ; ; ; LF EQU 0AH ;LINE FEED CR EQU 0DH ;CARRIAGE RETURN ; ; ; COMMAND TO EXECUTE ON COLD AND WARM BOOT ; ; AUTOTXT : DEFB 3 ;LENGTH OF COMMAND (FOR CCP) DEFM 'XWS' ;FILE NAME TO EXECUTE DEFB 00 ;ALWAYS A TRAILING ZERO ; DSKMSG: DEFB CR,LF DEFM 'disk $' ERRMSG: DEFM 'error $' RDYMSG: DEFM 'drive not ready -$' WRTERR: DEFM 'write protected$' SIGNON: DEFB CR,LF DEFM 'COPYRIGHT (C) 1981, XEROX CORPORATION' DEFB CR,LF DEFB CR,LF DEFM 'CP/M REG. TM 2.2 WP 1.3 2-294 ' XEROXID: DEFM ' ' CRLF: DEFB CR,LF DEFB '$' ; ; UNIT: DEFS 1 PUNIT DEFS 1 WUNIT DEFS 1 TRACK: DEFS 1 SECTOR: DEFS 1 POINTR: 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 IF DSKTY5 ;ONLY FOR 5.25 INCH DISK 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 ENDIF ; ; ; ; ; END