]> wirehaze git hosting - MS-DOS.git/blob - v2.0/source/HRDDRV.ASM

wirehaze git hosting

Update SECURITY.md
[MS-DOS.git] / v2.0 / source / HRDDRV.ASM
1 TITLE HRDDRV.SYS for the ALTOS ACS-86C.
2
3 ; Hard Disk Drive for Version 2.x of MSDOS.
4
5 ; Constants for commands in Altos ROM.
6
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.
13
14
15 CODE SEGMENT
16 ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE
17
18 ORG 0 ;Starts at an offset of zero.
19
20 PAGE
21 SUBTTL Device driver tables.
22
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. ;
30 ; ;
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. ;
36 ; ;
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 ;
48 ; field. ;
49 ; Block devices contain # of units in ;
50 ; the first byte. ;
51 ;-----------------------------------------------+
52
53 DSKDEV: ;Header for hard disk driver.
54 DW -1,-1 ;Last device
55 DW 2000H ;Is a block device
56 DW STRATEGY
57 DW DSK_INT
58 MEMMAX DB 1 ;Number of Units
59
60 PAGE
61 SUBTTL Dispatch tables for each device.
62
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.
76
77 PAGE
78 SUBTTL Strategy and Software Interrupt routines.
79
80 ;Define offsets for io data packet
81
82 IODAT STRUC
83 CMDLEN DB ? ;LENGTH OF THIS COMMAND
84 UNIT DB ? ;SUB UNIT SPECIFIER
85 CMD DB ? ;COMMAND CODE
86 STATUS DW ? ;STATUS
87 DB 8 DUP (?)
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
92 IODAT ENDS
93
94 PTRSAV DD 0 ;Strategy pointer save.
95
96 ;
97 ; Simplistic Strategy routine for non-multi-Tasking system.
98 ;
99 ; Currently just saves I/O packet pointers in PTRSAV for
100 ; later processing by the individual interrupt routines.
101 ;
102
103 STRATP PROC FAR
104
105 STRATEGY:
106 MOV WORD PTR CS:[PTRSAV],BX
107 MOV WORD PTR CS:[PTRSAV+2],ES
108 RET
109
110 STRATP ENDP
111
112
113 ;
114 ; Ram memory driver interrupt routine for processing I/O packets.
115 ;
116
117 DSK_INT:
118 PUSH SI ;Save SI from caller.
119 MOV SI,OFFSET DSK_TBL
120
121 ;
122 ; Common program for handling the simplistic I/O packet
123 ; processing scheme in MSDOS 2.0
124 ;
125
126 ENTRY: PUSH AX ;Save all nessacary registers.
127 PUSH CX
128 PUSH DX
129 PUSH DI
130 PUSH BP
131 PUSH DS
132 PUSH ES
133 PUSH BX
134
135 LDS BX,CS:[PTRSAV] ;Retrieve pointer to I/O Packet.
136
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.
145 ADD SI,AX
146 CMP AL,11 ;Verify that not more than 11 commands.
147 JA CMDERR ;Ah, well, error out.
148 XCHG AX,DI
149 LES DI,[BX.TRANS] ;DI contains addess of Transfer address.
150 ;ES contains segment.
151 PUSH CS
152 POP DS ;Data segment same as Code segment.
153 JMP [SI] ;Perform I/O packet command.
154
155 PAGE
156 SUBTTL Common error and exit points.
157
158 BUS_EXIT: ;Device busy exit.
159 MOV AH,00000011B ;Set busy and done bits.
160 JMP SHORT EXIT1
161
162 CMDERR: MOV AL,3 ;Set unknown command error #.
163
164 ;
165 ; Common error processing routine.
166 ; AL contains actual error code.
167 ;
168 ; Error # 0 = Write Protect violation.
169 ; 1 = Unkown unit.
170 ; 2 = Drive not ready.
171 ; 3 = Unknown command in I/O packet.
172 ; 4 = CRC error.
173 ; 5 = Bad drive request structure length.
174 ; 6 = Seek error.
175 ; 7 = Unknown media discovered.
176 ; 8 = Sector not found.
177 ; 9 = Printer out of paper.
178 ; 10 = Write fault.
179 ; 11 = Read fault.
180 ; 12 = General failure.
181 ;
182
183 ERR_EXIT:
184 MOV AH,10000001B ;Set error and done bits.
185 STC ;Set carry bit also.
186 JMP SHORT EXIT1 ;Quick way out.
187
188 EXITP PROC FAR ;Normal exit for device drivers.
189
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.
193
194 POP BX ;Restore registers.
195 POP ES
196 POP DS
197 POP BP
198 POP DI
199 POP DX
200 POP CX
201 POP AX
202 POP SI
203 RET ;RESTORE REGS AND RETURN
204 EXITP ENDP
205
206 PAGE
207
208 subttl Hard Disk drive control.
209
210 ;
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.
217 ;
218 ; Busy = 01 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.
226 ;
227
228 hd_read equ 09h
229 hd_writ equ 02h
230 hd_wmsk equ 5dh
231 hd_rmsk equ 9ch
232 page
233
234 SUBTTL Altos monitor ram and 8089 IOPB structures.
235
236 ;
237 ; Structure to reference 8089 and ROM command table.
238 ;
239
240 SIOPB STRUC
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.
255 SIOPB ENDS
256
257 IOPB SIOPB <,0,0,0,0,0,0,0,0,0,0,0,0,>
258
259 PAGE
260 SUBTTL Common Drive parameter block definitions on Altos.
261
262 DBP STRUC
263
264 JMPNEAR DB 3 DUP (?) ;Jmp Near xxxx for boot.
265 NAMEVER DB 8 DUP (?) ;Name / Version of OS.
266
267 ;------- Start of Drive Parameter Block.
268
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)
277
278 ;------- End of Drive Parameter Block.
279
280 SECTRK DW ? ;Number of Sectors per track.
281 HEADS DW ? ;Number of heads per cylinder.
282 HIDDEN DW ? ;Number of hidden sectors.
283
284 DBP ENDS
285
286 HDDRIVE DBP <,,512,4,0,2,256,4000,0F5H,3,12,4,0>
287
288
289 INI_TAB DW OFFSET HDDRIVE.SECSIZE
290
291 PAGE
292 SUBTTL Media check routine
293
294 ;
295 ; Media check routine.
296 ; On entry:
297 ; AL = memory driver unit number.
298 ; AH = media byte
299 ; On exit:
300 ;
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.
304 ;
305
306 MEDIAC: LDS BX,CS:[PTRSAV]
307 MOV BYTE PTR [BX.TRANS],1
308 JMP EXIT
309
310 PAGE
311 SUBTTL Build and return Bios Parameter Block for a diskette.
312
313 ;
314 ; Build Bios Parameter Blocks.
315 ;
316 ; On entry: ES:BX contains the address of a scratch sector buffer.
317 ; AL = Unit number.
318 ; AH = Current media byte.
319 ;
320 ; On exit: Return a DWORD pointer to the associated BPB
321 ; in the Request packet.
322 ;
323
324 GET_BPB:
325 MOV SI,OFFSET HDDRIVE+11
326 LDS BX,CS:[PTRSAV]
327 MOV WORD PTR [BX.COUNT],SI
328 MOV WORD PTR [BX.COUNT+2],CS
329 JMP EXIT
330
331 PAGE
332 SUBTTL MSDOS 2.x Disk I/O drivers.
333
334 ;
335 ; Disk READ/WRITE functions.
336 ;
337 ; On entry:
338 ; AL = Disk I/O driver number
339 ; AH = Media byte.
340 ; ES = Disk transfer segment.
341 ; DI = Disk transfer offset in ES.
342 ; CX = Number of sectors to transfer
343 ; DX = Logical starting sector.
344 ;
345 ; On exit:
346 ; Normal exit through common exit routine.
347 ;
348 ; Abnormal exit through common error routine.
349 ;
350
351 DSK_RED:
352 MOV AH,HD_READ
353 JMP SHORT DSK_COM
354 DSK_WRV:
355 DSK_WRT:
356 MOV AH,HD_WRIT
357 DSK_COM:
358 MOV SI,OFFSET HDDRIVE ;Keeps code size down.
359 MOV [IOPB.DMASEG],ES
360 MOV [IOPB.DMAOFF],DI
361 MOV DI,[SI.SECSIZE]
362 MOV [IOPB.SECLENG],DI
363 MOV [IOPB.RETRIES],1
364 MOV [IOPB.RETMASK],05DH ;Error return mask.
365 MOV [IOPB.OPCODE],AH
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
369 DSK_IO1:
370 PUSH DX ;Save starting sector.
371 MOV AX,DX
372 MOV DX,0 ;32 bit divide coming up.
373 MOV CX,[SI.SECTRK]
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.
377 MOV DX,0
378 MOV CX,[SI.HEADS]
379 DIV CX ;Compute head we are on.
380 MOV [IOPB.HEAD],DL
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.
385 MOV AH,0
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.
391 JMP SHORT DSK_IO3
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.
396 MOV BX,ROM_DISKIO
397 MOV CX,OFFSET IOPB
398 PUSH CS
399 POP ES
400 CALL ROM_CALL ;Do disk operation.
401 MOV AL,[IOPB.RETCODE] ;Get error code.
402 OR AL,AL
403 JNZ DERROR
404 MOV AX,DI ;Retrieve number of sectors read.
405 MOV CX,[SI.SECSIZE] ;Number of bytes per sector.
406 PUSH DX
407 MUL CX
408 POP DX
409 TEST AL,0FH ;Make sure no strange sizes.
410 JNZ SERR1
411 MOV CL,4
412 SHR AX,CL ;Convert number of bytes to para.
413 ADD AX,[IOPB.DMASEG]
414 MOV [IOPB.DMASEG],AX
415 OR BP,BP
416 JNZ DSK_IO1 ;Still more to do.
417 MOV AL,0
418 JMP EXIT ;All done.
419 SERR1: MOV AL,12
420 JMP ERR_EXIT
421
422 PAGE
423 SUBTTL Disk Error processing.
424
425 ;
426 ; Disk error routine.
427 ;
428
429 DERROR:
430 LDS BX,CS:[PTRSAV]
431 MOV [BX.COUNT],0
432 PUSH CS
433 POP DS
434
435 MOV BL,-1
436 MOV AH,AL
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.
443 DEC BH
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.
447 JMP ERR_EXIT
448
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.
462
463 PAGE
464 SUBTTL Common ROM call routine.
465
466 ;
467 ; Save all registers except CX, BX and AX.
468
469 ROMRTN DD 0FE000000H ;Main ROM entry point.
470
471 ROM_CALL:
472 PUSH DI
473 PUSH SI
474 PUSH BP
475 PUSH DX
476 PUSH ES
477 CALL CS:DWORD PTR [ROMRTN]
478 POP ES
479 POP DX
480 POP BP
481 POP SI
482 POP DI
483 RET
484
485
486 PAGE
487 SUBTTL Hard Disk Drive initalization routine.
488
489 DSK_INI:
490 LDS BX,CS:[PTRSAV]
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
496 JMP EXIT
497
498 CODE ENDS
499
500 END
501