;------------------------------------------------------------ ; ; MICRO/SYS BASIC I/O SYSTEM (MBIOS) FOR CP/M ; ; I/O DRIVERS FOR MICRO/SYS SB8500 FLOPPY DISK AND ; SB8420 DUAL SERIAL CARDS TO RUN UNDER CP/M 2.2 ; ; OPTIONAL SUPPORT FOR SB8341 DMA CONTROLLER ; ; 10/1/80 MICRO/SYS, DYSCUS ; ;------------------------------------------------------------ ; FALSE: EQU 0 TRUE: EQU NOT FALSE ; ; MSIZE: EQU 20 ;MEMORY SIZE DRIVES: EQU 1 ;NUMBER OF DISK DRIVES MULTI: EQU FALSE ;MULTIPLE DRIVE SYSTEM DMA: EQU FALSE ;DMA SYSTEM INTRP: EQU FALSE ;ALLOW INTERRUPTS ; SINGL: EQU NOT MULTI;SINGLE DRIVE SYSTEM ; ; CBASE: EQU 0C8H ;SB8410 BASE ADDRESS CSTAT: EQU CBASE+1 ;CONSOLE STATUS PORT CCOM: EQU CBASE+1 ;CONSOLE COMMAND PORT CDATA: EQU CBASE ;CONSOLE DATA PORT CKBR: EQU 2 ;KEYBOARD READY BIT CPTR: EQU 1 ;OUTPUT READY BIT LSTAT: EQU CBASE+3 ;PRINTER STATUS PORT LCOM: EQU CBASE+3 ;PRINTER COMMAND PORT LDATA: EQU CBASE+2 ;PRINTER DATA PORT LKBR: EQU 2 ;PRINTER KEYBOARD READY BIT LPTR: EQU 1 ;PRINTER READY BIT FDBASE: EQU 0C0H ;SB8500 BASE ADDRESS FDSTAT: EQU FDBASE ;FDC STATUS PORT FDDATA: EQU FDBASE+1;FDC DATA PORT FDTC: EQU FDBASE+2;FDC TERMINAL COUNT PORT FDCREQ: EQU FDBASE+2;FDC INT, DRQ REQUEST PORT FDCBSY: EQU 10H ;FDC BUSY BIT FDCNDM: EQU 20H ;FDC NON-DMA EXECUTION BIT DBASE: EQU 80H ;SB8341 DMA BASE ADDRESS DMA0: EQU DBASE ;SB8341 CHAN 0 PORT DMAMS: EQU DBASE+8 ;SB8341 CHAN 1 PORT XN: EQU 0 ;BYTES/SECTOR CODE XEOT: EQU 26 ;SECTORS/TRACK XGPL: EQU 7 ;GAP LENGTH XDTL: EQU 128 ;DATA LENGTH XNOSTR: EQU 2 ;NUMBER OF TRACKS FOR CP/M XBSIZE: EQU 128 ;BUFFER SIZE XREAD: EQU 26H ;READ COMMAND XWRITE: EQU 25H ;WRITE COMMAND XSEEK: EQU 0FH ;SEEK COMMAND XRECAL: EQU 7 ;HOME COMMAND XSNSIS: EQU 8 ;SENSE INTERRUPT COMMAND XSPCFY: EQU 3 ;SPECIFY COMMAND ; ; CTRLC: EQU 3 ;CONTROL C RTCNT: EQU 10 ;RETRIES ON FDC ERROR BIAS: EQU (MSIZE-20)*1024 CCP: EQU BIAS+3400H BDOS: EQU CCP+806H BIOS: EQU CCP+1600H STACK: EQU 80H DEFDRV: EQU 4 ;DEFAULT DRIVE ORG BIOS ; ; JMP BOOT ;FROM SBOOT COLD START LOADER WBOOTE: JMP WBOOT ;FROM WARM BOOT JMP CONST ;CHECK CONSOLE INPUT STATUS JMP CONIN ;GET CHARACTER FROM CONSOLE JMP CONOT ;SEND CHARACTER TO CONSOLE JMP LIST ;SEND CHARACTER TO LIST DEVICE JMP PUNCH ;SEND CHARACTER TO PUNCH DEVICE JMP READER ;GET CHARACTER FROM READER DEVICE JMP HOME ;SEND DISK DRIVE HEAD TO TRACK 0 JMP SELDSK ;SELECT DISK DRIVE JMP SETTRK ;SELECT TRACK NUMBER JMP SETSEC ;SELECT SECTOR NUMBER JMP SETDMA ;SET DISK DATA BUFFER ADDRESS JMP READ ;READ SELECTED SECTOR JMP WRITE ;WRITE SELECTED SECTOR JMP LISTST ;LIST DEVICE STATUS JMP SECTRN ;SECTOR TRANSLATE ; ; DPBASE: ; DISK 0 PARAMETER HEADER ; DW TRANS,0 DW 0,0 DW DIRBUF,DPBLK DW CHK00,ALL00 ; ; DISK 1 PARAMETER HEADER ; DW TRANS,0 DW 0,0 DW DIRBUF,DPBLK DW CHK01,ALL01 IF MULTI ; ; DISK 2 PARAMETER HEADER ; DW TRANS,0 DW 0,0 DW DIRBUF,DPBLK DW CHK02,ALL02 ; ; DISK 3 PARAMETER HEADER ; DW TRANS,0 DW 0,0 DW DIRBUF,DPBLK DW CHK03,ALL03 ENDIF ; ; TRANS: DB 1,7,13,19,25,5,11,17,23,3,9,15,21 DB 2,8,14,20,26,6,12,18,24,4,10,16,22 ; ; DPBLK: DW XEOT ;SECTORS/TRACK DB 3 ;BLOCK SHIFT FACTOR DB 7 ;BLOCK MASK DB 0 ;NULL MASK DW 242 ;DISK SIZE-1 DW 63 ;DIRECTORY MAX DB 192 ;ALLOC 0 DB 0 ;ALLOC 1 DW 16 ;CHECK SIZE DW XNOSTR ;TRACK OFFSET ; ; ;------------------------------------------------------- ; ; COLD BOOT ENTRY INTO CPM - INITIALIZE ; ;------------------------------------------------------- BOOT: LXI SP,STACK;SET STACK POINTER MVI A,4EH ;ASYNC USART OUT LCOM ;TO PRINTER MVI A,27H ;TXE, RXE, RTS, DTR OUT CCOM ;TO CONSOLE OUT LCOM ;AND PRINTER XRA A STA DEFDRV ;SELECT DRIVE 0 IF SINGL STA LOGIDR ;SET LOGICAL DRIVE TO A ENDIF LXI H,HELLO ;POINT TO SIGNON CALL PRINT ;PRINT IT GOCPM: IF INTRP EI ;ENABLE INTERRUPTS IF ALLOWED ENDIF IF DMA ;DO SPECIFY IN HERE IF DMA LXI H,FDCBS ;POINT TO SPECIFY FDCB MVI B,3 ;3 BYTE FDCB CALL FCMDX ;SEND TO FDC ENDIF MVI A,0C3H ;GET JUMP INSTRUCTION STA 0 ;PUT ONE AT 0 LXI H,WBOOTE;GET WARM BOOT ADDRESS SHLD 1 ;PART OF JUMP AT 0 STA 5 ;ANOTHER JUMP AT 5 LXI H,BDOS ;BDOS ENTRY ADDRESS SHLD 6 ;PART OF JUMP AT 5 LXI H,80H ;DEFAULT DISK DATA BUFFER ADDRESS SHLD DMAADD ;PUT THERE LDA DEFDRV ;GET DRIVE NUMBER MOV C,A ;PUT IN C JMP CCP ;AND GO TO CP/M ;------------------------------------------------------- ; ; WARM BOOT - READ IN ALL OF CPM EXCEPT BIOS ; ;------------------------------------------------------- WBOOT: LXI SP,STACK;SET STACK POINTER IF INTRP EI ;ENABLE INTERRUPTS IF ALLOWED ENDIF LXI H,FDCBS ;POINT TO SPECIFY FDCB MVI B,3 ;3 BYTE FDCB CALL FCMDX ;SEND TO FDC MVI C,0 ;SELECT DRIVE A CALL SELDSK CALL HOME ;SEND TO TRACK 0 MVI A,2 ;START WITH SECTOR 2 STA SECTOR ;STORE IT IN FDCB LXI H,CCP ;SET LOAD ADDRESS IF NOT DMA LXI D,3200 ;NUMBER BYTES TRACK 0 ENDIF IF DMA LXI D,3199 ;DMAC EXPECTS # BYTES-1 ENDIF CALL READX ;READ TRACK 0 MVI C,1 CALL SETTRK ;SET FDCB TO TRACK 1 CALL SETSEC ;SET FDCB TO SECTOR 1 LXI H,CCP+3200 ;START ADDRESS IF NOT DMA LXI D,2432 ;NUMBER BYTES TRACK 1 ENDIF IF DMA LXI D,2431 ;DMAC EXPECTS # BYTES-1 ENDIF CALL READX ;READ TRACK 1 JMP GOCPM ;WE'RE DONE ; ; READX: IF NOT DMA PUSH H ;SAVE MEMORY ADDRESS ENDIF IF DMA MVI A,40H ;DMAC WRITE BIT CALL DMAST ;SET UP DMAC TO WRITE TO MEMORY ENDIF LXI H,FDCB ;POINT TO FDCB MVI M,XREAD ;SET READ COMMAND CALL FCMD9 ;SEND TO FDC IF NOT DMA POP H ;GET MEMORY ADDRESS READN: IN FDSTAT ;GET FDC STATUS ORA A ;TEST FOR RQM JP READN ;NOT YET IN FDDATA ;GET BYTE MOV M,A ;PUT IN ITS PLACE INX H ;BUMP POINTER DCX D ;COUNT BYTES MOV A,D ;GET HIGH ORA E ;AND LOW JNZ READN ;MORE TO DO OUT FDTC ;STOP FDC ENDIF CALL INTWAIT ;WAIT FOR INT, GET RESULTS RET ;---------------------------------------------------- ; ; CHECK FOR CONSOLE INPUT ; ;---------------------------------------------------- CONST: IN CSTAT ;GET CONSOLE STATUS ANI CKBR ;CHECK FOR INPUTS MVI A,0 ;ASSUME NOT RZ ;CORRECT ASSUMPTION CMA ;NOPE, THERE WAS SOMETHING RET ;----------------------------------------------------- ; ; INPUT CHARACTER FROM CONSOLE ; ;----------------------------------------------------- CONIN: IN CSTAT ;GET CONSOLE STATUS ANI CKBR ;CHECK FOR INPUT JZ CONIN ;WAIT TILL THERE IS IN CDATA ;GET CHARACTER ANI 7FH ;STRIP PARITY RET ;----------------------------------------------------- ; ; OUTPUT A CHARACTER TO CONSOLE ; ;----------------------------------------------------- CONOT: IN CSTAT ;GET CONSOLE STATUS ANI CPTR ;CHECK PRINTER READY BIT JZ CONOT ;NOT YET MOV A,C ;GET CHARACTER OUT CDATA ;SEND TO CONSOLE RET ;------------------------------------------------------ ; ; OUTPUT CHARACTER TO LIST DEVICE ; ;------------------------------------------------------ LIST: IN LSTAT ;GET LIST DEVICE STATUS ANI LPTR ;CHECK PRINTER READY BIT JZ LIST ;NOT YET MOV A,C ;GET CHARACTER OUT LDATA ;SEND TO PORT RET ;------------------------------------------------------ ; ; GET LIST DEVICE STATUS ; ;------------------------------------------------------ LISTST: IN LSTAT ;GET STATUS BYTE ANI LPTR ;READY BIT MASK MVI A,0 ;ASSUME NOT READY RZ ;GOOD GUESS CMA ;MAKE FF RET ;------------------------------------------------------ ; ; OUTPUT CHARACTER TO PUNCH ; ;------------------------------------------------------ PUNCH: EQU LIST ;SAME AS LIST DEVICE ;------------------------------------------------------ ; ; INPUT CHARACTER FROM READER ; ;------------------------------------------------------ READER: IN LSTAT ;SAVE PORT AS LIST DEVICE ANI LKBR ;CHECK INPUT READY BIT JZ READER ;NOT YET IN LDATA ;GET INPUT DATA ANI 7FH ;STRIP PARITY RET ;---------------------------------------------------- ; ; SEND DRIVE TO TRACK 0 ; ;---------------------------------------------------- HOME: XRA A ;MAKE A 0 STA TRACK ;SET TRACK TO 0 CALL SETDRV ;SET DRIVE MVI A,RTCNT ;RETRY COUNT FOR ERRORS HRETRY: STA SERCNT ;SET SEEK ERROR CNTR LXI H,FDCB ;POINT TO FDCB MVI M,XRECAL;PUT A HOME COMMAND MVI B,2 ;2 BYTE FDCB CALL FCMDX ;SEND TO FDC CALL INTWAIT ;WAIT FOR DONE INTERRUPT LDA STAT0 ;GET STATUS BYTE ANI 0C0H ;TOP 2 BITS RZ ;SUCCESSFUL COMPLETION LDA SERCNT ;GET ERROR COUNT DCR A ;COUNT ANOTHER JNZ HRETRY ;TRY AGAIN MVI A,'H' ;HOME ERROR CALL ERROR ;TELL ABOUT IT JMP HOME ;TRY AGAIN ;-------------------------------------------------- ; ; SET DRIVE NUMBER ACCORDING TO REGISTER C ; ;-------------------------------------------------- SELDSK: LXI H,0 ;FOR ERROR RETURN MOV A,C ;GET DESIRED DRIVE IF MULTI CPI DRIVES ;CHECK WITHIN LIMITS ENDIF IF SINGL CPI 2 ;ALLOW 2 LOGICAL DRIVES ENDIF RNC ;ERROR RETURN STA DRVSEL ;SAVE FOR LATER I/O MOV L,A ;DRIVE NUMBER MVI H,0 ;16 BIT DAD H ;X2 DAD H ;X4 DAD H ;X8 DAD H ;X16 LXI D,DPBASE;BASE ADDRESS DAD D ;+OFFSET RET ;------------------------------------------------------ ; ; SET TRACK NUMBER ACCORDING TO C AND SEEK ; ;------------------------------------------------------ SETTRK: MOV A,C ;GET DESIRED TRACK STA TRACK ;SELECT IT CALL SETDRV ;SET DRIVE RSETRK: MVI A,RTCNT ;GET RETRY COUNT SRETRY: STA SERCNT ;SET ERROR COUNTER LXI H,FDCB ;POINT TO FDCB MVI M,XSEEK ;PUT SEEK COMMAND MVI B,3 ;3 BYTE FDCB CALL FCMDX ;SEND TO FDC CALL INTWAIT ;WAIT FOR DONE INTERRUPT LDA STAT0 ;GET STATUS BYTE ANI 0F8H ;CHECK TOP 5 BITS SUI 20H ;SUCCESSFUL? RZ ;YES, RETURN LDA SERCNT ;GET ERROR COUNTER DCR A ;COUNT ANOTHER JNZ SRETRY ;TRY AGAIN IF NOT OUT OF TRIES MVI A,'S' ;SEEK ERROR CALL ERROR ;TELL ABOUT IT JMP RSETRK ;TRY AGAIN ;---------------------------------------------------- ; ; SET SECTOR NUMBER ACCORDING TO REGISTER C ; ;---------------------------------------------------- SETSEC: MOV A,C ;GET DESIRED SECTOR STA SECTOR ;PUT IN FDCB RET ;---------------------------------------------------- ; ; TRANSLATE LOGICAL TO PHYSICAL SECTOR ; ;---------------------------------------------------- SECTRN: MVI B,0 ;16 BIT SECTOR NUMBER XCHG ;TABLE ADDRESS TO HL DAD B ;ADD SECTOR NUMBER MOV A,M ;GET PHYSICAL SECTOR STA SECTOR ;PUT IN FDCB MOV L,A ;AND RETURN IN L RET ;---------------------------------------------------- ; ; SET DISK BUFFER MEMORY ADDRESS FROM BC ; ;---------------------------------------------------- SETDMA: MOV H,B ;GET HIGH MOV L,C ;AND LOW ADDRESS SHLD DMAADD ;STORE RET ;---------------------------------------------------- ; ; READ SECTOR ESTABLISHED IN FDCB ; ;---------------------------------------------------- READ: CALL SETDRV ;SET DRIVE MVI A,RTCNT ;GET RETRY COUNT RRETRY: STA ERCNT ;SET RETRY COUNTER IF NOT DMA LHLD DMAADD ;GET BUFFER ADDRESS PUSH H ;SAVE IT ENDIF IF DMA MVI A,40H ;DMAC WRITE BIT CALL DMASECT ;SET DMAC FOR SECTOR WRITE TO MEMORY ENDIF LXI H,FDCB ;POINT TO FDCB MVI M,XREAD ;PUT READ COMMAND CALL FCMD9 ;SEND TO FDC IF NOT DMA DI ;NO TIME FOR THEM NOW MVI B,XBSIZE;GET BUFFER SIZE POP H ;GET BUFFER ADDRESS RDRQM: IN FDSTAT ;GET FDC STATUS ORA A ;TEST RQM JP RDRQM ;NOT YET IN FDDATA ;GET BYTE MOV M,A ;PUT IN BUFFER INX H ;BUMP POINTER DCR B ;COUNT BYTES JNZ RDRQM ;MORE TO DO IN FDSTAT ;GET FDC STATUS OUT FDTC ;STOP FDC ANI FDCNDM ;PREMATURE EXIT? JNZ RDEND ;NO, SKIP NEXT CLRFDC: CALL FDCRDY ;WAIT FOR RQM JP RDERR ;NO MORE INPUTS IN FDDATA ;GET BYTE JMP CLRFDC ;LOOK FOR MORE ENDIF RDEND: CALL INTWAIT ;WAIT FOR INT, GET RESULTS IF INTRP EI ENDIF LDA STAT0 ;GET STATUS REGISTER 0 ANI 0C0H ;MASK TERMINATION BITS RZ ;ALL OK RDERR: LDA ERCNT ;COUNT ERRORS DCR A JNZ RRETRY ;TRY AGAIN MVI A,'R' ;READ ERROR CALL ERROR ;TELL ABOUT IT MVI A,1 ;TELL BDOS RET ;--------------------------------------------------- ; ; WRITE BUFFER TO SECTOR ESTABLISHED BY FDCB ; ;--------------------------------------------------- WRITE: CALL SETDRV ;SET DRIVE MVI A,RTCNT ;GET RETRY COUNT WRETRY: STA ERCNT ;SET RETRY COUNTER IF NOT DMA LHLD DMAADD ;GET BUFFER ADDRESS PUSH H ;SAVE IT ENDIF IF DMA MVI A,80H ;DMAC READ BIT CALL DMASECT ;SET DMAC FOR READ FROM MEMORY ENDIF LXI H,FDCB ;POINT TO FDCB MVI M,XWRITE;PUT WRITE COMMAND CALL FCMD9 ;SEND TO FDC IF NOT DMA DI ;NO TIME FOR THEM NOW MVI B,XBSIZE;GET BUFFER SIZE POP H ;GET BUFFER ADDRESS WRRQM: IN FDSTAT ;GET FDC STATUS ORA A ;TEST RQM JP WRRQM ;NOT YET MOV A,M ;GET BYTE OUT FDDATA ;SEND TO FDC INX H ;BUMP POINTER DCR B ;COUNT BYTES JNZ WRRQM ;MORE TO DO IN FDSTAT ;GET FDC STATUS OUT FDTC ;STOP FDC ANI FDCNDM ;CHECK PREMATURE EXIT JNZ WREND ;OK, SKIP NEXT CALL RESULT ;GET RESULT BYTES JMP WRERR ;THIS IS AN ERROR ENDIF WREND: CALL INTWAIT;WAIT FOR INT, GET RESULTS IF INTRP EI ENDIF LDA STAT0 ;GET STATUS REGISTER 0 ANI 0C0H ;MASK TERMINATION BITS RZ ;ALL OK WRERR: LDA ERCNT ;COUNT ERRORS DCR A JNZ WRETRY ;TRY AGAIN MVI A,'W' ;WRITE ERROR CALL ERROR ;TELL ABOUT IT MVI A,1 ;TELL BDOS RET ;---------------------------------------------------- ; ; DISK CONTROLLER SUBROUTINES ; ;---------------------------------------------------- FCMD9: MVI B,9 ;FOR 9 BYTE FDCB'S FCMDX: PUSH H ;SAVE FDCB ADDRESS DI ;NOT NOW IN FDSTAT ;GET FDC STATUS ANI FDCBSY ;CHECK IF BUSY JZ FDCCM ;NO, CONTINUE OUT FDTC ;STOP FDC EXECUTION CALL RESULT ;GET RESULT BYTES FDCCM: CALL FDCRDY ;WAIT FOR RQM JP CMDOUT ;READY FOR COMMAND IN FDDATA ;GET UNKNOWN INPUT BYTE JMP FDCCM ;TRY AGAIN CMDOUT: MOV A,M ;GET FDCB BYTE OUT FDDATA ;SEND TO FDC INX H ;BUMP FDCB POINTER DCR B ;COUNT BYTES JNZ FDCCM ;MORE TO DO POP H ;RESTORE FDCB ADDRESS IF INTRP EI ENDIF RET ; ;---------------------------------------------------------- ; ; DMA ROUTINES ; ;---------------------------------------------------------- IF DMA DMASECT:LXI D,127 ;# OF BYTES/SECTOR LHLD DMAADD ;GET BUFFER ADDRESS DMAST: DI ;DMAC DOESN'T LIKE INTERRUPTIONS ORA D ;OR COMMAND WITH MSB OF COUNT MOV D,A ;AND REPLACE MOV A,E ;GET LOW COUNT OUT DMA0+1 ;SEND TO DMAC MOV A,D ;GET HIGH COUNT OUT DMA0+1 ;SEND TO DMAC MOV A,L ;GET ADDRESS LOW OUT DMA0 ;SEND TO DMAC MOV A,H ;GET ADDRESS HIGH OUT DMA0 ;SEND TO DMAC MVI A,61H ;TC STOP,EXT WR,CH0 ENABLE OUT DMAMS ;SEND TO DMAC ENDIF IF INTRP AND DMA EI ENDIF IF DMA RET ENDIF ; ;---------------------------------------------------------- ; INTWAIT:IN FDSTAT ;GET FDC STATUS ANI 1FH ;ANYTHING BUSY? JZ FSTAT ;NO, WHY WAIT? INTW1: IN FDCREQ ;GET FDC REQUESTS ORA A ;TEST FOR INT REQUEST JP INTW1 ;WAIT FOR IT RESULT: XTHL ;WAIT FOR CONTROLLER XTHL ;IS SOMETIMES NECESSARY IN FDSTAT ;GET FDC STATUS ANI FDCBSY ;CHECK FDC BUSY JNZ FSTAT ;MUST BE READ OR WRITE (AUTO RESULT) CALL FDCRDY ;WAIT FOR RQM MVI A,XSNSIS;SENSE INTERRUPT STATUS OUT FDDATA ;SEND TO FDC FSTAT: LXI H,STAT0 ;POINT TO STATUS BUFFER FSTAT1: CALL FDCRDY ;WAIT FOR RQM JM FSTAT2 ;READY TO INPUT MVI M,80H ;INDICATE ERROR IN STAT0 RET FSTAT2: IN FDDATA ;GET RESULT BYTE MOV M,A ;PUT IN STATUS BUFFER INX H ;BUMP POINTER XTHL ;DELAY TO ALLOW FDC TO CLEAR XTHL ;BUSY BIT IF FINISHED XTHL XTHL IN FDSTAT ;GET FDC STATUS ANI FDCBSY ;CHECK IF BUSY JNZ FSTAT1 ;YES, INPUT MORE RESULTS RET ; ;--------------------------------------------------- ; SETDRV: LDA DRVSEL ;GET DESIRED DRIVE IF MULTI STA DRIVE ;PUT IN FDCB RET ENDIF IF SINGL LXI H,LOGIDR;POINT TO LOGICAL DRIVE CMP M ;SAME AS DESIRED? RZ ;YES, DO NOTHING MOV B,A ;SAVE DESIRED DRIVE ADI 'A' ;MAKE ASCII STA DNAME ;PUT IN MESSAGE XCHG ;SAVE HL LXI H,LOADM ;POINT TO LOAD MESSAGE CALL PRINT ;PRINT IT CALL CONIN ;WAIT FOR SWAP LXI H,CRLF ;POINT TO CRLF CALL PRINT ;DO IT XCHG ;GET LOGIDR ADDR BACK MOV M,B ;PUT NEW LOGICAL DRIVE RET ;DONE ENDIF ; ;--------------------------------------------------- ; FDCRDY: IN FDSTAT ;GET FDC STATUS ADD A ;RQM TO CARRY RC ;RETURN, DIO IN SIGN FLAG JMP FDCRDY ;NO RQM, WAIT ; ;----------------------------------------------------- ; ERROR: STA ETYPE ;PUT ERROR IN MESSAGE PUSH H ;SAVE HL LXI H,ERMSG ;POINT TO MESSAGE CALL PRINT ;PRINT IT CALL CONIN ;GET REPLY CPI CTRLC ;CONTROL C? PUSH PSW ;SAVE RESULTS LXI H,CRLF ;POINT TO CRLF CALL PRINT ;DO IT POP PSW ;RESTORE CTRLC CHECK POP H ;RESTORE HL RNZ ;NOT CONTROL C, RETURN XRA A ;MAKE A 0 STA DEFDRV ;SET DRIVE TO 0 JMP WBOOT ;REBOOT ; ;------------------------------------------------------ ; PRINT: MOV A,M ;GET CHARACTER ORA A ;CHECK FOR END RZ ;FINISHED MOV C,A ;PUT IN THE RIGHT PLACE CALL CONOT ;PRINT IT INX H ;BUMP POINTER JMP PRINT ;GET NEXT ; ; HELLO: DB 13,10,13,10,'MICRO/SYS CP/M 2.2',13,10 DB 13,10,'10/1/80 ' DB MSIZE/10+'0',MSIZE MOD 10+'0','K ' DB DRIVES+'0',' DRIVE' IF MULTI DB 'S' ENDIF IF DMA DB ' DMA' ENDIF DB 13,10 CRLF: DB 13,10,0 ERMSG: DB 13,10,'DISK ERROR ' ETYPE: DB ' :',0 IF SINGL LOADM: DB 13,10,'LOAD ' DNAME: DB ' :',0 ENDIF ; ; ;------------------------------------------------------ ; ; FLOPPY DISK CONTROL BLOCK (FDCB) ; ;------------------------------------------------------ FDCB: EQU $ COMND: DB 0 ;COMMAND DRIVE: DB 0 ;DRIVE SELECT TRACK: DB 0 ;TRACK SELECT HEAD: DB 0 ;HEAD SELECT SECTOR: DB 1 ;SECTOR SELECT N: DB XN ;BYTES/SECTOR CODE EOT: DB XEOT ;LAST SECTOR NUMBER GPL: DB XGPL ;GAP LENGTH DTL: DB XDTL ;DATA LENGTH ; ; FDCBS: DB XSPCFY ;SPECIFY FDCB DB 7FH ;9 MS STEP TIME, 240 MS UNLOAD IF NOT DMA DB 25H ;36 MS HEAD LOAD, NON-DMA MODE ENDIF IF DMA DB 24H ;36 MS HEAD LOAD, DMA MODE ENDIF ; ;------------------------------------------------------- ; ; There are only 7 sectors on track 1 for BIOS. ; The preceding address must be no greater than ; BIOS+37F (xD7F) so that it can be recorded ; on track 1. ; ; The following locations are in uninitialized ; RAM and can start at xD80. ; ;------------------------------------------------------- ; ; DMAADD: DS 2 ;DISK MEMORY BUFFER ADDR ERCNT: DS 1 ;ERROR RETRY COUNTER SERCNT: DS 1 ;SEEK RETRY COUNTER DRVSEL: DS 1 ;DESIRED DRIVE FOR NEXT I/O LOGIDR: DS 1 ;LOGICAL DRIVE IF ONLY 1 ; STAT0: DS 1 ;STATUS REGISTER 0 STAT1: DS 1 ;STATUS REGISTER 1 STAT2: DS 1 ;STATUS REGISTER 2 STRK: DS 1 ;STATUS TRACK SHEAD: DS 1 ;STATUS HEAD SSECT: DS 1 ;STATUS SECTOR SN: DS 1 ;STATUS BYTE/SECTOR CODE ; ; DIRBUF: DS 128 ;SCRATCH DIRECTORY AREA ALL00: DS 31 ;ALLOCATION VECTOR 0 ALL01: DS 31 ;ALLOCATION VECTOR 1 ALL02: DS 31 ;ALLOCATION VECTOR 2 ALL03: DS 31 ;ALLOCATION VECTOR 3 CHK00: DS 16 ;CHECK VECTOR 0 CHK01: DS 16 ;CHECK VECTOR 1 CHK02: DS 16 ;CHECK VECTOR 2 CHK03: DS 16 ;CHECK VECTOR 3 ENDDAT: EQU $ END