summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/FORMAT/MSFOR.ASM
diff options
context:
space:
mode:
authorGravatar Mark Zbikowski2024-04-25 21:24:10 +0100
committerGravatar Microsoft Open Source2024-04-25 22:32:27 +0000
commit2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch)
tree80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/CMD/FORMAT/MSFOR.ASM
parentMerge pull request #430 from jpbaltazar/typoptbr (diff)
downloadms-dos-main.tar.gz
ms-dos-main.tar.xz
ms-dos-main.zip
MZ is back!HEADmain
Diffstat (limited to 'v4.0/src/CMD/FORMAT/MSFOR.ASM')
-rw-r--r--v4.0/src/CMD/FORMAT/MSFOR.ASM1936
1 files changed, 1936 insertions, 0 deletions
diff --git a/v4.0/src/CMD/FORMAT/MSFOR.ASM b/v4.0/src/CMD/FORMAT/MSFOR.ASM
new file mode 100644
index 0000000..6931115
--- /dev/null
+++ b/v4.0/src/CMD/FORMAT/MSFOR.ASM
@@ -0,0 +1,1936 @@
1; e forproc.sal= @(#)ibmfor.asm 1.28 85/10/15
2 name OemFormatRoutines
3;
4;******************************************************************************
5;AN001 - ???
6;AN002 - D304 Modify Boot record structure for OS2 11/09/87 J.K.
7;******************************************************************************
8
9INCLUDE FORCHNG.INC
10debug equ 0
11;-------------------------------------------------------------------------------
12; Public for debugging only
13
14 public CheckSwitches
15 public LastChanceToSaveIt
16 public WriteBootSector
17 public OemDone
18 public WriteBogusDos
19 public ConvertToOldDirectoryFormat
20 public SetPartitionTable
21 public ReadSector
22 public WriteSector
23 public SectorIO
24 public GetVolumeId
25
26 public customBPBs
27 public NotSlashB
28 public NotSingleSided
29 public EndSwitchCheck
30 public WeCanNotIgnoreThisError
31 public HardDisk?
32 public BogusDos
33 public sys_mess_loop
34 public end_sys_loop
35 public DirectoryRead
36 public wrtdir
37 public DirectoryWritten
38 public FCBforVolumeIdSearch
39 public CopyVolumeId
40 public CompareVolumeIds
41 public BadVolumeId
42
43 public boot2
44 public boot
45 public scratchBuffer
46 public biosFilename
47 public dosFilename
48 public oldDrive
49 public oldVolumeId
50 public Read_Write_Relative
51 public Serial_Num_Low
52 public Serial_Num_High
53 public SizeMap
54
55 public ptr_msgWhatIsVolumeId?
56
57 public trackReadWritePacket
58
59 public BPB81
60 public BPB82
61 public BPB91
62 public BPB92
63
64;-------------------------------------------------------------------------------
65
66data segment public para 'DATA'
67data ends
68
69code segment public para 'CODE'
70 assume cs:code,ds:data
71
72 Public AccessDisk
73 public CheckSwitches
74 public LastChanceToSaveIt
75 public OemDone
76 public BiosFile
77 public DosFile
78
79data segment public para 'DATA'
80 extrn AddToSystemSize:near
81 extrn currentCylinder:word
82 extrn currentHead:word
83 extrn deviceParameters:byte
84 extrn drive:byte
85 extrn driveLetter:byte
86 extrn fBigFAT:byte
87 extrn inbuff:byte
88 extrn switchmap:word
89 extrn Old_Dir:byte
90 extrn fLastChance:byte
91 extrn Fatal_Error:Byte
92 extrn Bios:Byte
93 extrn Dos:Byte
94 extrn Command:Byte
95
96 extrn msgBad_T_N:byte
97 extrn msgBadVolumeId:byte
98 extrn msgBadPartitionTable:byte
99 extrn msgBootWriteError:byte
100 extrn msgDirectoryReadError:byte
101 extrn msgDirectoryWriteError:byte
102 extrn msgInvalidParameter:byte
103 extrn msgIncompatibleParameters:byte
104 extrn msgIncompatibleParametersForHardDisk:byte
105 extrn msgParametersNotSupportedByDrive:byte
106 extrn msgPartitionTableReadError:byte
107 extrn msgPartitionTableWriteError:byte
108 extrn msgWhatIsVolumeId?:byte
109 extrn NumSectors:word, TrackCnt:word
110
111IF DEBUG
112 extrn msgFormatBroken:byte
113ENDIF
114
115data ends
116
117 extrn PrintString:near
118 extrn std_printf:near
119 extrn crlf:near
120 extrn user_string:near
121 extrn Read_Disk:near
122 extrn Write_Disk:near
123
124
125;-------------------------------------------------------------------------------
126; Constants
127
128.xlist
129INCLUDE DOSMAC.INC
130INCLUDE FORMACRO.INC
131INCLUDE FOREQU.INC
132INCLUDE FORSWTCH.INC
133
134; This defines all the int 21H system calls
135INCLUDE SYSCALL.INC
136
137; Limits
138
139INCLUDE filesize.inc
140
141;-------------------------------------------------------------------------------
142; These are the data structures which we will need
143
144INCLUDE DIRENT.INC
145INCLUDE ioctl.INC
146INCLUDE version.inc
147
148.list
149
150;-------------------------------------------------------------------------------
151; And this is the actual data
152data segment public para 'DATA'
153
154Read_Write_Relative Relative_Sector_Buffer <> ; ;AN000;
155
156
157 IF IBMCOPYRIGHT
158BiosFile db "x:\IBMBIO.COM", 0
159DosFile db "x:\IBMDOS.COM", 0
160 ELSE
161BiosFile db "x:\IO.SYS", 0
162DosFile db "x:\MSDOS.SYS", 0
163 ENDIF
164
165Dummy_Label db "NO NAME "
166Dummy_Label_Size dw 11 ;AN028
167
168Serial_Num_Low dw 0 ; ;AN000;
169Serial_Num_High dw 0 ; ;AN000;
170
171SizeMap db 0 ; ;AN000;
172
173trackReadWritePacket a_TrackReadWritePacket <>
174
175
176; BIOS parameter blocks for various media
177customBPBs label byte
178BPB92 a_BPB <512, 2, 1, 2, 112, 2*9*40, 0fdH, 2, 9, 2, 0, 0, 0, 0>
179BPB91 a_BPB <512, 1, 1, 2, 64, 1*9*40, 0fcH, 2, 9, 1, 0, 0, 0, 0>
180BPB82 a_BPB <512, 2, 1, 2, 112, 2*8*40, 0ffH, 1, 8, 2, 0, 0, 0, 0>
181BPB81 a_BPB <512, 1, 1, 2, 64, 1*8*40, 0feH, 1, 8, 1, 0, 0, 0, 0>
182BPB720 a_BPB <512, 2, 1, 2, 112, 2*9*80, 0F9h, 3, 9, 2, 0, 0, 0, 0>
183
184
185
186boot2 db 0,0,0, "Boot 1.x"
187 db 512 - 11 dup(?)
188
189REORG2 LABEL BYTE
190 ORG BOOT2
191 INCLUDE BOOT11.INC
192 ORG REORG2
193
194
195
196INCLUDE BOOTFORM.INC
197
198
199BOOT LABEL BYTE
200 INCLUDE BOOT.INC
201
202scratchBuffer db 512 dup(?)
203
204ptr_msgWhatIsVolumeId? dw offset msgWhatIsVolumeId?
205 dw offset driveLetter
206
207
208FAT12_String db "FAT12 "
209FAT16_String db "FAT16 "
210
211Media_ID_Buffer Media_ID <>
212
213
214data ends
215;-------------------------------------------------------------------------------
216; AccessDisk:
217; Called whenever a different disk is about to be accessed
218;
219; Input:
220; al - drive letter (0=A, 1=B, ...)
221;
222; Output:
223; none
224AccessDisk proc near
225
226 push ax ; save drive letter
227 mov bl,al ; Set up GENERIC IOCTL REQUEST preamble
228 inc bl
229 mov ax,(IOCTL SHL 8) + Set_Drv_Owner ; IOCTL function
230 int 21h
231 pop ax
232 return
233
234AccessDisk endp
235
236;-------------------------------------------------------------------------------
237; CheckSwitches:
238; Check switches against device parameters
239; Use switches to modify device parameters
240;
241; Input:
242; deviceParameters
243;
244; Output:
245; deviceParameters may be modified
246; Carry set if error
247;
248;
249; /B <> /S
250; /B/8 <> /V
251; /1 or /8 <> /T/N
252;
253
254
255Public CHeckSwitches
256CheckSwitches proc near
257
258
259; Disallow /C
260 ;lea dx, msgInvalidParameter ;AC000;
261 test switchmap, SWITCH_C
262 jz CheckExcl
263 Message msgInvalidParameter ;AC000;
264SwitchError:
265 ;call PrintString ;AC000;
266 stc
267 ret
268
269CheckExcl:
270
271 test SwitchMap,Switch_F ;Specify size? ;AN001;
272; $IF NZ ;Yes ;AN001;
273 JZ $$IF1
274 test SwitchMap,(Switch_1+Switch_8+Switch_4+Switch_N+Switch_T) ;AN001;
275; $IF NZ ;/F replaces above switches ;AN001;
276 JZ $$IF2
277 Message msgIncompatibleParameters ;Print error ;AN001;
278 mov Fatal_Error,Yes ;Force exit ;AN001;
279; $ELSE ; ;AN001;
280 JMP SHORT $$EN2
281$$IF2:
282 call Size_To_Switch ;Go set switches based ;AN001;
283; $ENDIF ; on the size ;AN001;
284$$EN2:
285; $ENDIF ; ;AN001;
286$$IF1:
287 cmp Fatal_Error,NO ; ;AN007;
288; $IF E ; ;AN007;
289 JNE $$IF6
290 call Check_Switch_8_B ; ;ac007
291 call Check_T_N
292; $ENDIF ; ;AN009;
293$$IF6:
294 cmp Fatal_Error,Yes ; ;AN007;
295 jne ExclChkDone ; ;AN007;
296 stc ; ;AN007;
297 ret ; ;AN007;
298
299ExclChkDone:
300; Patch the boot sector so that the boot strap loader knows what disk to
301; boot from
302; mov Boot.Boot_PhyDrv, 00H ;AC000;
303 mov Boot.EXT_PHYDRV, 00H ;AN00?;
304
305 cmp deviceParameters.DP_DeviceType, DEV_HARDDISK
306 jne CheckFor5InchDrives
307
308; Formatting a hard disk so we must repatch the boot sector
309; mov Boot.Boot_PhyDrv, 80H ;AC000;
310 mov Boot.EXT_PHYDRV, 80H ;AN00?;
311 test switchmap, not (SWITCH_S or SWITCH_V or SWITCH_Select or SWITCH_AUTOTEST or Switch_B) ;AN007;
312 jz SwitchesOkForHardDisk
313
314 Message msgIncompatibleParametersForHardDisk ; ;AC000;
315 stc
316 ret
317
318; Before checking the Volume Id we need to verify that a valid one exists
319; We assume that unless a valid boot sector exists on the target disk, no
320; valid Volume Id can exist.
321
322SwitchesOkForHardDisk:
323 SaveReg <ax,bx,cx,dx,ds>
324 mov al,drive
325 mov cx,LogBootSect
326 xor dx,dx
327 lea bx,scratchBuffer ; ScratchBuffer := Absolute_Read_Disk(
328 ;INT 25h ; Logical_sec_1 )
329
330 ;Assume Dir for vol ID exists in 1st 32mb of partition
331
332 mov Read_Write_Relative.Start_Sector_High,0
333 call Read_Disk ; ;AC000;
334 ; on the stack. We throw them away
335
336 jnc CheckSignature
337 stc
338 RestoreReg <ds,dx,cx,bx,ax>
339 ret
340
341CheckSignature: ; IF (Boot.Boot_Signature != aa55)
342
343 mov ax, word ptr ScratchBuffer.Boot_Signature ;AC000;
344 cmp ax, 0aa55h ;Find a valid boot record?
345 RestoreReg <ds,dx,cx,bx,ax>
346 clc ;No, so no need to check label
347; $IF Z ;No further checking needed ;AC000;
348 JNZ $$IF8
349 test SwitchMap,(SWITCH_Select or SWITCH_AUTOTEST) ;Should we prompt for vol label?;AN000;
350; $IF Z ;Yes, if /Select not entered ;AN000;
351 JNZ $$IF9
352 call CheckVolumeId ;Go ask user for vol label ; ;
353; $ELSE ;/Select entered ;AN000;
354 JMP SHORT $$EN9
355$$IF9:
356 clc ;CLC indicates passed label test;AN000;
357; $ENDIF ; for the return ;AN000;
358$$EN9:
359; $ENDIF
360$$IF8:
361 return
362
363Incomp_Message: ;an000; fix PTM 809
364
365 Message msgIncompatibleParameters ;an000; print incompatible parms
366 stc ;an000; signal error
367 return ;an000; return to caller
368
369Print_And_Return:
370 ;call PrintString ; ;AC000;
371 stc
372 return
373
374
375CheckFor5InchDrives:
376
377 ;If drive type is anything other than 48 or 96, then only /V/S/H/N/T allowed
378 cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH96TPI
379 je Got96
380
381 cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH
382 je Got48
383
384 xor ax,ax ;an000; dms;clear reg
385 or ax,(Switch_V or Switch_S or Switch_N or Switch_T or Switch_B) ;an000; dms;set up switch mask
386 or ax,(Switch_Backup or Switch_Select or Switch_Autotest) ;an000; dms;
387IF ShipDisk
388 or ax,Switch_Z ;an000; dms;
389ENDIF
390 not ax ;an000; dms;
391 test switchmap,ax ;an000; dms;invalid switch?
392 jz Goto_Got_BPB1 ;an000;dms;continue format
393 Message msgParametersNotSupportedByDrive ; ;AC000;
394 jmp short Print_And_Return
395
396Goto_Got_BPB1:
397 jmp Goto_Got_BPB
398 ; We have a 96tpi floppy drive
399 ; /4 allows just about all switches however, /1 requires /4
400Got96:
401;;;DMS;;test switchmap, SWITCH_8 ;an000; If /8 we have an error
402;;;DMS;;jnz Incomp_message ;an000; tell user error
403
404 test switchmap, SWITCH_4
405 jnz CheckForInterestingSwitches ;If /4 check /N/T/V/S
406
407 test switchmap, SWITCH_1 ;If /1 and /4 check others
408 jz Got48
409
410 ;If only /1 with no /4, see if /N/T
411 test SwitchMap,(Switch_N or Switch_T)
412 jnz CheckForInterestingSwitches
413
414 jmp Incomp_message ;an000; tell user error occurred
415
416Got48:
417 ;Ignore /4 for non-96tpi 5 1/4" drives
418 and switchmap, not SWITCH_4
419
420 ;Ignore /1 if drive has only one head and not /8
421 cmp word ptr deviceParameters.DP_BPB.BPB_Heads, 1
422 ja CheckForInterestingSwitches
423 test switchmap, SWITCH_8
424 jz CheckForInterestingSwitches
425 and switchmap, not SWITCH_1
426
427 ;Are any interesting switches set?
428CheckForInterestingSwitches:
429 test switchmap, not (SWITCH_V or SWITCH_S or Switch_Backup or SWITCH_SELECT or SWITCH_AUTOTEST or Switch_B)
430 jz Goto_EndSwitchCheck ;No, everything ok
431
432 ;At this point there are switches other than /v/s/h
433 test SwitchMap,(SWITCH_N or SWITCH_T)
434 jz Use_48tpi ;Not /n/t, so must be /b/1/8/4
435
436 ;We've got /N/T, see if there are others
437 test SwitchMap, not (SWITCH_N or SWITCH_T or SWITCH_V or SWITCH_S or Switch_Backup or SWITCH_SELECT or SWITCH_AUTOTEST)
438 jz NT_Compatible ;Nope, all is well
439
440 ;If 96tpi drive and /1 exists with /N/T, then okay, otherwise error
441 cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH96TPI
442 jne Bad_NT_Combo
443
444 test SwitchMap, not (SWITCH_1 or SWITCH_N or SWITCH_T or SWITCH_V)
445 jnz Bad_NT_Combo
446 test SwitchMap, not (SWITCH_S or Switch_Backup or SWITCH_SELECT or Switch_Autotest)
447 jz Goto_Got_BPB
448
449Bad_NT_Combo:
450 Message msgIncompatibleParameters ; ;AC000;
451 jmp Print_And_Return
452
453Goto_Got_BPB:
454 jmp Got_BPB_Ok ;Sleazy, but je won't reach it
455
456Goto_EndSwitchCheck:
457 jmp EndSwitchCheck
458 ;There is a problem with /N/T in that IBMBIO will default to a BPB with the
459 ;media byte set to F0 (other) if the /N/T combo is used for the format. This
460 ;will cause problems if we are creating a media that has an assigned media
461 ;byte, i.e. 160,180,320,360, or 720k media using /N/T. To avoid this problem,
462 ;if we detect a /N/T combo that would correspond to one of these medias, then
463 ; we will set things up using the /4/1/8 switches instead of the /N/T
464 ; MT - 7/17/86 PTR 33D0110
465
466 ; Combo's that we look for - 96tpi drive @ /T:40, /N:9
467 ; 96tpi drive @ /T:40, /N:8
468 ;
469 ; Look for this combo after we set everything up with the /T/N routine
470 ; 1.44 drive @ /T:80, /N:9
471
472NT_Compatible:
473 cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH96TPI
474 jne Goto_Got_BPB
475
476 cmp TrackCnt,40 ;Look for 40 tracks
477 jne Got_BPB_Ok
478
479 cmp NumSectors,9 ;9 sectors?
480 je Found_48tpi_Type
481
482 cmp NumSectors,8 ;8 sectors?
483 jne Goto_Got_BPB ;Nope, different type, let it go thru
484
485 or SwitchMap,SWITCH_8 ;Yes, turn on /8 switch
486
487Found_48tpi_Type:
488 and SwitchMap,not (SWITCH_N or SWITCH_T) ;Turn off /T/N
489
490;******End PTR fix
491
492; if we have a 96 tpi drive then we will be using it in 48 tpi mode
493Use_48tpi:
494 cmp byte ptr deviceParameters.DP_DeviceType, DEV_5INCH96TPI
495 jne Not96tpi
496
497 mov byte ptr deviceParameters.DP_MediaType, 1
498 mov word ptr deviceParameters.DP_Cylinders, 40
499Not96tpi:
500
501; Since we know we are formatting in 48 tpi mode turn on /4 switch
502; (We use this info in LastChanceToSaveIt)
503 or switchmap, SWITCH_4
504
505; At this point we know that we will require a special BPB
506; It will be one of:
507; 0) 9 track 2 sides - if no switches
508; 1) 9 track 1 side - if only /1 specified
509; 2) 8 track 2 sides - if only /8 specified
510; 3) 8 track 1 side - if /8 and /1 specified
511;
512Get_BPBs:
513; ax is used to keep track of which of the above BPB's we want
514 xor ax, ax
515
516NotSlashB:
517
518 test switchmap, SWITCH_1
519 jz NotSingleSided
520 add ax, 1
521NotSingleSided:
522
523 test switchmap, SWITCH_8
524 jz Not8SectorsPerTrack
525 add ax, 2
526; /8 implies Old_Dir = TRUE
527 mov Old_Dir,TRUE
528Not8SectorsPerTrack:
529
530; Ok now we know which BPB to use so lets move it to the device parameters
531
532 mov bx, size a_BPB
533 mul bx
534 lea si, CustomBPBs
535 add si, ax
536 lea di, deviceParameters.DP_BPB
537 mov cx, size a_BPB
538 push ds
539 pop es
540 repnz movsb
541
542;*****************************************************************
543;* /N/T DCR stuff. Possible flaw exists if we are dealing with a
544;* HardDisk. If they support the "custom format" features for
545;* Harddisks too, then CheckForInterestingSwitches should
546;* consider /n/t UNinteresting, and instead of returning
547;* after setting up the custom BPB we fall through and do our
548;* Harddisk Check.
549Got_BPB_OK:
550 test switchmap,SWITCH_N+SWITCH_T
551 jnz Setup_Stuff
552 jmp EndSwitchCheck
553Setup_Stuff:
554; Set up NumSectors and SectorsPerTrack entries correctly
555 test switchmap,SWITCH_N
556 jz No_Custom_Seclim
557 mov ax,word ptr NumSectors
558 mov DeviceParameters.DP_BPB.BPB_SectorsPerTrack,ax
559 jmp short Handle_Cyln
560No_Custom_Seclim:
561 mov ax,deviceParameters.DP_BPB.BPB_SectorsPerTrack
562 mov NumSectors,ax
563
564Handle_Cyln:
565 test switchmap,SWITCH_T
566 jz No_Custom_Cyln
567; Set up TrackCnt and Cylinders entries correctly
568 mov ax,TrackCnt
569 mov DeviceParameters.DP_Cylinders,ax
570 jmp short Check_720
571No_Custom_Cyln:
572 mov ax,DeviceParameters.DP_Cylinders
573 mov TrackCnt,ax
574
575;****PTM P868 - Always making 3 1/2 media byte 0F0h. If 720, then set to
576; 0F9h and use the DOS 3.20 BPB. Should check all drives
577; at this point (Make sure not 5 inch just for future
578; protection)
579; We will use the known BPB info for 720 3 1/2 diskettes for
580; this special case. All other new diskette media will use the
581; calculations that follow Calc_Total for BPB info.
582; Fix MT 11/12/86
583
584Check_720:
585
586 cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH96TPI
587 je Calc_Total
588
589 cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH
590 je Calc_Total
591
592 cmp TrackCnt,80
593 jne Calc_Total
594
595 cmp NumSectors,9
596 jne Calc_Total
597
598; At this point we know we have a 3 1/2 720kb diskette to format. Use the
599; built in BPB rather than the one handed to us by DOS, because the DOS one
600; will be based on the default for that drive, and it can be different from
601; what we used in DOS 3.20 for the 720's. Short sighted on our part to use
602; 0F9h as the media byte, should have use 0F0h (OTHER) and then we wouldn't
603; have this problem.
604
605 SaveReg <ds,es,si,di,cx>
606
607
608 mov cx,seg data ;Setup seg regs, just in case they ain't!
609 mov ds,cx
610 mov es,cx
611
612 mov si,offset BPB720 ;Copy the BPB!
613 mov di,offset deviceParameters.DP_BPB
614 mov cx,size a_BPB
615 rep movsb
616 RestoreReg <cx,di,si,es,ds>
617 jmp EndSwitchCheck
618
619;End PTM P868 fix ****************************************
620
621Calc_Total:
622 mov ax,NumSectors
623 mov bx,DeviceParameters.DP_BPB.BPB_Heads
624 mul bl ; AX = # of sectors * # of heads
625 mul TrackCnt ; DX:AX = Total Sectors
626 or dx,dx
627 jnz Got_BigTotalSectors
628 mov DeviceParameters.DP_BPB.BPB_TotalSectors,ax
629 jmp short Set_BPB
630Got_BigTotalSectors:
631 mov DeviceParameters.DP_BPB.BPB_BigTotalSectors,ax
632 mov DeviceParameters.DP_BPB.BPB_BigTotalSectors+2,dx
633 push dx ; preserve dx for further use
634 xor dx,dx
635 mov DeviceParameters.DP_BPB.BPB_TotalSectors,dx
636 pop dx
637
638Set_BPB:
639; We calculate the number of sectors required in a FAT. This is done as:
640; # of FAT Sectors = TotalSectors / SectorsPerCluster * # of bytes in FAT to
641; represent one cluster (i.e. 3/2) / BytesPerSector (i.e. 512)
642 xor bx,bx
643 mov bl,DeviceParameters.DP_BPB.BPB_SectorsPerCluster
644 div bx ; DX:AX contains # of clusters
645; now multiply by 3/2
646 mov bx,3
647 mul bx
648 mov bx,2
649 div bx
650 xor dx,dx ; throw away modulo
651; now divide by 512
652 mov bx,512
653 div bx
654; dx:ax contains number of FAT sectors necessary
655 inc ax ; Go one higher
656 mov DeviceParameters.DP_BPB.BPB_SectorsPerFAT,ax
657 mov DeviceParameters.DP_MediaType,0
658 mov DeviceParameters.DP_BPB.BPB_MediaDescriptor,Custom_Media
659
660
661EndSwitchCheck:
662 clc
663 return
664
665CheckSwitches endp
666
667;*****************************************************************************
668;Routine name: Size_To_Switch
669;*****************************************************************************
670;
671;Description: Given the SizeMap field as input indicating the SIZE= value
672; entered, validate that the specified size is valid for the
673; drive, and if so, turn on the appropriate data fields and
674; switches that would be turned on by the equivilent command line
675; using only switchs. All defined DOS 4.00 sizes are hardcoded,
676; in case a drive type of other is encountered that doesn't
677; qualify as a DOS 4.00 defined drive. Exit with error message if
678; unsupported drive. The switches will be setup for the CheckSwitches
679; routine to sort out, using existing switch matrix logic.
680;
681;Called Procedures: Low_Density_Drive
682; High_Capacity_Drive
683; 720k_Drives
684; Other_Drives
685;
686;Change History: Created 8/1/87 MT
687;
688;Input: SizeMap
689; Fatal_Error = NO
690;
691;Output: Fatal_Error = YES/NO
692; SwitchMap = appropriate Switch_?? values turned on
693; TrackCnt, NumSectors set if Switch_T,Switch_N turned on
694;*****************************************************************************
695
696
697Procedure Size_To_Switch
698
699 cmp SizeMap,0 ;Are there sizes entered? ;AN001;
700; $IF NE ;Yes ;AN001;
701 JE $$IF13
702 cmp deviceParameters.DP_DeviceType,DEV_HARDDISK ;AN000; ;AN001;
703; $IF E ;No size for fixed disk ;AN001;
704 JNE $$IF14
705 Message msgIncompatibleParametersForHardDisk ; ;AN001;
706; $ELSE ;Diskette, see what type ;AN001;
707 JMP SHORT $$EN14
708$$IF14:
709 cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH ; ;AN001;
710; $IF E ;Found 180/360k drive ;AN001;
711 JNE $$IF16
712 call Low_Density_Drive ;Go set switches ;AN001;
713; $ELSE ;Check for 96TPI ;AN001;
714 JMP SHORT $$EN16
715$$IF16:
716 cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH96TPI ;AN001; ;
717; $IF E ;Found it ;AN001;
718 JNE $$IF18
719 call High_Capacity_Drive ; ;AN001;
720; $ELSE ; ;AN001;
721 JMP SHORT $$EN18
722$$IF18:
723 cmp byte ptr deviceParameters.DP_DeviceType,DEV_3INCH720KB ;AN0001;
724; $IF E ;Found 720k drive ;AN001;
725 JNE $$IF20
726 call Small_Drives ; ;AN001;
727; $ELSE ; ;AN001;
728 JMP SHORT $$EN20
729$$IF20:
730 cmp byte ptr deviceParameters.DP_DeviceType,DEV_OTHER ;AN001;
731; $IF E ;Must be 1.44mb ;AN001;
732 JNE $$IF22
733 call Other_Drives ; ;AN001;
734; $ELSE ; ;AN001;
735 JMP SHORT $$EN22
736$$IF22:
737 Message msgParametersNotSupportedByDrive ; ;AN001;
738 mov Fatal_Error,Yes ; ;AN001;
739; $ENDIF ; ;AN001;
740$$EN22:
741; $ENDIF ; ;AN001;
742$$EN20:
743; $ENDIF ; ;AN001;
744$$EN18:
745; $ENDIF ; ;AN001;
746$$EN16:
747; $ENDIF ; ;AN001;
748$$EN14:
749; $ENDIF ; ;AN001;
750$$IF13:
751 cmp Fatal_Error,Yes ; ;AN001;
752; $IF E ; ;AN001;
753 JNE $$IF30
754 Message msgIncompatibleParameters ; ;AN001;
755; $ENDIF ; ;AN001;
756$$IF30:
757
758 cmp deviceParameters.DP_DeviceType,DEV_HARDDISK ;an001;
759; $if e ;an001;
760 JNE $$IF32
761 mov Fatal_Error,Yes ;an001;
762; $endif ;an001;
763$$IF32:
764
765 and SwitchMap,not Switch_F ;Turn off /F so doesn't effect ;AN001;
766 ret ; following logic ;AN001;
767
768Size_To_Switch endp
769
770;*****************************************************************************
771;Routine name: High_Capacity_Drive
772;*****************************************************************************
773;
774;Description: See if 1.2mb diskette, or one of the other 5 1/4 sizes. Turn
775; on /4 if 360k or lower
776;
777;Called Procedures: Low_Density_Drive
778;
779;Change History: Created 8/1/87 MT
780;
781;Input: SizeMap
782; Fatal_Error = NO
783;
784;Output: Fatal_Error = YES/NO
785; SwitchMap = Switch_4 if 360k or lowere
786;*****************************************************************************
787
788Procedure High_Capacity_Drive ;
789
790 test SizeMap,Size_1200 ;1.2mb diskette? ;AN001;
791; $IF Z ;Nope ;AN001;
792 JNZ $$IF34
793 call Low_Density_Drive ;Check for /4 valid types ;AN001;
794 cmp Fatal_Error, No ;Find 160/180/320/360k? ;AN001;
795; $IF E ;Yes ;AN001;
796 JNE $$IF35
797 or SwitchMap,Switch_4 ;Turn on /4 switch ;AN001;
798; $ELSE ;Did not find valid size ;AN001;
799 JMP SHORT $$EN35
800$$IF35:
801 mov Fatal_Error,Yes ;Indicate invalid device ;AN001;
802; $ENDIF ; ;AN001;
803$$EN35:
804; $ENDIF ; ;AN001;
805$$IF34:
806 ret ; ;AN001;
807
808High_Capacity_Drive endp
809
810;*****************************************************************************
811;Routine name: Low_Density_Drive
812;*****************************************************************************
813;
814;Description: See if 360k diskete or one of the other 5 1/4 sizes. Turn
815; on the /1/8 switch to match sizes
816;
817;Called Procedures: Low_Density_Drive
818;
819;Change History: Created 8/1/87 MT
820;
821;Input: SizeMap
822; Fatal_Error = NO
823;
824;Output: Fatal_Error = YES/NO
825; SwitchMap = Switch_1, Switch_8 to define size
826;
827; 360k = No switch
828; 320k = Switch_8
829; 180k = Switch_1
830; 160k = Switch_1 + Switch_8
831;*****************************************************************************
832
833
834Procedure Low_Density_Drive ; ;AN000;
835 ;
836 test SizeMap,Size_160 ; ;AN001;
837; $IF NZ ; ;AN001;
838 JZ $$IF39
839 or SwitchMap,Switch_1+Switch_8 ; ;AN001;
840; $ELSE ; ;AN001;
841 JMP SHORT $$EN39
842$$IF39:
843 test SizeMap,Size_180 ; ;AN001;
844; $IF NZ ; ;AN001;
845 JZ $$IF41
846 or SwitchMap,Switch_1 ; ;AN001;
847; $ELSE ; ;AN001;
848 JMP SHORT $$EN41
849$$IF41:
850 test SizeMap,Size_320 ; ;AN001;
851; $IF NZ ; ;AN001;
852 JZ $$IF43
853 or SwitchMap,Switch_8 ; ;AN001;
854; $ELSE ; ;AN001;
855 JMP SHORT $$EN43
856$$IF43:
857 test SizeMap,Size_360 ; ;AN001;
858; $IF Z ;None of the above, not valid ;AN001;
859 JNZ $$IF45
860 mov Fatal_Error,Yes ; ;AN001;
861; $ENDIF ; ;AN001;
862$$IF45:
863; $ENDIF ; ;AN001;
864$$EN43:
865; $ENDIF ; ;AN001;
866$$EN41:
867; $ENDIF ; ;AN001;
868$$EN39:
869 ret ; ;AN001;
870
871Low_Density_Drive endp
872
873;*****************************************************************************
874;Routine name: Small_Drives
875;*****************************************************************************
876;
877;Description: See if 720k media in 720 drive, set up /T/N if so, otherwise
878; error
879;
880;Called Procedures: None
881;
882;Change History: Created 8/1/87 MT
883;
884;Input: SizeMap
885; Fatal_Error = NO
886;
887;Output: Fatal_Error = YES/NO
888; SwitchMap
889; TrackCnt
890; NumSectors
891; 720k = /T:80 /N:9
892;*****************************************************************************
893
894Procedure Small_Drives ; ;AN000;
895
896 test SizeMap,Size_720 ;Ask for 720k? ;AN001;
897; $IF Z ;Nope, thats all drive can do ;AN001;
898 JNZ $$IF50
899 mov Fatal_Error,Yes ;Indicate error ;AN001;
900; $ENDIF ; ;AN001;
901$$IF50:
902 ret ; ;AN001;
903
904Small_Drives endp
905
906
907;*****************************************************************************
908;Routine name: Other_Drives
909;*****************************************************************************
910;
911;Description: See if 1.44 media or 720k media, setup /t/n, otherwise error
912;
913;Called Procedures: Small_Drives
914;
915;Change History: Created 8/1/87 MT
916;
917;Input: SizeMap
918; Fatal_Error = NO
919;
920;Output: Fatal_Error = YES/NO
921; SwitchMap
922; TrackCnt
923; NumSectors
924; 720k = /T:80 /N:9
925;*****************************************************************************
926
927Procedure Other_Drives ; ;AN001;
928
929 test SizeMap,Size_1440 ;Ask for 1.44mb diskette? ;AN001;
930; $IF Z ;Nope ;AN001;
931 JNZ $$IF52
932 call Small_Drives ;See if 720k ;AN001;
933 cmp Fatal_Error,No ;Fatal_error=Yes if not ;AN001;
934; $IF E ;Got 720k ;AN001;
935 JNE $$IF53
936 or SwitchMap,Switch_T+Switch_N ;Turn on /T:80 /N:9 ;AN001;
937 mov TrackCnt,80 ; ;AN001;
938 mov NumSectors,9 ; ;AN001;
939; $ENDIF ; ;AN001;
940$$IF53:
941; $ELSE ;Asked for 1.44mb ;AN001;
942 JMP SHORT $$EN52
943$$IF52:
944 or SwitchMap,Switch_T+Switch_N ;Turn on /T:80 /N:18; ;AN001;
945 mov TrackCnt,80 ;This will protect SIZE=1440 ;AN001;
946 mov NumSectors,18 ; from non-standard drives with ;AN001;
947; $ENDIF ; type of 'other' ;AN001;
948$$EN52:
949 ret ; ;AN001;
950
951Other_Drives endp
952
953
954;*****************************************************************************
955;Routine name:Check_T_N
956;*****************************************************************************
957;
958;Description: Make sure than if /T is entered, /N is also entered
959;
960;Called Procedures: None
961;
962;Change History: Created 8/23/87 MT
963;
964;Input: SizeMap
965; Fatal_Error = NO
966;
967;Output: Fatal_Error = YES/NO
968;*****************************************************************************
969
970Procedure Check_T_N
971
972 test SwitchMap,Switch_N ;Make sure /T entered if /N ;AN009;
973; $IF NZ,AND ; ;AN009;
974 JZ $$IF57
975 test SwitchMap,Switch_T ; ;AN009;
976; $IF Z ; ;AN009;
977 JNZ $$IF57
978 Message msgBad_T_N ;It wasn't, so barf ;AN009;
979 mov Fatal_Error,Yes ;Indicate error ;AN009;
980; $ELSE ; ;AN009;
981 JMP SHORT $$EN57
982$$IF57:
983 test SwitchMap,Switch_T ;Make sure /N entered if /T ;AN009;
984; $IF NZ,AND ; ;AN009;
985 JZ $$IF59
986 test SwitchMap,Switch_N ; ;AN009;
987; $IF Z ;It wasn't, so also barf ;AN009;
988 JNZ $$IF59
989 Message msgBad_T_N ; ;AN009;
990 mov Fatal_Error,Yes ;Indicate error ;AN009;
991; $ENDIF ; ;AN009;
992$$IF59:
993; $ENDIF ; ;AN009;
994$$EN57:
995 ret
996
997Check_T_N endp
998
999
1000
1001;-------------------------------------------------------------------------------
1002; LastChanceToSaveIt:
1003; This routine is called when an error is detected in DiskFormat.
1004; If it returns with carry not set then DiskFormat is restarted.
1005; It gives the oem one last chance to try formatting differently.
1006; fLastChance gets set Then to prevent multiple prompts from being
1007; issued for the same diskette.
1008;
1009; Algorithm:
1010; IF (error_loc == Track_0_Head_1) &
1011; ( Device_type < 96TPI )
1012; THEN
1013; fLastChance := TRUE
1014; try formatting 48TPI_Single_Sided
1015; ELSE return ERROR
1016;
1017LastChanceToSaveIt proc near
1018
1019 cmp currentCylinder, 0
1020 jne WeCanNotIgnoreThisError
1021 cmp currentHead, 1
1022 jne WeCanNotIgnoreThisError
1023
1024 cmp deviceParameters.DP_DeviceType, DEV_5INCH
1025 ja WeCanNotIgnoreThisError
1026
1027 mov fLastChance, TRUE
1028
1029 or switchmap, SWITCH_1
1030 call CheckSwitches
1031 clc
1032 ret
1033
1034WeCanNotIgnoreThisError:
1035 stc
1036 ret
1037
1038LastChanceToSaveIt endp
1039
1040;-------------------------------------------------------------------------------
1041
1042
1043;*****************************************************************************
1044;Routine name WriteBootSector
1045;*****************************************************************************
1046;
1047;DescriptioN: Copy EBPB information to boot record provided by Get recommended
1048; BPB, write out boot record, error
1049; if can write it, then fill in new fields (id, etc..). The volume
1050; label will not be added at this time, but will be set by the
1051; create volume label call later.
1052;
1053;Called Procedures: Message (macro)
1054;
1055;Change History: Created 4/20/87 MT
1056;
1057;Input: DeviceParameters.DP_BPB
1058;
1059;Output: CY clear if ok
1060; CY set if error writing boot or media_id info
1061;
1062;Psuedocode
1063;----------
1064;
1065; Copy recommended EBPB information to canned boot record
1066; Write boot record out (INT 26h)
1067; IF error
1068; Display boot error message
1069; stc
1070; ELSE
1071; Compute serial id and put into field (CALL Create_Serial_ID)
1072; Point at 'FAT_12' string for file system type
1073; IF fBIGFat ;16 bit FAT
1074; Point at 'FAT_16' for file system type
1075; ENDIF
1076; Copy file system string into media_id field
1077; Write info to boot (INT 21h AX=440Dh, CX=0843h SET MEDIA_ID)
1078; IF error (CY set)
1079; Display boot error message
1080; stc
1081; ELSE
1082; clc
1083; ENDIF
1084; ENDIF
1085; ret
1086;*****************************************************************************
1087
1088Procedure WriteBootSector ; ;AN000;
1089
1090 lea si, deviceParameters.DP_BPB ;Copy EBPB to the boot record ;
1091 lea di, Boot.EXT_BOOT_BPB ; " " " " ;AC000:
1092 mov cx, size EXT_BPB_INFO ; " " " " ;AC000:
1093 push ds ;Set ES=DS (data segment) ; ;
1094 pop es ; " " " " ; ;
1095 repnz movsb ;Do the copy ; ;
1096 ;Write out the boot record ; ;
1097 mov al, drive ;Get drive letter ; ;
1098 mov cx, 1 ;Specify 1 sector ; ;
1099 xor dx, dx ;Logical sector 0 ; ;
1100 lea bx, boot ;Point at boot record ; ;
1101;Boot record in 1st 32mb of partition
1102 mov Read_Write_Relative.Start_Sector_High,0 ; ;AN000;
1103 call Write_Disk ; ;AC000;
1104; $IF C ;Error on write ;AC000;
1105 JNC $$IF62
1106 Message msgBootWriteError ;Print error ; ;
1107 stc ;CY=1 means error ; ;
1108; $ELSE ;Good write of boot record! ;AN000;
1109 JMP SHORT $$EN62
1110$$IF62:
1111 mov cx,Dummy_Label_Size ;Put in dummy volume label size ;ac026;ac028;
1112 lea si,Dummy_Label ; " " " " ;AN000;
1113 lea di,Media_ID_Buffer.Media_ID_Volume_Label ; " " " " ;AN000;
1114 rep movsb ; " " " " ;AN000;
1115 call Create_Serial_ID ;Go create unique ID number ;AN000;
1116 lea si,FAT12_String ;Assume 12 bit FAT ;AN000;
1117 cmp fBigFAT,TRUE ;Is it? ;AN000;
1118; $IF E ;Not if fBigFat is set.... ;AN000;
1119 JNE $$IF64
1120 lea si,FAT16_String ;Got 16 bit FAT ;AN000;
1121; $ENDIF ; ;AN000;
1122$$IF64:
1123 ;Copy file system string ; ;
1124 mov cx,8 ; to buffer ;AN000;
1125 lea di,Media_ID_Buffer.Media_ID_File_System ; " " ;AN000;
1126 repnz movsb ; " " " " ;AN000;
1127 mov al,Generic_IOCtl ;Generic IOCtl call ;AN000;
1128 mov bl,Drive ;Get drive ;AN000;
1129 inc bl ;Make it 1 based ;AN000;
1130 xor bh,bh ;Set bh=0 ;AN000;
1131 mov ch,RawIO ;Set Media ID call ;AN000;
1132 mov cl,Set_Media_ID
1133 mov dx,offset Media_ID_Buffer ;Point at buffer ;AN000;
1134 DOS_Call IOCtl ;Do function call ;AN000;
1135; $IF C ;Error ? (Write or old boot rec);AN000;
1136 JNC $$IF66
1137 Message msgBootWriteError ;Indicate we couldn't write it ;AN000;
1138 stc ;CY=1 for error return ;AN000;
1139; $ELSE ;Set Media ID okay ;AN000;
1140 JMP SHORT $$EN66
1141$$IF66:
1142 clc ;CY=0 for good return ;AN000;
1143; $ENDIF ; ;AN000;
1144$$EN66:
1145; $ENDIF ; ;AN000;
1146$$EN62:
1147 ret ; ;AN000;
1148
1149WriteBootSector endp ; ;AN000;
1150
1151
1152;*****************************************************************************
1153;Routine name Create_Serial_ID
1154;*****************************************************************************
1155;
1156;DescriptioN&gml Create unique 32 bit serial number by getting current date and
1157; time and then scrambling it around.
1158;
1159;Called Procedures: Message (macro)
1160;
1161;Change History&gml Created 4/20/87 MT
1162;
1163;Input&gml None
1164;
1165;Output&gml Media_ID_Buffer.Serial_Number = set
1166; AX,CX,DX destroyed
1167; Serial_Num_Low/High = Serial number generated
1168;
1169;Psuedocode
1170;----------
1171;
1172; Get date (INT 21h, AH=2Bh)
1173; Get time (INT 21h, AH=2Ch)
1174; Serial_ID+0 = DX reg date + DX reg time
1175; Serial_ID+2 = CX reg date + CX reg time
1176; Serial_Num_Low = Serial_ID+2
1177; Serial_Num_High = Serial_ID+0
1178; ret
1179;*****************************************************************************
1180
1181Procedure Create_Serial_ID ; ;AN000;
1182
1183 DOS_Call Get_Date ;Get date from DOS ;AN000;
1184 push cx ;Save results ;AN000;
1185 push dx ; ;AN000;
1186 DOS_Call Get_Time ;Get_Time ;AN000;
1187 mov ax,dx ;Scramble it ;AN000;
1188 pop dx ; ;AN000;
1189 add ax,dx ; ;AN000;
1190 mov word ptr Media_ID_Buffer.Media_ID_Serial_Number+2,ax ; ;AC004;
1191 mov Serial_Num_Low,ax ; ;AN000;
1192 mov ax,cx ; ;AN000;
1193 pop cx ; ;AN000;
1194 add ax,cx ; ;AN000;
1195 mov word ptr Media_ID_Buffer.Media_ID_Serial_Number,ax ; ;AC004;
1196 mov Serial_Num_High,ax ; ;AN000;
1197 ret ; ;AN000;
1198
1199Create_Serial_ID endp ; ;AN000;
1200
1201;-------------------------------------------------------------------------------
1202
1203; OemDone:
1204;
1205OemDone proc near
1206
1207; if /b write out a fake dos & bios
1208 test switchmap, SWITCH_B
1209 jz Switch8?
1210 call WriteBogusDos
1211 retc
1212
1213Switch8?:
1214 test switchmap, SWITCH_8
1215 jz HardDisk?
1216 call ConvertToOldDirectoryFormat
1217 retc
1218
1219HardDisk?:
1220 cmp deviceParameters.DP_DeviceType, DEV_HARDDISK
1221 clc
1222 retnz
1223 call SetPartitionTable
1224
1225 return
1226
1227OemDone endp
1228
1229;------------------------------------------------------------------------------
1230
1231data segment public para 'DATA'
1232
1233 if IBMCOPYRIGHT
1234biosFilename db "x:\ibmbio.com",0
1235dosFilename db "x:\ibmdos.com",0
1236 else
1237biosFilename db "x:\io.sys",0
1238dosFilename db "x:\msdos.sys",0
1239 endif
1240
1241data ends
1242
1243; simple code to stuff bogus dos in old-style diskette.
1244
1245BogusDos:
1246 push cs
1247 pop ds
1248 mov al,20h
1249 out 20h,al ; turn on the timer so the disk motor
1250 mov si,mesofs ; shuts off
1251sys_mess_loop:
1252 lodsb
1253if ibmcopyright
1254end_sys_loop:
1255endif
1256 or al,al
1257 jz end_sys_loop
1258 mov ah,14
1259 mov bx,7
1260 int 16
1261 jmp sys_mess_loop
1262if not ibmcopyright
1263end_sys_loop:
1264 xor ah, ah ; get next char function
1265 int 16h ; call keyboard services
1266 int 19h ; reboot
1267endif
1268
1269 include BOOT.CL1
1270mesofs equ sysmsg - BogusDos
1271
1272WriteBogusDos proc near
1273
1274 mov al,driveLetter
1275 mov biosFilename,al
1276 mov dosFilename,al
1277 mov cx, ATTR_HIDDEN or ATTR_SYSTEM
1278 lea dx, biosFilename
1279 mov ah,CREAT
1280 int 21h
1281 mov bx,ax
1282 mov cx, BIOS_SIZE
1283 push ds
1284 push cs
1285 pop ds
1286 assume ds:code
1287 lea dx, BogusDos
1288 mov ah,WRITE
1289 int 21h
1290 pop ds
1291 assume ds:data
1292 mov ah,CLOSE
1293 int 21h
1294 mov cx, ATTR_HIDDEN or ATTR_SYSTEM
1295 lea dx, dosFilename
1296 mov ah,CREAT
1297 int 21h
1298 mov bx,ax
1299 mov cx, DOS_SIZE
1300 lea dx, BogusDos
1301 mov ah,WRITE
1302 int 21h
1303 mov ah,CLOSE
1304 int 21h
1305; Comunicate system size to the main format program
1306 mov word ptr DOS.FileSizeInBytes,DOS_SIZE ;an000; dms;get size of DOS
1307 mov word ptr DOS.FileSizeInBytes+2,00h ;an000; dms;
1308
1309 xor dx,dx
1310 mov ax,DOS_SIZE
1311 call AddToSystemSize
1312
1313 mov word ptr Bios.FileSizeInBytes,BIOS_SIZE ;an000; dms;get size of BIOS
1314 mov word ptr Bios.FileSizeInBytes+2,00h ;an000; dms;
1315
1316 xor dx,dx
1317 mov ax,BIOS_SIZE
1318 call AddToSystemSize
1319
1320 clc
1321 return
1322
1323WriteBogusDos endp
1324
1325;-------------------------------------------------------------------------------
1326
1327ConvertToOldDirectoryFormat proc near
1328
1329;
1330; convert to 1.1 directory
1331;
1332 mov al,drive ; Get 1st sector of directory
1333 mov cx,1 ; 1.1 directory always starts on
1334 mov dx,3 ; sector 3
1335 lea bx,scratchBuffer
1336;Root Directory always in 1st 32mb of partition
1337 mov Read_Write_Relative.Start_Sector_High,0 ; ;AN000;
1338 call Read_Disk ; ;AC000;
1339 jnc DirectoryRead
1340 Message msgDirectoryReadError ; ;AC000;
1341 stc
1342 ret
1343DirectoryRead:
1344
1345; fix attribute of ibmbio and ibmdos
1346 lea bx,scratchBuffer
1347 mov byte ptr [bx].dir_attr, ATTR_HIDDEN or ATTR_SYSTEM
1348 add bx, size dir_entry
1349 mov byte ptr [bx].dir_attr, ATTR_HIDDEN or ATTR_SYSTEM
1350
1351wrtdir:
1352 mov al,[drive] ; write out the directory
1353 cbw
1354 mov cx,1
1355 mov dx,3
1356 lea bx,scratchBuffer
1357;Root Directory always in 1st 32mb of partition
1358 mov Read_Write_Relative.Start_Sector_High,0 ; ;AN000;
1359 call Write_Disk ; ;AC000;
1360 jnc DirectoryWritten
1361 Message msgDirectoryWriteError ; ;AC000;
1362 stc
1363 ret
1364DirectoryWritten:
1365
1366 test switchmap, SWITCH_S ; Was system requested?
1367 retnz ; yes, don't write old boot sector
1368 mov al,drive
1369 cbw
1370 mov bx,offset boot2 ; no, write old boot sector
1371 cmp deviceParameters.DP_BPB.BPB_Heads, 1
1372 je bootset8
1373 mov word ptr [bx+3],0103h ; start address for double sided drives
1374bootset8:
1375 mov cx,1
1376 xor dx,dx
1377;Boot record in 1st 32mb of partition
1378 mov Read_Write_Relative.Start_Sector_High,0 ; ;AN000;
1379 call Write_Disk ; ;AC000;
1380 retnc
1381
1382 Message msgBootWriteError ; ;AC000;
1383 stc
1384 ret
1385
1386ConvertToOldDirectoryFormat endp
1387
1388;-------------------------------------------------------------------------------
1389
1390a_PartitionTableEntry struc
1391BootInd db ?
1392BegHead db ?
1393BegSector db ?
1394BegCylinder db ?
1395SysInd db ?
1396EndHead db ?
1397EndSector db ?
1398EndCylinder db ?
1399RelSec dd ?
1400CSec dd ?
1401a_PartitionTableEntry ends
1402
1403; structure of the IBM hard disk boot sector:
1404IBMBoot STRUC
1405 db 512 - (4*size a_PartitionTableEntry + 2) dup(?)
1406PartitionTable db 4*size a_PartitionTableEntry dup(?)
1407Signature dw ?
1408IBMBoot ENDS
1409
1410
1411;*****************************************************************************
1412;Routine name: SetPartitionTable
1413;*****************************************************************************
1414;
1415;Description: Find location for DOS partition in partition table, get the
1416; correct system indicator byte, and write it out. If can not
1417; read/write boot record or can't find DOS partition, display
1418; error
1419;
1420;Called Procedures: Message (macro)
1421; Determine_Partition_Type
1422; ReadSector
1423; WriteSector
1424;
1425;Change History: Created 4/20/87 MT
1426;
1427;Input: None
1428;
1429;Output: CY set if error
1430;
1431;Psuedocode
1432;----------
1433;
1434; Read the partition table (Call ReadSector)
1435; IF ok
1436; IF boot signature of 55AAh
1437; Point at system partition table
1438; SEARCH
1439; Assume DOS found
1440; IF System_Indicator <> 1,AND
1441; IF System_Indicator <> 4,AND
1442; IF System_Indicator <> 6
1443; STC (DOS not found)
1444; ELSE
1445; CLC
1446; ENDIF
1447; EXITIF DOS found (CLC)
1448; CALL Determine_Partition_Type
1449; Write the partition table (CALL WriteSector)
1450; IF error
1451; Display boot write error message
1452; stc
1453; ELSE
1454; clc
1455; ENDIF
1456; ORELSE
1457; Point at next partition entry (add 16 to partition table ptr)
1458; ENDLOOP if checked all 4 partition entries
1459; Display Bad partition table message
1460; stc
1461; ENDSRCH
1462; ELSE invalid boot record
1463; Display Bad partition table message
1464; stc
1465; ENDIF
1466; ELSE error
1467; Display Partition table error
1468; stc
1469; ENDIF
1470; ret
1471;*****************************************************************************
1472
1473Procedure SetPartitionTable ; ;AN000;
1474
1475 xor ax, ax ;Head ;AC000;
1476 xor bx, bx ;Cylinder ;AC000;
1477 xor cx, cx ;Sector ;AC000;
1478 lea dx, boot2 ;Never use 1.x boot on hardfile,; ;
1479 call ReadSector ;this will use space as buffer ; ;
1480; $IF NC ;If read okay ;AN000;
1481 JC $$IF70
1482 cmp Boot2.Boot_Signature,Boot_ID ; ;AC000;
1483; $IF E ;Does signature match? ;AN000;
1484 JNE $$IF71
1485 lea bx, boot2.PartitionTable ;Yes, point at partition table ;AN000;
1486; $SEARCH ;Look for DOS partition ;AN000;
1487$$DO72:
1488 cmp [bx].sysind,FAT12_File_System ; ;AC000;
1489; $IF NE,AND ; ;AN000;
1490 JE $$IF73
1491 cmp [bx].sysind,FAT16_File_System ; ;AC000;
1492; $IF NE,AND ; ;AN000;
1493 JE $$IF73
1494 cmp [bx].sysind,New_File_System ; ;AC000;
1495; $IF NE ; ;AN000;
1496 JE $$IF73
1497 stc ;We didn't find partition ;AN000;
1498; $ELSE ; ;AN000;
1499 JMP SHORT $$EN73
1500$$IF73:
1501 clc ;Indicate found partition ;AN000;
1502; $ENDIF ; ;AN000;
1503$$EN73:
1504; $EXITIF NC ;Get correct id for it ;AN000;
1505 JC $$IF72
1506 CALL Determine_Partition_Type ; ;AN000;
1507 mov ax, 0 ;Head ; ;
1508 mov bx, 0 ;Cylinder ; ;
1509 mov cx, 0 ;Sector ; ;
1510 lea dx, boot2 ; ; ;
1511 call WriteSector ;Write out partition table ; ;
1512; $IF C ;Error writing boot record ;AN000;
1513 JNC $$IF77
1514 MESSAGE msgPartitionTableWriteError ; ;AC000;
1515 stc ;Set CY to indicate error ; ;
1516; $ELSE ; ;AN000;
1517 JMP SHORT $$EN77
1518$$IF77:
1519 clc ;No error means no CY ; ;
1520; $ENDIF ; ;AN000;
1521$$EN77:
1522; $ORELSE ; ;AN000;
1523 JMP SHORT $$SR72
1524$$IF72:
1525 add bx,size a_PartitionTableEntry ; ; ;
1526 cmp bx,(offset Boot2.PartitionTable)+4*size a_PartitionTableEntry ; ;
1527; $ENDLOOP ;Checked all 4 partition entries;AN000;
1528 JMP SHORT $$DO72
1529 MESSAGE msgBadPartitionTable ;Tell user bad table ;AC000;
1530 stc ;Set CY for exit ; ;
1531; $ENDSRCH ; ;AN000;
1532$$SR72:
1533; $ELSE ;Invalid boot record ;AN000;
1534 JMP SHORT $$EN71
1535$$IF71:
1536 MESSAGE msgBadPartitionTable ; ;AC000;
1537 stc ;Set CY for error return ; ;
1538; $ENDIF ; ;AN000;
1539$$EN71:
1540; $ELSE ;Couldn't read boot record ;AN000;
1541 JMP SHORT $$EN70
1542$$IF70:
1543 MESSAGE msgPartitionTableReadError ; ;AC000;
1544 stc ;Set CY for error return ; ;
1545; $ENDIF ; ;AN000;
1546$$EN70:
1547 ret ; ; ;
1548
1549SetPartitionTable endp ; ;AN000;
1550
1551;*****************************************************************************
1552;Routine name: Determine_Partition_Type
1553;*****************************************************************************
1554;
1555;DescriptioN: Set the system indicator field to its correct value as
1556; determined by the following rules:
1557;
1558; - Set SysInd = 01h if partition or logical drive size is < 10mb
1559; and completely contained within the first 32mb of DASD.
1560; - Set SysInd = 04h if partition or logical drive size is >10mb,
1561; <32mb, and completely contained within the first 32mb of DASD
1562; - Set SysInd to 06h if partition or logical drive size is > 32mb,
1563;
1564;Called Procedures: Message (macro)
1565;
1566;Change History: Created 3/18/87 MT
1567;
1568;Input: BX has offset of partition table entry
1569; fBigFAT = TRUE if 16bit FAT
1570;
1571;Output: BX.SysInd = correct partition system indicator value (1,4,6)
1572;
1573;Psuedocode
1574;----------
1575; Add partition start location to length of partition
1576; IF end > 32mb
1577; BX.SysInd = 6
1578; ELSE
1579; IF fBigFat
1580; BX.SysInd = 4
1581; ELSE
1582; BX.SysInd = 1
1583; ENDIF
1584; ret
1585;*****************************************************************************
1586
1587Procedure Determine_Partition_Type ;AN000;
1588
1589 mov dx,word ptr [bx].Csec+2 ;an000; dms;Get high word of sector count
1590 cmp dx,0 ;AN000; ;> 32Mb?
1591; $IF NE ;AN000; ;yes
1592 JE $$IF87
1593 mov [BX].SysInd,New_File_System ;AN000; ;type 6
1594; $ELSE ;AN000;
1595 JMP SHORT $$EN87
1596$$IF87:
1597 call Calc_Total_Sectors_For_Partition ;an000; dms;returns DX:AX total sectors
1598 cmp DeviceParameters.DP_BPB.BPB_HiddenSectors[+2],0 ;an000; dms;> 32Mb?
1599; $if ne ;an000; dms;yes
1600 JE $$IF89
1601 mov [bx].SysInd,New_File_System ;an000; dms; type 6
1602; $else ;an000; dms;
1603 JMP SHORT $$EN89
1604$$IF89:
1605 cmp dx,0 ;an000; dms; partition > 32 Mb?
1606; $if ne ;an000; dms; yes
1607 JE $$IF91
1608 mov [bx].SysInd,New_File_System ;an000; dms; type 6
1609; $else ;an000; dms; < 32 Mb partition
1610 JMP SHORT $$EN91
1611$$IF91:
1612 cmp fBigFat,True ;an000; ;16 bit FAT
1613; $IF E ;AC000; ;yes
1614 JNE $$IF93
1615 mov [BX].SysInd,FAT16_File_System ;an000; ;type 4
1616; $ELSE ;an000; ;12 bit FAT
1617 JMP SHORT $$EN93
1618$$IF93:
1619 mov [bx].SysInd,FAT12_File_System ;an000; ;type 1
1620; $ENDIF ;AN000;
1621$$EN93:
1622; $ENDIF ;an000;
1623$$EN91:
1624; $ENDIF ;an000;
1625$$EN89:
1626; $endif ;an000;
1627$$EN87:
1628 ret ;an000;
1629
1630Determine_Partition_Type endp ; ;AN000;
1631
1632
1633;=========================================================================
1634; Calc_Total_Sectors_For_Partition : This routine determines the
1635; total number of sectors within
1636; this partition.
1637;
1638; Inputs : DeviceParameters
1639;
1640; Outputs : DX:AX - Double word partition size
1641;=========================================================================
1642
1643Procedure Calc_Total_Sectors_For_Partition ;an000; dms;
1644
1645 mov ax,word ptr DeviceParameters.DP_BPB.BPB_HiddenSectors[+0] ;an000; dms; low word
1646 mov dx,word ptr DeviceParameters.DP_BPB.BPB_HiddenSectors[+2] ;an000; dms; high word
1647 cmp DeviceParameters.DP_BPB.BPB_TotalSectors,0 ;an000; dms; extended BPB?
1648; $if e ;an000; dms; yes
1649 JNE $$IF99
1650 add ax,word ptr DeviceParameters.DP_BPB.BPB_BigTotalSectors[+0] ;an000; dms; add in low word
1651 adc dx,0 ;an000; dms; pick up carry if any
1652 add dx,word ptr DeviceParameters.DP_BPB.BPB_BigTotalSectors[+2] ;an000; dms; add in high word
1653; $else ;an000; dms; standard BPB
1654 JMP SHORT $$EN99
1655$$IF99:
1656 add ax,word ptr DeviceParameters.DP_BPB.BPB_TotalSectors ;an000; dms; add in total sector count
1657 adc dx,0 ;an000; dms; pick up carry if any
1658; $endif ;an000; dms;
1659$$EN99:
1660
1661 ret
1662
1663Calc_Total_Sectors_For_Partition endp
1664
1665
1666;-------------------------------------------------------------------------------
1667; ReadSector:
1668; Read one sector
1669;
1670; Input:
1671; ax - head
1672; bx - cylinder
1673; cx - sector
1674; dx - transfer address
1675
1676ReadSector proc near
1677
1678 mov TrackReadWritePacket.TRWP_FirstSector, cx
1679 mov cx,(RAWIO shl 8) or READ_TRACK
1680 call SectorIO
1681 return
1682
1683ReadSector endp
1684
1685;-------------------------------------------------------------------------------
1686; WriteSector:
1687; Write one sector
1688;
1689; Input:
1690; ax - head
1691; bx - cylinder
1692; cx - sector
1693; dx - transfer address
1694
1695WriteSector proc near
1696
1697 mov TrackReadWritePacket.TRWP_FirstSector, cx
1698 mov cx,(RAWIO shl 8) or WRITE_TRACK
1699 call SectorIO
1700 return
1701
1702WriteSector endp
1703
1704;-------------------------------------------------------------------------------
1705; SectorIO:
1706; Read/Write one sector
1707;
1708; Input:
1709; ax - head
1710; bx - cylinder
1711; cx - (RAWIO shl 8) or READ_TRACK
1712; - (RAWIO shl 8) or WRITE_TRACK
1713; dx - transfer address
1714
1715SectorIO proc near
1716
1717 mov TrackReadWritePacket.TRWP_Head, ax
1718 mov TrackReadWritePacket.TRWP_Cylinder, bx
1719 mov WORD PTR TrackReadWritePacket.TRWP_TransferAddress, dx
1720 mov WORD PTR TrackReadWritePacket.TRWP_TransferAddress + 2, ds
1721 mov TrackReadWritePacket.TRWP_SectorsToReadWrite, 1
1722
1723 mov bl, drive
1724 inc bl
1725 mov ax, (IOCTL shl 8) or GENERIC_IOCTL
1726 lea dx, trackReadWritePacket
1727 int 21H
1728 return
1729
1730SectorIO endp
1731
1732;-------------------------------------------------------------------------------
1733
1734data segment public para 'DATA'
1735
1736oldDrive db ?
1737
1738FCBforVolumeIdSearch db 0ffH
1739 db 5 dup(0)
1740 db 08H
1741 db 0
1742 db "???????????"
1743 db 40 DUP(0)
1744
1745data ends
1746
1747GetVolumeId proc near
1748; Input:
1749; dl = drive
1750; di = name buffer
1751
1752; Save current drive
1753 mov ah,19H
1754 int 21H
1755 mov oldDrive, al
1756
1757; Change current drive to the drive that has the volume id we want
1758 mov ah, 0eH
1759 int 21H
1760
1761; Search for the volume id
1762 mov ah, 11H
1763 lea dx, FCBforVolumeIdSearch
1764 int 21H
1765 push ax
1766
1767; Restore current drive
1768 mov ah, 0eH
1769 mov dl,oldDrive
1770 int 21H
1771
1772; Did the search succeed?
1773 pop ax
1774 or al,al
1775 jz CopyVolumeId
1776 stc
1777 ret
1778
1779CopyVolumeId:
1780; Find out where the FCB for the located volume id was put
1781 mov ah,2fH
1782 int 21H
1783
1784; Copy the Volume Id
1785 mov si, bx
1786 add si, 8
1787 push es
1788 push ds
1789 pop es
1790 pop ds
1791 mov cx, 11
1792 rep movsb
1793 push es
1794 pop ds
1795
1796 clc
1797 ret
1798
1799GetVolumeId endp
1800
1801data segment public para 'DATA'
1802oldVolumeId db 11 dup(0)
1803data ends
1804
1805CheckVolumeId proc near
1806
1807; Get the volume id that's on the disk
1808 lea di, oldVolumeId
1809 mov dl, drive
1810 call GetVolumeId
1811 jnc Ask_User ;Did we find one?
1812 clc ;No, return with no error
1813 ret
1814
1815; Ask the user to enter the volume id that he/she thinks is on the disk
1816; (first blank out the input buffer)
1817Ask_User:
1818
1819 Message msgWhatIsVolumeId? ; ;AC000;
1820 ;lea dx, ptr_msgWhatIsVolumeId?
1821 ;call std_printf
1822 call user_string
1823 call crlf
1824
1825; If the user just pressed ENTER, then there must be no label
1826 cmp inbuff+1, 0
1827 jne CompareVolumeIds
1828 cmp oldVolumeId, 0
1829 jne BadVolumeId
1830 ret
1831
1832CompareVolumeIds:
1833; pad the reponse with blanks
1834; The buffer is big enough so just add 11 blanks to what the user typed in
1835 push ds
1836 pop es
1837 mov cx, Label_Length ;AC000;
1838 xor bx,bx
1839 mov bl, inbuff + 1
1840 lea di, inbuff + 2
1841 add di, bx
1842 mov al, ' '
1843 rep stosb
1844; Make the reply all uppercase
1845 mov byte ptr Inbuff+2+Label_Length,ASCIIZ_End ;Make string ASCIIZ ;AN000;
1846 mov dx, offset inbuff + 2 ;Start of buffer ;AC000;
1847 mov al,22h ;Capitalize asciiz ;AC000;
1848 DOS_Call GetExtCntry ;Do it ;AC000;
1849
1850; Now compare what the user specified with what is really out there
1851 mov cx, Label_Length ; ;AC000;
1852 lea si, inbuff + 2
1853 lea di, oldVolumeId
1854 repe cmpsb
1855 jne BadVolumeId
1856 ret
1857
1858BadVolumeId:
1859 Message msgBadVolumeID ; ;AC000;
1860 stc
1861 ret
1862
1863CheckVolumeId endp
1864
1865
1866Check_Switch_8_B proc near
1867
1868 test SwitchMap, SWITCH_B ;/8/B <> /V because ;AC007;
1869; $IF NZ,AND ; old directory type ;AC007;
1870 JZ $$IF102
1871 test SwitchMap, Switch_8 ; used which didn't support ;AC007;
1872; $IF NZ,AND ; volume labels. ;AC007;
1873 JZ $$IF102
1874 test SwitchMap, SWITCH_V ; ;AC007;
1875; $IF NZ ; ;AC007;
1876 JZ $$IF102
1877 Message msgIncompatibleParameters ;Tell user ;AC007;
1878 mov Fatal_Error,Yes ;Bad stuff ;AC007;
1879; $ELSE ;No problem so far ;AC007;
1880 JMP SHORT $$EN102
1881$$IF102:
1882 test SwitchMap, Switch_B ;Can't reserve space and ;AC007;
1883; $IF NZ,AND ; install sys files at the ;AC007;
1884 JZ $$IF104
1885 test SwitchMap, Switch_S ; same time. ;AC007;
1886; $IF NZ ; No /S/B ;AC007;
1887 JZ $$IF104
1888 Message msgIncompatibleParameters ;Tell user ;AC007;
1889 mov Fatal_Error,Yes ;Bad stuff ;AC007;
1890; $ELSE ;Still okay ;AC007;
1891 JMP SHORT $$EN104
1892$$IF104:
1893 test SwitchMap,Switch_1 ;/1/8/4 not okay with /N/T ;AC007;
1894; $IF NZ,OR ; ;AC007;
1895 JNZ $$LL106
1896 test SwitchMap,Switch_8 ; ;AC007;
1897; $IF NZ,OR ; ;AC007;
1898 JNZ $$LL106
1899 test SwitchMap,Switch_4 ; ;AC007;
1900; $IF NZ ; ;AC007;
1901 JZ $$IF106
1902$$LL106:
1903 test SwitchMap,(Switch_T or Switch_N) ; ;AC007;
1904; $IF NZ ;Found /T/N <> /1/8 ;AC007;
1905 JZ $$IF107
1906 Message msgIncompatibleParameters ;Tell user ;AC007;
1907 mov Fatal_Error,Yes ;Bad stuff ;AC007;
1908; $ELSE ; ;ac007;
1909 JMP SHORT $$EN107
1910$$IF107:
1911 test SwitchMap,Switch_V ;ac007;
1912; $IF NZ,AND ;ac007;
1913 JZ $$IF109
1914 test SwitchMap,Switch_8 ;ac007;
1915; $IF NZ ;ac007;
1916 JZ $$IF109
1917 Message msgIncompatibleParameters ;ac007;
1918 mov Fatal_Error,Yes ;ac007;
1919; $ENDIF ;ac007;
1920$$IF109:
1921; $ENDIF ; ;AC007;
1922$$EN107:
1923; $ENDIF ; ;AC007;
1924$$IF106:
1925; $ENDIF ; ;AC007;
1926$$EN104:
1927; $ENDIF ; ;AC007;
1928$$EN102:
1929 ret
1930
1931Check_Switch_8_B endp
1932
1933
1934code ends
1935 end
1936 \ No newline at end of file