From 2d04cacc5322951f187bb17e017c12920ac8ebe2 Mon Sep 17 00:00:00 2001 From: Mark Zbikowski Date: Thu, 25 Apr 2024 21:24:10 +0100 Subject: MZ is back! --- v4.0/src/CMD/FORMAT/MSFOR.ASM | 1936 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1936 insertions(+) create mode 100644 v4.0/src/CMD/FORMAT/MSFOR.ASM (limited to 'v4.0/src/CMD/FORMAT/MSFOR.ASM') 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 @@ +; e forproc.sal= @(#)ibmfor.asm 1.28 85/10/15 + name OemFormatRoutines +; +;****************************************************************************** +;AN001 - ??? +;AN002 - D304 Modify Boot record structure for OS2 11/09/87 J.K. +;****************************************************************************** + +INCLUDE FORCHNG.INC +debug equ 0 +;------------------------------------------------------------------------------- +; Public for debugging only + + public CheckSwitches + public LastChanceToSaveIt + public WriteBootSector + public OemDone + public WriteBogusDos + public ConvertToOldDirectoryFormat + public SetPartitionTable + public ReadSector + public WriteSector + public SectorIO + public GetVolumeId + + public customBPBs + public NotSlashB + public NotSingleSided + public EndSwitchCheck + public WeCanNotIgnoreThisError + public HardDisk? + public BogusDos + public sys_mess_loop + public end_sys_loop + public DirectoryRead + public wrtdir + public DirectoryWritten + public FCBforVolumeIdSearch + public CopyVolumeId + public CompareVolumeIds + public BadVolumeId + + public boot2 + public boot + public scratchBuffer + public biosFilename + public dosFilename + public oldDrive + public oldVolumeId + public Read_Write_Relative + public Serial_Num_Low + public Serial_Num_High + public SizeMap + + public ptr_msgWhatIsVolumeId? + + public trackReadWritePacket + + public BPB81 + public BPB82 + public BPB91 + public BPB92 + +;------------------------------------------------------------------------------- + +data segment public para 'DATA' +data ends + +code segment public para 'CODE' + assume cs:code,ds:data + + Public AccessDisk + public CheckSwitches + public LastChanceToSaveIt + public OemDone + public BiosFile + public DosFile + +data segment public para 'DATA' + extrn AddToSystemSize:near + extrn currentCylinder:word + extrn currentHead:word + extrn deviceParameters:byte + extrn drive:byte + extrn driveLetter:byte + extrn fBigFAT:byte + extrn inbuff:byte + extrn switchmap:word + extrn Old_Dir:byte + extrn fLastChance:byte + extrn Fatal_Error:Byte + extrn Bios:Byte + extrn Dos:Byte + extrn Command:Byte + + extrn msgBad_T_N:byte + extrn msgBadVolumeId:byte + extrn msgBadPartitionTable:byte + extrn msgBootWriteError:byte + extrn msgDirectoryReadError:byte + extrn msgDirectoryWriteError:byte + extrn msgInvalidParameter:byte + extrn msgIncompatibleParameters:byte + extrn msgIncompatibleParametersForHardDisk:byte + extrn msgParametersNotSupportedByDrive:byte + extrn msgPartitionTableReadError:byte + extrn msgPartitionTableWriteError:byte + extrn msgWhatIsVolumeId?:byte + extrn NumSectors:word, TrackCnt:word + +IF DEBUG + extrn msgFormatBroken:byte +ENDIF + +data ends + + extrn PrintString:near + extrn std_printf:near + extrn crlf:near + extrn user_string:near + extrn Read_Disk:near + extrn Write_Disk:near + + +;------------------------------------------------------------------------------- +; Constants + +.xlist +INCLUDE DOSMAC.INC +INCLUDE FORMACRO.INC +INCLUDE FOREQU.INC +INCLUDE FORSWTCH.INC + +; This defines all the int 21H system calls +INCLUDE SYSCALL.INC + +; Limits + +INCLUDE filesize.inc + +;------------------------------------------------------------------------------- +; These are the data structures which we will need + +INCLUDE DIRENT.INC +INCLUDE ioctl.INC +INCLUDE version.inc + +.list + +;------------------------------------------------------------------------------- +; And this is the actual data +data segment public para 'DATA' + +Read_Write_Relative Relative_Sector_Buffer <> ; ;AN000; + + + IF IBMCOPYRIGHT +BiosFile db "x:\IBMBIO.COM", 0 +DosFile db "x:\IBMDOS.COM", 0 + ELSE +BiosFile db "x:\IO.SYS", 0 +DosFile db "x:\MSDOS.SYS", 0 + ENDIF + +Dummy_Label db "NO NAME " +Dummy_Label_Size dw 11 ;AN028 + +Serial_Num_Low dw 0 ; ;AN000; +Serial_Num_High dw 0 ; ;AN000; + +SizeMap db 0 ; ;AN000; + +trackReadWritePacket a_TrackReadWritePacket <> + + +; BIOS parameter blocks for various media +customBPBs label byte +BPB92 a_BPB <512, 2, 1, 2, 112, 2*9*40, 0fdH, 2, 9, 2, 0, 0, 0, 0> +BPB91 a_BPB <512, 1, 1, 2, 64, 1*9*40, 0fcH, 2, 9, 1, 0, 0, 0, 0> +BPB82 a_BPB <512, 2, 1, 2, 112, 2*8*40, 0ffH, 1, 8, 2, 0, 0, 0, 0> +BPB81 a_BPB <512, 1, 1, 2, 64, 1*8*40, 0feH, 1, 8, 1, 0, 0, 0, 0> +BPB720 a_BPB <512, 2, 1, 2, 112, 2*9*80, 0F9h, 3, 9, 2, 0, 0, 0, 0> + + + +boot2 db 0,0,0, "Boot 1.x" + db 512 - 11 dup(?) + +REORG2 LABEL BYTE + ORG BOOT2 + INCLUDE BOOT11.INC + ORG REORG2 + + + +INCLUDE BOOTFORM.INC + + +BOOT LABEL BYTE + INCLUDE BOOT.INC + +scratchBuffer db 512 dup(?) + +ptr_msgWhatIsVolumeId? dw offset msgWhatIsVolumeId? + dw offset driveLetter + + +FAT12_String db "FAT12 " +FAT16_String db "FAT16 " + +Media_ID_Buffer Media_ID <> + + +data ends +;------------------------------------------------------------------------------- +; AccessDisk: +; Called whenever a different disk is about to be accessed +; +; Input: +; al - drive letter (0=A, 1=B, ...) +; +; Output: +; none +AccessDisk proc near + + push ax ; save drive letter + mov bl,al ; Set up GENERIC IOCTL REQUEST preamble + inc bl + mov ax,(IOCTL SHL 8) + Set_Drv_Owner ; IOCTL function + int 21h + pop ax + return + +AccessDisk endp + +;------------------------------------------------------------------------------- +; CheckSwitches: +; Check switches against device parameters +; Use switches to modify device parameters +; +; Input: +; deviceParameters +; +; Output: +; deviceParameters may be modified +; Carry set if error +; +; +; /B <> /S +; /B/8 <> /V +; /1 or /8 <> /T/N +; + + +Public CHeckSwitches +CheckSwitches proc near + + +; Disallow /C + ;lea dx, msgInvalidParameter ;AC000; + test switchmap, SWITCH_C + jz CheckExcl + Message msgInvalidParameter ;AC000; +SwitchError: + ;call PrintString ;AC000; + stc + ret + +CheckExcl: + + test SwitchMap,Switch_F ;Specify size? ;AN001; +; $IF NZ ;Yes ;AN001; + JZ $$IF1 + test SwitchMap,(Switch_1+Switch_8+Switch_4+Switch_N+Switch_T) ;AN001; +; $IF NZ ;/F replaces above switches ;AN001; + JZ $$IF2 + Message msgIncompatibleParameters ;Print error ;AN001; + mov Fatal_Error,Yes ;Force exit ;AN001; +; $ELSE ; ;AN001; + JMP SHORT $$EN2 +$$IF2: + call Size_To_Switch ;Go set switches based ;AN001; +; $ENDIF ; on the size ;AN001; +$$EN2: +; $ENDIF ; ;AN001; +$$IF1: + cmp Fatal_Error,NO ; ;AN007; +; $IF E ; ;AN007; + JNE $$IF6 + call Check_Switch_8_B ; ;ac007 + call Check_T_N +; $ENDIF ; ;AN009; +$$IF6: + cmp Fatal_Error,Yes ; ;AN007; + jne ExclChkDone ; ;AN007; + stc ; ;AN007; + ret ; ;AN007; + +ExclChkDone: +; Patch the boot sector so that the boot strap loader knows what disk to +; boot from +; mov Boot.Boot_PhyDrv, 00H ;AC000; + mov Boot.EXT_PHYDRV, 00H ;AN00?; + + cmp deviceParameters.DP_DeviceType, DEV_HARDDISK + jne CheckFor5InchDrives + +; Formatting a hard disk so we must repatch the boot sector +; mov Boot.Boot_PhyDrv, 80H ;AC000; + mov Boot.EXT_PHYDRV, 80H ;AN00?; + test switchmap, not (SWITCH_S or SWITCH_V or SWITCH_Select or SWITCH_AUTOTEST or Switch_B) ;AN007; + jz SwitchesOkForHardDisk + + Message msgIncompatibleParametersForHardDisk ; ;AC000; + stc + ret + +; Before checking the Volume Id we need to verify that a valid one exists +; We assume that unless a valid boot sector exists on the target disk, no +; valid Volume Id can exist. + +SwitchesOkForHardDisk: + SaveReg + mov al,drive + mov cx,LogBootSect + xor dx,dx + lea bx,scratchBuffer ; ScratchBuffer := Absolute_Read_Disk( + ;INT 25h ; Logical_sec_1 ) + + ;Assume Dir for vol ID exists in 1st 32mb of partition + + mov Read_Write_Relative.Start_Sector_High,0 + call Read_Disk ; ;AC000; + ; on the stack. We throw them away + + jnc CheckSignature + stc + RestoreReg + ret + +CheckSignature: ; IF (Boot.Boot_Signature != aa55) + + mov ax, word ptr ScratchBuffer.Boot_Signature ;AC000; + cmp ax, 0aa55h ;Find a valid boot record? + RestoreReg + clc ;No, so no need to check label +; $IF Z ;No further checking needed ;AC000; + JNZ $$IF8 + test SwitchMap,(SWITCH_Select or SWITCH_AUTOTEST) ;Should we prompt for vol label?;AN000; +; $IF Z ;Yes, if /Select not entered ;AN000; + JNZ $$IF9 + call CheckVolumeId ;Go ask user for vol label ; ; +; $ELSE ;/Select entered ;AN000; + JMP SHORT $$EN9 +$$IF9: + clc ;CLC indicates passed label test;AN000; +; $ENDIF ; for the return ;AN000; +$$EN9: +; $ENDIF +$$IF8: + return + +Incomp_Message: ;an000; fix PTM 809 + + Message msgIncompatibleParameters ;an000; print incompatible parms + stc ;an000; signal error + return ;an000; return to caller + +Print_And_Return: + ;call PrintString ; ;AC000; + stc + return + + +CheckFor5InchDrives: + + ;If drive type is anything other than 48 or 96, then only /V/S/H/N/T allowed + cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH96TPI + je Got96 + + cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH + je Got48 + + xor ax,ax ;an000; dms;clear reg + or ax,(Switch_V or Switch_S or Switch_N or Switch_T or Switch_B) ;an000; dms;set up switch mask + or ax,(Switch_Backup or Switch_Select or Switch_Autotest) ;an000; dms; +IF ShipDisk + or ax,Switch_Z ;an000; dms; +ENDIF + not ax ;an000; dms; + test switchmap,ax ;an000; dms;invalid switch? + jz Goto_Got_BPB1 ;an000;dms;continue format + Message msgParametersNotSupportedByDrive ; ;AC000; + jmp short Print_And_Return + +Goto_Got_BPB1: + jmp Goto_Got_BPB + ; We have a 96tpi floppy drive + ; /4 allows just about all switches however, /1 requires /4 +Got96: +;;;DMS;;test switchmap, SWITCH_8 ;an000; If /8 we have an error +;;;DMS;;jnz Incomp_message ;an000; tell user error + + test switchmap, SWITCH_4 + jnz CheckForInterestingSwitches ;If /4 check /N/T/V/S + + test switchmap, SWITCH_1 ;If /1 and /4 check others + jz Got48 + + ;If only /1 with no /4, see if /N/T + test SwitchMap,(Switch_N or Switch_T) + jnz CheckForInterestingSwitches + + jmp Incomp_message ;an000; tell user error occurred + +Got48: + ;Ignore /4 for non-96tpi 5 1/4" drives + and switchmap, not SWITCH_4 + + ;Ignore /1 if drive has only one head and not /8 + cmp word ptr deviceParameters.DP_BPB.BPB_Heads, 1 + ja CheckForInterestingSwitches + test switchmap, SWITCH_8 + jz CheckForInterestingSwitches + and switchmap, not SWITCH_1 + + ;Are any interesting switches set? +CheckForInterestingSwitches: + test switchmap, not (SWITCH_V or SWITCH_S or Switch_Backup or SWITCH_SELECT or SWITCH_AUTOTEST or Switch_B) + jz Goto_EndSwitchCheck ;No, everything ok + + ;At this point there are switches other than /v/s/h + test SwitchMap,(SWITCH_N or SWITCH_T) + jz Use_48tpi ;Not /n/t, so must be /b/1/8/4 + + ;We've got /N/T, see if there are others + test SwitchMap, not (SWITCH_N or SWITCH_T or SWITCH_V or SWITCH_S or Switch_Backup or SWITCH_SELECT or SWITCH_AUTOTEST) + jz NT_Compatible ;Nope, all is well + + ;If 96tpi drive and /1 exists with /N/T, then okay, otherwise error + cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH96TPI + jne Bad_NT_Combo + + test SwitchMap, not (SWITCH_1 or SWITCH_N or SWITCH_T or SWITCH_V) + jnz Bad_NT_Combo + test SwitchMap, not (SWITCH_S or Switch_Backup or SWITCH_SELECT or Switch_Autotest) + jz Goto_Got_BPB + +Bad_NT_Combo: + Message msgIncompatibleParameters ; ;AC000; + jmp Print_And_Return + +Goto_Got_BPB: + jmp Got_BPB_Ok ;Sleazy, but je won't reach it + +Goto_EndSwitchCheck: + jmp EndSwitchCheck + ;There is a problem with /N/T in that IBMBIO will default to a BPB with the + ;media byte set to F0 (other) if the /N/T combo is used for the format. This + ;will cause problems if we are creating a media that has an assigned media + ;byte, i.e. 160,180,320,360, or 720k media using /N/T. To avoid this problem, + ;if we detect a /N/T combo that would correspond to one of these medias, then + ; we will set things up using the /4/1/8 switches instead of the /N/T + ; MT - 7/17/86 PTR 33D0110 + + ; Combo's that we look for - 96tpi drive @ /T:40, /N:9 + ; 96tpi drive @ /T:40, /N:8 + ; + ; Look for this combo after we set everything up with the /T/N routine + ; 1.44 drive @ /T:80, /N:9 + +NT_Compatible: + cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH96TPI + jne Goto_Got_BPB + + cmp TrackCnt,40 ;Look for 40 tracks + jne Got_BPB_Ok + + cmp NumSectors,9 ;9 sectors? + je Found_48tpi_Type + + cmp NumSectors,8 ;8 sectors? + jne Goto_Got_BPB ;Nope, different type, let it go thru + + or SwitchMap,SWITCH_8 ;Yes, turn on /8 switch + +Found_48tpi_Type: + and SwitchMap,not (SWITCH_N or SWITCH_T) ;Turn off /T/N + +;******End PTR fix + +; if we have a 96 tpi drive then we will be using it in 48 tpi mode +Use_48tpi: + cmp byte ptr deviceParameters.DP_DeviceType, DEV_5INCH96TPI + jne Not96tpi + + mov byte ptr deviceParameters.DP_MediaType, 1 + mov word ptr deviceParameters.DP_Cylinders, 40 +Not96tpi: + +; Since we know we are formatting in 48 tpi mode turn on /4 switch +; (We use this info in LastChanceToSaveIt) + or switchmap, SWITCH_4 + +; At this point we know that we will require a special BPB +; It will be one of: +; 0) 9 track 2 sides - if no switches +; 1) 9 track 1 side - if only /1 specified +; 2) 8 track 2 sides - if only /8 specified +; 3) 8 track 1 side - if /8 and /1 specified +; +Get_BPBs: +; ax is used to keep track of which of the above BPB's we want + xor ax, ax + +NotSlashB: + + test switchmap, SWITCH_1 + jz NotSingleSided + add ax, 1 +NotSingleSided: + + test switchmap, SWITCH_8 + jz Not8SectorsPerTrack + add ax, 2 +; /8 implies Old_Dir = TRUE + mov Old_Dir,TRUE +Not8SectorsPerTrack: + +; Ok now we know which BPB to use so lets move it to the device parameters + + mov bx, size a_BPB + mul bx + lea si, CustomBPBs + add si, ax + lea di, deviceParameters.DP_BPB + mov cx, size a_BPB + push ds + pop es + repnz movsb + +;***************************************************************** +;* /N/T DCR stuff. Possible flaw exists if we are dealing with a +;* HardDisk. If they support the "custom format" features for +;* Harddisks too, then CheckForInterestingSwitches should +;* consider /n/t UNinteresting, and instead of returning +;* after setting up the custom BPB we fall through and do our +;* Harddisk Check. +Got_BPB_OK: + test switchmap,SWITCH_N+SWITCH_T + jnz Setup_Stuff + jmp EndSwitchCheck +Setup_Stuff: +; Set up NumSectors and SectorsPerTrack entries correctly + test switchmap,SWITCH_N + jz No_Custom_Seclim + mov ax,word ptr NumSectors + mov DeviceParameters.DP_BPB.BPB_SectorsPerTrack,ax + jmp short Handle_Cyln +No_Custom_Seclim: + mov ax,deviceParameters.DP_BPB.BPB_SectorsPerTrack + mov NumSectors,ax + +Handle_Cyln: + test switchmap,SWITCH_T + jz No_Custom_Cyln +; Set up TrackCnt and Cylinders entries correctly + mov ax,TrackCnt + mov DeviceParameters.DP_Cylinders,ax + jmp short Check_720 +No_Custom_Cyln: + mov ax,DeviceParameters.DP_Cylinders + mov TrackCnt,ax + +;****PTM P868 - Always making 3 1/2 media byte 0F0h. If 720, then set to +; 0F9h and use the DOS 3.20 BPB. Should check all drives +; at this point (Make sure not 5 inch just for future +; protection) +; We will use the known BPB info for 720 3 1/2 diskettes for +; this special case. All other new diskette media will use the +; calculations that follow Calc_Total for BPB info. +; Fix MT 11/12/86 + +Check_720: + + cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH96TPI + je Calc_Total + + cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH + je Calc_Total + + cmp TrackCnt,80 + jne Calc_Total + + cmp NumSectors,9 + jne Calc_Total + +; At this point we know we have a 3 1/2 720kb diskette to format. Use the +; built in BPB rather than the one handed to us by DOS, because the DOS one +; will be based on the default for that drive, and it can be different from +; what we used in DOS 3.20 for the 720's. Short sighted on our part to use +; 0F9h as the media byte, should have use 0F0h (OTHER) and then we wouldn't +; have this problem. + + SaveReg + + + mov cx,seg data ;Setup seg regs, just in case they ain't! + mov ds,cx + mov es,cx + + mov si,offset BPB720 ;Copy the BPB! + mov di,offset deviceParameters.DP_BPB + mov cx,size a_BPB + rep movsb + RestoreReg + jmp EndSwitchCheck + +;End PTM P868 fix **************************************** + +Calc_Total: + mov ax,NumSectors + mov bx,DeviceParameters.DP_BPB.BPB_Heads + mul bl ; AX = # of sectors * # of heads + mul TrackCnt ; DX:AX = Total Sectors + or dx,dx + jnz Got_BigTotalSectors + mov DeviceParameters.DP_BPB.BPB_TotalSectors,ax + jmp short Set_BPB +Got_BigTotalSectors: + mov DeviceParameters.DP_BPB.BPB_BigTotalSectors,ax + mov DeviceParameters.DP_BPB.BPB_BigTotalSectors+2,dx + push dx ; preserve dx for further use + xor dx,dx + mov DeviceParameters.DP_BPB.BPB_TotalSectors,dx + pop dx + +Set_BPB: +; We calculate the number of sectors required in a FAT. This is done as: +; # of FAT Sectors = TotalSectors / SectorsPerCluster * # of bytes in FAT to +; represent one cluster (i.e. 3/2) / BytesPerSector (i.e. 512) + xor bx,bx + mov bl,DeviceParameters.DP_BPB.BPB_SectorsPerCluster + div bx ; DX:AX contains # of clusters +; now multiply by 3/2 + mov bx,3 + mul bx + mov bx,2 + div bx + xor dx,dx ; throw away modulo +; now divide by 512 + mov bx,512 + div bx +; dx:ax contains number of FAT sectors necessary + inc ax ; Go one higher + mov DeviceParameters.DP_BPB.BPB_SectorsPerFAT,ax + mov DeviceParameters.DP_MediaType,0 + mov DeviceParameters.DP_BPB.BPB_MediaDescriptor,Custom_Media + + +EndSwitchCheck: + clc + return + +CheckSwitches endp + +;***************************************************************************** +;Routine name: Size_To_Switch +;***************************************************************************** +; +;Description: Given the SizeMap field as input indicating the SIZE= value +; entered, validate that the specified size is valid for the +; drive, and if so, turn on the appropriate data fields and +; switches that would be turned on by the equivilent command line +; using only switchs. All defined DOS 4.00 sizes are hardcoded, +; in case a drive type of other is encountered that doesn't +; qualify as a DOS 4.00 defined drive. Exit with error message if +; unsupported drive. The switches will be setup for the CheckSwitches +; routine to sort out, using existing switch matrix logic. +; +;Called Procedures: Low_Density_Drive +; High_Capacity_Drive +; 720k_Drives +; Other_Drives +; +;Change History: Created 8/1/87 MT +; +;Input: SizeMap +; Fatal_Error = NO +; +;Output: Fatal_Error = YES/NO +; SwitchMap = appropriate Switch_?? values turned on +; TrackCnt, NumSectors set if Switch_T,Switch_N turned on +;***************************************************************************** + + +Procedure Size_To_Switch + + cmp SizeMap,0 ;Are there sizes entered? ;AN001; +; $IF NE ;Yes ;AN001; + JE $$IF13 + cmp deviceParameters.DP_DeviceType,DEV_HARDDISK ;AN000; ;AN001; +; $IF E ;No size for fixed disk ;AN001; + JNE $$IF14 + Message msgIncompatibleParametersForHardDisk ; ;AN001; +; $ELSE ;Diskette, see what type ;AN001; + JMP SHORT $$EN14 +$$IF14: + cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH ; ;AN001; +; $IF E ;Found 180/360k drive ;AN001; + JNE $$IF16 + call Low_Density_Drive ;Go set switches ;AN001; +; $ELSE ;Check for 96TPI ;AN001; + JMP SHORT $$EN16 +$$IF16: + cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH96TPI ;AN001; ; +; $IF E ;Found it ;AN001; + JNE $$IF18 + call High_Capacity_Drive ; ;AN001; +; $ELSE ; ;AN001; + JMP SHORT $$EN18 +$$IF18: + cmp byte ptr deviceParameters.DP_DeviceType,DEV_3INCH720KB ;AN0001; +; $IF E ;Found 720k drive ;AN001; + JNE $$IF20 + call Small_Drives ; ;AN001; +; $ELSE ; ;AN001; + JMP SHORT $$EN20 +$$IF20: + cmp byte ptr deviceParameters.DP_DeviceType,DEV_OTHER ;AN001; +; $IF E ;Must be 1.44mb ;AN001; + JNE $$IF22 + call Other_Drives ; ;AN001; +; $ELSE ; ;AN001; + JMP SHORT $$EN22 +$$IF22: + Message msgParametersNotSupportedByDrive ; ;AN001; + mov Fatal_Error,Yes ; ;AN001; +; $ENDIF ; ;AN001; +$$EN22: +; $ENDIF ; ;AN001; +$$EN20: +; $ENDIF ; ;AN001; +$$EN18: +; $ENDIF ; ;AN001; +$$EN16: +; $ENDIF ; ;AN001; +$$EN14: +; $ENDIF ; ;AN001; +$$IF13: + cmp Fatal_Error,Yes ; ;AN001; +; $IF E ; ;AN001; + JNE $$IF30 + Message msgIncompatibleParameters ; ;AN001; +; $ENDIF ; ;AN001; +$$IF30: + + cmp deviceParameters.DP_DeviceType,DEV_HARDDISK ;an001; +; $if e ;an001; + JNE $$IF32 + mov Fatal_Error,Yes ;an001; +; $endif ;an001; +$$IF32: + + and SwitchMap,not Switch_F ;Turn off /F so doesn't effect ;AN001; + ret ; following logic ;AN001; + +Size_To_Switch endp + +;***************************************************************************** +;Routine name: High_Capacity_Drive +;***************************************************************************** +; +;Description: See if 1.2mb diskette, or one of the other 5 1/4 sizes. Turn +; on /4 if 360k or lower +; +;Called Procedures: Low_Density_Drive +; +;Change History: Created 8/1/87 MT +; +;Input: SizeMap +; Fatal_Error = NO +; +;Output: Fatal_Error = YES/NO +; SwitchMap = Switch_4 if 360k or lowere +;***************************************************************************** + +Procedure High_Capacity_Drive ; + + test SizeMap,Size_1200 ;1.2mb diskette? ;AN001; +; $IF Z ;Nope ;AN001; + JNZ $$IF34 + call Low_Density_Drive ;Check for /4 valid types ;AN001; + cmp Fatal_Error, No ;Find 160/180/320/360k? ;AN001; +; $IF E ;Yes ;AN001; + JNE $$IF35 + or SwitchMap,Switch_4 ;Turn on /4 switch ;AN001; +; $ELSE ;Did not find valid size ;AN001; + JMP SHORT $$EN35 +$$IF35: + mov Fatal_Error,Yes ;Indicate invalid device ;AN001; +; $ENDIF ; ;AN001; +$$EN35: +; $ENDIF ; ;AN001; +$$IF34: + ret ; ;AN001; + +High_Capacity_Drive endp + +;***************************************************************************** +;Routine name: Low_Density_Drive +;***************************************************************************** +; +;Description: See if 360k diskete or one of the other 5 1/4 sizes. Turn +; on the /1/8 switch to match sizes +; +;Called Procedures: Low_Density_Drive +; +;Change History: Created 8/1/87 MT +; +;Input: SizeMap +; Fatal_Error = NO +; +;Output: Fatal_Error = YES/NO +; SwitchMap = Switch_1, Switch_8 to define size +; +; 360k = No switch +; 320k = Switch_8 +; 180k = Switch_1 +; 160k = Switch_1 + Switch_8 +;***************************************************************************** + + +Procedure Low_Density_Drive ; ;AN000; + ; + test SizeMap,Size_160 ; ;AN001; +; $IF NZ ; ;AN001; + JZ $$IF39 + or SwitchMap,Switch_1+Switch_8 ; ;AN001; +; $ELSE ; ;AN001; + JMP SHORT $$EN39 +$$IF39: + test SizeMap,Size_180 ; ;AN001; +; $IF NZ ; ;AN001; + JZ $$IF41 + or SwitchMap,Switch_1 ; ;AN001; +; $ELSE ; ;AN001; + JMP SHORT $$EN41 +$$IF41: + test SizeMap,Size_320 ; ;AN001; +; $IF NZ ; ;AN001; + JZ $$IF43 + or SwitchMap,Switch_8 ; ;AN001; +; $ELSE ; ;AN001; + JMP SHORT $$EN43 +$$IF43: + test SizeMap,Size_360 ; ;AN001; +; $IF Z ;None of the above, not valid ;AN001; + JNZ $$IF45 + mov Fatal_Error,Yes ; ;AN001; +; $ENDIF ; ;AN001; +$$IF45: +; $ENDIF ; ;AN001; +$$EN43: +; $ENDIF ; ;AN001; +$$EN41: +; $ENDIF ; ;AN001; +$$EN39: + ret ; ;AN001; + +Low_Density_Drive endp + +;***************************************************************************** +;Routine name: Small_Drives +;***************************************************************************** +; +;Description: See if 720k media in 720 drive, set up /T/N if so, otherwise +; error +; +;Called Procedures: None +; +;Change History: Created 8/1/87 MT +; +;Input: SizeMap +; Fatal_Error = NO +; +;Output: Fatal_Error = YES/NO +; SwitchMap +; TrackCnt +; NumSectors +; 720k = /T:80 /N:9 +;***************************************************************************** + +Procedure Small_Drives ; ;AN000; + + test SizeMap,Size_720 ;Ask for 720k? ;AN001; +; $IF Z ;Nope, thats all drive can do ;AN001; + JNZ $$IF50 + mov Fatal_Error,Yes ;Indicate error ;AN001; +; $ENDIF ; ;AN001; +$$IF50: + ret ; ;AN001; + +Small_Drives endp + + +;***************************************************************************** +;Routine name: Other_Drives +;***************************************************************************** +; +;Description: See if 1.44 media or 720k media, setup /t/n, otherwise error +; +;Called Procedures: Small_Drives +; +;Change History: Created 8/1/87 MT +; +;Input: SizeMap +; Fatal_Error = NO +; +;Output: Fatal_Error = YES/NO +; SwitchMap +; TrackCnt +; NumSectors +; 720k = /T:80 /N:9 +;***************************************************************************** + +Procedure Other_Drives ; ;AN001; + + test SizeMap,Size_1440 ;Ask for 1.44mb diskette? ;AN001; +; $IF Z ;Nope ;AN001; + JNZ $$IF52 + call Small_Drives ;See if 720k ;AN001; + cmp Fatal_Error,No ;Fatal_error=Yes if not ;AN001; +; $IF E ;Got 720k ;AN001; + JNE $$IF53 + or SwitchMap,Switch_T+Switch_N ;Turn on /T:80 /N:9 ;AN001; + mov TrackCnt,80 ; ;AN001; + mov NumSectors,9 ; ;AN001; +; $ENDIF ; ;AN001; +$$IF53: +; $ELSE ;Asked for 1.44mb ;AN001; + JMP SHORT $$EN52 +$$IF52: + or SwitchMap,Switch_T+Switch_N ;Turn on /T:80 /N:18; ;AN001; + mov TrackCnt,80 ;This will protect SIZE=1440 ;AN001; + mov NumSectors,18 ; from non-standard drives with ;AN001; +; $ENDIF ; type of 'other' ;AN001; +$$EN52: + ret ; ;AN001; + +Other_Drives endp + + +;***************************************************************************** +;Routine name:Check_T_N +;***************************************************************************** +; +;Description: Make sure than if /T is entered, /N is also entered +; +;Called Procedures: None +; +;Change History: Created 8/23/87 MT +; +;Input: SizeMap +; Fatal_Error = NO +; +;Output: Fatal_Error = YES/NO +;***************************************************************************** + +Procedure Check_T_N + + test SwitchMap,Switch_N ;Make sure /T entered if /N ;AN009; +; $IF NZ,AND ; ;AN009; + JZ $$IF57 + test SwitchMap,Switch_T ; ;AN009; +; $IF Z ; ;AN009; + JNZ $$IF57 + Message msgBad_T_N ;It wasn't, so barf ;AN009; + mov Fatal_Error,Yes ;Indicate error ;AN009; +; $ELSE ; ;AN009; + JMP SHORT $$EN57 +$$IF57: + test SwitchMap,Switch_T ;Make sure /N entered if /T ;AN009; +; $IF NZ,AND ; ;AN009; + JZ $$IF59 + test SwitchMap,Switch_N ; ;AN009; +; $IF Z ;It wasn't, so also barf ;AN009; + JNZ $$IF59 + Message msgBad_T_N ; ;AN009; + mov Fatal_Error,Yes ;Indicate error ;AN009; +; $ENDIF ; ;AN009; +$$IF59: +; $ENDIF ; ;AN009; +$$EN57: + ret + +Check_T_N endp + + + +;------------------------------------------------------------------------------- +; LastChanceToSaveIt: +; This routine is called when an error is detected in DiskFormat. +; If it returns with carry not set then DiskFormat is restarted. +; It gives the oem one last chance to try formatting differently. +; fLastChance gets set Then to prevent multiple prompts from being +; issued for the same diskette. +; +; Algorithm: +; IF (error_loc == Track_0_Head_1) & +; ( Device_type < 96TPI ) +; THEN +; fLastChance := TRUE +; try formatting 48TPI_Single_Sided +; ELSE return ERROR +; +LastChanceToSaveIt proc near + + cmp currentCylinder, 0 + jne WeCanNotIgnoreThisError + cmp currentHead, 1 + jne WeCanNotIgnoreThisError + + cmp deviceParameters.DP_DeviceType, DEV_5INCH + ja WeCanNotIgnoreThisError + + mov fLastChance, TRUE + + or switchmap, SWITCH_1 + call CheckSwitches + clc + ret + +WeCanNotIgnoreThisError: + stc + ret + +LastChanceToSaveIt endp + +;------------------------------------------------------------------------------- + + +;***************************************************************************** +;Routine name WriteBootSector +;***************************************************************************** +; +;DescriptioN: Copy EBPB information to boot record provided by Get recommended +; BPB, write out boot record, error +; if can write it, then fill in new fields (id, etc..). The volume +; label will not be added at this time, but will be set by the +; create volume label call later. +; +;Called Procedures: Message (macro) +; +;Change History: Created 4/20/87 MT +; +;Input: DeviceParameters.DP_BPB +; +;Output: CY clear if ok +; CY set if error writing boot or media_id info +; +;Psuedocode +;---------- +; +; Copy recommended EBPB information to canned boot record +; Write boot record out (INT 26h) +; IF error +; Display boot error message +; stc +; ELSE +; Compute serial id and put into field (CALL Create_Serial_ID) +; Point at 'FAT_12' string for file system type +; IF fBIGFat ;16 bit FAT +; Point at 'FAT_16' for file system type +; ENDIF +; Copy file system string into media_id field +; Write info to boot (INT 21h AX=440Dh, CX=0843h SET MEDIA_ID) +; IF error (CY set) +; Display boot error message +; stc +; ELSE +; clc +; ENDIF +; ENDIF +; ret +;***************************************************************************** + +Procedure WriteBootSector ; ;AN000; + + lea si, deviceParameters.DP_BPB ;Copy EBPB to the boot record ; + lea di, Boot.EXT_BOOT_BPB ; " " " " ;AC000: + mov cx, size EXT_BPB_INFO ; " " " " ;AC000: + push ds ;Set ES=DS (data segment) ; ; + pop es ; " " " " ; ; + repnz movsb ;Do the copy ; ; + ;Write out the boot record ; ; + mov al, drive ;Get drive letter ; ; + mov cx, 1 ;Specify 1 sector ; ; + xor dx, dx ;Logical sector 0 ; ; + lea bx, boot ;Point at boot record ; ; +;Boot record in 1st 32mb of partition + mov Read_Write_Relative.Start_Sector_High,0 ; ;AN000; + call Write_Disk ; ;AC000; +; $IF C ;Error on write ;AC000; + JNC $$IF62 + Message msgBootWriteError ;Print error ; ; + stc ;CY=1 means error ; ; +; $ELSE ;Good write of boot record! ;AN000; + JMP SHORT $$EN62 +$$IF62: + mov cx,Dummy_Label_Size ;Put in dummy volume label size ;ac026;ac028; + lea si,Dummy_Label ; " " " " ;AN000; + lea di,Media_ID_Buffer.Media_ID_Volume_Label ; " " " " ;AN000; + rep movsb ; " " " " ;AN000; + call Create_Serial_ID ;Go create unique ID number ;AN000; + lea si,FAT12_String ;Assume 12 bit FAT ;AN000; + cmp fBigFAT,TRUE ;Is it? ;AN000; +; $IF E ;Not if fBigFat is set.... ;AN000; + JNE $$IF64 + lea si,FAT16_String ;Got 16 bit FAT ;AN000; +; $ENDIF ; ;AN000; +$$IF64: + ;Copy file system string ; ; + mov cx,8 ; to buffer ;AN000; + lea di,Media_ID_Buffer.Media_ID_File_System ; " " ;AN000; + repnz movsb ; " " " " ;AN000; + mov al,Generic_IOCtl ;Generic IOCtl call ;AN000; + mov bl,Drive ;Get drive ;AN000; + inc bl ;Make it 1 based ;AN000; + xor bh,bh ;Set bh=0 ;AN000; + mov ch,RawIO ;Set Media ID call ;AN000; + mov cl,Set_Media_ID + mov dx,offset Media_ID_Buffer ;Point at buffer ;AN000; + DOS_Call IOCtl ;Do function call ;AN000; +; $IF C ;Error ? (Write or old boot rec);AN000; + JNC $$IF66 + Message msgBootWriteError ;Indicate we couldn't write it ;AN000; + stc ;CY=1 for error return ;AN000; +; $ELSE ;Set Media ID okay ;AN000; + JMP SHORT $$EN66 +$$IF66: + clc ;CY=0 for good return ;AN000; +; $ENDIF ; ;AN000; +$$EN66: +; $ENDIF ; ;AN000; +$$EN62: + ret ; ;AN000; + +WriteBootSector endp ; ;AN000; + + +;***************************************************************************** +;Routine name Create_Serial_ID +;***************************************************************************** +; +;DescriptioN&gml Create unique 32 bit serial number by getting current date and +; time and then scrambling it around. +; +;Called Procedures: Message (macro) +; +;Change History&gml Created 4/20/87 MT +; +;Input&gml None +; +;Output&gml Media_ID_Buffer.Serial_Number = set +; AX,CX,DX destroyed +; Serial_Num_Low/High = Serial number generated +; +;Psuedocode +;---------- +; +; Get date (INT 21h, AH=2Bh) +; Get time (INT 21h, AH=2Ch) +; Serial_ID+0 = DX reg date + DX reg time +; Serial_ID+2 = CX reg date + CX reg time +; Serial_Num_Low = Serial_ID+2 +; Serial_Num_High = Serial_ID+0 +; ret +;***************************************************************************** + +Procedure Create_Serial_ID ; ;AN000; + + DOS_Call Get_Date ;Get date from DOS ;AN000; + push cx ;Save results ;AN000; + push dx ; ;AN000; + DOS_Call Get_Time ;Get_Time ;AN000; + mov ax,dx ;Scramble it ;AN000; + pop dx ; ;AN000; + add ax,dx ; ;AN000; + mov word ptr Media_ID_Buffer.Media_ID_Serial_Number+2,ax ; ;AC004; + mov Serial_Num_Low,ax ; ;AN000; + mov ax,cx ; ;AN000; + pop cx ; ;AN000; + add ax,cx ; ;AN000; + mov word ptr Media_ID_Buffer.Media_ID_Serial_Number,ax ; ;AC004; + mov Serial_Num_High,ax ; ;AN000; + ret ; ;AN000; + +Create_Serial_ID endp ; ;AN000; + +;------------------------------------------------------------------------------- + +; OemDone: +; +OemDone proc near + +; if /b write out a fake dos & bios + test switchmap, SWITCH_B + jz Switch8? + call WriteBogusDos + retc + +Switch8?: + test switchmap, SWITCH_8 + jz HardDisk? + call ConvertToOldDirectoryFormat + retc + +HardDisk?: + cmp deviceParameters.DP_DeviceType, DEV_HARDDISK + clc + retnz + call SetPartitionTable + + return + +OemDone endp + +;------------------------------------------------------------------------------ + +data segment public para 'DATA' + + if IBMCOPYRIGHT +biosFilename db "x:\ibmbio.com",0 +dosFilename db "x:\ibmdos.com",0 + else +biosFilename db "x:\io.sys",0 +dosFilename db "x:\msdos.sys",0 + endif + +data ends + +; simple code to stuff bogus dos in old-style diskette. + +BogusDos: + push cs + pop ds + mov al,20h + out 20h,al ; turn on the timer so the disk motor + mov si,mesofs ; shuts off +sys_mess_loop: + lodsb +if ibmcopyright +end_sys_loop: +endif + or al,al + jz end_sys_loop + mov ah,14 + mov bx,7 + int 16 + jmp sys_mess_loop +if not ibmcopyright +end_sys_loop: + xor ah, ah ; get next char function + int 16h ; call keyboard services + int 19h ; reboot +endif + + include BOOT.CL1 +mesofs equ sysmsg - BogusDos + +WriteBogusDos proc near + + mov al,driveLetter + mov biosFilename,al + mov dosFilename,al + mov cx, ATTR_HIDDEN or ATTR_SYSTEM + lea dx, biosFilename + mov ah,CREAT + int 21h + mov bx,ax + mov cx, BIOS_SIZE + push ds + push cs + pop ds + assume ds:code + lea dx, BogusDos + mov ah,WRITE + int 21h + pop ds + assume ds:data + mov ah,CLOSE + int 21h + mov cx, ATTR_HIDDEN or ATTR_SYSTEM + lea dx, dosFilename + mov ah,CREAT + int 21h + mov bx,ax + mov cx, DOS_SIZE + lea dx, BogusDos + mov ah,WRITE + int 21h + mov ah,CLOSE + int 21h +; Comunicate system size to the main format program + mov word ptr DOS.FileSizeInBytes,DOS_SIZE ;an000; dms;get size of DOS + mov word ptr DOS.FileSizeInBytes+2,00h ;an000; dms; + + xor dx,dx + mov ax,DOS_SIZE + call AddToSystemSize + + mov word ptr Bios.FileSizeInBytes,BIOS_SIZE ;an000; dms;get size of BIOS + mov word ptr Bios.FileSizeInBytes+2,00h ;an000; dms; + + xor dx,dx + mov ax,BIOS_SIZE + call AddToSystemSize + + clc + return + +WriteBogusDos endp + +;------------------------------------------------------------------------------- + +ConvertToOldDirectoryFormat proc near + +; +; convert to 1.1 directory +; + mov al,drive ; Get 1st sector of directory + mov cx,1 ; 1.1 directory always starts on + mov dx,3 ; sector 3 + lea bx,scratchBuffer +;Root Directory always in 1st 32mb of partition + mov Read_Write_Relative.Start_Sector_High,0 ; ;AN000; + call Read_Disk ; ;AC000; + jnc DirectoryRead + Message msgDirectoryReadError ; ;AC000; + stc + ret +DirectoryRead: + +; fix attribute of ibmbio and ibmdos + lea bx,scratchBuffer + mov byte ptr [bx].dir_attr, ATTR_HIDDEN or ATTR_SYSTEM + add bx, size dir_entry + mov byte ptr [bx].dir_attr, ATTR_HIDDEN or ATTR_SYSTEM + +wrtdir: + mov al,[drive] ; write out the directory + cbw + mov cx,1 + mov dx,3 + lea bx,scratchBuffer +;Root Directory always in 1st 32mb of partition + mov Read_Write_Relative.Start_Sector_High,0 ; ;AN000; + call Write_Disk ; ;AC000; + jnc DirectoryWritten + Message msgDirectoryWriteError ; ;AC000; + stc + ret +DirectoryWritten: + + test switchmap, SWITCH_S ; Was system requested? + retnz ; yes, don't write old boot sector + mov al,drive + cbw + mov bx,offset boot2 ; no, write old boot sector + cmp deviceParameters.DP_BPB.BPB_Heads, 1 + je bootset8 + mov word ptr [bx+3],0103h ; start address for double sided drives +bootset8: + mov cx,1 + xor dx,dx +;Boot record in 1st 32mb of partition + mov Read_Write_Relative.Start_Sector_High,0 ; ;AN000; + call Write_Disk ; ;AC000; + retnc + + Message msgBootWriteError ; ;AC000; + stc + ret + +ConvertToOldDirectoryFormat endp + +;------------------------------------------------------------------------------- + +a_PartitionTableEntry struc +BootInd db ? +BegHead db ? +BegSector db ? +BegCylinder db ? +SysInd db ? +EndHead db ? +EndSector db ? +EndCylinder db ? +RelSec dd ? +CSec dd ? +a_PartitionTableEntry ends + +; structure of the IBM hard disk boot sector: +IBMBoot STRUC + db 512 - (4*size a_PartitionTableEntry + 2) dup(?) +PartitionTable db 4*size a_PartitionTableEntry dup(?) +Signature dw ? +IBMBoot ENDS + + +;***************************************************************************** +;Routine name: SetPartitionTable +;***************************************************************************** +; +;Description: Find location for DOS partition in partition table, get the +; correct system indicator byte, and write it out. If can not +; read/write boot record or can't find DOS partition, display +; error +; +;Called Procedures: Message (macro) +; Determine_Partition_Type +; ReadSector +; WriteSector +; +;Change History: Created 4/20/87 MT +; +;Input: None +; +;Output: CY set if error +; +;Psuedocode +;---------- +; +; Read the partition table (Call ReadSector) +; IF ok +; IF boot signature of 55AAh +; Point at system partition table +; SEARCH +; Assume DOS found +; IF System_Indicator <> 1,AND +; IF System_Indicator <> 4,AND +; IF System_Indicator <> 6 +; STC (DOS not found) +; ELSE +; CLC +; ENDIF +; EXITIF DOS found (CLC) +; CALL Determine_Partition_Type +; Write the partition table (CALL WriteSector) +; IF error +; Display boot write error message +; stc +; ELSE +; clc +; ENDIF +; ORELSE +; Point at next partition entry (add 16 to partition table ptr) +; ENDLOOP if checked all 4 partition entries +; Display Bad partition table message +; stc +; ENDSRCH +; ELSE invalid boot record +; Display Bad partition table message +; stc +; ENDIF +; ELSE error +; Display Partition table error +; stc +; ENDIF +; ret +;***************************************************************************** + +Procedure SetPartitionTable ; ;AN000; + + xor ax, ax ;Head ;AC000; + xor bx, bx ;Cylinder ;AC000; + xor cx, cx ;Sector ;AC000; + lea dx, boot2 ;Never use 1.x boot on hardfile,; ; + call ReadSector ;this will use space as buffer ; ; +; $IF NC ;If read okay ;AN000; + JC $$IF70 + cmp Boot2.Boot_Signature,Boot_ID ; ;AC000; +; $IF E ;Does signature match? ;AN000; + JNE $$IF71 + lea bx, boot2.PartitionTable ;Yes, point at partition table ;AN000; +; $SEARCH ;Look for DOS partition ;AN000; +$$DO72: + cmp [bx].sysind,FAT12_File_System ; ;AC000; +; $IF NE,AND ; ;AN000; + JE $$IF73 + cmp [bx].sysind,FAT16_File_System ; ;AC000; +; $IF NE,AND ; ;AN000; + JE $$IF73 + cmp [bx].sysind,New_File_System ; ;AC000; +; $IF NE ; ;AN000; + JE $$IF73 + stc ;We didn't find partition ;AN000; +; $ELSE ; ;AN000; + JMP SHORT $$EN73 +$$IF73: + clc ;Indicate found partition ;AN000; +; $ENDIF ; ;AN000; +$$EN73: +; $EXITIF NC ;Get correct id for it ;AN000; + JC $$IF72 + CALL Determine_Partition_Type ; ;AN000; + mov ax, 0 ;Head ; ; + mov bx, 0 ;Cylinder ; ; + mov cx, 0 ;Sector ; ; + lea dx, boot2 ; ; ; + call WriteSector ;Write out partition table ; ; +; $IF C ;Error writing boot record ;AN000; + JNC $$IF77 + MESSAGE msgPartitionTableWriteError ; ;AC000; + stc ;Set CY to indicate error ; ; +; $ELSE ; ;AN000; + JMP SHORT $$EN77 +$$IF77: + clc ;No error means no CY ; ; +; $ENDIF ; ;AN000; +$$EN77: +; $ORELSE ; ;AN000; + JMP SHORT $$SR72 +$$IF72: + add bx,size a_PartitionTableEntry ; ; ; + cmp bx,(offset Boot2.PartitionTable)+4*size a_PartitionTableEntry ; ; +; $ENDLOOP ;Checked all 4 partition entries;AN000; + JMP SHORT $$DO72 + MESSAGE msgBadPartitionTable ;Tell user bad table ;AC000; + stc ;Set CY for exit ; ; +; $ENDSRCH ; ;AN000; +$$SR72: +; $ELSE ;Invalid boot record ;AN000; + JMP SHORT $$EN71 +$$IF71: + MESSAGE msgBadPartitionTable ; ;AC000; + stc ;Set CY for error return ; ; +; $ENDIF ; ;AN000; +$$EN71: +; $ELSE ;Couldn't read boot record ;AN000; + JMP SHORT $$EN70 +$$IF70: + MESSAGE msgPartitionTableReadError ; ;AC000; + stc ;Set CY for error return ; ; +; $ENDIF ; ;AN000; +$$EN70: + ret ; ; ; + +SetPartitionTable endp ; ;AN000; + +;***************************************************************************** +;Routine name: Determine_Partition_Type +;***************************************************************************** +; +;DescriptioN: Set the system indicator field to its correct value as +; determined by the following rules: +; +; - Set SysInd = 01h if partition or logical drive size is < 10mb +; and completely contained within the first 32mb of DASD. +; - Set SysInd = 04h if partition or logical drive size is >10mb, +; <32mb, and completely contained within the first 32mb of DASD +; - Set SysInd to 06h if partition or logical drive size is > 32mb, +; +;Called Procedures: Message (macro) +; +;Change History: Created 3/18/87 MT +; +;Input: BX has offset of partition table entry +; fBigFAT = TRUE if 16bit FAT +; +;Output: BX.SysInd = correct partition system indicator value (1,4,6) +; +;Psuedocode +;---------- +; Add partition start location to length of partition +; IF end > 32mb +; BX.SysInd = 6 +; ELSE +; IF fBigFat +; BX.SysInd = 4 +; ELSE +; BX.SysInd = 1 +; ENDIF +; ret +;***************************************************************************** + +Procedure Determine_Partition_Type ;AN000; + + mov dx,word ptr [bx].Csec+2 ;an000; dms;Get high word of sector count + cmp dx,0 ;AN000; ;> 32Mb? +; $IF NE ;AN000; ;yes + JE $$IF87 + mov [BX].SysInd,New_File_System ;AN000; ;type 6 +; $ELSE ;AN000; + JMP SHORT $$EN87 +$$IF87: + call Calc_Total_Sectors_For_Partition ;an000; dms;returns DX:AX total sectors + cmp DeviceParameters.DP_BPB.BPB_HiddenSectors[+2],0 ;an000; dms;> 32Mb? +; $if ne ;an000; dms;yes + JE $$IF89 + mov [bx].SysInd,New_File_System ;an000; dms; type 6 +; $else ;an000; dms; + JMP SHORT $$EN89 +$$IF89: + cmp dx,0 ;an000; dms; partition > 32 Mb? +; $if ne ;an000; dms; yes + JE $$IF91 + mov [bx].SysInd,New_File_System ;an000; dms; type 6 +; $else ;an000; dms; < 32 Mb partition + JMP SHORT $$EN91 +$$IF91: + cmp fBigFat,True ;an000; ;16 bit FAT +; $IF E ;AC000; ;yes + JNE $$IF93 + mov [BX].SysInd,FAT16_File_System ;an000; ;type 4 +; $ELSE ;an000; ;12 bit FAT + JMP SHORT $$EN93 +$$IF93: + mov [bx].SysInd,FAT12_File_System ;an000; ;type 1 +; $ENDIF ;AN000; +$$EN93: +; $ENDIF ;an000; +$$EN91: +; $ENDIF ;an000; +$$EN89: +; $endif ;an000; +$$EN87: + ret ;an000; + +Determine_Partition_Type endp ; ;AN000; + + +;========================================================================= +; Calc_Total_Sectors_For_Partition : This routine determines the +; total number of sectors within +; this partition. +; +; Inputs : DeviceParameters +; +; Outputs : DX:AX - Double word partition size +;========================================================================= + +Procedure Calc_Total_Sectors_For_Partition ;an000; dms; + + mov ax,word ptr DeviceParameters.DP_BPB.BPB_HiddenSectors[+0] ;an000; dms; low word + mov dx,word ptr DeviceParameters.DP_BPB.BPB_HiddenSectors[+2] ;an000; dms; high word + cmp DeviceParameters.DP_BPB.BPB_TotalSectors,0 ;an000; dms; extended BPB? +; $if e ;an000; dms; yes + JNE $$IF99 + add ax,word ptr DeviceParameters.DP_BPB.BPB_BigTotalSectors[+0] ;an000; dms; add in low word + adc dx,0 ;an000; dms; pick up carry if any + add dx,word ptr DeviceParameters.DP_BPB.BPB_BigTotalSectors[+2] ;an000; dms; add in high word +; $else ;an000; dms; standard BPB + JMP SHORT $$EN99 +$$IF99: + add ax,word ptr DeviceParameters.DP_BPB.BPB_TotalSectors ;an000; dms; add in total sector count + adc dx,0 ;an000; dms; pick up carry if any +; $endif ;an000; dms; +$$EN99: + + ret + +Calc_Total_Sectors_For_Partition endp + + +;------------------------------------------------------------------------------- +; ReadSector: +; Read one sector +; +; Input: +; ax - head +; bx - cylinder +; cx - sector +; dx - transfer address + +ReadSector proc near + + mov TrackReadWritePacket.TRWP_FirstSector, cx + mov cx,(RAWIO shl 8) or READ_TRACK + call SectorIO + return + +ReadSector endp + +;------------------------------------------------------------------------------- +; WriteSector: +; Write one sector +; +; Input: +; ax - head +; bx - cylinder +; cx - sector +; dx - transfer address + +WriteSector proc near + + mov TrackReadWritePacket.TRWP_FirstSector, cx + mov cx,(RAWIO shl 8) or WRITE_TRACK + call SectorIO + return + +WriteSector endp + +;------------------------------------------------------------------------------- +; SectorIO: +; Read/Write one sector +; +; Input: +; ax - head +; bx - cylinder +; cx - (RAWIO shl 8) or READ_TRACK +; - (RAWIO shl 8) or WRITE_TRACK +; dx - transfer address + +SectorIO proc near + + mov TrackReadWritePacket.TRWP_Head, ax + mov TrackReadWritePacket.TRWP_Cylinder, bx + mov WORD PTR TrackReadWritePacket.TRWP_TransferAddress, dx + mov WORD PTR TrackReadWritePacket.TRWP_TransferAddress + 2, ds + mov TrackReadWritePacket.TRWP_SectorsToReadWrite, 1 + + mov bl, drive + inc bl + mov ax, (IOCTL shl 8) or GENERIC_IOCTL + lea dx, trackReadWritePacket + int 21H + return + +SectorIO endp + +;------------------------------------------------------------------------------- + +data segment public para 'DATA' + +oldDrive db ? + +FCBforVolumeIdSearch db 0ffH + db 5 dup(0) + db 08H + db 0 + db "???????????" + db 40 DUP(0) + +data ends + +GetVolumeId proc near +; Input: +; dl = drive +; di = name buffer + +; Save current drive + mov ah,19H + int 21H + mov oldDrive, al + +; Change current drive to the drive that has the volume id we want + mov ah, 0eH + int 21H + +; Search for the volume id + mov ah, 11H + lea dx, FCBforVolumeIdSearch + int 21H + push ax + +; Restore current drive + mov ah, 0eH + mov dl,oldDrive + int 21H + +; Did the search succeed? + pop ax + or al,al + jz CopyVolumeId + stc + ret + +CopyVolumeId: +; Find out where the FCB for the located volume id was put + mov ah,2fH + int 21H + +; Copy the Volume Id + mov si, bx + add si, 8 + push es + push ds + pop es + pop ds + mov cx, 11 + rep movsb + push es + pop ds + + clc + ret + +GetVolumeId endp + +data segment public para 'DATA' +oldVolumeId db 11 dup(0) +data ends + +CheckVolumeId proc near + +; Get the volume id that's on the disk + lea di, oldVolumeId + mov dl, drive + call GetVolumeId + jnc Ask_User ;Did we find one? + clc ;No, return with no error + ret + +; Ask the user to enter the volume id that he/she thinks is on the disk +; (first blank out the input buffer) +Ask_User: + + Message msgWhatIsVolumeId? ; ;AC000; + ;lea dx, ptr_msgWhatIsVolumeId? + ;call std_printf + call user_string + call crlf + +; If the user just pressed ENTER, then there must be no label + cmp inbuff+1, 0 + jne CompareVolumeIds + cmp oldVolumeId, 0 + jne BadVolumeId + ret + +CompareVolumeIds: +; pad the reponse with blanks +; The buffer is big enough so just add 11 blanks to what the user typed in + push ds + pop es + mov cx, Label_Length ;AC000; + xor bx,bx + mov bl, inbuff + 1 + lea di, inbuff + 2 + add di, bx + mov al, ' ' + rep stosb +; Make the reply all uppercase + mov byte ptr Inbuff+2+Label_Length,ASCIIZ_End ;Make string ASCIIZ ;AN000; + mov dx, offset inbuff + 2 ;Start of buffer ;AC000; + mov al,22h ;Capitalize asciiz ;AC000; + DOS_Call GetExtCntry ;Do it ;AC000; + +; Now compare what the user specified with what is really out there + mov cx, Label_Length ; ;AC000; + lea si, inbuff + 2 + lea di, oldVolumeId + repe cmpsb + jne BadVolumeId + ret + +BadVolumeId: + Message msgBadVolumeID ; ;AC000; + stc + ret + +CheckVolumeId endp + + +Check_Switch_8_B proc near + + test SwitchMap, SWITCH_B ;/8/B <> /V because ;AC007; +; $IF NZ,AND ; old directory type ;AC007; + JZ $$IF102 + test SwitchMap, Switch_8 ; used which didn't support ;AC007; +; $IF NZ,AND ; volume labels. ;AC007; + JZ $$IF102 + test SwitchMap, SWITCH_V ; ;AC007; +; $IF NZ ; ;AC007; + JZ $$IF102 + Message msgIncompatibleParameters ;Tell user ;AC007; + mov Fatal_Error,Yes ;Bad stuff ;AC007; +; $ELSE ;No problem so far ;AC007; + JMP SHORT $$EN102 +$$IF102: + test SwitchMap, Switch_B ;Can't reserve space and ;AC007; +; $IF NZ,AND ; install sys files at the ;AC007; + JZ $$IF104 + test SwitchMap, Switch_S ; same time. ;AC007; +; $IF NZ ; No /S/B ;AC007; + JZ $$IF104 + Message msgIncompatibleParameters ;Tell user ;AC007; + mov Fatal_Error,Yes ;Bad stuff ;AC007; +; $ELSE ;Still okay ;AC007; + JMP SHORT $$EN104 +$$IF104: + test SwitchMap,Switch_1 ;/1/8/4 not okay with /N/T ;AC007; +; $IF NZ,OR ; ;AC007; + JNZ $$LL106 + test SwitchMap,Switch_8 ; ;AC007; +; $IF NZ,OR ; ;AC007; + JNZ $$LL106 + test SwitchMap,Switch_4 ; ;AC007; +; $IF NZ ; ;AC007; + JZ $$IF106 +$$LL106: + test SwitchMap,(Switch_T or Switch_N) ; ;AC007; +; $IF NZ ;Found /T/N <> /1/8 ;AC007; + JZ $$IF107 + Message msgIncompatibleParameters ;Tell user ;AC007; + mov Fatal_Error,Yes ;Bad stuff ;AC007; +; $ELSE ; ;ac007; + JMP SHORT $$EN107 +$$IF107: + test SwitchMap,Switch_V ;ac007; +; $IF NZ,AND ;ac007; + JZ $$IF109 + test SwitchMap,Switch_8 ;ac007; +; $IF NZ ;ac007; + JZ $$IF109 + Message msgIncompatibleParameters ;ac007; + mov Fatal_Error,Yes ;ac007; +; $ENDIF ;ac007; +$$IF109: +; $ENDIF ; ;AC007; +$$EN107: +; $ENDIF ; ;AC007; +$$IF106: +; $ENDIF ; ;AC007; +$$EN104: +; $ENDIF ; ;AC007; +$$EN102: + ret + +Check_Switch_8_B endp + + +code ends + end + \ No newline at end of file -- cgit v1.2.3