summaryrefslogtreecommitdiff
path: root/v2.0/source/HRDDRV.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v2.0/source/HRDDRV.ASM')
-rw-r--r--v2.0/source/HRDDRV.ASM501
1 files changed, 501 insertions, 0 deletions
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 @@
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
7ROM_CONSTA EQU 01 ;Return status AL of console selected in CX.
8ROM_CONIN EQU 02 ;Get char. from console in CX to AL
9ROM_CONOUT EQU 03 ;Write char. in DL to console in CX.
10ROM_PMSG EQU 07 ;Write string ES:DX to console in CX.
11ROM_DISKIO EQU 08 ;Perform disk I/O from IOPB in ES:CX.
12ROM_INIT EQU 10 ;Returns boot console and top memory ES:DX.
13
14
15CODE SEGMENT
16ASSUME 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
53DSKDEV: ;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
58MEMMAX DB 1 ;Number of Units
59
60 PAGE
61 SUBTTL Dispatch tables for each device.
62
63DSK_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
82IODAT STRUC
83CMDLEN DB ? ;LENGTH OF THIS COMMAND
84UNIT DB ? ;SUB UNIT SPECIFIER
85CMD DB ? ;COMMAND CODE
86STATUS DW ? ;STATUS
87 DB 8 DUP (?)
88MEDIA DB ? ;MEDIA DESCRIPTOR
89TRANS DD ? ;TRANSFER ADDRESS
90COUNT DW ? ;COUNT OF BLOCKS OR CHARACTERS
91START DW ? ;FIRST BLOCK TO TRANSFER
92IODAT ENDS
93
94PTRSAV 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
103STRATP PROC FAR
104
105STRATEGY:
106 MOV WORD PTR CS:[PTRSAV],BX
107 MOV WORD PTR CS:[PTRSAV+2],ES
108 RET
109
110STRATP ENDP
111
112
113;
114; Ram memory driver interrupt routine for processing I/O packets.
115;
116
117DSK_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
126ENTRY: 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
158BUS_EXIT: ;Device busy exit.
159 MOV AH,00000011B ;Set busy and done bits.
160 JMP SHORT EXIT1
161
162CMDERR: 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
183ERR_EXIT:
184 MOV AH,10000001B ;Set error and done bits.
185 STC ;Set carry bit also.
186 JMP SHORT EXIT1 ;Quick way out.
187
188EXITP PROC FAR ;Normal exit for device drivers.
189
190EXIT: MOV AH,00000001B ;Set done bit for MSDOS.
191EXIT1: 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
204EXITP 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
228hd_read equ 09h
229hd_writ equ 02h
230hd_wmsk equ 5dh
231hd_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
240SIOPB STRUC
241 DB 4 DUP (?) ;Monitor Use Only
242OPCODE DB ? ;I/O operation code.
243DRIVE DB ? ;Logical drive spec.
244TRACK DW ? ;Logical track number.
245HEAD DB ? ;Logical head number.
246SECTOR DB ? ;Logical sector to start with.
247SCOUNT DB ? ;Number of logical sectors in buffer.
248RETCODE DB ? ;Error code after masking.
249RETMASK DB ? ;Error mask.
250RETRIES DB ? ;Number of retries before error exit.
251DMAOFF DW ? ;Buffer offset address.
252DMASEG DW ? ;Buffer segment.
253SECLENG DW ? ;Sector Length.
254 DB 6 DUP (?) ;8089 use only.
255SIOPB ENDS
256
257IOPB 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
262DBP STRUC
263
264JMPNEAR DB 3 DUP (?) ;Jmp Near xxxx for boot.
265NAMEVER DB 8 DUP (?) ;Name / Version of OS.
266
267;------- Start of Drive Parameter Block.
268
269SECSIZE DW ? ;Sector size in bytes. (dpb)
270ALLOC DB ? ;Number of sectors per alloc. block. (dpb)
271RESSEC DW ? ;Reserved sectors. (dpb)
272FATS DB ? ;Number of FAT's. (dpb)
273MAXDIR DW ? ;Number of root directory entries. (dpb)
274SECTORS DW ? ;Number of sectors per diskette. (dpb)
275MEDIAID DB ? ;Media byte ID. (dpb)
276FATSEC DW ? ;Number of FAT Sectors. (dpb)
277
278;------- End of Drive Parameter Block.
279
280SECTRK DW ? ;Number of Sectors per track.
281HEADS DW ? ;Number of heads per cylinder.
282HIDDEN DW ? ;Number of hidden sectors.
283
284DBP ENDS
285
286HDDRIVE DBP <,,512,4,0,2,256,4000,0F5H,3,12,4,0>
287
288
289INI_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
306MEDIAC: 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
324GET_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
351DSK_RED:
352 MOV AH,HD_READ
353 JMP SHORT DSK_COM
354DSK_WRV:
355DSK_WRT:
356 MOV AH,HD_WRIT
357DSK_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
369DSK_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
392DSK_IO2:MOV AX,BP ;Only read enough of sector
393 MOV BP,0 ;to finish buffer and clear # left.
394DSK_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.
419SERR1: MOV AL,12
420 JMP ERR_EXIT
421
422 PAGE
423 SUBTTL Disk Error processing.
424
425;
426; Disk error routine.
427;
428
429DERROR:
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
439DERROR2: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.
446DERROR3:MOV AL,BL ;Now we've got the code.
447 JMP ERR_EXIT
448
449DERRTAB 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
469ROMRTN DD 0FE000000H ;Main ROM entry point.
470
471ROM_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
489DSK_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
498CODE ENDS
499
500 END
501