;*********************************************************** ;* * ;* HARD DISK DRIVER...S100/S1410 HARD DISK SUBSYSTEM * ;* * ;* CP/M-80 S100 I/O HOST COMPUTER * ;* * ;* COPYRIGHT 1982 XEBEC CORP. * ;* 432 LAKESIDE DR. * ;* SUNNYVALE, CA. 94086 * ;* * ;*********************************************************** ; ; ;S100 NON-DMA HARD DISK DRIVER ;REV. 2.0 02-11-83 ; ; ; ; REVISION HISTORY ;********************************************** ; ;AUGUST 20,1982...INITIAL RELEASE ;FEBRUARY 11, 1983...ADDED DIFFERENT DRIVE SIZES CAPS. ; SEND A DRIVE INITIALIZE COMMAND BEFORE ; EACH COMMAND TRUE EQU 0FFFFH FALSE EQU NOT TRUE ; ;************************************************************************** ; ; BELOW ARE THE EQUATES THAT MUST BE CHANGED ; SUCH THAT THEY REFLECT THE CHARACTERISTICS ; OF THE DRIVE WHAT WILL BE ATTACHED TO THIS ; SYSTEM. ; ; NOTE: THESE VALUES ARE ALL RELATIVE TO '1' ; ;************************************************************************** ; MXCL EQU 153 ;MAX CYLINDER MXHD EQU 4 ;MAX HEAD RWC EQU 128 ;STARTING REDUCED WRITE CURRENT CYL. WPC EQU 64 ;STARTING WRITE PRECOMP CYLINDER ECC EQU 11 ;ECC DATA BURST LENGTH CNTRLB EQU 0 ;LOWER NIBBLE OF THE CONTROL ;BYTE OF THE DCB (FAST STEP OPT.) FLAG1 EQU FALSE ;GREATER THAN 6 MBYTES ??? (4K/8K) FLAG2 EQU FALSE ;GREATER THAN 12 MBYTES ??? (512/1024) ; ;************************************************************************ ; ; BELOW ARE THE EQUATES WHICH MUST BE CHANGED TO MATCH ; THE SYSTEM FOR WHICH THIS DRIVER WILL BE INSTALLED ; ;************************************************************************ ; START EQU 0D800H ;START OF DRIVER PROGRAM AREA BASE EQU 0E0H ;HOST ADAPTOR BASE ADDRESS C8080 EQU TRUE ;CPU TYPE Z80 EQU NOT C8080 ;CPU TYPE, IF TRUE THE DRIVER WILL ;WILL USE THE Z-80 BLOCK MOVE INSTR. ;BETWEEN THE USER AND THE DISK ; ; END OF USER MODIFYABLE CODE ; ;************************************************************************* ; ; FLAG1 = MAX # OF CYLINDERS * MAX # OF HEADS ; IT IS THE SWITCH POINT FROM 511 DIR ; ENTRIES TO 1023 DIR ENTRIES ; ; FLAG2 = MAX # OF CYLINDERS * MAX # OF HEADS ; IT IS THE SWITCH POINT FROM 8K BLKS ; TO 16K BLOCKS ; ; 1 MBYTE 6 MBYTES 12 MBYTES ; ' ' ' ; +--------------------+-----------------------+----------------------+ ; ' ' ' ' ; ' BLKS SIZE = 8K ' BLKS SIZE = 8K ' BLKS SIZE = 16K ' ; ' ' ' ' ; ' DIR ENTRIES = 511 ' DIR ENTRIES = 1023 ' DIR ENTRIES = 1023 ' ; ' ' ' ' ; +--------------------+-----------------------+----------------------+ ; ' ' ; FLAG1 FLAG2 ;************************************************************************** ; MCL EQU MXCL MOD 256 ;SPLIT UP THE WORDS INTO BYTES MCH EQU MXCL / 256 ; RWL EQU RWC MOD 256 ; RWH EQU RWC / 256 ; WPL EQU WPC MOD 256 ; WPH EQU WPC / 256 ; ; NFLAG1 EQU NOT FLAG1 ; NFLAG2 EQU NOT FLAG2 ; ; ;************************************************************************** ; ; THE DPB WILL BE SET-UP USING THE VALUES WHICH ; WERE EQUATED IN ABOVE. ; ; NOTE: THE ASSUMPTION WAS MADE THAT WE ARE USING ; 32 SECTORS PER TRACK ( 256 BYTES PER SECT.) ; ;************************************************************************** ; IF FLAG2 ;SET-UP FOR 16K BLOCKS BSH EQU 7 ; BLM EQU 127 ; EXM EQU 7 ; DSM EQU ((( MXCL * MXHD ) - MXHD ) / 2 ) ;32 SEC, MINUS 1 CYL ENDIF ; IF NFLAG2 ;SET-UP FOR 8K BLOCKS BSH EQU 6 ; BLM EQU 63 ; EXM EQU 3 ; DSM EQU (( MXCL * MXHD ) - MXHD ) ;32 SEC, MINUS 1 CYLINDER ENDIF ; IF FLAG1 ;SET-UP 1023 DIR ENTRIES DRM EQU 1023 ;ALLOW 1023 DIR ENTRIES ENDIF ; IF NFLAG1 ;SET-UP FOR 511 DIR ENTRIES DRM EQU 511 ;ALLOW 511 DIR ENTRIES ENDIF ; IF NFLAG2 AND FLAG1 ;BETWEEN 6 AND 12 MBYTES AL0 EQU 0F0H ;ALLOW 4 BLKS FOR DIRECTORY ENDIF ; IF NFLAG1 OR FLAG2 ;LESS THAN 6 OR MORE THAN 12 MBYTES AL0 EQU 0C0H ;ALLOW 2 BLKS FOR DIRECTORY ENDIF ; IDC EQU 0CH ;DRIVE INITIALIZE COMMAND ; ; ; ;THE NEXT TWO EQUATES ARE FILLED IN ;BY THE LINK PROGRAM...THEY HAVE NO MEANING ;AT THIS TIME. ; ; BA EQU 0 ;MEMORY LOCATION FOR START OF FLOPPY BIOS JUMP TABLE DIRBUF EQU 0 ;MEMORY LOCATION FOR DIRECTORY BUFFER, IN FLOPPY BIOS ; ; DATAIN EQU BASE ;DATA INPUT PORT DATAOT EQU BASE ;DATA OUTPUT PORT DCON EQU BASE+1 ;DISK CONTROL PORT DSTA EQU BASE+2 ;DISK STATUS PORT DRST EQU BASE+2 ;DISK RESET PORT ; WRT EQU 0AH ;WRITE COMMAND RDD EQU 08H ;READ COMMAND RECAL EQU 01H ;RECALIBRATE COMMAND RQSNS EQU 03H ;REQUEST SENSE COMMAND ; SPT EQU 32 ;SECTORS PER TRACK ; DMY EQU 0 ;WARM BOOT JUMP ADDRESS IF NO ADDRESS PASSED IN HDNUM EQU 2 ;DRIVE NUMBER FOR HARD DISC (DRIVE C) HDNUM2 EQU 3 ;DRIVE D BDOS EQU 5 ;BDOS CALL LOCATION PSTRING EQU 9 ;PRINT STRING CR EQU 0DH ;CARRIAGE RETURN LF EQU 0AH ;LINE FEED CTLC EQU 03H ;CONTROL-C CONIN EQU 1 ;CONSOLE IN ; ; ;*********************************************************** ;* * ;* DO NOT MOVE OR MODIFY THE CODE FROM START (LABEL * ;* INSTAL) TO THE LABEL WBOOT. IF ANY MODIFICATIONS ARE * ;* MADE HERE, THE PROGRAM "HDLINK" MUST ALSO BE CHANGED * ;* * ;*********************************************************** ; ;START OF HARD DISK DRIVER ORG START ; ; INSTAL: ;PROGRAM TO LINK TO BIOS ;THIS CODE CHANGES THE BIOS JUMP ;TABLE TO POINT TO THE HARD DISK DRIVER, AFTER ;USING THE EXISTING JUMP TABLE VALUES TO FILL ;IN THE VECTORS BACK TO THE FLOPPY BIOS ;IN THE HARD DISK DRIVER. LHLD BA+4 ; SHLD WBX+1 ;WARM BOOT LHLD BA+019H ; SHLD SHX+1 ;HOME LHLD BA+1CH ; SHLD SDX+1 ;SELECT LHLD BA+1FH ; SHLD SEX+1 ;SELECT TRACK LHLD BA+22H ; SHLD SSX+1 ;SELECT SECTOR LHLD BA+25H ; SHLD SAX+1 ;DMA ADDRESS LHLD BA+28H ; SHLD SRX+1 ;READ LHLD BA+2BH ; SHLD SWX+1 ;WRITE LHLD BA+31H ; SHLD STX+1 ;TRANSLATE LXI H,WBOOT ; SHLD BA+4H ; LXI H,SH ; SHLD BA+19H ; LXI H,SD ; SHLD BA+1CH ; LXI H,SE ; SHLD BA+1FH ; LXI H,SS ; SHLD BA+22H ; LXI H,SA ; SHLD BA+25H ; LXI H,SR ; SHLD BA+28H ; LXI H,SW ; SHLD BA+2BH ; LXI H,ST ; SHLD BA+31H ; INSEND RET ; ;NOW SET UP THIS AREA AS A BUFFER ;SINCE THE ABOVE CODE IS ONLY EXECUTED ;ONCE, IT WILL BE OVERLAID BY THE BLOCKING/ ;DEBLOCKING BUFFER FOR THIS DRIVER. ; REMBUF DS 255-(INSEND-INSTAL) ;PAD BUFFER TO 256 BYTES ; ;NEED ADDRESSES OF DIRBUF FOR LOADER DW HDTBL1+8 ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ NOP ;REPLACE THIS NOP WITH DW HDTBL2+8 FOR TWO DRIVE NOP ;DELETE THIS LINE (I NEEDED 2-NOPS FOR 1 WORD) SUPPORT ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ; ;******************************************************* ;* * ;* END OF NONMODIFYABLE TABLE AREA IN BIOS * ;* * ;******************************************************* ; ;******************************************************* ;* WARM BOOT * ;******************************************************* WBOOT: ; MVI A,HDNUM ;RECAL DRIVE "C" STA DRIVE CALL REST ;RESTORE DRIVES WBX: ; JMP DMY ; ; ;******************************************************* ;* SELECT DRIVE * ;******************************************************* SD: ;SELECT DRIVE MOV A,C ; STA DRIVE ;SAVE DRIVE NUMBER CPI HDNUM ;THIS DRIVE? JZ TD1 ; ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ;CPI HDNUM2 ;REMOVE COMMENT SYMBOL FOR TWO DRIVE ;JZ TD2 ;REMOVE COMMENT SYMBOL SUPPORT ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ SDX: ; JMP DMY ; ; TD1: ;DRIVE C LXI H,HDTBL ;TABLE FOR CP/M RET ;BACK TO CPM ; TD2: ; ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ;LXI H,HDTBL2 ;REMOVE COMMENT SYMBOL FOR TWO DRIVE ;RET ;REMOVE COMMENT SYMBOL SUPPORT ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ; ; ; ;***************************************************** ;* HOME DRIVE * ;***************************************************** SH: ;HOME DRIVE CALL TESTD ; SHX: ; JNZ DMY ;TO OTHER BIOS ; ; CALL REST ;IF RECAL NEEDED REMOVE COMMENT SYMBOL RET ;HOMED, SO RETURN ; ;******************************************************* ;* SET TRACK * ;******************************************************* SE: ;SELECT TRACK CALL TESTD ; SEX: ; JNZ DMY ;TO OTHER BIOS ; MOV A,C ; STA TRACK ;B,C HOLD TRACK, WE NEED ONLY C RET ; ; ;******************************************************* ;* SET SECTOR * ;******************************************************* SS: ;SELECT SECTOR CALL TESTD ; SSX: ; JNZ DMY ;TO OTHER BIOS ; MOV A,C ;SAVE SECTOR VALUE STA SECTR ; RET ; ; ;******************************************************* ;* SET DMA ADDRESS * ;******************************************************* SA: ;SET DMA ADDRESS MOV A,B ; STA DMAAD+1 ; MOV A,C ; STA DMAAD ; SAX: ; JMP DMY ; ; ;***************************************************** ;* READ DISC * ;***************************************************** SR: ;READ CALL TESTD ; SRX: ; JNZ DMY ; ; CALL RSETB ; ANA A ;TEST FOR READ ERROR RNZ ;RETURN WITH ERROR CODE TO CP/M ; XCHG ;SET DATA DIRECTION TO CALLER'S CALL MOVDAT ;BUFFER - MOVE DATA ; ROUT: ; CORERR XRA A ; RET ;RETURN WITH GOOD READ ; ;*************************************************** ;* WRITE DISC * ;*************************************************** SW: ;WRITE CALL TESTD ; SWX: ; JNZ DMY ;TO OTHER BIOS ; CALL RSETB ; ANA A ;TEST FOR READ ERROR RNZ ;GOT ONE ; CALL MOVDAT ;MOVE DATA FROM CALLER'S BUFFER ; CALL WRITE ; RET ;RETURN WITH ERROR CODE FROM WRITE ; ;************************************************* ;* TRANSLATE SECTOR NUMBER * ;************************************************* ST: ;TRANSLATE CALL TESTD ; STX: ; JNZ DMY ;TO OTHER BIOS ; MOV H,B ; MOV L,C ;SAME SECTOR (NO TRANSLATE) RET ; ; ;**************************************************** ;* * ;* THE CODE ABOVE THIS POINT IS HOUSEKEEPING CODE * ;* TO LINK THE FLOPPY DISC BIOS AND TO OBTAIN THE * ;* VALUES OF TRACK, SECTOR, DMAADR, DRIVE #, AND * ;* READ OR WRITE REQUESTS FROM CP/M * ;* * ;* THE CODE BELOW THIS POINT MUST BE CHANGED FOR * ;* ANY CHANGE IN THE HARDWARE CONTROLLER/ DRIVE * ;* CONFIGURATION * ;* * ;**************************************************** ; ;THIS ROUTINE READS A SECTOR OF DATA FROM THE DISK INTO THE ;BUFFER, THEN RETURNS WITH D,E SET TO THE PORTION OF THE ;BUFFER DESIRED BY THE CALLER. H,L POINT TO ;THE USER'S BUFFER, AND C CONTAINS THE COUNT. ; RSETB: ; CALL READ ;READ SECTOR ANA A ;TEST FOR READ ERROR RNZ ;RETURN TO CP/M WITH ERROR CODE LDA SECTR ; MVI C,128 ;TRANSFER LENGTH LHLD DMAAD ;DATA BUFFER ADRESS ANI 01 ;WHICH BUFFER PORTION MVI A,0 ;GOOD READ LXI D,INSTAL;SET FOR LOWER PORTION RZ ;THAT'S IT ; LXI D,INSTAL+80H ;SET FOR UPPER PORTION RET ; ; ;THIS ROUTINE MOVES THE DATA FROM H,L TO ;D,E UNTIL C=C-1 GOES TO ZERO. ; MOVDAT: ; IF C8080 MOV A,M ; STAX D ; INX D ; INX H ; DCR C ; JNZ MOVDAT ; ENDIF IF Z80 ;IF Z80 USE BLOCK MOVE MVI B,0 ;SET B,C PAIR COUNT DB 0EDH,0B0H ;Z80 LDIR INSTR. ENDIF RET ; ; ;ROUTINE TO SET UP THE TASK PARAMETER BLOCK ;TO BE PASSED TO THE S1410 CONTROLLER ;ROUTINE RETURNS WITH THE ZERO FLAG SET IF ;THE COMPUTED ADRESS IS THE SAME AS THE ;CURRENT ADRESS. RETURNS NOT ZERO IF THE ;ADRESSES ARE DIFFERENT. ; UPTASK: ;SET UP TASK REGISTERS ; ;SET UP THE DRIVE NUMBER ; LDA DRIVE ;GET SELECTED DRIVE CPI HDNUM ;IS IS FIRST DRIVE MVI D,0 ;ASSUME ZERO JZ DRIV0 ;YES MVI D,20H ;MUST BE SECOND DRIVE DRIV0: ; ; ;SET UP THE DISK ADRESS ; LDA TRACK ;TRACK VALUE RRC ;ISOLATE LSB IN CARRY MOV B,A ;SAVE SHIFTED TRACK AS MAD LDA SECTR ;GET PASSED SECTOR NUMBER RAR ;SHIFT LSB OF TRACK INTO SECTOR MOV C,A ;SAVE AS LAD MVI A,07FH ;NOW FIX UP MAD - MASK OFF MSB ANA B ;WHICH WAS LSB OF TRACK MOV B,A ;NOW B,C HAS DISK ADR, D HAS LUN ; ;CHECK IF THIS ADRESS IS THE SAME AS LAST ACCESS ; LXI H,LUN ;POINT AT COMMAND PARM BLOCK MOV A,D ;CHECK LUN XRA M ;THE SAME? JNZ PRMSAV ;NO, DONE INX H ;CHECK MAD MOV A,B ; XRA M ;THE SAME? JNZ PRMSAV ;NO, DONE INX H ;CHECK LAD MOV A,C ; XRA M ;SET ZERO FLAG ON LAST COMPARE ; ;NOW SAVE NEW PARMS ; PRMSAV: LXI H,LUN ;POINT AT COMMAND PARM BLOCK MOV M,D ;SAVE LUN INX H ;POINT AT MAD MOV M,B ;SAVE INX H ;POINT AT LAD MOV M,C ;SAVE ; ;NOW RETURN WITH ZERO FLAG AS DERIVED ABOVE ; RET ; ; ;ROUTINE TO READ A SECTOR FROM THE DISK ; READ: ; CALL UPTASK ;SET UP THE COMMAND TABLE RZ ;RETURN IF ADRESS IS THE SAME MVI A,RDD ;READ COMMAND CALL OUTCOM ;SEND THE COMMAND ;LET THE READ ROUTINE DEBLOCK FROM RET ;THE BUFFER AREA ; ;ROUTINE TO WRITE A SECTOR TO THE DISK ; WRITE: ; CALL UPTASK ;SET UP THE COMMAND TABLE MVI A,WRT ;WRITE COMMAND CALL OUTCOM ;SEND THE COMMAND RET ; ; ;ROUTINE TO RESET THE CONTROLLER AND RECAL DRIVE ; REST: ; MVI A,0 ;RESET THE CONTROLLER OUT DRST ;ASSERT RESET LDA DRIVE ;WHICH DRIVE? CPI HDNUM MVI A,0 ;ASSUME DRIVE "C" JZ RCDRV0 ;IT IS MVI A,020H ;NO, IT'S "D" RCDRV0 STA LUN ;PUT IN COMMAND BLOCK MVI A,0FFH ;INSURE BUFFER REREAD STA MAD ;AFTER RECAL MVI A,RECAL ; CALL OUTCOM ;SEND A RECALIBRATE RET ; ; Š ; ; ;************************************************************* ; ; STORE REGISTERS ONTO STACK AND SEND OUT ; A DRIVE INITIALIZE DRIVE COMMAND ; UPON COMPLETION, RESTORE REGISTERS AND ; CONTINUE ; ;************************************************************* ; OUTCOM: PUSH PSW ;STORE REGISTERS ON STACK PUSH B ; PUSH D ; PUSH H ; MVI A,IDC ;INITIALIZE DRIVE COMMAND LXI H,COMND ;STORE COMMAND ADDRESS IN HL MOV M,A ;STORE ACC IN MEMORY LXI D,DRVCHR ;CHARACTERISTS ADDRESS MVI C,8 ;SEND 8 BYTES CALL EXCMD ;DO IT !! POP H ;RESTORE REGISTERS POP D ; POP B ; POP PSW ; LXI H,COMND ;COMMAND ADDRESS IN HL MOV M,A ;STORE ACC IN MEMORY LXI D,INSTAL ;DATA BUFFER MVI C,0 ;256 BYTES ; ; ;ON ENTRY HL SHOULD CONTAIN THE COMMAND BLOCK ADRESS ;DE SHOULD CONTAIN THE DATA BLOCK ADRESS, AND C SHOULD ;CONTAIN THE DATA COUNT. THIS PARTICULAR MODULE IS ;SET UP FOR THE S100 NON-DMA HOST ADAPTOR. ;ON RETURN, THE A REG CONTAINS A ZERO IF NO ERROR ;OCCURED, AND A ONE IF AN ERROR OCCURED. ; EXCMD: MVI A,1 ;SELECT THE CONTROLLER OUT DATAOT MVI A,42H ;ASSERT SELECT OUT DCON CONBSY: IN DSTA ;WAIT FOR CONTROLLER ANI 08H ;TO ASSERT BUSY JZ CONBSY MVI A,2 ;SET FOR OUTBOUND DATA FLOW OUT DCON MVI B,6 ;SET FOR 6 BYTE TRANSFER CONREQ: IN DSTA ;WAIT FOR REQUEST ANI 80H JZ CONREQ CONSND: IF C8080 MOV A,M ;GET DATA BYTE OUT DATAOT ;SEND IT INX H ;STEP POINTER DCR B ;STEP COUNT JNZ CONSND ;NOT DONE ENDIF IF Z80 MOV A,C ;SAVE XFER COUNT MVI C,DATAOT ;SET PORT NUMBER DB 0EDH,0B3H ;Z80 OUTIR INSTR. MOV C,A ;RESTORE XFER COUNT ENDIF DATREQ: IN DSTA ;WAIT FOR NEXT DATA REQUEST ANI 80H JZ DATREQ IN DSTA ;IS COMMAND HIGH? ANI 10H JNZ GETSTA ;YES, NO DATA XFER XCHG ;SET UP DATA XFER BUFFER IN DSTA ;TRANSFER WHICH DIRECTION? ANI 40H JNZ DATWRT ;HIGH MEANS WRITE DATA DATRD: ;GET THE BYTES IF C8080 IN DATAIN ;GET BYTE MOV M,A ;SAVE AWAY IN BUFFER INX H ;ADVANCE ADRESS DCR C ;STEP COUNT JNZ DATRD ;CONTINUE ENDIF IF Z80 MOV B,C ;SET UP XFER COUNT MVI C,DATAIN ;SET PORT DB 0EDH,0B2H ;Z80 INIR INSTR. ENDIF GETSTA: ;RETRIVE STATUS BYTES IN DSTA ;WAIT FOR REQUEST ANI 80H JZ GETSTA IN DATAIN ;FETCH FIRST BYTE MOV B,A ;SAVE GETST2: IN DSTA ;WAIT FOR REQ ANI 80H JZ GETST2 IN DATAIN ;RETRIVE 2ND BYTE MOV A,B ;GET FIRST BYTE ANI 02H ;CHECK ERROR BIT JNZ ERRRPT ;ERROR, REPORT IT RET ;DONE ; DATWRT: ;SEND DATA TO CONTROLLER IF C8080 MOV A,M ;GET BYTE OUT DATAOT ;SEND INX H ;STEP ADRESS DCR C ;STEP COUNT JNZ DATWRT ;NOT DONE ENDIF IF Z80 MOV B,C ;SET COUNT MVI C,DATAOT ;SET PORT DB 0EDH,0B3H ;Z80 OUTIR INSTR. ENDIF JMP GETSTA ;NOW FINISH ; ; ; ERRRPT: ;ERROR REPORTING LXI D,RQBUF ;SET BUFFER MVI A,0FFH ;PRESET ERROR CODE IN CASE STAX D ;SENSE COMMAND FAILS LDA LUN ;GET DRIVE NUMBER LXI H,RQSCM+1 ;POINT AT COM. BLOCK MOV M,A ;SET UP DRIVE NUMBER DCX H ;SET FOR START MVI C,4 ;NUMBER OF SENSE BYTES CALL EXCMD ;PROCESS COMMAND LDA RQBUF ;GET SENSE BYTE ANI 07FH ;MASK ADR VALID BIT ; ;CHECK FOR CORRECTABLE DATA ERROR...TREAT IT ;AS NO ERROR ; CPI 18H ;CORRECTABLE DATA ERROR? JZ CORERR ;BR. IF YES ; LXI H,ERRORM+36 ;POINT TO LOCATION FOR ERROR CODE CALL HTA ;CONVERT TO ASCII FOR CONSOLE LHLD 1 ;LINK DRIVER CALL TO CONOUT ROUTINE MVI L,0CH ;IN BIOS (4TH ENTRY IN JUMP TABLE) SHLD CONOUT+1 MVI D,45 ;SET UP MESSAGE OUTPUT LXI H,ERRORM NXTCHR: ;CHAR OUTPUT LOOP MOV C,M ;GET CHAR PUSH D ;SAVE ADRESS AND COUNT PUSH H CONOUT CALL DMY ;THIS CALL IS FIXED ABOVE POP H ;RESTORE POP D INX H ;STEP ADRESS DCR D ;STEP COUNT JNZ NXTCHR ;NOT DONE MVI A,0FFH ;DESTROY ADRESS SO RETRY WILL WORK STA MAD MVI A,01H ;RETURN ERROR TO BDOS RET ; ;ROUTINE TO TEST FOR HARD DISK I/O ;RETURNS WITH ZERO FLAG SET IF HARD DISK I/O ; TESTD: ; LDA DRIVE ; CPI HDNUM ; RZ ; CPI HDNUM2 ; RET ; ; ;THIS ROUTINE CONVERTS A HEXADECIMAL BYTE TO 2 ASCII ;BYTES FOR DISPLAY ON THE CONSOLE. ; ;ON ENTRY, A CONTAINS THE BYTE TO BE CONVERTED AND HL ;CONTAINS THE MEMORY ADDRESS WHERE THE RESULTING ;TWO ASCII BYTES ARE TO BE STORED...BC AND DE ARE ;RESTORED ON EXIT. ; HTA: PUSH B ;SAVE REG MOV B,A ;SAVE NUMBER RAR ;GET HIGH NIBBLE RAR RAR RAR CALL HTAX ;CONVERT MOV M,A ;AND STORE INX H ;STEP STORE LOCATION MOV A,B ;GET LOW NIBBLE CALL HTAX ;CONVERT MOV M,A ;AND STORE POP B ;RESTORE RET ; ; HTAX: ANI 0FH ;ISOLATE NIBBLE ADI 48 ;ADD ASCII "0" CPI 58 ;48+10 - ORIGINAL # LESS THAN 10? RC ;YES, DONE ADI 7 ;65-10-48 - CONVERT TO ALPHA A-F RET ; ; ; ; ; ; ; ; ; Š; ; RQSCM: DB 3,0 ;USE NEXT 4 BYTES AS REMAINDER OF COMMAND RQBUF: DS 4 ERRORM: DB CR,LF,'**** HARD DISK ERROR...ERROR CODE 00 ****' DB CR,LF TRACK: DB 0 ; SECTR: DB 0 ; DMAAD: DW 0 ; DRIVE: DB 0 ; HDTBL: ; HDTBL1: ; DW 0 ;TRANSLATE TABLE DW 0 ;SCRATCH DW 0 ; DW 0 ; DW DIRBUF ;DIRECTORY BUFFER AREA DW DPB ; DW CSV1 ; DW ALV1 ;DPB IS IN TABLE BELOW, CSV AND ALV ;ARE AREAS AT END OF CODE ; ; ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ;HDTBL2: ;REMOVE COMMENT SYMBOL ; DW 0 ;REMOVE COMMENT SYMBOL ; DW 0 ;REMOVE COMMENT SYMBOL ; DW 0 ;REMOVE COMMENT SYMBOL FOR TWO DRIVE ; DW 0 ;REMOVE COMMENT SYMBOL SUPPORT ; DW DIRBUF ;REMOVE COMMENT SYMBOL ; DW DPB ;REMOVE COMMENT SYMBOL ; DW CSV2 ;REMOVE COMMENT SYMBOL ; DW ALV2 ;REMOVE COMMENT SYMBOL ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ; ; ; DRVCHR: MXCLH DB MCH ;HIGH BYTE OF MXCL EQU MXCLL DB MCL ;LOW BYTE OF MSCL EQU LHD DB MXHD ;MXHD EQU RWCH DB RWH ;HIGH BYTE OF RWC EQU RWCL DB RWL ;LOW BYTE OF RWC EQU WPCH DB WPH ;HIGH BYTE OF WPC EQU WPCL DB WPL ;LOW BYTE OF WPC EQU MECC DB ECC ;ECC EQU DPB: DW 256 ;# OF BYTES PER SECTOR DB BSH ; DB BLM ; DB EXM ; DW DSM ;# OF BLKS ON DRIVE DW DRM ;# OF DIR ON DRIVE DB AL0 ;LOWER BYTE # OF SECTORS FOR DIR DW 0 ;CKS DW 0 ;OFFSET COMND: DB 0 ;OPCODE LUN DB 0 ;LUN & HIGH ADDRESS MAD DB 0FFH ;MIDDLE ADDRESS LAD DB 0FFH ;LOW ADDRESS DB 01H ;INTERLEAVE OR BLOCK COUNT DB CNTRLB ;CONTROL BYTE (FAST STEP OPT.) ; CSV1: ; DW 0 ; ALV1: ; DS DSM / 8 ;NOTE 1 BIT PER ALOC. UNIT ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ;CSV2: ;REMOVE COMMENT SYMBOL ; DW 0 ;REMOVE COMMENT SYMBOL FOR TWO DRIVE ;ALV2: ;REMOVE COMMENT SYMBOL SUPPORT ; DS DSM / 8 ;REMOVE COMMENT SYMBOL ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ END ;