From 80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6 Mon Sep 17 00:00:00 2001 From: Rich Turner Date: Fri, 12 Aug 1983 17:53:34 -0700 Subject: MS-DOS v2.0 Release --- v2.0/source/HRDDRV.ASM | 501 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 501 insertions(+) create mode 100644 v2.0/source/HRDDRV.ASM (limited to 'v2.0/source/HRDDRV.ASM') diff --git a/v2.0/source/HRDDRV.ASM b/v2.0/source/HRDDRV.ASM new file mode 100644 index 0000000..672b99d --- /dev/null +++ b/v2.0/source/HRDDRV.ASM @@ -0,0 +1,501 @@ + TITLE HRDDRV.SYS for the ALTOS ACS-86C. + +; Hard Disk Drive for Version 2.x of MSDOS. + +; Constants for commands in Altos ROM. + +ROM_CONSTA EQU 01 ;Return status AL of console selected in CX. +ROM_CONIN EQU 02 ;Get char. from console in CX to AL +ROM_CONOUT EQU 03 ;Write char. in DL to console in CX. +ROM_PMSG EQU 07 ;Write string ES:DX to console in CX. +ROM_DISKIO EQU 08 ;Perform disk I/O from IOPB in ES:CX. +ROM_INIT EQU 10 ;Returns boot console and top memory ES:DX. + + +CODE SEGMENT +ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE + + ORG 0 ;Starts at an offset of zero. + + PAGE + SUBTTL Device driver tables. + +;-----------------------------------------------+ +; DWORD pointer to next device | 1 word offset. +; (-1,-1 if last device) | 1 word segement. +;-----------------------------------------------+ +; Device attribute WORD ; 1 word. +; Bit 15 = 1 for chacter devices. ; +; 0 for Block devices. ; +; ; +; Charcter devices. (Bit 15=1) ; +; Bit 0 = 1 current sti device. ; +; Bit 1 = 1 current sto device. ; +; Bit 2 = 1 current NUL device. ; +; Bit 3 = 1 current Clock device. ; +; ; +; Bit 13 = 1 for non IBM machines. ; +; 0 for IBM machines only. ; +; Bit 14 = 1 IOCTL control bit. ; +;-----------------------------------------------+ +; Device strategy pointer. ; 1 word offset. +;-----------------------------------------------+ +; Device interrupt pointer. ; 1 word offset. +;-----------------------------------------------+ +; Device name field. ; 8 bytes. +; Character devices are any valid name ; +; left justified, in a space filled ; +; field. ; +; Block devices contain # of units in ; +; the first byte. ; +;-----------------------------------------------+ + +DSKDEV: ;Header for hard disk driver. + DW -1,-1 ;Last device + DW 2000H ;Is a block device + DW STRATEGY + DW DSK_INT +MEMMAX DB 1 ;Number of Units + + PAGE + SUBTTL Dispatch tables for each device. + +DSK_TBL:DW DSK_INI ;0 - Initialize Driver. + DW MEDIAC ;1 - Return current media code. + DW GET_BPB ;2 - Get Bios Parameter Block. + DW CMDERR ;3 - Reserved. (currently returns error) + DW DSK_RED ;4 - Block read. + DW BUS_EXIT ;5 - (Not used, return busy flag) + DW EXIT ;6 - Return status. (Not used) + DW EXIT ;7 - Flush input buffer. (Not used.) + DW DSK_WRT ;8 - Block write. + DW DSK_WRV ;9 - Block write with verify. + DW EXIT ;10 - Return output status. + DW EXIT ;11 - Flush output buffer. (Not used.) + DW EXIT ;12 - IO Control. + + PAGE + SUBTTL Strategy and Software Interrupt routines. + +;Define offsets for io data packet + +IODAT STRUC +CMDLEN DB ? ;LENGTH OF THIS COMMAND +UNIT DB ? ;SUB UNIT SPECIFIER +CMD DB ? ;COMMAND CODE +STATUS DW ? ;STATUS + DB 8 DUP (?) +MEDIA DB ? ;MEDIA DESCRIPTOR +TRANS DD ? ;TRANSFER ADDRESS +COUNT DW ? ;COUNT OF BLOCKS OR CHARACTERS +START DW ? ;FIRST BLOCK TO TRANSFER +IODAT ENDS + +PTRSAV DD 0 ;Strategy pointer save. + +; +; Simplistic Strategy routine for non-multi-Tasking system. +; +; Currently just saves I/O packet pointers in PTRSAV for +; later processing by the individual interrupt routines. +; + +STRATP PROC FAR + +STRATEGY: + MOV WORD PTR CS:[PTRSAV],BX + MOV WORD PTR CS:[PTRSAV+2],ES + RET + +STRATP ENDP + + +; +; Ram memory driver interrupt routine for processing I/O packets. +; + +DSK_INT: + PUSH SI ;Save SI from caller. + MOV SI,OFFSET DSK_TBL + +; +; Common program for handling the simplistic I/O packet +; processing scheme in MSDOS 2.0 +; + +ENTRY: PUSH AX ;Save all nessacary registers. + PUSH CX + PUSH DX + PUSH DI + PUSH BP + PUSH DS + PUSH ES + PUSH BX + + LDS BX,CS:[PTRSAV] ;Retrieve pointer to I/O Packet. + + MOV AL,[BX.UNIT] ;AL = Unit code. + MOV AH,[BX.MEDIA] ;AH = Media descriptor. + MOV CX,[BX.COUNT] ;CX = Contains byte/sector count. + MOV DX,[BX.START] ;DX = Starting Logical sector. + XCHG DI,AX ;Save Unit and Media Temporarily. + MOV AL,[BX.CMD] ;Retrieve Command type. (1 => 11) + XOR AH,AH ;Clear upper half of AX for calculation. + ADD SI,AX ;Compute entry pointer in dispatch table. + ADD SI,AX + CMP AL,11 ;Verify that not more than 11 commands. + JA CMDERR ;Ah, well, error out. + XCHG AX,DI + LES DI,[BX.TRANS] ;DI contains addess of Transfer address. + ;ES contains segment. + PUSH CS + POP DS ;Data segment same as Code segment. + JMP [SI] ;Perform I/O packet command. + + PAGE + SUBTTL Common error and exit points. + +BUS_EXIT: ;Device busy exit. + MOV AH,00000011B ;Set busy and done bits. + JMP SHORT EXIT1 + +CMDERR: MOV AL,3 ;Set unknown command error #. + +; +; Common error processing routine. +; AL contains actual error code. +; +; Error # 0 = Write Protect violation. +; 1 = Unkown unit. +; 2 = Drive not ready. +; 3 = Unknown command in I/O packet. +; 4 = CRC error. +; 5 = Bad drive request structure length. +; 6 = Seek error. +; 7 = Unknown media discovered. +; 8 = Sector not found. +; 9 = Printer out of paper. +; 10 = Write fault. +; 11 = Read fault. +; 12 = General failure. +; + +ERR_EXIT: + MOV AH,10000001B ;Set error and done bits. + STC ;Set carry bit also. + JMP SHORT EXIT1 ;Quick way out. + +EXITP PROC FAR ;Normal exit for device drivers. + +EXIT: MOV AH,00000001B ;Set done bit for MSDOS. +EXIT1: LDS BX,CS:[PTRSAV] + MOV [BX.STATUS],AX ;Save operation compete and status. + + POP BX ;Restore registers. + POP ES + POP DS + POP BP + POP DI + POP DX + POP CX + POP AX + POP SI + RET ;RESTORE REGS AND RETURN +EXITP ENDP + + PAGE + + subttl Hard Disk drive control. + +; +; Read command = 09 hex. +; Write command = 02 hex. +; Seek command = 10 hex. +; Recal command = 20 hex. +; Rezero command = 40 hex. +; Reset command = 80 hex. +; +; Busy = 01 hex. +; Operation Complete = 02 hex. +; Bad Sector = 04 hex. +; Record Not found = 08 hex. +; CRC error = 10 hex. +; (not used) = 20 hex. +; Write fault = 40 hex. +; Drive Ready = 80 hex. +; + +hd_read equ 09h +hd_writ equ 02h +hd_wmsk equ 5dh +hd_rmsk equ 9ch + page + + SUBTTL Altos monitor ram and 8089 IOPB structures. + +; +; Structure to reference 8089 and ROM command table. +; + +SIOPB STRUC + DB 4 DUP (?) ;Monitor Use Only +OPCODE DB ? ;I/O operation code. +DRIVE DB ? ;Logical drive spec. +TRACK DW ? ;Logical track number. +HEAD DB ? ;Logical head number. +SECTOR DB ? ;Logical sector to start with. +SCOUNT DB ? ;Number of logical sectors in buffer. +RETCODE DB ? ;Error code after masking. +RETMASK DB ? ;Error mask. +RETRIES DB ? ;Number of retries before error exit. +DMAOFF DW ? ;Buffer offset address. +DMASEG DW ? ;Buffer segment. +SECLENG DW ? ;Sector Length. + DB 6 DUP (?) ;8089 use only. +SIOPB ENDS + +IOPB SIOPB <,0,0,0,0,0,0,0,0,0,0,0,0,> + + PAGE + SUBTTL Common Drive parameter block definitions on Altos. + +DBP STRUC + +JMPNEAR DB 3 DUP (?) ;Jmp Near xxxx for boot. +NAMEVER DB 8 DUP (?) ;Name / Version of OS. + +;------- Start of Drive Parameter Block. + +SECSIZE DW ? ;Sector size in bytes. (dpb) +ALLOC DB ? ;Number of sectors per alloc. block. (dpb) +RESSEC DW ? ;Reserved sectors. (dpb) +FATS DB ? ;Number of FAT's. (dpb) +MAXDIR DW ? ;Number of root directory entries. (dpb) +SECTORS DW ? ;Number of sectors per diskette. (dpb) +MEDIAID DB ? ;Media byte ID. (dpb) +FATSEC DW ? ;Number of FAT Sectors. (dpb) + +;------- End of Drive Parameter Block. + +SECTRK DW ? ;Number of Sectors per track. +HEADS DW ? ;Number of heads per cylinder. +HIDDEN DW ? ;Number of hidden sectors. + +DBP ENDS + +HDDRIVE DBP <,,512,4,0,2,256,4000,0F5H,3,12,4,0> + + +INI_TAB DW OFFSET HDDRIVE.SECSIZE + + PAGE + SUBTTL Media check routine + +; +; Media check routine. +; On entry: +; AL = memory driver unit number. +; AH = media byte +; On exit: +; +; [MEDIA FLAG] = -1 (FF hex) if disk is changed. +; [MEDIA FLAG] = 0 if don't know. +; [MEDIA FLAG] = 1 if not changed. +; + +MEDIAC: LDS BX,CS:[PTRSAV] + MOV BYTE PTR [BX.TRANS],1 + JMP EXIT + + PAGE + SUBTTL Build and return Bios Parameter Block for a diskette. + +; +; Build Bios Parameter Blocks. +; +; On entry: ES:BX contains the address of a scratch sector buffer. +; AL = Unit number. +; AH = Current media byte. +; +; On exit: Return a DWORD pointer to the associated BPB +; in the Request packet. +; + +GET_BPB: + MOV SI,OFFSET HDDRIVE+11 + LDS BX,CS:[PTRSAV] + MOV WORD PTR [BX.COUNT],SI + MOV WORD PTR [BX.COUNT+2],CS + JMP EXIT + + PAGE + SUBTTL MSDOS 2.x Disk I/O drivers. + +; +; Disk READ/WRITE functions. +; +; On entry: +; AL = Disk I/O driver number +; AH = Media byte. +; ES = Disk transfer segment. +; DI = Disk transfer offset in ES. +; CX = Number of sectors to transfer +; DX = Logical starting sector. +; +; On exit: +; Normal exit through common exit routine. +; +; Abnormal exit through common error routine. +; + +DSK_RED: + MOV AH,HD_READ + JMP SHORT DSK_COM +DSK_WRV: +DSK_WRT: + MOV AH,HD_WRIT +DSK_COM: + MOV SI,OFFSET HDDRIVE ;Keeps code size down. + MOV [IOPB.DMASEG],ES + MOV [IOPB.DMAOFF],DI + MOV DI,[SI.SECSIZE] + MOV [IOPB.SECLENG],DI + MOV [IOPB.RETRIES],1 + MOV [IOPB.RETMASK],05DH ;Error return mask. + MOV [IOPB.OPCODE],AH + MOV [IOPB.DRIVE],4 ;Drive 4 is only available. + ADD DX,[SI.HIDDEN] ;Account for invisible sectors. + MOV BP,CX ;Save number of sectors to R/W +DSK_IO1: + PUSH DX ;Save starting sector. + MOV AX,DX + MOV DX,0 ;32 bit divide coming up. + MOV CX,[SI.SECTRK] + DIV CX ;Get track+head and start sector. + MOV [IOPB.SECTOR],DL ;Starting sector. + MOV BL,DL ;Save starting sector for later. + MOV DX,0 + MOV CX,[SI.HEADS] + DIV CX ;Compute head we are on. + MOV [IOPB.HEAD],DL + MOV [IOPB.TRACK],AX ;Track to read/write. + MOV AX,[SI.SECTRK] ;Now see how many sectors + INC AL ; we can burst read. + SUB AL,BL ;BL is the starting sector. + MOV AH,0 + POP DX ;Retrieve logical sector start. + CMP AX,BP ;See if on last partial track+head. + JG DSK_IO2 ;Yes, on last track+head. + SUB BP,AX ;No, update number of sectors left. + ADD DX,AX ;Update next starting sector. + JMP SHORT DSK_IO3 +DSK_IO2:MOV AX,BP ;Only read enough of sector + MOV BP,0 ;to finish buffer and clear # left. +DSK_IO3:MOV [IOPB.SCOUNT],AL + MOV DI,AX ;Save number sectors for later. + MOV BX,ROM_DISKIO + MOV CX,OFFSET IOPB + PUSH CS + POP ES + CALL ROM_CALL ;Do disk operation. + MOV AL,[IOPB.RETCODE] ;Get error code. + OR AL,AL + JNZ DERROR + MOV AX,DI ;Retrieve number of sectors read. + MOV CX,[SI.SECSIZE] ;Number of bytes per sector. + PUSH DX + MUL CX + POP DX + TEST AL,0FH ;Make sure no strange sizes. + JNZ SERR1 + MOV CL,4 + SHR AX,CL ;Convert number of bytes to para. + ADD AX,[IOPB.DMASEG] + MOV [IOPB.DMASEG],AX + OR BP,BP + JNZ DSK_IO1 ;Still more to do. + MOV AL,0 + JMP EXIT ;All done. +SERR1: MOV AL,12 + JMP ERR_EXIT + + PAGE + SUBTTL Disk Error processing. + +; +; Disk error routine. +; + +DERROR: + LDS BX,CS:[PTRSAV] + MOV [BX.COUNT],0 + PUSH CS + POP DS + + MOV BL,-1 + MOV AH,AL + MOV BH,14 ;Lenght of table. + MOV SI,OFFSET DERRTAB +DERROR2:INC BL ;Increment to next error code. + LODS BYTE PTR CS:[SI] + CMP AH,AL ;See if error code matches disk status. + JZ DERROR3 ;Got the right error, exit. + DEC BH + JNZ DERROR2 ;Keep checking table. + MOV BL,12 ;Set general type of error. +DERROR3:MOV AL,BL ;Now we've got the code. + JMP ERR_EXIT + +DERRTAB DB 00H ; 0. Write protect error + DB 00H ; 1. Unknown unit. + DB 00H ; 2. Not ready error. + DB 00H ; 3. Unknown command. + DB 10H ; 4. CRC error + DB 00H ; 5. Bad drive request. + DB 00H ; 6. Seek error + DB 00H ; 7. Unknown media. + DB 08H ; 8. Sector not found + DB 00H ; 9. (Not used.) + DB 40H ;10. Write fault. + DB 04H ;11. Read fault. + DB 01H ;12. General type of failure. + + PAGE + SUBTTL Common ROM call routine. + +; +; Save all registers except CX, BX and AX. + +ROMRTN DD 0FE000000H ;Main ROM entry point. + +ROM_CALL: + PUSH DI + PUSH SI + PUSH BP + PUSH DX + PUSH ES + CALL CS:DWORD PTR [ROMRTN] + POP ES + POP DX + POP BP + POP SI + POP DI + RET + + + PAGE + SUBTTL Hard Disk Drive initalization routine. + +DSK_INI: + LDS BX,CS:[PTRSAV] + MOV BYTE PTR [BX.MEDIA],1 + MOV WORD PTR [BX.TRANS],OFFSET DSK_INI + MOV WORD PTR [BX.TRANS+2],CS + MOV WORD PTR [BX.COUNT],OFFSET INI_TAB + MOV WORD PTR [BX.COUNT+2],CS + JMP EXIT + +CODE ENDS + + END +  \ No newline at end of file -- cgit v1.2.3