1 ; e forproc.sal= @(#)ibmfor.asm 1.28 85/10/15
4 ;******************************************************************************
6 ;AN002 - D304 Modify Boot record structure for OS2 11/09/87 J.K.
7 ;******************************************************************************
11 ;-------------------------------------------------------------------------------
12 ; Public for debugging only
15 public LastChanceToSaveIt
16 public WriteBootSector
19 public ConvertToOldDirectoryFormat
20 public SetPartitionTable
30 public WeCanNotIgnoreThisError
37 public DirectoryWritten
38 public FCBforVolumeIdSearch
40 public CompareVolumeIds
50 public Read_Write_Relative
52 public Serial_Num_High
55 public ptr_msgWhatIsVolumeId?
57 public trackReadWritePacket
64 ;-------------------------------------------------------------------------------
66 data segment public para
'DATA'
69 code segment public para
'CODE'
70 assume
cs:code,ds:data
74 public LastChanceToSaveIt
79 data segment public para
'DATA'
80 extrn AddToSystemSize
:near
81 extrn currentCylinder
:word
82 extrn currentHead
:word
83 extrn deviceParameters
:byte
85 extrn driveLetter
:byte
90 extrn fLastChance
:byte
91 extrn Fatal_Error
: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
112 extrn msgFormatBroken
:byte
117 extrn PrintString
:near
118 extrn std_printf
:near
120 extrn user_string
:near
122 extrn Write_Disk
:near
125 ;-------------------------------------------------------------------------------
134 ; This defines all the int 21H system calls
141 ;-------------------------------------------------------------------------------
142 ; These are the data structures which we will need
150 ;-------------------------------------------------------------------------------
151 ; And this is the actual data
152 data segment public para
'DATA'
154 Read_Write_Relative Relative_Sector_Buffer
<> ; ;AN000;
158 BiosFile db "x:\IBMBIO.COM", 0
159 DosFile db "x:\IBMDOS.COM", 0
161 BiosFile db "x:\IO.SYS", 0
162 DosFile db "x:\MSDOS.SYS", 0
165 Dummy_Label db "NO NAME "
166 Dummy_Label_Size dw 11 ;AN028
168 Serial_Num_Low dw 0 ; ;AN000;
169 Serial_Num_High dw 0 ; ;AN000;
171 SizeMap db 0 ; ;AN000;
173 trackReadWritePacket a_TrackReadWritePacket
<>
176 ; BIOS parameter blocks for various media
177 customBPBs
label byte
178 BPB92 a_BPB
<512, 2, 1, 2, 112, 2*9*40, 0fdH, 2, 9, 2, 0, 0, 0, 0>
179 BPB91 a_BPB
<512, 1, 1, 2, 64, 1*9*40, 0fcH, 2, 9, 1, 0, 0, 0, 0>
180 BPB82 a_BPB
<512, 2, 1, 2, 112, 2*8*40, 0ffH, 1, 8, 2, 0, 0, 0, 0>
181 BPB81 a_BPB
<512, 1, 1, 2, 64, 1*8*40, 0feH, 1, 8, 1, 0, 0, 0, 0>
182 BPB720 a_BPB
<512, 2, 1, 2, 112, 2*9*80, 0F9h, 3, 9, 2, 0, 0, 0, 0>
186 boot2 db 0,0,0, "Boot 1.x"
202 scratchBuffer db 512 dup(?
)
204 ptr_msgWhatIsVolumeId?
dw offset msgWhatIsVolumeId?
205 dw offset driveLetter
208 FAT12_String db "FAT12 "
209 FAT16_String db "FAT16 "
211 Media_ID_Buffer Media_ID
<>
215 ;-------------------------------------------------------------------------------
217 ; Called whenever a different disk is about to be accessed
220 ; al - drive letter (0=A, 1=B, ...)
226 push ax ; save drive letter
227 mov bl,al ; Set up GENERIC IOCTL REQUEST preamble
229 mov ax,(IOCTL
SHL 8) + Set_Drv_Owner
; IOCTL function
236 ;-------------------------------------------------------------------------------
238 ; Check switches against device parameters
239 ; Use switches to modify device parameters
245 ; deviceParameters may be modified
256 CheckSwitches proc
near
260 ;lea dx, msgInvalidParameter ;AC000;
261 test switchmap
, SWITCH_C
263 Message msgInvalidParameter
;AC000;
265 ;call PrintString ;AC000;
271 test SwitchMap
,Switch_F
;Specify size? ;AN001;
272 ; $IF NZ ;Yes ;AN001;
274 test SwitchMap
,(Switch_1
+Switch_8
+Switch_4
+Switch_N
+Switch_T
) ;AN001;
275 ; $IF NZ ;/F replaces above switches ;AN001;
277 Message msgIncompatibleParameters
;Print error ;AN001;
278 mov Fatal_Error
,Yes
;Force exit ;AN001;
282 call Size_To_Switch
;Go set switches based ;AN001;
283 ; $ENDIF ; on the size ;AN001;
287 cmp Fatal_Error
,NO
; ;AN007;
290 call Check_Switch_8_B
; ;ac007
294 cmp Fatal_Error
,Yes
; ;AN007;
295 jne ExclChkDone
; ;AN007;
300 ; Patch the boot sector so that the boot strap loader knows what disk to
302 ; mov Boot.Boot_PhyDrv, 00H ;AC000;
303 mov Boot
.EXT_PHYDRV
, 00H ;AN00?;
305 cmp deviceParameters
.DP_DeviceType
, DEV_HARDDISK
306 jne CheckFor5InchDrives
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
314 Message msgIncompatibleParametersForHardDisk
; ;AC000;
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.
322 SwitchesOkForHardDisk:
323 SaveReg
<ax,bx,cx,dx,ds>
327 lea bx,scratchBuffer
; ScratchBuffer := Absolute_Read_Disk(
328 ;INT 25h ; Logical_sec_1 )
330 ;Assume Dir for vol ID exists in 1st 32mb of partition
332 mov Read_Write_Relative
.Start_Sector_High
,0
333 call Read_Disk
; ;AC000;
334 ; on the stack. We throw them away
338 RestoreReg
<ds,dx,cx,bx,ax>
341 CheckSignature: ; IF (Boot.Boot_Signature != aa55)
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;
349 test SwitchMap
,(SWITCH_Select
or SWITCH_AUTOTEST
) ;Should we prompt for vol label?;AN000;
350 ; $IF Z ;Yes, if /Select not entered ;AN000;
352 call CheckVolumeId
;Go ask user for vol label ; ;
353 ; $ELSE ;/Select entered ;AN000;
356 clc ;CLC indicates passed label test;AN000;
357 ; $ENDIF ; for the return ;AN000;
363 Incomp_Message: ;an000; fix PTM 809
365 Message msgIncompatibleParameters
;an000; print incompatible parms
366 stc ;an000; signal error
367 return
;an000; return to caller
370 ;call PrintString ; ;AC000;
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
381 cmp byte ptr deviceParameters
.DP_DeviceType
,DEV_5INCH
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;
388 or ax,Switch_Z
;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
398 ; We have a 96tpi floppy drive
399 ; /4 allows just about all switches however, /1 requires /4
401 ;;;DMS;;test switchmap, SWITCH_8 ;an000; If /8 we have an error
402 ;;;DMS;;jnz Incomp_message ;an000; tell user error
404 test switchmap
, SWITCH_4
405 jnz CheckForInterestingSwitches
;If /4 check /N/T/V/S
407 test switchmap
, SWITCH_1
;If /1 and /4 check others
410 ;If only /1 with no /4, see if /N/T
411 test SwitchMap
,(Switch_N
or Switch_T
)
412 jnz CheckForInterestingSwitches
414 jmp Incomp_message
;an000; tell user error occurred
417 ;Ignore /4 for non-96tpi 5 1/4" drives
418 and switchmap
, not SWITCH_4
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
427 ;Are any interesting switches set?
428 CheckForInterestingSwitches:
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
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
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
440 ;If 96tpi drive and /1 exists with /N/T, then okay, otherwise error
441 cmp byte ptr deviceParameters
.DP_DeviceType
,DEV_5INCH96TPI
444 test SwitchMap
, not (SWITCH_1
or SWITCH_N
or SWITCH_T
or SWITCH_V
)
446 test SwitchMap
, not (SWITCH_S
or Switch_Backup
or SWITCH_SELECT
or Switch_Autotest
)
450 Message msgIncompatibleParameters
; ;AC000;
454 jmp Got_BPB_Ok
;Sleazy, but je won't reach it
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
466 ; Combo's that we look for - 96tpi drive @ /T:40, /N:9
467 ; 96tpi drive @ /T:40, /N:8
469 ; Look for this combo after we set everything up with the /T/N routine
470 ; 1.44 drive @ /T:80, /N:9
473 cmp byte ptr deviceParameters
.DP_DeviceType
,DEV_5INCH96TPI
476 cmp TrackCnt
,40 ;Look for 40 tracks
479 cmp NumSectors
,9 ;9 sectors?
482 cmp NumSectors
,8 ;8 sectors?
483 jne Goto_Got_BPB
;Nope, different type, let it go thru
485 or SwitchMap
,SWITCH_8
;Yes, turn on /8 switch
488 and SwitchMap
,not (SWITCH_N
or SWITCH_T
) ;Turn off /T/N
492 ; if we have a 96 tpi drive then we will be using it in 48 tpi mode
494 cmp byte ptr deviceParameters
.DP_DeviceType
, DEV_5INCH96TPI
497 mov byte ptr deviceParameters
.DP_MediaType
, 1
498 mov word ptr deviceParameters
.DP_Cylinders
, 40
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
505 ; At this point we know that we will require a special BPB
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
513 ; ax is used to keep track of which of the above BPB's we want
518 test switchmap
, SWITCH_1
523 test switchmap
, SWITCH_8
524 jz Not8SectorsPerTrack
526 ; /8 implies Old_Dir = TRUE
530 ; Ok now we know which BPB to use so lets move it to the device parameters
536 lea di, deviceParameters
.DP_BPB
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
550 test switchmap
,SWITCH_N
+SWITCH_T
554 ; Set up NumSectors and SectorsPerTrack entries correctly
555 test switchmap
,SWITCH_N
557 mov ax,word ptr NumSectors
558 mov DeviceParameters
.DP_BPB
.BPB_SectorsPerTrack
,ax
559 jmp short Handle_Cyln
561 mov ax,deviceParameters
.DP_BPB
.BPB_SectorsPerTrack
565 test switchmap
,SWITCH_T
567 ; Set up TrackCnt and Cylinders entries correctly
569 mov DeviceParameters
.DP_Cylinders
,ax
572 mov ax,DeviceParameters
.DP_Cylinders
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
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.
586 cmp byte ptr deviceParameters
.DP_DeviceType
,DEV_5INCH96TPI
589 cmp byte ptr deviceParameters
.DP_DeviceType
,DEV_5INCH
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
605 SaveReg
<ds,es,si,di,cx>
608 mov cx,seg
data ;Setup seg regs, just in case they ain't!
612 mov si,offset BPB720
;Copy the BPB!
613 mov di,offset deviceParameters
.DP_BPB
616 RestoreReg
<cx,di,si,es,ds>
619 ;End PTM P868 fix ****************************************
623 mov bx,DeviceParameters
.DP_BPB
.BPB_Heads
624 mul bl ; AX = # of sectors * # of heads
625 mul TrackCnt
; DX:AX = Total Sectors
627 jnz Got_BigTotalSectors
628 mov DeviceParameters
.DP_BPB
.BPB_TotalSectors
,ax
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
635 mov DeviceParameters
.DP_BPB
.BPB_TotalSectors
,dx
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)
643 mov bl,DeviceParameters
.DP_BPB
.BPB_SectorsPerCluster
644 div bx ; DX:AX contains # of clusters
645 ; now multiply by 3/2
650 xor dx,dx ; throw away modulo
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
667 ;*****************************************************************************
668 ;Routine name: Size_To_Switch
669 ;*****************************************************************************
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.
681 ;Called Procedures: Low_Density_Drive
682 ; High_Capacity_Drive
686 ;Change History: Created 8/1/87 MT
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 ;*****************************************************************************
697 Procedure Size_To_Switch
699 cmp SizeMap
,0 ;Are there sizes entered? ;AN001;
700 ; $IF NE ;Yes ;AN001;
702 cmp deviceParameters
.DP_DeviceType
,DEV_HARDDISK
;AN000; ;AN001;
703 ; $IF E ;No size for fixed disk ;AN001;
705 Message msgIncompatibleParametersForHardDisk
; ;AN001;
706 ; $ELSE ;Diskette, see what type ;AN001;
709 cmp byte ptr deviceParameters
.DP_DeviceType
,DEV_5INCH
; ;AN001;
710 ; $IF E ;Found 180/360k drive ;AN001;
712 call Low_Density_Drive
;Go set switches ;AN001;
713 ; $ELSE ;Check for 96TPI ;AN001;
716 cmp byte ptr deviceParameters
.DP_DeviceType
,DEV_5INCH96TPI
;AN001; ;
717 ; $IF E ;Found it ;AN001;
719 call High_Capacity_Drive
; ;AN001;
723 cmp byte ptr deviceParameters
.DP_DeviceType
,DEV_3INCH720KB
;AN0001;
724 ; $IF E ;Found 720k drive ;AN001;
726 call Small_Drives
; ;AN001;
730 cmp byte ptr deviceParameters
.DP_DeviceType
,DEV_OTHER
;AN001;
731 ; $IF E ;Must be 1.44mb ;AN001;
733 call Other_Drives
; ;AN001;
737 Message msgParametersNotSupportedByDrive
; ;AN001;
738 mov Fatal_Error
,Yes
; ;AN001;
751 cmp Fatal_Error
,Yes
; ;AN001;
754 Message msgIncompatibleParameters
; ;AN001;
758 cmp deviceParameters
.DP_DeviceType
,DEV_HARDDISK
;an001;
761 mov Fatal_Error
,Yes
;an001;
765 and SwitchMap
,not Switch_F
;Turn off /F so doesn't effect ;AN001;
766 ret ; following logic ;AN001;
770 ;*****************************************************************************
771 ;Routine name: High_Capacity_Drive
772 ;*****************************************************************************
774 ;Description: See if 1.2mb diskette, or one of the other 5 1/4 sizes. Turn
775 ; on /4 if 360k or lower
777 ;Called Procedures: Low_Density_Drive
779 ;Change History: Created 8/1/87 MT
784 ;Output: Fatal_Error = YES/NO
785 ; SwitchMap = Switch_4 if 360k or lowere
786 ;*****************************************************************************
788 Procedure High_Capacity_Drive
;
790 test SizeMap
,Size_1200
;1.2mb diskette? ;AN001;
791 ; $IF Z ;Nope ;AN001;
793 call Low_Density_Drive
;Check for /4 valid types ;AN001;
794 cmp Fatal_Error
, No
;Find 160/180/320/360k? ;AN001;
797 or SwitchMap
,Switch_4
;Turn on /4 switch ;AN001;
798 ; $ELSE ;Did not find valid size ;AN001;
801 mov Fatal_Error
,Yes
;Indicate invalid device ;AN001;
808 High_Capacity_Drive endp
810 ;*****************************************************************************
811 ;Routine name: Low_Density_Drive
812 ;*****************************************************************************
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
817 ;Called Procedures: Low_Density_Drive
819 ;Change History: Created 8/1/87 MT
824 ;Output: Fatal_Error = YES/NO
825 ; SwitchMap = Switch_1, Switch_8 to define size
830 ; 160k = Switch_1 + Switch_8
831 ;*****************************************************************************
834 Procedure Low_Density_Drive
; ;AN000;
836 test SizeMap
,Size_160
; ;AN001;
839 or SwitchMap
,Switch_1
+Switch_8
; ;AN001;
843 test SizeMap
,Size_180
; ;AN001;
846 or SwitchMap
,Switch_1
; ;AN001;
850 test SizeMap
,Size_320
; ;AN001;
853 or SwitchMap
,Switch_8
; ;AN001;
857 test SizeMap
,Size_360
; ;AN001;
858 ; $IF Z ;None of the above, not valid ;AN001;
860 mov Fatal_Error
,Yes
; ;AN001;
871 Low_Density_Drive endp
873 ;*****************************************************************************
874 ;Routine name: Small_Drives
875 ;*****************************************************************************
877 ;Description: See if 720k media in 720 drive, set up /T/N if so, otherwise
880 ;Called Procedures: None
882 ;Change History: Created 8/1/87 MT
887 ;Output: Fatal_Error = YES/NO
892 ;*****************************************************************************
894 Procedure Small_Drives
; ;AN000;
896 test SizeMap
,Size_720
;Ask for 720k? ;AN001;
897 ; $IF Z ;Nope, thats all drive can do ;AN001;
899 mov Fatal_Error
,Yes
;Indicate error ;AN001;
907 ;*****************************************************************************
908 ;Routine name: Other_Drives
909 ;*****************************************************************************
911 ;Description: See if 1.44 media or 720k media, setup /t/n, otherwise error
913 ;Called Procedures: Small_Drives
915 ;Change History: Created 8/1/87 MT
920 ;Output: Fatal_Error = YES/NO
925 ;*****************************************************************************
927 Procedure Other_Drives
; ;AN001;
929 test SizeMap
,Size_1440
;Ask for 1.44mb diskette? ;AN001;
930 ; $IF Z ;Nope ;AN001;
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;
936 or SwitchMap
,Switch_T
+Switch_N
;Turn on /T:80 /N:9 ;AN001;
937 mov TrackCnt
,80 ; ;AN001;
938 mov NumSectors
,9 ; ;AN001;
941 ; $ELSE ;Asked for 1.44mb ;AN001;
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;
954 ;*****************************************************************************
955 ;Routine name:Check_T_N
956 ;*****************************************************************************
958 ;Description: Make sure than if /T is entered, /N is also entered
960 ;Called Procedures: None
962 ;Change History: Created 8/23/87 MT
967 ;Output: Fatal_Error = YES/NO
968 ;*****************************************************************************
972 test SwitchMap
,Switch_N
;Make sure /T entered if /N ;AN009;
973 ; $IF NZ,AND ; ;AN009;
975 test SwitchMap
,Switch_T
; ;AN009;
978 Message msgBad_T_N
;It wasn't, so barf ;AN009;
979 mov Fatal_Error
,Yes
;Indicate error ;AN009;
983 test SwitchMap
,Switch_T
;Make sure /N entered if /T ;AN009;
984 ; $IF NZ,AND ; ;AN009;
986 test SwitchMap
,Switch_N
; ;AN009;
987 ; $IF Z ;It wasn't, so also barf ;AN009;
989 Message msgBad_T_N
; ;AN009;
990 mov Fatal_Error
,Yes
;Indicate error ;AN009;
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.
1010 ; IF (error_loc == Track_0_Head_1) &
1011 ; ( Device_type < 96TPI )
1013 ; fLastChance := TRUE
1014 ; try formatting 48TPI_Single_Sided
1017 LastChanceToSaveIt proc
near
1019 cmp currentCylinder
, 0
1020 jne WeCanNotIgnoreThisError
1022 jne WeCanNotIgnoreThisError
1024 cmp deviceParameters
.DP_DeviceType
, DEV_5INCH
1025 ja WeCanNotIgnoreThisError
1027 mov fLastChance
, TRUE
1029 or switchmap
, SWITCH_1
1034 WeCanNotIgnoreThisError:
1038 LastChanceToSaveIt endp
1040 ;-------------------------------------------------------------------------------
1043 ;*****************************************************************************
1044 ;Routine name WriteBootSector
1045 ;*****************************************************************************
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.
1053 ;Called Procedures: Message (macro)
1055 ;Change History: Created 4/20/87 MT
1057 ;Input: DeviceParameters.DP_BPB
1059 ;Output: CY clear if ok
1060 ; CY set if error writing boot or media_id info
1065 ; Copy recommended EBPB information to canned boot record
1066 ; Write boot record out (INT 26h)
1068 ; Display boot error message
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
1076 ; Copy file system string into media_id field
1077 ; Write info to boot (INT 21h AX=440Dh, CX=0843h SET MEDIA_ID)
1079 ; Display boot error message
1086 ;*****************************************************************************
1088 Procedure WriteBootSector
; ;AN000;
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;
1106 Message msgBootWriteError
;Print error ; ;
1107 stc ;CY=1 means error ; ;
1108 ; $ELSE ;Good write of boot record! ;AN000;
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;
1120 lea si,FAT16_String
;Got 16 bit FAT ;AN000;
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;
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;
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;
1142 clc ;CY=0 for good return ;AN000;
1149 WriteBootSector endp
; ;AN000;
1152 ;*****************************************************************************
1153 ;Routine name Create_Serial_ID
1154 ;*****************************************************************************
1156 ;DescriptioN&gml Create unique 32 bit serial number by getting current date and
1157 ; time and then scrambling it around.
1159 ;Called Procedures: Message (macro)
1161 ;Change History&gml Created 4/20/87 MT
1165 ;Output&gml Media_ID_Buffer.Serial_Number = set
1166 ; AX,CX,DX destroyed
1167 ; Serial_Num_Low/High = Serial number generated
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
1179 ;*****************************************************************************
1181 Procedure Create_Serial_ID
; ;AN000;
1183 DOS_Call Get_Date
;Get date from DOS ;AN000;
1184 push cx ;Save results ;AN000;
1186 DOS_Call Get_Time
;Get_Time ;AN000;
1187 mov ax,dx ;Scramble it ;AN000;
1190 mov word ptr Media_ID_Buffer
.Media_ID_Serial_Number
+2,ax ; ;AC004;
1191 mov Serial_Num_Low
,ax ; ;AN000;
1195 mov word ptr Media_ID_Buffer
.Media_ID_Serial_Number
,ax ; ;AC004;
1196 mov Serial_Num_High
,ax ; ;AN000;
1199 Create_Serial_ID endp
; ;AN000;
1201 ;-------------------------------------------------------------------------------
1207 ; if /b write out a fake dos & bios
1208 test switchmap
, SWITCH_B
1214 test switchmap
, SWITCH_8
1216 call ConvertToOldDirectoryFormat
1220 cmp deviceParameters
.DP_DeviceType
, DEV_HARDDISK
1223 call SetPartitionTable
1229 ;------------------------------------------------------------------------------
1231 data segment public para
'DATA'
1234 biosFilename db "x:\ibmbio.com",0
1235 dosFilename db "x:\ibmdos.com",0
1237 biosFilename db "x:\io.sys",0
1238 dosFilename db "x:\msdos.sys",0
1243 ; simple code to stuff bogus dos in old-style diskette.
1249 out 20h
,al ; turn on the timer so the disk motor
1250 mov si,mesofs
; shuts off
1264 xor ah, ah ; get next char function
1265 int 16h
; call keyboard services
1270 mesofs equ sysmsg
- BogusDos
1272 WriteBogusDos proc
near
1277 mov cx, ATTR_HIDDEN
or ATTR_SYSTEM
1278 lea dx, biosFilename
1294 mov cx, ATTR_HIDDEN
or ATTR_SYSTEM
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;
1311 call AddToSystemSize
1313 mov word ptr Bios
.FileSizeInBytes
,BIOS_SIZE
;an000; dms;get size of BIOS
1314 mov word ptr Bios
.FileSizeInBytes
+2,00h ;an000; dms;
1318 call AddToSystemSize
1325 ;-------------------------------------------------------------------------------
1327 ConvertToOldDirectoryFormat proc
near
1330 ; convert to 1.1 directory
1332 mov al,drive
; Get 1st sector of directory
1333 mov cx,1 ; 1.1 directory always starts on
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;
1340 Message msgDirectoryReadError
; ;AC000;
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
1352 mov al,[drive
] ; write out the directory
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;
1366 test switchmap
, SWITCH_S
; Was system requested?
1367 retnz
; yes, don't write old boot sector
1370 mov bx,offset boot2
; no, write old boot sector
1371 cmp deviceParameters
.DP_BPB
.BPB_Heads
, 1
1373 mov word ptr [bx+3],0103h ; start address for double sided drives
1377 ;Boot record in 1st 32mb of partition
1378 mov Read_Write_Relative
.Start_Sector_High
,0 ; ;AN000;
1379 call Write_Disk
; ;AC000;
1382 Message msgBootWriteError
; ;AC000;
1386 ConvertToOldDirectoryFormat endp
1388 ;-------------------------------------------------------------------------------
1390 a_PartitionTableEntry
struc
1401 a_PartitionTableEntry ends
1403 ; structure of the IBM hard disk boot sector:
1405 db 512 - (4*size a_PartitionTableEntry
+ 2) dup(?
)
1406 PartitionTable db 4*size a_PartitionTableEntry
dup(?
)
1411 ;*****************************************************************************
1412 ;Routine name: SetPartitionTable
1413 ;*****************************************************************************
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
1420 ;Called Procedures: Message (macro)
1421 ; Determine_Partition_Type
1425 ;Change History: Created 4/20/87 MT
1429 ;Output: CY set if error
1434 ; Read the partition table (Call ReadSector)
1436 ; IF boot signature of 55AAh
1437 ; Point at system partition table
1440 ; IF System_Indicator <> 1,AND
1441 ; IF System_Indicator <> 4,AND
1442 ; IF System_Indicator <> 6
1443 ; STC (DOS not found)
1447 ; EXITIF DOS found (CLC)
1448 ; CALL Determine_Partition_Type
1449 ; Write the partition table (CALL WriteSector)
1451 ; Display boot write error message
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
1462 ; ELSE invalid boot record
1463 ; Display Bad partition table message
1467 ; Display Partition table error
1471 ;*****************************************************************************
1473 Procedure SetPartitionTable
; ;AN000;
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;
1482 cmp Boot2
.Boot_Signature
,Boot_ID
; ;AC000;
1483 ; $IF E ;Does signature match? ;AN000;
1485 lea bx, boot2
.PartitionTable
;Yes, point at partition table ;AN000;
1486 ; $SEARCH ;Look for DOS partition ;AN000;
1488 cmp [bx].sysind
,FAT12_File_System
; ;AC000;
1489 ; $IF NE,AND ; ;AN000;
1491 cmp [bx].sysind
,FAT16_File_System
; ;AC000;
1492 ; $IF NE,AND ; ;AN000;
1494 cmp [bx].sysind
,New_File_System
; ;AC000;
1497 stc ;We didn't find partition ;AN000;
1501 clc ;Indicate found partition ;AN000;
1504 ; $EXITIF NC ;Get correct id for it ;AN000;
1506 CALL Determine_Partition_Type
; ;AN000;
1508 mov bx, 0 ;Cylinder ; ;
1509 mov cx, 0 ;Sector ; ;
1511 call WriteSector
;Write out partition table ; ;
1512 ; $IF C ;Error writing boot record ;AN000;
1514 MESSAGE msgPartitionTableWriteError
; ;AC000;
1515 stc ;Set CY to indicate error ; ;
1519 clc ;No error means no CY ; ;
1525 add bx,size a_PartitionTableEntry
; ; ;
1526 cmp bx,(offset Boot2
.PartitionTable
)+4*size a_PartitionTableEntry
; ;
1527 ; $ENDLOOP ;Checked all 4 partition entries;AN000;
1529 MESSAGE msgBadPartitionTable
;Tell user bad table ;AC000;
1530 stc ;Set CY for exit ; ;
1531 ; $ENDSRCH ; ;AN000;
1533 ; $ELSE ;Invalid boot record ;AN000;
1536 MESSAGE msgBadPartitionTable
; ;AC000;
1537 stc ;Set CY for error return ; ;
1540 ; $ELSE ;Couldn't read boot record ;AN000;
1543 MESSAGE msgPartitionTableReadError
; ;AC000;
1544 stc ;Set CY for error return ; ;
1549 SetPartitionTable endp
; ;AN000;
1551 ;*****************************************************************************
1552 ;Routine name: Determine_Partition_Type
1553 ;*****************************************************************************
1555 ;DescriptioN: Set the system indicator field to its correct value as
1556 ; determined by the following rules:
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,
1564 ;Called Procedures: Message (macro)
1566 ;Change History: Created 3/18/87 MT
1568 ;Input: BX has offset of partition table entry
1569 ; fBigFAT = TRUE if 16bit FAT
1571 ;Output: BX.SysInd = correct partition system indicator value (1,4,6)
1575 ; Add partition start location to length of partition
1585 ;*****************************************************************************
1587 Procedure Determine_Partition_Type
;AN000;
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
1593 mov [BX].SysInd
,New_File_System
;AN000; ;type 6
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
1601 mov [bx].SysInd
,New_File_System
;an000; dms; type 6
1602 ; $else ;an000; dms;
1605 cmp dx,0 ;an000; dms; partition > 32 Mb?
1606 ; $if ne ;an000; dms; yes
1608 mov [bx].SysInd
,New_File_System
;an000; dms; type 6
1609 ; $else ;an000; dms; < 32 Mb partition
1612 cmp fBigFat
,True
;an000; ;16 bit FAT
1613 ; $IF E ;AC000; ;yes
1615 mov [BX].SysInd
,FAT16_File_System
;an000; ;type 4
1616 ; $ELSE ;an000; ;12 bit FAT
1619 mov [bx].SysInd
,FAT12_File_System
;an000; ;type 1
1630 Determine_Partition_Type endp
; ;AN000;
1633 ;=========================================================================
1634 ; Calc_Total_Sectors_For_Partition : This routine determines the
1635 ; total number of sectors within
1638 ; Inputs : DeviceParameters
1640 ; Outputs : DX:AX - Double word partition size
1641 ;=========================================================================
1643 Procedure Calc_Total_Sectors_For_Partition
;an000; dms;
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
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
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;
1663 Calc_Total_Sectors_For_Partition endp
1666 ;-------------------------------------------------------------------------------
1674 ; dx - transfer address
1676 ReadSector proc
near
1678 mov TrackReadWritePacket
.TRWP_FirstSector
, cx
1679 mov cx,(RAWIO
shl 8) or READ_TRACK
1685 ;-------------------------------------------------------------------------------
1693 ; dx - transfer address
1695 WriteSector proc
near
1697 mov TrackReadWritePacket
.TRWP_FirstSector
, cx
1698 mov cx,(RAWIO
shl 8) or WRITE_TRACK
1704 ;-------------------------------------------------------------------------------
1706 ; Read/Write one sector
1711 ; cx - (RAWIO shl 8) or READ_TRACK
1712 ; - (RAWIO shl 8) or WRITE_TRACK
1713 ; dx - transfer address
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
1725 mov ax, (IOCTL
shl 8) or GENERIC_IOCTL
1726 lea dx, trackReadWritePacket
1732 ;-------------------------------------------------------------------------------
1734 data segment public para
'DATA'
1738 FCBforVolumeIdSearch db 0ffH
1747 GetVolumeId proc
near
1752 ; Save current drive
1757 ; Change current drive to the drive that has the volume id we want
1761 ; Search for the volume id
1763 lea dx, FCBforVolumeIdSearch
1767 ; Restore current drive
1772 ; Did the search succeed?
1780 ; Find out where the FCB for the located volume id was put
1784 ; Copy the Volume Id
1801 data segment public para
'DATA'
1802 oldVolumeId db 11 dup(0)
1805 CheckVolumeId proc
near
1807 ; Get the volume id that's on the disk
1811 jnc Ask_User
;Did we find one?
1812 clc ;No, return with no error
1815 ; Ask the user to enter the volume id that he/she thinks is on the disk
1816 ; (first blank out the input buffer)
1819 Message msgWhatIsVolumeId?
; ;AC000;
1820 ;lea dx, ptr_msgWhatIsVolumeId?
1825 ; If the user just pressed ENTER, then there must be no label
1827 jne CompareVolumeIds
1833 ; pad the reponse with blanks
1834 ; The buffer is big enough so just add 11 blanks to what the user typed in
1837 mov cx, Label_Length
;AC000;
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;
1850 ; Now compare what the user specified with what is really out there
1851 mov cx, Label_Length
; ;AC000;
1859 Message msgBadVolumeID
; ;AC000;
1866 Check_Switch_8_B proc
near
1868 test SwitchMap
, SWITCH_B
;/8/B <> /V because ;AC007;
1869 ; $IF NZ,AND ; old directory type ;AC007;
1871 test SwitchMap
, Switch_8
; used which didn't support ;AC007;
1872 ; $IF NZ,AND ; volume labels. ;AC007;
1874 test SwitchMap
, SWITCH_V
; ;AC007;
1877 Message msgIncompatibleParameters
;Tell user ;AC007;
1878 mov Fatal_Error
,Yes
;Bad stuff ;AC007;
1879 ; $ELSE ;No problem so far ;AC007;
1882 test SwitchMap
, Switch_B
;Can't reserve space and ;AC007;
1883 ; $IF NZ,AND ; install sys files at the ;AC007;
1885 test SwitchMap
, Switch_S
; same time. ;AC007;
1886 ; $IF NZ ; No /S/B ;AC007;
1888 Message msgIncompatibleParameters
;Tell user ;AC007;
1889 mov Fatal_Error
,Yes
;Bad stuff ;AC007;
1890 ; $ELSE ;Still okay ;AC007;
1893 test SwitchMap
,Switch_1
;/1/8/4 not okay with /N/T ;AC007;
1894 ; $IF NZ,OR ; ;AC007;
1896 test SwitchMap
,Switch_8
; ;AC007;
1897 ; $IF NZ,OR ; ;AC007;
1899 test SwitchMap
,Switch_4
; ;AC007;
1903 test SwitchMap
,(Switch_T
or Switch_N
) ; ;AC007;
1904 ; $IF NZ ;Found /T/N <> /1/8 ;AC007;
1906 Message msgIncompatibleParameters
;Tell user ;AC007;
1907 mov Fatal_Error
,Yes
;Bad stuff ;AC007;
1911 test SwitchMap
,Switch_V
;ac007;
1912 ; $IF NZ,AND ;ac007;
1914 test SwitchMap
,Switch_8
;ac007;
1917 Message msgIncompatibleParameters
;ac007;
1918 mov Fatal_Error
,Yes
;ac007;
1931 Check_Switch_8_B endp