summaryrefslogtreecommitdiff
path: root/v4.0/src/BIOS/MSIOCTL.INC
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/BIOS/MSIOCTL.INC')
-rw-r--r--v4.0/src/BIOS/MSIOCTL.INC1362
1 files changed, 1362 insertions, 0 deletions
diff --git a/v4.0/src/BIOS/MSIOCTL.INC b/v4.0/src/BIOS/MSIOCTL.INC
new file mode 100644
index 0000000..9967605
--- /dev/null
+++ b/v4.0/src/BIOS/MSIOCTL.INC
@@ -0,0 +1,1362 @@
1 %OUT MSIOCTL.SIL...
2 INCLUDE IOCTL.INC
3; $SALUT $ioctl$
4
5;==============================================================================
6;REVISION HISTORY:
7;AN000 - New for DOS Version 4.00 - J.K.
8;AC000 - Changed for DOS Version 4.00 - J.K.
9;AN00x - PTM number for DOS Version 4.00 - J.K.
10;==============================================================================
11;AN001 - P58 Diskcopy format fails when error occurs during format op.6/26/87 J.K.
12;AN002; - d24 MultiTrack= command added. 6/29/87 J.K.
13;AN003; - p155 Format intermittant failre due to haed settle time 8/18/87 J.K.
14;AN004; D113 Disable I/O access to unformatted media 9/03/87 J.K.
15;AN005; P985 Allow I/O access to unformtted media 9/14/87 J.K.
16;AN006; D241 Provide support of Multi-track Format/Verify 9/23/87 J.K.
17;AN007; P1535 Unformatted hard file problem 10/15/87 J.K.
18;AN008; P2590 Change the recommended BPB info. after AFS format 11/20/87 J.K.
19;AN009; P2828 Do not retry for multi-track format request 12/08/87 J.K.
20;AN010; P2781 Changeline error behavior incompatibile with DOS 3.3. 1/06/88 J.K.
21;AN011; P3178 Set Media ID should update media info in BDS table. 1/21/88 J.K.
22;AN012; D490 IOCTL subfunction 63h,43h,64h,44h conflicts with OS2 2/26/88 J.K.
23;==============================================================================
24
25;J.K. 10/15/87
26;NOTE: GetAccessFlag/SetAccessFlag is unpublished function.
27; This function is intended to give the user to control the
28; BDS table FLAGS of UNFORMATTED_MEDIA bit.
29; GetAccessFlag will show the status -
30; A_DISKACCESS_CONTROL.DAC_ACCESS_FLAG = 0 DISK I/O not allowed
31; 1 DISK I/O allowed
32; SetAccessFlag will Set/Reset the UNFORMATTED_MEDIA bit in FLAGS -
33; A_DISKACCESS_CONTROL.DAC_ACCESS_FLAG = 0 Allow disk I/O
34; 1 Disallow disk I/O
35;------------------------------------------------------------------------------
36
37; GENERIC IOCTL DISPATCH TABLES
38;
39IOREADJUMPTABLE DB 7 ;AN012;maximum number (0 based)
40 DW OFFSET GETDEVICEPARAMETERS ;60h
41 DW OFFSET READTRACK ;61h
42 DW OFFSET VERIFYTRACK ;62h
43 dw Cmd_Err_Proc ;AN012;Overlapped with OS2 subfunction
44 dw Cmd_Err_Proc ;AN012;
45 dw Cmd_Err_Proc ;AN012;
46 dw GetMediaID ;AN000;AN012;66h
47 dw GetAccessFlag ;AN007;AN012;67h Unpublished function
48
49IOWRITEJUMPTABLE DB 7 ;AN012;
50 DW OFFSET SETDEVICEPARAMETERS ;40h
51 DW OFFSET WRITETRACK ;41h
52 DW OFFSET FORMATTRACK ;42h
53 dw Cmd_Err_Proc ;AN012;
54 dw Cmd_Err_Proc ;AN012;
55 dw Cmd_Err_Proc ;AN012;
56 dw SetMediaID ;AN000;AN012;46h
57 dw SetAccessFlag ;AN007;AN012;47h Unpublished function
58;
59; TRACKTABLE CONTAINS A 4-TUPLES (C,H,R,N) FOR EACH SECTOR IN A TRACK
60; C = CYLINDER NUMBER, H = HEAD NUMBER, R = SECTOR ID, N = BYTES PER SECTOR
61; N BYTES PER SECTOR
62; --- ----------------
63; 0 128
64; 1 256
65; 2 512
66; 3 1024
67;
68MAX_SECTORS_CURR_SUP EQU 63 ; CURRENT MAXIMUM SEC/TRK THAT
69 ; WE SUPPORT (Was 40 in DOS 3.2)
70SECTORSPERTRACK DW 36
71TRACKTABLE DB 0,0,1,2
72 DB 0,0,2,2
73 DB 0,0,3,2
74 DB 0,0,4,2
75 DB 0,0,5,2
76 DB 0,0,6,2
77 DB 0,0,7,2
78 DB 0,0,8,2
79 DB 0,0,9,2
80 DB 0,0,10,2
81 DB 0,0,11,2
82 DB 0,0,12,2
83 DB 0,0,13,2
84 DB 0,0,14,2
85 DB 0,0,15,2
86 db 0,0,16,2
87 db 0,0,17,2
88 db 0,0,18,2
89 db 0,0,19,2
90 db 0,0,20,2
91 db 0,0,21,2
92 db 0,0,22,2
93 db 0,0,23,2
94 db 0,0,24,2
95 db 0,0,25,2
96 db 0,0,26,2
97 db 0,0,27,2
98 db 0,0,28,2
99 db 0,0,29,2
100 db 0,0,30,2
101 db 0,0,31,2
102 db 0,0,32,2
103 db 0,0,33,2
104 db 0,0,34,2
105 db 0,0,35,2
106 db 0,0,36,2
107 DB 4*MAX_SECTORS_CURR_SUP - ($ - TRACKTABLE) DUP (0)
108
109; THIS IS A REAL UGLY PLACE TO PUT THIS
110; IT SHOULD REALLY GO IN THE BDS
111MEDIATYPE DB 0
112
113MEDIA_SET_FOR_FORMAT DB 0 ; 1 IF WE HAVE DONE AN INT 13 SET MEDIA
114 ; TYPE FOR FORMAT CALL
115Had_Format_Error db 0 ; 1 if the previous format operation
116 ; failed. - J.K. 7/8/86
117Dsk_time_out_Err equ 80h ; Time out error (No media present).
118Dsk_change_line_Err equ 6h ; Change line error
119Dsk_illegal_combination equ 0Ch ; Return code of ah=18h function.
120
121; TEMP DISK BASE TABLE. IT HOLDS THE THE CURRENT DPT WHICH IS THEN REPLACED BY
122; THE ONE PASSED BY "NEW ROMS" BEFORE WE PERFORM A FORMAT OPERATION. THE OLD
123; DPT IS RESTORED IN RESTOREOLDDPT. THE FIRST ENTRY (DISK_SPECIFY_1) IS -1 IF
124; THIS TABLE DOES NOT CONTAIN THE PREVIOUSLY SAVED DPT.
125TEMPDPT DD -1
126
127;
128; GENERIC$IOCTL:
129; PERFORM GENERIC IOCTL REQUEST
130; INPUT:
131; AL - UNIT NUMBER
132; OUTPUT:
133; IF CARRY SET THEN AL CONTAINS ERROR CODE
134;
135 PUBLIC GENERIC$IOCTL
136GENERIC$IOCTL:
137 MESSAGE FTESTDISK,<"GENERIC IOCTL",CR,LF>
138 LES BX,CS:[PTRSAV] ; ES:BX POINTS TO REQUEST HEADER.
139 CALL SETDRIVE ; DS:DI POINTS TO BDS FOR DRIVE.
140;
141; AT THIS POINT:
142; ES:BX - POINTS TO THE REQUEST HEADER
143; DS:DI POINTS TO THE BDS FOR THE DRIVE
144;
145 CMP ES:[BX].MAJORFUNCTION, RAWIO
146 JNE IOCTL_FUNC_ERR
147 MOV AL, ES:[BX].MINORFUNCTION
148 MOV SI, OFFSET IOREADJUMPTABLE
149 TEST AL, GEN_IOCTL_FN_TST ; TEST OF REQ. FUNCTION
150 JNZ NOTGENERICIOCTLWRITE ; FUNCTION IS A READ.
151 MOV SI, OFFSET IOWRITEJUMPTABLE
152NOTGENERICIOCTLWRITE:
153; AND AL, 0FH
154 and al, 9fH ;AN000; Try to check other than 6x, 4x.
155 CMP AL, CS:[SI]
156 JA IOCTL_FUNC_ERR
157 CBW
158 SHL AX, 1
159 INC SI
160 ADD SI,AX
161 LES BX, ES:[BX].GENERICIOCTL_PACKET
162 CALL CS:[SI]
163 JC FAILGENERIC$IOCTL
164 JMP EXIT
165
166FAILGENERIC$IOCTL:
167 JMP ERR$EXIT
168
169IOCTL_FUNC_ERR:
170 JMP CMDERR
171Cmd_Err_Proc: ;AN012;
172 pop dx ;AN012;clear up stack
173 pop dx ;AN012;clear up stack
174 jmp IOCTL_FUNC_ERR ;AN012;Cmd error
175;
176; GETDEVICEPARAMETERS:
177;
178; INPUT: DS:DI POINTS TO BDS FOR DRIVE
179; ES:BX POINTS TO DEVICE PARAMETER PACKET
180;
181 PUBLIC GETDEVICEPARAMETERS
182GETDEVICEPARAMETERS PROC NEAR
183; COPY INFO FROM BDS TO THE DEVICE PARAMETERS PACKET
184 MOV AL, BYTE PTR DS:[DI].FORMFACTOR
185 MOV BYTE PTR ES:[BX].DP_DEVICETYPE, AL
186 MOV AX, WORD PTR DS:[DI].FLAGS
187 AND AX,FNON_REMOVABLE+FCHANGELINE ; MASK OFF OTHER BITS
188 MOV WORD PTR ES:[BX].DP_DEVICEATTRIBUTES, AX
189 MOV AX, WORD PTR DS:[DI].CCYLN
190 MOV WORD PTR ES:[BX].DP_CYLINDERS, AX
191
192; SET MEDIA TYPE TO DEFAULT
193 XOR AL, AL
194 MOV BYTE PTR ES:[BX].DP_MEDIATYPE, AL
195
196; COPY RECOMMENDED BPB
197 LEA SI, BYTE PTR [DI].RBYTEPERSEC
198 TEST BYTE PTR ES:[BX].DP_SPECIALFUNCTIONS, BUILD_DEVICE_BPB
199 JZ USE_BPB_PRESENT
200; GET THE CORRECT DISK IN THE DRIVE
201 CALL CHECKSINGLE
202; BUILD THE BPB FROM SCRATCH
203 CALL GETBP
204 JC GET_PARM_RET
205 LEA SI,BYTE PTR [DI].BYTEPERSEC
206USE_BPB_PRESENT:
207 LEA DI, BYTE PTR [BX].DP_BPB
208 MOV CX, SIZE BPB_TYPE ; FOR NOW USE 'SMALL' BPB
209 REP MOVSB
210 CLC
211GET_PARM_RET:
212 RET
213GETDEVICEPARAMETERS ENDP
214
215;
216; SETDEVICEPARAMETERS:
217;
218; INPUT: DS:DI POINTS TO BDS FOR DRIVE
219; ES:BX POINTS TO DEVICE PARAMETER PACKET
220;
221 PUBLIC SETDEVICEPARAMETERS
222SETDEVICEPARAMETERS PROC NEAR
223; MAKE SURE THE FCHANGED_BY_FORMAT FLAG GETS SET TO KICK DOS INTO LOOKING AT
224; THE BPB
225 OR WORD PTR DS:[DI].FLAGS, FCHANGED_BY_FORMAT OR FCHANGED
226 TEST BYTE PTR ES:[BX].DP_SPECIALFUNCTIONS, ONLY_SET_TRACKLAYOUT
227 JZ SHORT SETDEVPARM_1
228 JMP SETTRACKTABLE ; ORIGINALLY TRACKLAYOUT
229
230SETDEVPARM_1:
231; COPY INFO FROM THE DEVICE PARAMETERS PACKET TO BDS
232 MOV AL, BYTE PTR ES:[BX].DP_DEVICETYPE
233 MOV BYTE PTR DS:[DI].FORMFACTOR, AL
234
235 MOV AX, WORD PTR ES:[BX].DP_CYLINDERS
236 MOV WORD PTR DS:[DI].CCYLN, AX
237
238; IF CHANGE LINE IS NOT LOADED THEN IGNORE CHANGELING FLAG
239 MOV AX, WORD PTR ES:[BX].DP_DEVICEATTRIBUTES
240 CMP CS:[FHAVE96],0
241 JNZ HAVE_CHANGE
242 AND AX,NOT FCHANGELINE
243HAVE_CHANGE:
244; IGNORE ALL BITS EXCEPT NON_REMOVABLE AND CHANGELINE
245 AND AX,FNON_REMOVABLE OR FCHANGELINE
246 MOV CX, WORD PTR DS:[DI].FLAGS
247; AND CX, NOT (FNON_REMOVABLE OR FCHANGELINE OR GOOD_TRACKLAYOUT)
248 AND CX, NOT (FNON_REMOVABLE OR FCHANGELINE OR GOOD_TRACKLAYOUT or UNFORMATTED_MEDIA) ;AN004;AN005;AN007;
249 OR AX, CX
250 MOV WORD PTR DS:[DI].FLAGS, AX
251
252; SET MEDIA TYPE
253 MOV AL, BYTE PTR ES:[BX].DP_MEDIATYPE
254 MOV CS:MEDIATYPE, AL
255; THE MEDIA CHANGED (MAYBE) SO WE WILL HAVE TO DO A SETDASD THE NEXT TIME
256; WE FORMAT A TRACK
257 OR WORD PTR DS:[DI].FLAGS, SET_DASD_TRUE
258
259 SAVEREG <DS,DI,ES,BX>
260; FIGURE OUT WHAT WE ARE SUPPOSED TO DO WITH THE BPB
261
262; WERE WE ASKED TO INSTALL A FAKE BPB?
263 TEST BYTE PTR ES:[BX].DP_SPECIALFUNCTIONS, INSTALL_FAKE_BPB
264 JNZ SHORT INSTALLFAKEBPB
265
266; WERE WE RETURNING A FAKE BPB WHEN ASKED TO BUILD A BPB?
267 TEST WORD PTR DS:[DI].FLAGS, RETURN_FAKE_BPB
268 JZ SHORT INSTALLRECOMMENDEDBPB
269
270; WE WERE RETURNING A FAKE BPB BUT WE CAN STOP NOW
271 AND WORD PTR DS:[DI].FLAGS, NOT RETURN_FAKE_BPB
272; JMP DONEWITHBPBSTUFF ;AN008; Comment out this instruction.
273
274INSTALLRECOMMENDEDBPB:
275 MOV CX, SIZE A_BPB
276 LEA DI, BYTE PTR [DI].RBYTEPERSEC
277 JMP SHORT COPYTHEBPB
278
279INSTALLFAKEBPB:
280 or word ptr ds:[di].flags, return_fake_bpb ;AN000; Problem
281 ;reported by WHS.
282 MOV CX, SIZE BPB_TYPE ; MOVE 'SMALLER' BPB
283 LEA DI, BYTE PTR [DI].BYTEPERSEC
284COPYTHEBPB:
285 LEA SI, BYTE PTR [BX].DP_BPB
286; EXCHANGE ES AND DS
287 PUSH ES
288 PUSH DS
289 POP ES
290 POP DS
291
292 REP MOVSB
293
294DONEWITHBPBSTUFF:
295 CALL RESTOREOLDDPT ; RESTORE THE OLD DPT FROM TEMPDPT
296 RESTOREREG <BX,ES,DI,DS>
297
298; SET UP TRACK TABLE (IF NECCESSARY)
299SETTRACKTABLE:
300 MOV CX, WORD PTR ES:[BX].DP_TRACKTABLEENTRIES
301 MOV CS:SECTORSPERTRACK, CX
302 AND WORD PTR DS:[DI].FLAGS, NOT GOOD_TRACKLAYOUT
303 TEST BYTE PTR ES:[BX].DP_SPECIALFUNCTIONS, TRACKLAYOUT_IS_GOOD
304 JZ UGLYTRACKLAYOUT
305 OR WORD PTR DS:[DI].FLAGS, GOOD_TRACKLAYOUT
306
307UGLYTRACKLAYOUT:
308 CMP CX, MAX_SECTORS_IN_TRACK
309 JA TOOMANYSECTORSPERTRACK
310 JCXZ SECTORINFOSAVED
311 MOV DI, OFFSET TRACKTABLE
312 LEA SI, ES:[BX].DP_SECTORTABLE
313 PUSH ES
314 POP DS
315 PUSH CS
316 POP ES
317STORESECTORINFO:
318 INC DI ; SKIP OVER CYLINDER
319 INC DI ; SKIP OVER HEAD
320 LODSW ; GET SECTOR ID
321 PUSH AX ; SAVE IT
322 LODSW ; GET SECTOR SIZE
323 CALL SECTORSIZETOSECTORINDEX
324 POP DX ; GET SECTOR ID BACK
325 MOV AL, DL ; AH = SECTOR SIZE INDEX
326 ; AL = SECTOR ID
327 STOSW
328 LOOP STORESECTORINFO
329
330SECTORINFOSAVED:
331 CLC
332 RET
333
334TOOMANYSECTORSPERTRACK:
335 MOV AL, 0CH
336 STC
337 RET
338
339SETDEVICEPARAMETERS ENDP
340
341;
342; SET MEDIA TYPE FOR FORMAT
343; PERFORMS THE INT 13 WITH AH = 18H TO SEE IF THE MEDIUM DESCRIBED IN THE
344; BPB AREA IN THE BDS CAN BE HANDLED BY THE ROM.
345; ON INPUT, DS:DI -> CURRENT BDS.
346; THE STATUS OF THE OPERATION IS RETURNED IN AL
347; - 0 - IF THE SUPPORT IS AVAILABLE, AND THE COMBINATION IS VALID.
348; - 1 - NO ROM SUPPORT
349; - 2 - ILLEGAL COMBINATION
350; - 3 - No media present (ROM support exists but cannot determine now)
351; FLAGS ALSO MAY BE ALTERED. ALL OTHER REGISTERS PRESERVED.
352; IF THE CALL TO ROM RETURNS NO ERROR, THEN THE CURRENT DPT IS "REPLACED" BY
353; THE ONE RETURNED BY THE ROM. THIS IS DONE BY CHANGING THE POINTER IN [DPT]
354; TO THE ONE RETURNED. THE ORIGINAL POINTER TO THE DISK BASE TABLE IS STORED
355; IN TEMPDPT, UNTIL IT IS RESTORED.
356;
357 PUBLIC SET_MEDIA_FOR_FORMAT
358SET_MEDIA_FOR_FORMAT PROC NEAR
359 SAVEREG <CX,DX>
360 XOR AX,AX
361 cmp cs:[Had_Format_Error],1 ;Did we have a format error before?
362 jne No_Form_Err ;AN001;
363 call ResetDisk
364No_Form_Err: ;AN001;
365 CMP BYTE PTR CS:[MEDIA_SET_FOR_FORMAT],1
366 jnz Do_Set_Media_for_Format
367 jmp SET_MED_RET ; MEDIA ALREADY SET
368Do_Set_Media_for_Format:
369 SAVEREG <DS,SI>
370 MOV DS,AX
371 LDS SI,DWORD PTR DS:[DSKADR] ; GET POINTER TO DISK BASE TABLE
372 MOV WORD PTR CS:[DPT],SI
373 MOV WORD PTR CS:[DPT+2],DS ; SAVE POINTER TO TABLE
374;SB34IOCTL000******************************************************************
375;SB Initialise the head settle time to 0fh. See the offsets given in
376;SB DSKPRM.INC. 1 LOC.
377
378 mov ds:[si].DISK_HEAD_STTL, 0Fh
379;SB34IOCTL000******************************************************************
380 RESTOREREG <SI,DS>
381 mov cs:[New_Rom], 1 ;assume a new ROM.
382 XOR AL,AL
383;SB33031****************************************************************
384 mov cx,ds:[di.ccyln] ;get number of cylinders ;SB ;3.30*
385 dec cx ;cylinder must be zero based ;SB ;3.30*
386 and ch,03h ; blank out unnecessary bits
387 ror ch,1 ;put in int form ;SB ;3.30*
388 ror ch,1 ; ;SB ;3.30*
389 xchg ch,cl ; ;SB ;3.30*
390 or cl,byte ptr ds:[di.seclim] ;get number of sectors ;SB ;3.30*
391 mov dl,ds:[di.drivenum] ;get drive number ;SB ;3.30*
392 mov ah,18h ;set media for format ;SB ;3.30*
393 SAVEREG <ES,DS,SI,DI>
394 int 13h ;call rom bios ;SB ;3.30*
395;SB33031****************************************************************
396 JC FORMAT_STAT_ERR
397; ES:DI POINTS TO A DISK BASE TABLE FOR THIS COMBINATION FOR THIS DRIVE.
398 XOR CX,CX
399 MOV DS,CX ; HAVE DS -> SEGMENT 0
400 LDS SI,DWORD PTR DS:[DSKADR] ; GET CURRENT DISK BASE TABLE
401 MOV WORD PTR CS:[TEMPDPT],SI
402 MOV WORD PTR CS:[TEMPDPT+2],DS ; SAVE IT
403 MOV WORD PTR DS:[DSKADR],DI
404 MOV WORD PTR DS:[DSKADR+2],ES ; REPLACE WITH ONE RETURNED BY ROM
405 MOV BYTE PTR CS:[MEDIA_SET_FOR_FORMAT],1
406Skip_Disk_Base_setting:
407 XOR AL,AL ; LEGAL COMBINATION + ROM SUPPORT CODE
408 mov cs:[Had_Format_Error],al ;reset the flag
409 JMP SHORT POP_STAT_RET
410
411FORMAT_STAT_ERR:
412 cmp ah, Dsk_illegal_combination ;J.K. illegal combination = 0ch
413 je Format_stat_illegal_comb
414 cmp ah, Dsk_Time_Out_Err ;J.K. = 80h
415 je Format_stat_Time_out
416 mov al, 1 ;Function not supported.
417 mov cs:[New_Rom], 0 ;So, it is an old rom.
418 jmp short Pop_stat_ret
419Format_stat_illegal_comb: ;J.K. Function supported, but
420 MOV AL,2 ;J.K. illegal sect/trk, trk combination.
421 jmp short Pop_stat_ret
422Format_stat_Time_out: ;J.K. Function supported, but
423 mov al, 3 ;J.K. media not present.
424POP_STAT_RET:
425 RESTOREREG <DI,SI,DS,ES>
426SET_MED_RET:
427 RESTOREREG <DX,CX>
428 RET
429
430SET_MEDIA_FOR_FORMAT ENDP
431
432;
433; FORMATTRACK:
434; IF SPECIALFUNCTION BYTE IS 1, THEN THIS IS A STATUS CALL TO SEE IF THERE IS
435; ROM SUPPORT FOR THE COMBINATION OF SEC/TRK AND # OF CYLN, AND IF THE
436; COMBINATION IS LEGAL. IF SPECIALFUNCTION BYTE IS 0, THEN FORMAT THE TRACK.
437;
438; INPUT: DS:DI POINTS TO BDS FOR DRIVE
439; ES:BX POINTS TO FORMAT PACKET
440;
441; OUTPUT:
442; FOR STATUS CALL:
443; SPECIALFUNCTION BYTE SET TO:
444; 0 - ROM SUPPORT + LEGAL COMBINATION
445; 1 - NO ROM SUPPORT
446; 2 - ILLEGAL COMBINATION
447; 3 - no media present ;J.K. 7/8/86
448; CARRY CLEARED.
449;
450; FOR FORMAT TRACK:
451; CARRY SET IF ERROR
452;
453 PUBLIC FORMATTRACK
454FORMATTRACK PROC NEAR
455 TEST BYTE PTR ES:[BX].DP_SPECIALFUNCTIONS,STATUS_FOR_FORMAT
456 JZ DO_FORMAT_TRACK
457 CALL SET_MEDIA_FOR_FORMAT ; ALSO MOVES CURRENT DPT TO TEMPDPT
458STAT_RET:
459 MOV BYTE PTR ES:[BX].DP_SPECIALFUNCTIONS,AL
460 CLC
461 RET
462
463DO_FORMAT_TRACK:
464 CMP BYTE PTR DS:[DI].FORMFACTOR, DEV_HARDDISK
465 jne Do_Format_Diskette
466 jmp DoVerifyTrack
467Do_Format_Diskette:
468 SAVEREG <DS,DI,ES,BX>
469;SB34IOCTL001*************************************************************
470;SB check the special functions word to see if DO_FAST_FORMAT has been
471;SB specified. If so it is an error and we need to finish this operation
472;SB by indicating the error value 1 in register ah and going to the
473;SB the code at DO_MAP_IT to map the error. This is because we cannot
474;SB allow multitrack format on floppies - 5 LOCS
475
476 test byte ptr es:[bx].FP_SPECIALFUNCTIONS,DO_FAST_FORMAT
477 jz NO_FAST_FORMAT
478 mov ah, 1
479 jmp DO_MAP_IT
480NO_FAST_FORMAT:
481;SB34IOCTL001*************************************************************
482 CALL SET_MEDIA_FOR_FORMAT ; ALSO MOVES CURRENT DPT TO TEMPDPT
483 CMP AL,1 ; DO WE HAVE ROM SUPPORT FOR sector/trk, # trks combination?
484 JZ Need_Set_DASD ;Old ROM.
485 cmp al,3 ;time out error?
486 jnz No_Set_DASD ;No, fine.(At this point, don't care about the illegal combination.)
487 jmp Format_Failed
488Need_Set_DASD:
489 CALL SETDASD ;AH=17h, INT 13h
490;
491; STORE CYLINDER,HEAD IN TRACK TABLE
492; ***** ASSUMPTION *******
493; SINCE FORMAT REQUESTS ON FIXED MEDIA ARE CONVERTED TO VERIFIES, WE
494; ASSUME THAT WE ARE FORMATTING A FLOPPY AND HENCE HAVE 255 OR LESS
495; TRACKS AND HEADS. WE THEREFORE MUST CHANGE THE CYLINDER, HEAD DATA
496; FROM THE REQUEST PACKET SIZE TO THAT OF THE TRACKTABLE (SEE INT 13
497; INTERFACE IN IBM'S TECH REF.).
498
499NO_SET_DASD:
500; CHECK TO ENSURE CORRECT DISK IS IN DRIVE
501 CALL CHECKSINGLE
502
503 MOV AX, WORD PTR ES:[BX].FP_CYLINDER
504 MOV WORD PTR CS:[TRKNUM],AX
505 MOV CX, WORD PTR ES:[BX].FP_HEAD
506 MOV BYTE PTR CS:[HDNUM],CL
507 MOV AH,CL
508
509 PUSH DI ; SAVE PTR TO BDS
510 MOV DI, OFFSET TRACKTABLE
511 PUSH CS
512 POP ES
513 MOV CX, CS:SECTORSPERTRACK
514STORECYLINDERHEAD:
515 STOSW
516 INC DI ; SKIP SECTOR ID
517 INC DI ; SKIP SECTOR SIZE
518 LOOP STORECYLINDERHEAD
519 POP DI ; RESTORE PTR TO BDS
520
521 MOV CX, MAXERR ; SET UP RETRY COUNT
522FORMATRETRY:
523 PUSH CX
524 MOV BX, OFFSET TRACKTABLE
525 PUSH CS
526 POP ES
527 MOV AX, CS:SECTORSPERTRACK
528 MOV AH, ROMFORMAT
529 CALL TO_ROM
530 POP CX
531 JNC FORMATOK
532 call resetdisk
533 mov cs:[Had_Format_Error],1
534 push ax
535 push cx
536 push dx
537 call Set_Media_For_Format
538 cmp al, 1
539 jnz While_Err
540 call SetDASD
541While_Err:
542 pop dx
543 pop cx
544 pop ax
545 LOOP FORMATRETRY
546;SB33106*******************************************************************
547Format_Failed:
548 mov cs:[Had_Format_Error], 1 ;set the format error flag.
549 cmp ah, Dsk_Change_Line_Err ;=06h. Convert change line
550 jne Do_Map_it ;error to Time Out error.
551 mov ah, Dsk_Time_Out_Err ;=80h
552;SB33106*******************************************************************
553Do_Map_it:
554 CALL MAPERROR
555 RESTOREREG <BX,ES,DI,DS>
556 RET
557
558FORMATOK:
559 mov cs:[Had_Format_Error],0 ;reset the format error flag.
560 RESTOREREG <BX,ES,DI,DS>
561
562DOVERIFYTRACK:
563 CALL VERIFYTRACK
564 RET
565
566FORMATTRACK ENDP
567
568VerifyTrack_Err: ;AN006;
569 mov ah, 1 ;AN006;
570 call MapError ;AN006;
571 ret ;AN006;
572
573;
574; VERIFYTRACK:
575;
576; INPUT: DS:DI POINTS TO BDS FOR DRIVE
577; ES:BX POINTS TO VERIFY PACKET
578;
579 PUBLIC VERIFYTRACK
580VERIFYTRACK PROC NEAR
581 MOV CS:RFLAG, ROMVERIFY
582 MOV AX, WORD PTR ES:[BX].VP_CYLINDER
583 MOV CS:CURTRK, AX
584 MOV AX, WORD PTR ES:[BX].VP_HEAD
585
586; ****** ASSUMPTION ******
587; WE ASSUME THAT WE HAVE LESS THAN 256 HEADS, AND THAT THE REQUEST
588; HEADER DATA STRUCTURE IS UNNECCESSARILY BIG
589 MOV CS:CURHD, AL
590 MOV CX, CS:SECTORSPERTRACK ;CL = sectors/track
591;SB34IOCTL005*************************************************************
592;SB
593;SB Check SPECIALFUNCTIONS to see if DO_FAST_FORMAT has been specified
594;SB If not we should go to the normal track verification routine. If
595;SB fast format has been specified we should get the number of tracks
596;SB to be verified and check it to see if it is > 255. If it is then
597;SB it is an error and we should go to VerifyTrack_Err. If not multiply
598;SB the number of tracks by the sectors per track to get the total
599;SB number of sectors to be verified. This should also be less than
600;SB equal to 255 otherwise we go to same error exit. If everything
601;SB is okay we initalise cx to the total sectors. use ax as a temporary
602;SB register. 9 LOCS
603
604 test byte ptr es:[bx].FP_SPECIALFUNCTIONS,DO_FAST_FORMAT
605 jz Norm_VerifyTrack
606 mov ax,es:[bx].FP_TRACKCOUNT ;ax <- tracks to be verify
607 cmp ax,0FFh
608 ja VerifyTrack_Err ;#tracks > 255
609 mul cl
610 cmp ax,0FFh ;#sectors > 255
611 ja VerifyTrack_Err
612 mov cx,ax ;#sectors to verify
613;SB34IOCTL005*************************************************************
614
615;Set the multi track request flag
616 test word ptr [di].Flags, fNON_REMOVABLE ;AN009;hard disk?
617 jz Norm_VerifyTrack ;AN009;
618 test cs:Multrk_Flag, MULTRK_ON ;AN009;MultiTrack operation = on?
619 jz Norm_VerifyTrack ;AN009;
620 mov cs:Multitrk_Format_Flag, 1 ;AN009; then set the flag
621Norm_VerifyTrack: ;AN006;
622 XOR AX, AX ;1st sector
623; USE 0:0 AS THE TRANSFER ADDRESS FOR VERIFY
624 XOR BX, BX
625 MOV ES, BX
626 CALL TRACKIO
627 mov cs:Multitrk_Format_Flag, 0 ;AN009;Reset the flag.
628 RET
629VERIFYTRACK ENDP
630
631;
632; READTRACK:
633;
634; INPUT: DS:DI POINTS TO BDS FOR DRIVE
635; ES:BX POINTS TO READ PACKET
636;
637 PUBLIC READTRACK
638READTRACK:
639 MOV CS:RFLAG, ROMREAD
640 JMP READWRITETRACK
641
642;
643; WRITETRACK:
644;
645; INPUT: DS:DI POINTS TO BDS FOR DRIVE
646; ES:BX POINTS TO WRITE PACKET
647;
648 PUBLIC WRITETRACK
649WRITETRACK:
650 MOV CS:RFLAG, ROMWRITE
651 JMP READWRITETRACK
652;
653; READWRITETRACK:
654;
655; INPUT:
656; DS:DI POINTS TO BDS FOR DRIVE
657; ES:BX POINTS TO WRITE PACKET
658; RFLAG - 2 FOR READ, 3 FOR WRITE
659;
660 PUBLIC READWRITETRACK
661READWRITETRACK PROC NEAR
662 MOV AX, WORD PTR ES:[BX].TRWP_CYLINDER
663 MOV CS:CURTRK, AX
664 MOV AX, WORD PTR ES:[BX].TRWP_HEAD
665
666; ****** ASSUMPTION ******
667; WE ASSUME THAT WE HAVE LESS THAN 256 HEADS, AND THAT THE REQUEST
668; HEADER DATA STRUCTURE IS UNNECCESSARILY BIG
669 MOV CS:CURHD, AL
670 MOV AX, WORD PTR ES:[BX].TRWP_FIRSTSECTOR
671 MOV CX, WORD PTR ES:[BX].TRWP_SECTORSTOREADWRITE
672 LES BX, ES:[BX].TRWP_TRANSFERADDRESS
673 CALL TRACKIO
674 RET
675READWRITETRACK ENDP
676
677
678;
679; TRACKIO:
680; PERFORMS TRACK READ/WRITE/VERIFY
681;
682; INPUT:
683; RFLAG - 2 = READ
684; 3 = WRITE
685; 4 = VERIFY
686; AX - INDEX INTO TRACK TABLE OF FIRST SECTOR TO IO
687; CX - NUMBER OF SECTORS TO IO
688; ES:BX - TRANSFER ADDRESS
689; DS:DI - POINTER TO BDS
690; CURTRK - CURRENT CYLINDER
691; CURHD - CURRENT HEAD
692;
693 PUBLIC TRACKIO
694TRACKIO PROC NEAR
695; PROCEDURE `DISK' WILL POP STACK TO SPSAV AND RETURN IF ERROR
696 MOV CS:SPSAV, SP
697; ENSURE CORRECT DISK IS IN DRIVE
698 CALL CHECKSINGLE
699; SEE IF WE HAVE ALREADY SET THE DISK BASE TABLE
700 CMP BYTE PTR CS:[MEDIA_SET_FOR_FORMAT],1
701 JZ DPTALREADYSET
702;
703; SET UP TABLES AND VARIABLES FOR I/O
704;
705 SAVEREG <AX,CX>
706 CALL IOSETUP
707 RESTOREREG <CX,AX>
708;
709; POINT SI AT THE TABLE ENTRY OF THE FIRST SECTOR TO BE IO'D
710;
711DPTALREADYSET:
712 MOV SI, OFFSET TRACKTABLE
713 SHL AX, 1
714 SHL AX, 1
715 ADD SI, AX
716;
717; WE WANT:
718; CX TO BE THE NUMBER OF TIMES WE HAVE TO LOOP
719; DX TO BE THE NUMBER OF SECTORS WE READ ON EACH ITERATION
720 MOV DX, 1
721 TEST WORD PTR DS:[DI].FLAGS, GOOD_TRACKLAYOUT
722 JZ IONEXTSECTOR
723
724; HEY! WE CAN READ ALL THE SECTORS IN ONE BLOW
725 XCHG DX, CX
726
727IONEXTSECTOR:
728 PUSH CX
729 PUSH DX
730; SKIP OVER THE CYLINDER AND HEAD IN THE TRACK TABLE
731 INC SI
732 INC SI
733; GET SECTOR ID FROM TRACK TABLE
734 LODS BYTE PTR CS:[SI]
735 MOV CS:CURSEC, AL
736;*** For a Fixed disk multi-track disk I/O - J.K. 4/14/86
737;Assumptions: 1). In the input CX (# of sectors to go) to TRACKIO, only CL is
738;valid. 2). Sector size should be set to 512 bytes. 3). GOODTRACKLAYOUT.
739;
740 test word ptr [di].Flags, fNon_Removable ;Fixed disk? - J.K.
741 jz IOREMOVABLE ;no -J.K.
742 test cs:MulTrk_Flag, MULTRK_ON ;AN002; Allow multi-track operation?
743 jz IORemovable ;AN002; No, don't do that.
744 mov cs:[seccnt], dx ;# of sectors to I/O -J.K.
745 mov ax, dx ;J.K.
746 call disk ;J.K.
747 pop dx ;J.K.
748 pop cx ;J.K.
749 clc ;J.K.
750 ret ;J.K.
751IOREMOVABLE: ;J.K.
752; GET SECTOR SIZE INDEX FROM TRACK TABLE AND SAVE IT
753 LODS BYTE PTR CS:[SI]
754 PUSH AX
755; PATCH SECTOR SIZE IN DPT
756 PUSH SI
757 PUSH DS
758 LDS SI, CS:DPT
759 MOV BYTE PTR DS:[SI].DISK_SECTOR_SIZ,AL
760 MOV AL,CS:[EOT]
761 MOV [SI].DISK_EOT,AL ; SET UP THE MAX NUMBER OF SEC/TRACK
762 POP DS
763 MOV AL, DL
764DOTHEIO:
765 MOV CS:[SECCNT],AX ; SET UP THE COUNT OF SECTORS TO I/O
766 CALL DISK
767; ADVANCE BUFFER POINTER BY ADDING SECTOR SIZE
768 POP SI
769 POP AX
770 CALL SECTORSIZEINDEXTOSECTORSIZE
771 ADD BX, AX
772 POP DX
773 POP CX
774 LOOP IONEXTSECTOR
775 cmp byte ptr cs:[Media_Set_For_Format], 1 ;AN001;
776 je No_Need_Done ;AN001;
777 CALL DONE ; SET TIME OF LAST ACCESS, AND RESET
778No_Need_Done: ;AN001;
779 CLC ; ENTRIES IN DPT.
780 RET
781
782TRACKIO ENDP
783;
784; THE SECTOR SIZE IN BYTES NEEDS TO BE CONVERTED TO AN INDEX VALUE FOR THE IBM
785; ROM. (0=>128, 1=>256,2=>512,3=>1024). IT IS ASSUMED THAT ONLY THESE VALUES
786; ARE PERMISSIBLE.
787; ON INPUT AX CONTAINS SECTOR SIZE IN BYTES
788; ON OUTPUT AL CONTAINS INDEX
789;
790 PUBLIC SECTORSIZETOSECTORINDEX
791SECTORSIZETOSECTORINDEX PROC NEAR
792 CMP AH,2 ; EXAMINE UPPER BYTE ONLY
793 JA ONEK
794 MOV AL,AH ; VALUE IN AH IS THE INDEX!
795 RET
796ONEK:
797 MOV AL,3
798 RET
799SECTORSIZETOSECTORINDEX ENDP
800
801SECTORSIZEINDEXTOSECTORSIZE PROC NEAR
802 MOV CL, AL
803 MOV AX,128
804 SHL AX, CL
805 RET
806SECTORSIZEINDEXTOSECTORSIZE ENDP
807
808;
809; SET UP THE ROM FOR FORMATTING.
810; WE HAVE TO TELL THE ROM BIOS WHAT TYPE OF DISK IS IN THE DRIVE.
811; ON INPUT - DS:DI - POINTS TO BDS
812;
813 PUBLIC SETDASD
814SETDASD:
815; SEE IF WE HAVE PREVIOUSLY SET DASD TYPE
816;SB33114******************************************************************
817 cmp cs:[Had_Format_Error],1
818 je DoSetDasd
819;SB33114******************************************************************
820 TEST WORD PTR DS:[DI].FLAGS, SET_DASD_TRUE
821 JZ DASDHASBEENSET
822 AND WORD PTR DS:[DI].FLAGS, NOT SET_DASD_TRUE
823;SB33115******************************************************************
824DoSetDasd:
825 mov cs:[Had_Format_Error],0 ;reset it
826;SB33115******************************************************************
827 MOV CS:[GAP_PATCH],50H ; FORMAT GAP FOR 48TPI DISKS
828 MOV AL,4
829 CMP BYTE PTR DS:[DI].FORMFACTOR,DEV_3INCH720KB
830 JZ DO_SET
831 CMP BYTE PTR DS:[DI].FORMFACTOR, DEV_5INCH96TPI
832 JZ GOT_BIG
833 MOV AL,1 ; 160/320K IN A 160/320K DRIVE
834 JMP SHORT DO_SET
835GOT_BIG:
836 MOV AL,2 ; 160/320K IN A 1.2 MEG DRIVE
837 CMP CS:MEDIATYPE, 0
838 JNE DO_SET
839 MOV AL,3 ; 1.2MEG IN A 1.2MEG DRIVE
840 MOV CS:[GAP_PATCH],54H
841DO_SET:
842 push ds ;AN003;
843 push si ;AN003;
844;SB34IOCTL002****************************************************************
845;SB Get the disk parameter table address (dword address) from the location
846;SB 0:[DSKADR] and fix the head settle time in this to be 0fh. 4 LOCS
847
848 xor si, si
849 mov ds, si
850 lds si, dword ptr ds:[DSKADR]
851 mov ds:[si].DISK_HEAD_STTL, 0Fh
852;SB34IOCTL002****************************************************************
853 pop si ;AN003;
854 pop ds ;AN003;
855;SB33032******************************************************************
856 mov AH, 17h ; set command to Set DASD type;SB ;3.30*
857 mov DL, [di].DriveNum ; set drive number ;SB ;3.30*
858 int 13h ; call rom-bios ;SB ;3.30*
859;SB33032******************************************************************
860DASDHASBEENSET:
861 MOV AH,BYTE PTR [DI].SECLIM
862 MOV CS:[FORMT_EOT],AH
863 RET
864
865;
866; THIS ROUTINE IS CALLED IF AN ERROR OCCURS WHILE FORMATTING OR VERIFYING.
867; IT RESETS THE DRIVE, AND DECREMENTS THE RETRY COUNT.
868; ON ENTRY - DS:DI - POINTS TO BDS FOR THE DRIVE
869; BP - CONTAINS RETRY COUNT
870; ON EXIT FLAGS INDICATE RESULT OF DECREMENTING RETRY COUNT
871;
872AGAIN:
873 CALL RESETDISK
874
875;(deleted section here, as requested by D.L.)
876
877 DEC BP ; DECREMENT RETRY COUNT
878 RET
879
880
881; RESET THE DRIVE.
882; WE ALSO SET [STEP_DRV] TO -1 TO FORCE THE MAIN DISK ROUTINE TO USE THE
883; SLOW HEAD SETTLE TIME FOR THE NEXT OPERATION. THIS IS BECAUSE THE RESET
884; OPERATION MOVES THE HEAD TO CYLINDER 0, SO WE NEED TO DO A SEEK THE NEXT
885; TIME AROUND - THERE IS A PROBLEM WITH 3.5" DRIVES IN THAT THE HEAD DOES
886; NOT SETTLE DOWN IN TIME, EVEN FOR READ OPERATIONS!!
887;
888 PUBLIC RESETDISK
889RESETDISK:
890 SAVEREG <AX>
891;SB33033******************************************************************
892 xor AH, AH ; set command to reset disk ;SB ;3.30*
893 int 13h ; call the rom-bios ;SB ;3.30*
894;SB33033******************************************************************
895 MOV CS:[STEP_DRV],-1 ; ZAP UP THE SPEED
896 RESTOREREG <AX>
897 RET
898
899;
900; THIS ROUTINE SETS UP THE DRIVE PARAMETER TABLE WITH THE VALUES NEEDED FOR
901; FORMAT, DOES AN INT 13. VALUES IN DPT ARE RESTORED AFTER A VERIFY IS DONE.
902;
903; ON ENTRY - DS:DI - POINTS TO BDS FOR THE DRIVE
904; ES:BX - POINTS TO TRKBUF
905; AL - NUMBER OF SECTORS
906; AH - INT 13 FUNCTION CODE
907; CL - SECTOR NUMBER FOR VERIFY
908; ON EXIT - DS,DI,ES,BX REMAIN UNCHANGED.
909; AX AND FLAGS ARE THE RESULTS OF THE INT 13
910;
911 PUBLIC TO_ROM
912TO_ROM:
913 SAVEREG <DS,DI,ES,BX,SI>
914 TEST BYTE PTR CS:[NEW_ROM],1
915 JNZ GOT_VALID_DPT
916 PUSH AX
917 MOV DX,DS ; SAVE DS:DI-> BDS
918 XOR AX,AX
919 MOV DS,AX
920 LDS SI,DWORD PTR DS:[DSKADR] ; GET POINTER TO DISK BASE TABLE
921 MOV WORD PTR CS:[DPT],SI
922 MOV WORD PTR CS:[DPT+2],DS ; SAVE POINTER TO TABLE
923 MOV AL,CS:[FORMT_EOT]
924 MOV [SI].DISK_EOT,AL
925 MOV AL,CS:[GAP_PATCH]
926 MOV [SI].DISK_FORMT_GAP,AL ; IMPORTANT FOR FORMAT
927 MOV [SI].DISK_HEAD_STTL,15 ; ASSUME WE ARE DOING A SEEK OPERATION
928; SET UP MOTOR START CORRECTLY FOR 3.5" DRIVES.
929 PUSH ES
930 MOV ES,DX
931 CMP BYTE PTR ES:[DI].FORMFACTOR,FFSMALL ; IS IT A 3.5" DRIVE?
932 JNZ MOTORSTRTOK
933 MOV AL,4
934 XCHG AL,[SI].DISK_MOTOR_STRT
935MOTORSTRTOK:
936 POP ES
937;----------------------------------------------------------------------------
938; THE FOLLOWING TWO LINES ARE NO LONGER NECESSARY SINCE THEY ARE ONLY USEFUL
939; FOR A VERIFY OPERATION.
940; MOV AL,CS:[SECTOR_SIZ_IND]
941; MOV [SI].DISK_SECTOR_SIZ,AL ; IMPORTANT FOR VERIFY
942;----------------------------------------------------------------------------
943 MOV DS,DX ; RESTORE DS:DI-> BDS
944 POP AX
945GOT_VALID_DPT:
946;SB33034*******************************************************************
947 mov dx, cs:[trknum] ; set track number ;SB ;3.30*
948 mov ch,dl ; set low 8 bits in ch ;SB ;3.30*
949 mov DL, ds:[di].DriveNum ; set drive number ;SB ;3.30*
950 mov DH, CS:[HDNUM] ; set head number ;SB ;3.30*
951 int 13h ; call the rom-bios routines ;SB ;3.30*
952;SB33034*******************************************************************
953 RESTOREREG <SI,BX,ES,DI,DS>
954 RET
955
956;
957; GET THE OWNER OF THE PHYSICAL DRIVE REPRESENTED BY THE LOGICAL DRIVE IN BL.
958; THE ASSUMPTION IS THAT WE **ALWAYS** KEEP TRACK OF THE OWNER OF A DRIVE!!
959; IF THIS IS NOT THE CASE, THE SYSTEM MAY HANG, JUST FOLLOWING THE LINKED LIST.
960;
961 PUBLIC IOCTL$GETOWN
962IOCTL$GETOWN:
963 CALL SETDRIVE
964 MOV AL,BYTE PTR [DI].DRIVENUM ; GET PHYSICAL DRIVE NUMBER
965 PUSH CS
966 POP DS
967 MOV DI,WORD PTR START_BDS
968OWN_LOOP:
969 CMP BYTE PTR [DI].DRIVENUM,AL
970 JNE GETNEXTBDS
971 TEST WORD PTR [DI].FLAGS,FI_OWN_PHYSICAL
972 JNZ DONE_GETOWN
973GETNEXTBDS:
974 MOV BX,WORD PTR [DI].LINK+2
975 MOV DI,WORD PTR [DI].LINK
976 MOV DS,BX
977 JMP SHORT OWN_LOOP
978DONE_GETOWN:
979 JMP SHORT EXIT_OWN
980
981;
982; SET THE OWNERSHIP OF THE PHYSICAL DRIVE REPRESENTED BY THE LOGICAL DRIVE IN
983; BL TO BL.
984;
985 PUBLIC IOCTL$SETOWN
986IOCTL$SETOWN:
987 CALL SETDRIVE
988 MOV BYTE PTR CS:[FSETOWNER],1 ; SET FLAG FOR CHECKSINGLE TO
989 ; LOOK AT.
990 CALL CHECKSINGLE ; SET OWNERSHIP OF DRIVE
991 MOV BYTE PTR CS:[FSETOWNER],0 ; RESET FLAG
992 XOR BX,BX
993 MOV ES,BX
994 MOV CL,-1
995 MOV BYTE PTR ES:[LSTDRV],CL ; SET UP SDSB AS WELL
996
997EXIT_OWN:
998; IF THERE IS ONLY ONE LOGICAL DRIVE ASSIGNED TO THIS PHYSICAL DRIVE, RETURN
999; 0 TO USER TO INDICATE THIS.
1000 XOR CL,CL
1001 TEST WORD PTR [DI].FLAGS,FI_AM_MULT
1002 JZ EXIT_NO_MULT
1003 MOV CL,BYTE PTR [DI].DRIVELET ; GET LOGICAL DRIVE NUMBER
1004 INC CL ; GET IT 1-BASED
1005EXIT_NO_MULT:
1006 LDS BX,CS:[PTRSAV]
1007 MOV BYTE PTR [BX].UNIT,CL
1008 JMP EXIT
1009
1010
1011;
1012; MOVES THE OLD DPT THAT HAD BEEN SAVED IN TEMPDPT BACK TO DPT. THIS IS DONE
1013; ONLY IF THE FIRST BYTE OF TEMPDPT IS NOT -1.
1014; ALL REGISTERS (INCLUDING FLAGS) ARE PRESERVED.
1015;
1016 PUBLIC RESTOREOLDDPT
1017RESTOREOLDDPT:
1018; IF WE HAVE ALREADY RESTORED THE DISK BASE TABLE EARLIER, DO NOT DO IT
1019; AGAIN.
1020 PUSH AX
1021 XOR AL,AL
1022; RESET FLAG AND GET CURRENT FLAG SETTING
1023 mov cs:[Had_Format_Error],al
1024 XCHG BYTE PTR CS:[MEDIA_SET_FOR_FORMAT],AL
1025 OR AL,AL
1026 JZ DONTRESTORE
1027 SAVEREG <SI,DS,ES>
1028 LDS SI,CS:[TEMPDPT]
1029 XOR AX,AX
1030 MOV ES,AX ; HAVE ES -> SEGMENT 0
1031 MOV WORD PTR ES:[DSKADR],SI
1032 MOV WORD PTR ES:[DSKADR+2],DS
1033GOTCURRENTDPT:
1034 RESTOREREG <ES,DS,SI>
1035DONTRESTORE:
1036 POP AX
1037 CLC ; CLEAR CARRY
1038 RET
1039
1040;******************************************************************************
1041;AN000; Get Media ID
1042;*******************************************************************************
1043; *
1044; Function: Get the volume label, the system id and the serial number from *
1045; the media that has the extended boot record. *
1046; For the conventional media, this routine will return "Unknown *
1047; media type" error to DOS. *
1048; *
1049; Input : DS:DI -> BDS table for this drive. *
1050; ES:BX -> Request packet (= A_Media_ID_INFO structure) *
1051; *
1052; Output: The request packet filled with the information, if not carry. *
1053; If carry set, then AL contains the device driver error number *
1054; that will be returned to DOS. *
1055; Register DS,DX,AX,CX,DI,SI destroyed. *
1056; Subroutines to be called: *
1057; BOOT_IO:NEAR *
1058; *
1059; Logic: *
1060; /*To recognize the extended boot record, this logic will actually */ *
1061; /*access the boot sector even if it is a hard disk. */ *
1062; /*NOTE:the valid extended bpb is recognized by looking at the mediabyte*
1063; /*field of BPB and the extended Boot Signature. *
1064; *
1065; { *
1066; Get logical drive number from BDS table; *
1067; RFLAG = Read operation; *
1068; BOOT_IO; /*Get the media boot record into the buffer*/ *
1069; IF (no error) THEN *
1070; IF (extended boot record) THEN *
1071; { set Volume Label, Volume Serial number and System id *
1072; of the Request packet to those of the boot record; *
1073; }; *
1074; ELSE /*Not an extended BPB */ *
1075; { set Register AL to "Unknown media.." error code; *
1076; set Carry bit; *
1077; }; *
1078; ELSE *
1079; Exit; /*Already error code is set in the register AL*
1080; *
1081; Expected LOC: 40 (New) *
1082;*******************************************************************************
1083
1084GetMediaID proc near ;AN000;
1085 call Changeline_Chk ;AN010;
1086 mov al, DS:[DI].DRIVELET ;AN000; logical drive number
1087 mov cs:RFlag, ROMREAD ;AN000; read operation
1088 call Boot_IO ;AN000; read boot sector into cs:DiskSector
1089; $IF NC ;AN000;
1090 JC $IOCTL$IF1
1091 mov cl, cs:MediaByte ;AN000; Mediabyte in BPB
1092 and cl, 0F0h ;AN000;
1093 cmp cl, 0F0h ;AN000; Is it a valid BPB?
1094; $IF E,AND ;AN000;
1095 JNE $IOCTL$IF2
1096 cmp cs:Ext_Boot_Sig, EXT_BOOT_SIGNATURE ;AN000; =90h
1097; $IF E ;AN000; Extended Boot Record
1098 JNE $IOCTL$IF2
1099 push cs ;AN000;
1100 pop ds ;AN000;
1101 mov si, offset Boot_Serial_L ;AN000;
1102 mov di, bx ;AN000;
1103 add di, MI_SERIAL ;AN000;
1104 mov cx, BOOT_SERIAL_SIZE+BOOT_VOLUME_LABEL_SIZE+BOOT_SYSTEM_ID_SIZE
1105 rep movsb ;AN000;
1106; $ELSE ;AN000;
1107 JMP SHORT $IOCTL$EN2
1108$IOCTL$IF2:
1109 mov al, ERROR_UNKNOWN_MEDIA ;AN000; =7
1110 stc ;AN000;
1111; $ENDIF ;End Extended Boot Record check.
1112$IOCTL$EN2:
1113; $ENDIF ;Read boot sector failed. Hard error.
1114$IOCTL$IF1:
1115 ret ;AN000;
1116GetMediaID endp
1117
1118;******************************************************************************
1119;AN000; Set Media ID
1120;*******************************************************************************
1121; *
1122; Function: Set the volume label, the system id and the serial number of *
1123; the media that has the extended boot record. *
1124; For the conventional media, this routine will return "Unknown *
1125; media.." error to DOS. *
1126; This routine will also set the corresponding informations in *
1127; the BDS table. *
1128; *
1129; Input : DS:DI -> BDS table for this drive. *
1130; ES:BX -> Request packet (= A_Media_ID_INFO structure) *
1131; *
1132; Output: The extended boot record in the media will be set according to *
1133; the Request packet. *
1134; If carry set, then AL contains the device driver error number *
1135; that will be returned to DOS. *
1136; *
1137; Subroutines to be called: *
1138; BOOT_IO:NEAR *
1139; *
1140; Logic: *
1141; *
1142; *
1143; { *
1144; Get Drive_Number from BDS; *
1145; RFLAG = "Read operation"; *
1146; BOOT_IO; *
1147; IF (no error) THEN *
1148; IF (extended boot record) THEN *
1149; { set Volume Label, Volume Serial number and System id *
1150; of the boot record to those of the Request packet; *
1151; RFLAG = "Write operation"; *
1152; Get Drive Number from BDS; *
1153; BOOT_IO; /*Write it back*/ *
1154; }; *
1155; ELSE /*Not an extended BPB */ *
1156; { set Register AL to "Unknown media.." error code; *
1157; set Carry bit; *
1158; Exit; /*Return back to caller */ *
1159; }; *
1160; ELSE *
1161; Exit; /*Already error code is set */ *
1162; *
1163; Expected LOC: 45 (New) *
1164;*******************************************************************************
1165
1166SetMediaID proc near
1167 call Changeline_Chk ;AN010;
1168 mov al, DS:[DI].DRIVELET ;AN000; logical drive number
1169 mov dl, al ;AN000; save it for the time being.
1170 mov cs:RFlag, ROMREAD ;AN000; read operation
1171 push dx ;AN000; save drive number
1172 call Boot_IO ;AN000; read boot sector into cs:DiskSector
1173 pop dx ;AN000; restore drive number
1174; $IF NC ;AN000;
1175 JC $IOCTL$IF6
1176 mov cl, cs:MediaByte ;AN000; Mediabyte in BPB
1177 and cl, 0F0h ;AN000;
1178 cmp cl, 0F0h ;AN000; Is it a valid BPB?
1179; $IF E,AND ;AN000;
1180 JNE $IOCTL$IF7
1181 cmp cs:Ext_Boot_Sig, EXT_BOOT_SIGNATURE ;AN000; =41 (=29h)
1182; $IF E ;AN000; Extended Boot Record
1183 JNE $IOCTL$IF7
1184 push ds ;AN011; save BDS pointer
1185 push di ;AN011;
1186 push es ;AN000;
1187 pop ds ;AN000;Now DS-> Request packet
1188 push cs ;AN000;
1189 pop es ;AN000;Now ES -> Boot Record
1190 mov di, offset Boot_Serial_L ;AN000;
1191 mov si, bx ;AN000;
1192 add si, MI_Serial ;AN000;
1193 mov cx, BOOT_SERIAL_SIZE+BOOT_VOLUME_LABEL_SIZE+BOOT_SYSTEM_ID_SIZE
1194 rep movsb ;AN000;
1195 pop di ;AN011;Restore BDS pointer
1196 pop ds ;AN011;
1197 call Mov_Media_IDs ;AN011; Update the BDS media ID info.
1198 mov al, dl ;AN000; set drive number for Boot_IO
1199 mov cs:RFlag, ROMWRITE ;AN000;
1200 call Boot_IO ;AN000; write it back.
1201 mov cs:[TIM_DRV], -1 ;AN011; Make sure chk$media check the driver
1202; $ELSE ;AN000;
1203 JMP SHORT $IOCTL$EN7
1204$IOCTL$IF7:
1205 mov al, ERROR_UNKNOWN_MEDIA ;AN000; =7
1206 stc ;AN000;
1207; $ENDIF ;End Extended Boot Record check.
1208$IOCTL$EN7:
1209; $ENDIF ;Read boot sector failed. Hard error.
1210$IOCTL$IF6:
1211 ret ;AN000;
1212SetMediaID endp
1213
1214;******************************************************************************
1215;AN000; Boot_IO
1216;*******************************************************************************
1217; *
1218; Function: Read/Write the boot record into Boot sector. *
1219; *
1220; Input : *
1221; AL=logical drive number *
1222; RFLAG = operation (read/write) *
1223; *
1224; Output: For read operation, the boot record of the drive specified in BDS *
1225; be read into the DISKSECTOR buffer. *
1226; For write operation, the DISKSECTOR buffer image will be written *
1227; to the drive specified in BDS. *
1228; If carry set, then AL contains the device driver error number *
1229; that will be returned to DOS. *
1230; AX,CX,DX register destroyed. *
1231; If carry set, then AL will contain the error code from DISKIO. *
1232; *
1233; Subroutines to be called: *
1234; DISKIO:NEAR *
1235; *
1236; Logic: *
1237; *
1238; { *
1239; First_Sector = 0; /*logical sector 0 is the boot sector */ *
1240; SectorCount = 1; /*read 1 sector only */ *
1241; Buffer = DISKSECTOR; /*read it into the disksector buffer */ *
1242; Call DISKIO (RFLAG, Drive_Number,First_Sector,SectorCount,Buffer); *
1243; } *
1244; Expected LOC: 6 (New) *
1245;*******************************************************************************
1246Boot_IO proc near ;AN000;
1247 push ds ;AN000;
1248 push es ;AN000;
1249 push di ;AN000;
1250 push bx ;AN000;
1251;SB34IOCTL003**************************************************************
1252;SB Call DISKIO to read/write the boot sector. The parameters which
1253;SB need to be initialised for this subroutine out here are
1254;SB - transfer address to cs:DiskSector
1255;SB - low sector needs to be initalised to 0. This is a reg. param
1256;SB - hi sector in cs:[Start_Sec_H] needs to be initialised to 0.
1257;SB - number of sectors <-- 1
1258;SB 7 LOCS
1259
1260 mov di, cs
1261 mov ds, di
1262 mov es, di
1263 mov di, offset DiskSector ;es:di -> transfer address
1264 xor dx, dx ;first sector (H) -> 0
1265 mov [Start_Sec_H], dx ;start sector (H) -> 0
1266 mov cx, 01 ;one sector
1267 call DISKIO
1268;SB34IOCTL003**************************************************************
1269 pop bx ;AN000;
1270 pop di ;AN000;
1271 pop es ;AN000;
1272 pop ds ;AN000;
1273 ret ;AN000;
1274Boot_IO endp ;AN000;
1275
1276;*******************************************************************************
1277;AN010; Changeline_Chk
1278;*******************************************************************************
1279;When the user calls Get/Set media ID call before DOS establishes the media *
1280;by calling "Media$Chk", the change line activity of the drive is going to be *
1281;lost. This routine will check the change line activity and will save the *
1282;history in the flags. *
1283; *
1284; Function: Check the change line error activity *
1285; *
1286; Input : DS:DI -> BDS table. *
1287; *
1288; Output: FLAG in BDS table will be updated if change line occurs. *
1289; *
1290; Subroutines to be called: *
1291; SET_CHANGED_DL *
1292; *
1293;*******************************************************************************
1294Changeline_Chk proc near ;AN010;
1295 mov dl, byte ptr ds:[di].DRIVENUM ;AN010;
1296 or dl, dl ;AN010;Fixed disk?
1297 js Chln_Chk_Ret ;AN010;Yes, skip it.
1298 cmp cs:[fHave96], 1 ;AN011;This ROM support change line?
1299 jne Chln_Chk_Ret ;AN011;
1300 call HasChange ;AN011;This drive support change line?
1301 jz Chln_Chk_Ret ;AN011;do nothing
1302;SB34IOCTL004*****************************************************************
1303;SB Execute the ROM disk interrupt to check changeline activity. 2 LOCS
1304
1305 mov ah, 16h
1306 int 13h
1307;SB34IOCTL004*****************************************************************
1308 jnc Chln_Chk_Ret ;AN010;no change line activity?
1309 mov word ptr cs:[FLAGBITS], FCHANGED ;AN010;
1310 call SET_CHANGED_DL ;AN010;Update FLAG in BDS for this physical drive
1311Chln_Chk_Ret: ;AN010;
1312 ret ;AN010;
1313Changeline_Chk endp ;AN010;
1314
1315;******************************************************************************
1316;AN007; GetAccessFlag
1317;*******************************************************************************
1318; *
1319; Function: Get the status of UNFORMATTED_MEDIA bit of FLAGS in BDS table *
1320; *
1321; Input : *
1322; es:bx -> A_DISKACCESS_CONTROL structure *
1323; ds:di -> BDS table *
1324; *
1325; Output: A_DISKACCESS_CONTROL.DAC_ACCESS_FLAG = 0 if disk I/O not allowed. *
1326; = 1 if disk I/O allowed. *
1327;*******************************************************************************
1328GetAccessFlag proc ;AN007;
1329 test word ptr ds:[di].FLAGS, UNFORMATTED_MEDIA ;AN007;Is it unformtted media?
1330 jz GAF_Allowed ;AN007;No, formatted media
1331 mov es:[bx].DAC_ACCESS_FLAG, 0 ;AN007;
1332 jmp short GAF_Done ;AN007;
1333GAF_Allowed: ;AN007;
1334 mov es:[bx].DAC_ACCESS_FLAG, 1 ;AN007;
1335GAF_Done: ;AN007;
1336 ret ;AN007;
1337GetAccessFlag endp ;AN007;
1338
1339;******************************************************************************
1340;AN007; SetAccessFlag
1341;*******************************************************************************
1342; *
1343; Function: Set/Reset the UNFORMATTED_MEDIA bit of FLAGS in BDS table *
1344; *
1345; Input : *
1346; es:bx -> A_DISKACCESS_CONTROL structure *
1347; ds:di -> BDS table *
1348; *
1349; Output: UNFORMTTED_MEDIA bit modified according to the user request *
1350;*******************************************************************************
1351SetAccessFlag proc ;AN007;
1352 cmp es:[bx].DAC_ACCESS_FLAG, 0 ;AN007;
1353 jne SAF_Allow_Access ;AN007;
1354 or word ptr ds:[di].FLAGS, UNFORMATTED_MEDIA ;AN007;
1355 jmp short SAF_Done ;AN007;
1356SAF_Allow_Access: ;AN007;
1357 and word ptr ds:[di].FLAGS, not UNFORMATTED_MEDIA ;AN007;
1358SAF_Done: ;AN007;
1359 ret ;AN007;
1360SetAccessFlag endp ;AN007;
1361
1362 \ No newline at end of file