1 TITLE HRDDRV
.SYS for the ALTOS ACS
-86C
.
3 ; Hard Disk Drive for Version 2.x of MSDOS.
5 ; Constants for commands in Altos ROM.
7 ROM_CONSTA EQU
01 ;Return status AL of console selected in CX.
8 ROM_CONIN EQU
02 ;Get char. from console in CX to AL
9 ROM_CONOUT EQU
03 ;Write char. in DL to console in CX.
10 ROM_PMSG EQU
07 ;Write string ES:DX to console in CX.
11 ROM_DISKIO EQU
08 ;Perform disk I/O from IOPB in ES:CX.
12 ROM_INIT EQU
10 ;Returns boot console and top memory ES:DX.
16 ASSUME
CS:CODE,DS:CODE,ES:CODE,SS:CODE
18 ORG 0 ;Starts at an offset of zero.
21 SUBTTL Device driver tables
.
23 ;-----------------------------------------------+
24 ; DWORD pointer to next device | 1 word offset.
25 ; (-1,-1 if last device) | 1 word segement.
26 ;-----------------------------------------------+
27 ; Device attribute WORD ; 1 word.
28 ; Bit 15 = 1 for chacter devices. ;
29 ; 0 for Block devices. ;
31 ; Charcter devices. (Bit 15=1) ;
32 ; Bit 0 = 1 current sti device. ;
33 ; Bit 1 = 1 current sto device. ;
34 ; Bit 2 = 1 current NUL device. ;
35 ; Bit 3 = 1 current Clock device. ;
37 ; Bit 13 = 1 for non IBM machines. ;
38 ; 0 for IBM machines only. ;
39 ; Bit 14 = 1 IOCTL control bit. ;
40 ;-----------------------------------------------+
41 ; Device strategy pointer. ; 1 word offset.
42 ;-----------------------------------------------+
43 ; Device interrupt pointer. ; 1 word offset.
44 ;-----------------------------------------------+
45 ; Device name field. ; 8 bytes.
46 ; Character devices are any valid name ;
47 ; left justified, in a space filled ;
49 ; Block devices contain # of units in ;
51 ;-----------------------------------------------+
53 DSKDEV: ;Header for hard disk driver.
55 DW 2000H
;Is a block device
58 MEMMAX
DB 1 ;Number of Units
61 SUBTTL Dispatch tables for each device
.
63 DSK_TBL:DW DSK_INI
;0 - Initialize Driver.
64 DW MEDIAC
;1 - Return current media code.
65 DW GET_BPB
;2 - Get Bios Parameter Block.
66 DW CMDERR
;3 - Reserved. (currently returns error)
67 DW DSK_RED
;4 - Block read.
68 DW BUS_EXIT
;5 - (Not used, return busy flag)
69 DW EXIT
;6 - Return status. (Not used)
70 DW EXIT
;7 - Flush input buffer. (Not used.)
71 DW DSK_WRT
;8 - Block write.
72 DW DSK_WRV
;9 - Block write with verify.
73 DW EXIT
;10 - Return output status.
74 DW EXIT
;11 - Flush output buffer. (Not used.)
75 DW EXIT
;12 - IO Control.
78 SUBTTL Strategy
and Software Interrupt routines
.
80 ;Define offsets for io data packet
83 CMDLEN
DB ?
;LENGTH OF THIS COMMAND
84 UNIT
DB ?
;SUB UNIT SPECIFIER
85 CMD
DB ?
;COMMAND CODE
88 MEDIA
DB ?
;MEDIA DESCRIPTOR
89 TRANS
DD ?
;TRANSFER ADDRESS
90 COUNT
DW ?
;COUNT OF BLOCKS OR CHARACTERS
91 START
DW ?
;FIRST BLOCK TO TRANSFER
94 PTRSAV
DD 0 ;Strategy pointer save.
97 ; Simplistic Strategy routine for non-multi-Tasking system.
99 ; Currently just saves I/O packet pointers in PTRSAV for
100 ; later processing by the individual interrupt routines.
106 MOV WORD PTR CS:[PTRSAV
],BX
107 MOV WORD PTR CS:[PTRSAV
+2],ES
114 ; Ram memory driver interrupt routine for processing I/O packets.
118 PUSH SI ;Save SI from caller.
119 MOV SI,OFFSET DSK_TBL
122 ; Common program for handling the simplistic I/O packet
123 ; processing scheme in MSDOS 2.0
126 ENTRY: PUSH AX ;Save all nessacary registers.
135 LDS BX,CS:[PTRSAV
] ;Retrieve pointer to I/O Packet.
137 MOV AL,[BX.UNIT
] ;AL = Unit code.
138 MOV AH,[BX.MEDIA
] ;AH = Media descriptor.
139 MOV CX,[BX.COUNT
] ;CX = Contains byte/sector count.
140 MOV DX,[BX.START
] ;DX = Starting Logical sector.
141 XCHG DI,AX ;Save Unit and Media Temporarily.
142 MOV AL,[BX.CMD
] ;Retrieve Command type. (1 => 11)
143 XOR AH,AH ;Clear upper half of AX for calculation.
144 ADD SI,AX ;Compute entry pointer in dispatch table.
146 CMP AL,11 ;Verify that not more than 11 commands.
147 JA CMDERR
;Ah, well, error out.
149 LES DI,[BX.TRANS
] ;DI contains addess of Transfer address.
150 ;ES contains segment.
152 POP DS ;Data segment same as Code segment.
153 JMP [SI] ;Perform I/O packet command.
156 SUBTTL
Common error
and exit points
.
158 BUS_EXIT: ;Device busy exit.
159 MOV AH,00000011B ;Set busy and done bits.
162 CMDERR: MOV AL,3 ;Set unknown command error #.
165 ; Common error processing routine.
166 ; AL contains actual error code.
168 ; Error # 0 = Write Protect violation.
170 ; 2 = Drive not ready.
171 ; 3 = Unknown command in I/O packet.
173 ; 5 = Bad drive request structure length.
175 ; 7 = Unknown media discovered.
176 ; 8 = Sector not found.
177 ; 9 = Printer out of paper.
180 ; 12 = General failure.
184 MOV AH,10000001B ;Set error and done bits.
185 STC ;Set carry bit also.
186 JMP SHORT EXIT1
;Quick way out.
188 EXITP PROC
FAR ;Normal exit for device drivers.
190 EXIT: MOV AH,00000001B ;Set done bit for MSDOS.
191 EXIT1: LDS BX,CS:[PTRSAV
]
192 MOV [BX.STATUS
],AX ;Save operation compete and status.
194 POP BX ;Restore registers.
203 RET ;RESTORE REGS AND RETURN
208 subttl Hard Disk drive control
.
211 ; Read command = 09 hex.
212 ; Write command = 02 hex.
213 ; Seek command = 10 hex.
214 ; Recal command = 20 hex.
215 ; Rezero command = 40 hex.
216 ; Reset command = 80 hex.
219 ; Operation Complete = 02 hex.
220 ; Bad Sector = 04 hex.
221 ; Record Not found = 08 hex.
222 ; CRC error = 10 hex.
223 ; (not used) = 20 hex.
224 ; Write fault = 40 hex.
225 ; Drive Ready = 80 hex.
234 SUBTTL Altos
monitor ram
and 8089 IOPB structures
.
237 ; Structure to reference 8089 and ROM command table.
241 DB 4 DUP (?
) ;Monitor Use Only
242 OPCODE
DB ?
;I/O operation code.
243 DRIVE
DB ?
;Logical drive spec.
244 TRACK
DW ?
;Logical track number.
245 HEAD
DB ?
;Logical head number.
246 SECTOR
DB ?
;Logical sector to start with.
247 SCOUNT
DB ?
;Number of logical sectors in buffer.
248 RETCODE
DB ?
;Error code after masking.
249 RETMASK
DB ?
;Error mask.
250 RETRIES
DB ?
;Number of retries before error exit.
251 DMAOFF
DW ?
;Buffer offset address.
252 DMASEG
DW ?
;Buffer segment.
253 SECLENG
DW ?
;Sector Length.
254 DB 6 DUP (?
) ;8089 use only.
257 IOPB SIOPB
<,0,0,0,0,0,0,0,0,0,0,0,0,>
260 SUBTTL
Common Drive parameter block definitions
on Altos
.
264 JMPNEAR
DB 3 DUP (?
) ;Jmp Near xxxx for boot.
265 NAMEVER
DB 8 DUP (?
) ;Name / Version of OS.
267 ;------- Start of Drive Parameter Block.
269 SECSIZE
DW ?
;Sector size in bytes. (dpb)
270 ALLOC
DB ?
;Number of sectors per alloc. block. (dpb)
271 RESSEC
DW ?
;Reserved sectors. (dpb)
272 FATS
DB ?
;Number of FAT's. (dpb)
273 MAXDIR
DW ?
;Number of root directory entries. (dpb)
274 SECTORS
DW ?
;Number of sectors per diskette. (dpb)
275 MEDIAID
DB ?
;Media byte ID. (dpb)
276 FATSEC
DW ?
;Number of FAT Sectors. (dpb)
278 ;------- End of Drive Parameter Block.
280 SECTRK
DW ?
;Number of Sectors per track.
281 HEADS
DW ?
;Number of heads per cylinder.
282 HIDDEN
DW ?
;Number of hidden sectors.
286 HDDRIVE DBP
<,,512,4,0,2,256,4000,0F5H,3,12,4,0>
289 INI_TAB
DW OFFSET HDDRIVE
.SECSIZE
292 SUBTTL Media check routine
295 ; Media check routine.
297 ; AL = memory driver unit number.
301 ; [MEDIA FLAG] = -1 (FF hex) if disk is changed.
302 ; [MEDIA FLAG] = 0 if don't know.
303 ; [MEDIA FLAG] = 1 if not changed.
306 MEDIAC: LDS BX,CS:[PTRSAV
]
307 MOV BYTE PTR [BX.TRANS
],1
311 SUBTTL Build
and return Bios Parameter Block for a diskette
.
314 ; Build Bios Parameter Blocks.
316 ; On entry: ES:BX contains the address of a scratch sector buffer.
318 ; AH = Current media byte.
320 ; On exit: Return a DWORD pointer to the associated BPB
321 ; in the Request packet.
325 MOV SI,OFFSET HDDRIVE
+11
327 MOV WORD PTR [BX.COUNT
],SI
328 MOV WORD PTR [BX.COUNT
+2],CS
332 SUBTTL MSDOS
2.x Disk I
/O drivers
.
335 ; Disk READ/WRITE functions.
338 ; AL = Disk I/O driver number
340 ; ES = Disk transfer segment.
341 ; DI = Disk transfer offset in ES.
342 ; CX = Number of sectors to transfer
343 ; DX = Logical starting sector.
346 ; Normal exit through common exit routine.
348 ; Abnormal exit through common error routine.
358 MOV SI,OFFSET HDDRIVE
;Keeps code size down.
362 MOV [IOPB
.SECLENG
],DI
364 MOV [IOPB
.RETMASK
],05DH ;Error return mask.
366 MOV [IOPB
.DRIVE
],4 ;Drive 4 is only available.
367 ADD DX,[SI.HIDDEN
] ;Account for invisible sectors.
368 MOV BP,CX ;Save number of sectors to R/W
370 PUSH DX ;Save starting sector.
372 MOV DX,0 ;32 bit divide coming up.
374 DIV CX ;Get track+head and start sector.
375 MOV [IOPB
.SECTOR
],DL ;Starting sector.
376 MOV BL,DL ;Save starting sector for later.
379 DIV CX ;Compute head we are on.
381 MOV [IOPB
.TRACK
],AX ;Track to read/write.
382 MOV AX,[SI.SECTRK
] ;Now see how many sectors
383 INC AL ; we can burst read.
384 SUB AL,BL ;BL is the starting sector.
386 POP DX ;Retrieve logical sector start.
387 CMP AX,BP ;See if on last partial track+head.
388 JG DSK_IO2
;Yes, on last track+head.
389 SUB BP,AX ;No, update number of sectors left.
390 ADD DX,AX ;Update next starting sector.
392 DSK_IO2:MOV AX,BP ;Only read enough of sector
393 MOV BP,0 ;to finish buffer and clear # left.
394 DSK_IO3:MOV [IOPB
.SCOUNT
],AL
395 MOV DI,AX ;Save number sectors for later.
400 CALL ROM_CALL
;Do disk operation.
401 MOV AL,[IOPB
.RETCODE
] ;Get error code.
404 MOV AX,DI ;Retrieve number of sectors read.
405 MOV CX,[SI.SECSIZE
] ;Number of bytes per sector.
409 TEST AL,0FH ;Make sure no strange sizes.
412 SHR AX,CL ;Convert number of bytes to para.
416 JNZ DSK_IO1
;Still more to do.
423 SUBTTL Disk Error processing
.
426 ; Disk error routine.
437 MOV BH,14 ;Lenght of table.
438 MOV SI,OFFSET DERRTAB
439 DERROR2:INC BL ;Increment to next error code.
440 LODS BYTE PTR CS:[SI]
441 CMP AH,AL ;See if error code matches disk status.
442 JZ DERROR3
;Got the right error, exit.
444 JNZ DERROR2
;Keep checking table.
445 MOV BL,12 ;Set general type of error.
446 DERROR3:MOV AL,BL ;Now we've got the code.
449 DERRTAB
DB 00H ; 0. Write protect error
450 DB 00H ; 1. Unknown unit.
451 DB 00H ; 2. Not ready error.
452 DB 00H ; 3. Unknown command.
453 DB 10H
; 4. CRC error
454 DB 00H ; 5. Bad drive request.
455 DB 00H ; 6. Seek error
456 DB 00H ; 7. Unknown media.
457 DB 08H ; 8. Sector not found
458 DB 00H ; 9. (Not used.)
459 DB 40H
;10. Write fault.
460 DB 04H ;11. Read fault.
461 DB 01H ;12. General type of failure.
464 SUBTTL
Common ROM
call routine
.
467 ; Save all registers except CX, BX and AX.
469 ROMRTN
DD 0FE000000H ;Main ROM entry point.
477 CALL CS:DWORD PTR [ROMRTN
]
487 SUBTTL Hard Disk Drive initalization routine
.
491 MOV BYTE PTR [BX.MEDIA
],1
492 MOV WORD PTR [BX.TRANS
],OFFSET DSK_INI
493 MOV WORD PTR [BX.TRANS
+2],CS
494 MOV WORD PTR [BX.COUNT
],OFFSET INI_TAB
495 MOV WORD PTR [BX.COUNT
+2],CS