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/DISPLAY.ASM | 177 ++ v4.0/src/CMD/FORMAT/FILESIZE.INC | 6 + v4.0/src/CMD/FORMAT/FORCHNG.INC | 135 ++ v4.0/src/CMD/FORMAT/FOREQU.INC | 115 + v4.0/src/CMD/FORMAT/FOREXEC.ASM | 637 ++++++ v4.0/src/CMD/FORMAT/FORINIT.ASM | 1255 +++++++++++ v4.0/src/CMD/FORMAT/FORLABEL.ASM | 771 +++++++ v4.0/src/CMD/FORMAT/FORMACRO.INC | 102 + v4.0/src/CMD/FORMAT/FORMAT.ASM | 4509 ++++++++++++++++++++++++++++++++++++++ v4.0/src/CMD/FORMAT/FORMAT.LNK | 8 + v4.0/src/CMD/FORMAT/FORMAT.SKL | 229 ++ v4.0/src/CMD/FORMAT/FORMSG.INC | 861 ++++++++ v4.0/src/CMD/FORMAT/FORPARSE.INC | 523 +++++ v4.0/src/CMD/FORMAT/FORPROC.ASM | 521 +++++ v4.0/src/CMD/FORMAT/FORSWTCH.INC | 38 + v4.0/src/CMD/FORMAT/MAKEFILE | 55 + v4.0/src/CMD/FORMAT/MSFOR.ASM | 1936 ++++++++++++++++ 17 files changed, 11878 insertions(+) create mode 100644 v4.0/src/CMD/FORMAT/DISPLAY.ASM create mode 100644 v4.0/src/CMD/FORMAT/FILESIZE.INC create mode 100644 v4.0/src/CMD/FORMAT/FORCHNG.INC create mode 100644 v4.0/src/CMD/FORMAT/FOREQU.INC create mode 100644 v4.0/src/CMD/FORMAT/FOREXEC.ASM create mode 100644 v4.0/src/CMD/FORMAT/FORINIT.ASM create mode 100644 v4.0/src/CMD/FORMAT/FORLABEL.ASM create mode 100644 v4.0/src/CMD/FORMAT/FORMACRO.INC create mode 100644 v4.0/src/CMD/FORMAT/FORMAT.ASM create mode 100644 v4.0/src/CMD/FORMAT/FORMAT.LNK create mode 100644 v4.0/src/CMD/FORMAT/FORMAT.SKL create mode 100644 v4.0/src/CMD/FORMAT/FORMSG.INC create mode 100644 v4.0/src/CMD/FORMAT/FORPARSE.INC create mode 100644 v4.0/src/CMD/FORMAT/FORPROC.ASM create mode 100644 v4.0/src/CMD/FORMAT/FORSWTCH.INC create mode 100644 v4.0/src/CMD/FORMAT/MAKEFILE create mode 100644 v4.0/src/CMD/FORMAT/MSFOR.ASM (limited to 'v4.0/src/CMD/FORMAT') diff --git a/v4.0/src/CMD/FORMAT/DISPLAY.ASM b/v4.0/src/CMD/FORMAT/DISPLAY.ASM new file mode 100644 index 0000000..10ea538 --- /dev/null +++ b/v4.0/src/CMD/FORMAT/DISPLAY.ASM @@ -0,0 +1,177 @@ +; + +;***************************************************************************** +;***************************************************************************** +;UTILITY NAME: FORMAT.COM +; +;MODULE NAME: DISPLAY.ASM +; +; +; Change List: AN000 - New code DOS 3.3 spec additions +; AC000 - Changed code DOS 3.3 spec additions +;***************************************************************************** +;***************************************************************************** + + +; +;***************************************************************************** +; Define Segment ordering +;***************************************************************************** +; + + +.SEQ ; + +PSP segment public para 'DUMMY' +PSP ends + +data segment public para 'DATA' ; +Public Test_Data_Start +Test_Data_Start label byte +data ends ; + +stack segment para stack + db 62 dup ("-Stack!-") ; (362-80h) is the additionsal IBM ROM + assume ss:stack +stack ends + + +code segment public para 'CODE' ; + assume cs:code,ds:data ; +code ends + +End_Of_Memory segment public para 'BUFFERS' ; +Public Test_End +Test_End label byte +End_Of_Memory ends ; + + +; +;***************************************************************************** +; INCLUDE FILES +;***************************************************************************** +; + +.xlist +INCLUDE FORCHNG.INC +INCLUDE FOREQU.INC +INCLUDE FORMSG.INC +INCLUDE SYSMSG.INC +.list + +; +;***************************************************************************** +; Message Services +;***************************************************************************** +; + + +MSG_UTILNAME + + +data segment public para 'DATA' +Msg_Services +data ends + +code segment public para 'CODE' +Msg_Services +Msg_Services +Msg_Services +Msg_Services +code ends + +; +;***************************************************************************** +; Public Declarations +;***************************************************************************** +; + + Public SysDispMsg + Public SysLoadMsg + + +; +;*************************************************************************** +; Message Structures +;*************************************************************************** +; + + +Message_Table struc ; ;AN000; + ; +Entry1 dw 0 ; ;AN000; +Entry2 dw 0 ; ;AN000; +Entry3 dw 0 ; ;AN000; +Entry4 dw 0 ; ;AN000; +Entry5 db 0 ; ;AN000; +Entry6 db 0 ; ;AN000; +Entry7 dw 0 ; ;AN000; + ; +Message_Table ends ; ;AN000; + + + +code segment public para 'CODE' +;***************************************************************************** +;Routine name&gml Display_Interface +;***************************************************************************** +; +;DescriptioN&gml Save all registers, set up registers required for SysDispMsg +; routine. This information is contained in a message description +; table pointed to by the DX register. Call SysDispMsg, then +; restore registers. This routine assumes that the only time an +; error will be returned is if an extended error message was +; requested, so it will ignore error returns +; +;Called Procedures: Message (macro) +; +;Change History&gml Created 4/22/87 MT +; +;Input&gml ES&gmlDX = pointer to message description +; +;Output&gml None +; +;Psuedocode +;---------- +; +; Save all registers +; Setup registers for SysDispMsg from Message Description Tables +; CALL SysDispMsg +; Restore registers +; ret +;***************************************************************************** + +Public Display_Interface +Display_Interface proc ; ;AN000; + + push ds ; ;AN000; + push ax ;Save registers ;AN000; + push bx ; " " " " ;AN000; + push cx ; " " " " ;AN000; + push dx ; " " " " ;AN000; + push si ; " " " " ;AN000; + push di ; " " " " ;AN000; + mov di,dx ;Change pointer to table ;AN000; + mov dx,data ;Point to data segment + mov ds,dx ; + mov ax,[di].Entry1 ;Message number ;AN000; + mov bx,[di].Entry2 ;Handle ;AN000; + mov si,[di].Entry3 ;Sublist ;AN000; + mov cx,[di].Entry4 ;Count ;AN000; + mov dh,[di].Entry5 ;Class ;AN000; + mov dl,[di].Entry6 ;Function ;AN000; + mov di,[di].Entry7 ;Input ;AN000; + call SysDispMsg ;Display the message ;AN000; + pop di ;Restore registers ;AN000; + pop si ; " " " " ;AN000; + pop dx ; " " " " ;AN000; + pop cx ; " " " " ;AN000; + pop bx ; " " " " ;AN000; + pop ax ; " " " " ;AN000; + pop ds ; ;AN000; + ret ;All done ;AN000; + +Display_Interface endp ; ;AN000; +code ends + end + diff --git a/v4.0/src/CMD/FORMAT/FILESIZE.INC b/v4.0/src/CMD/FORMAT/FILESIZE.INC new file mode 100644 index 0000000..40f058d --- /dev/null +++ b/v4.0/src/CMD/FORMAT/FILESIZE.INC @@ -0,0 +1,6 @@ + + %out ..filesize.inc + +BIOS_SIZE equ 35000 ;actually +DOS_SIZE equ 37000 ;actually + \ No newline at end of file diff --git a/v4.0/src/CMD/FORMAT/FORCHNG.INC b/v4.0/src/CMD/FORMAT/FORCHNG.INC new file mode 100644 index 0000000..2aef46c --- /dev/null +++ b/v4.0/src/CMD/FORMAT/FORCHNG.INC @@ -0,0 +1,135 @@ +.xlist +; +; +;***************************************************************************** +;* * +;* Change list to FORMAT modules * +;* * +;* Lines are tagged ANxxx for new, ACxxx for changed * +;* --------------------------------------------------------------------------* +;* 000 - DOS 4.00 Spec additions and DCR's thru unit/function test * +;* Date: 8/3/87 Developer: MT * +;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * +;* 001 - DOS 4.00 DCR D146 Add support for /F switch * +;* Date: 8/13/87 Developer: MT * +;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * +;* 002 - DOS 4.00 DCR D166 Add logic to detect that switches entered * +;* multiple times, and print error message * +;* Date: 8/13/87 Developer: MT * +;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * +;* 003 - DOS 4.00 PTM P233 Do not allow Cntrl-Break when writing file * +;* system out, only during the actual format * +;* Date: 8/14/87 Developer: MT * +;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * +;* 004 - DOS 4.00 PTM P229 Volume serial number displayed in reverse word * +;* order from command.com and diskcopy. Reverse order of words * +;* Date: 8/17/87 Developer: MT * +;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * +;* 005 - DOS 4.00 DCR D64 Enable for 128k FAT * +;* Date: 8/19/87 Developer: DMS * +;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * +;* 006 - DOS 4.00 PTM P320 Not detecting write protect. Needed to use * +;* extended error messages * +;* Date 8/20/87 Developer: MT * +;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * +;* 007 - DOS 4.00 PTM P170 Straighten out the switch check logic to allow * +;* /B with all diskette formats, add /B/S check, and remove /V/B * +;* check except for /8 sectored diskettes (old dir and boot record * +;* Date 8/21/87 Developer: MT * +;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * +;* 008 - DOS 4.00 PTM P402 Fields that determine switch type not cleared, * +;* so switches got checked multiple times, causing error * +;* Date 8/23/87 Developer: MT , DS * +;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * +;* 009 - DOS 4.00 PTM P341 Check to make sure /N entered with /T * +;* Date 8/23/87 Developer: MT * +;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * +;* 010 - DOS 4.00 PTM P233 Capture the CTRL-BREAK interrupt and disable * +;* it during the writing of the FAT, DIR, and SYSTEM. * +;* Date 8/25/87 Developer: DMS * +;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * +;* 012 - DOS 4.00 DCR 200 If the NumberOfFATs field of the BPB is 0 we need * +;* to calculate various values in the BPB to be used by FORMAT. * +;* Date 9/10/87 Developer: DMS * +;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * +;* 013 - DOS 4.00 DCR 208 Set FORMAT in order that the space available it * +;* reports is consistent with DIR. * +;* Date 9/11/87 Developer: DMS * +;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * +;* 014 - DOS 4.00 PTM 1535 Allow access to a non-formatted disk. * +;* Date 10/15/87 Developer: DMS * +;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * +;* 015 - DOS 4.00 DCR 390 Multi-Track format of hard media * +;* Date 12/9/87 Developer: DMS * +;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * +;* 016 - DOS 4.00 DCR 395 SELECT message support. Use INT 2Fh, function * +;* ADC1h to print FORMAT disk prompt from SELECT. * +;* Date 12/14/87 Developer: DMS * +;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * +;* 017 - DOS 4.00 PTM 3125 SELECT message support. Disable write protect * +;* message under SELECT option. Addition of exit codes 6 (Drive Not * +;* Ready" and 7 (Write Protect). * +;* Date 1/14/88 Developer: DMS * +;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * +;* 018 - DOS 4.00 PTM 3130 Provide for conditional assembly of the /FS: * +;* code, since it is not being shipped with DOS 4.00. * +;* Date 1/26/88 Developer: DMS * +;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * +;* 019 - DOS 4.00 PTM 3994 FORMAT now has a "heartbeat" when it verifies * +;* bad sectors. By doing so the user knows the FORMAT is still * +;* proceeding well. Without this heartbeat, an AT appears to hang * +;* when the sectors are being verified. This is caused by the slow * +;* head resets on an AT. * +;* Date 3/25/88 Developer: DMS * +;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * +;* 020 - DOS 4.00 PTM 4058 When an invalid Volume ID is entered at the * +;* volume prompt, FORMAT should go to the next line so that the * +;* user can see the invalid volume id. * +;* Date 3/29/88 Developer: DMS * +;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * +;* 021 - DOS 4.00 PTM 4081 FORMAT was marking the incorrect cluster as * +;* bad under certain situations. This caused that sector to fail * +;* when read or written to. * +;* Date 3/31/88 Developer: DMS * +;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * +;* 022 - DOS 4.00 PTM 4180 FORMAT was not performing an FCB Close after * +;* it had done an FCB Create. This caused the change line counter * +;* to go "haywire". Also a bug was found in the FORMAT retry logic. * +;* FORMAT was never entering the retry logic because of a CY flag * +;* always existing on entry to the routine. * +;* Date 4/15/88 Developer: DMS * +;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * +;* 023 - DOS 4.00 DCR 524 FORMAT must accept a blank or carriage return to * +;* allow for a blank volume label. * +;* Date 4/19/88 Developer: DRM * +;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * +;* 024 - DOS 4.00 PTM 4487 FORMAT trys to get the A: drive when formatting * +;* drive B: and then hitting enter for the volume label. There is a * +;* problem with FCB Close but logic was also changed in FORLABEL.SAL * +;* to eliminate this condition. * +;* Date 4/26/88 Developer: DRM * +;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * +;* 025 - DOS 4.00 PTM 4539 FORMAT accesses the default disk instead of the * +;* boot disk when the default disk is different than the boot disk. * +;* This is incorrect behavior because the user could receive a system * +;* other than what they wanted. * +;* Date 4/28/88 Developer: DMS * +;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * +;* 026 - DOS 4.00 PTM 4805 FORMAT A: /B gives invalid bad byte count and * +;* FORMAT A: /F:160 on an 1.2 Mb drive gives parm error. * +;* Date 5/10/88 Developer: DMS * +;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * +;* 027 - DOS 4.00 PTM 4913 FORMAT A: /B displays the serial number of the * +;* diskette but never writes it to the diskette. Format will no * +;* display the serial number when formatting with /8. * +;* Date 5/19/88 Developer: DRM * +;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * +;* 028 - DOS 4.00 PTM 5023 FORMAT puts just the N of NO NAME in the volume * +;* label of the boot record. This is corrected in IBMFOR.SAL by * +;* setting up the CX register correctly. * +;* Date 6/09/88 Developer: DRM * +;***************************************************************************** +;* Note: This is file FORCHNG.INC for updating purposes * +;***************************************************************************** +.list + diff --git a/v4.0/src/CMD/FORMAT/FOREQU.INC b/v4.0/src/CMD/FORMAT/FOREQU.INC new file mode 100644 index 0000000..5d5d925 --- /dev/null +++ b/v4.0/src/CMD/FORMAT/FOREQU.INC @@ -0,0 +1,115 @@ +; ; ; ; + +NO equ 0 +YES equ not NO +FSExec equ NO ;an018; dms;conditional assembly +ShipDisk equ NO ;an000; dms;ship disk flag + +Boot_ID equ 0AA55h +DOS_Found equ 0 + +Not_Include equ 0 +Do_Include equ 1 + +INIT equ 0 + +FAT12_File_System equ 01h +FAT16_File_System equ 04h +New_File_System equ 06h + +FS_String_Max_Length equ 5 + +Paragraph_Size equ 16 ; ;AN005; +Len_FS_String_Buffer equ 13 + +Net_Check equ 1200h +Assign_Check equ 8000h + +Found_Yes equ 1 +Found_No equ 0 + +Asciiz_End equ 0 +DBCS equ 81h +DBCS_Blank equ 40h +DBCS_Vector_Size equ 2 +End_Of_Vector equ 0 + + +Blank equ " " + +Label_Length equ 11 +CR equ 13 + +DBCS_VECTOR equ NO + +;Limits +BIG_FAT_THRESHOLD equ 4086 + +;------------------------------------------------------------------------------- + + + + + +DRNUM EQU 5CH + + + +; Exit status defines +ExitOK equ 0 +ExitCtrlC equ 3 +ExitFatal equ 4 +ExitNo equ 5 + + +;------------------------------------------------------------------------------- +; These are the data structures which we will need + + +Media_ID struc +Media_ID_Info_Level dw 0 +Media_ID_Serial_Number dd 0 +Media_ID_Volume_Label db 11 dup(" ") +Media_ID_File_System db 8 dup(" ") +Media_ID ends + + +Relative_Sector_Buffer struc ; ;AN000; + +Start_Sector_Low dw ? ;Low word of RBA sector ;AN000; +Start_Sector_High dw ? ;High word of RBA sector ;AN000; +Number_Sectors dw ? ;Number of sectors ;AN000; +Buffer_Offset dw ? ;Address of data buffer ;AN000; +Buffer_Segment dw ? ; ;AN000; + +Relative_Sector_Buffer ends ; ;AN000; + + +;Per system file data structure + +a_FileStructure struc +fileHandle DW ? +fileSizeInParagraphs DW ? +fileSizeInBytes DD ? +fileOffset DD ? +fileStartSegment DW ? +fileDate DW ? +fileTime DW ? +a_FileStructure ends + +;------------------------------------------------------------------------------- + +LOGBOOTSECT equ 1 +Set_Drv_Owner equ 0Fh ; IOCTL subfunction +Custom_Media equ 0F0H ; Media byte for custom format +Dual_8_Media equ 0FFh ; Dual sided 8 sectored +Single_8_Media equ 0FEh ; Single sided 8 sectored +Dual_9_Media equ 0FDh ; Dual sided 9 sectored +Single_9_Media equ 0FCh ; Single sided 9 sectored +Dual_15_Media equ 0F9h ; Dual sided 15 sectored +Fixed_Disk equ 0F8h ; Fixed Disk +Invalid_Drive equ 000Fh ; Extended error 15 +Max_Format_Size equ 0FFFFh ; Max bytes to Format ;an015; dms; +Multi_Track_Format equ 02h ; Multi-track format ;an015; dms; +Single_Track_Format equ 00h ; Single track format ;an015; dms; +Select_Disk_Message equ 0ADC1h ; an016; dms; diff --git a/v4.0/src/CMD/FORMAT/FOREXEC.ASM b/v4.0/src/CMD/FORMAT/FOREXEC.ASM new file mode 100644 index 0000000..46026cb --- /dev/null +++ b/v4.0/src/CMD/FORMAT/FOREXEC.ASM @@ -0,0 +1,637 @@ +page ,132 ; +; + +;***************************************************************************** +;***************************************************************************** +;UTILITY NAME: FORMAT.COM +; +;MODULE NAME: FOREXEC.SAL +; +; +; +; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +; ³EXEC_FS_FORMAT³ +; ÀÄÂÄÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ +; ³ÚÄÄÄÄÄÄ¿ +; ôShrink³ +; ³ÀÄÄÄÄÄÄÙ +; ³ÚÄÄÄÄÄÄÄÄÄÄ¿ +; ôSetup_EXEC³ +; ³ÀÄÄÄÄÄÄÄÄÄÄÙ +; ³ÚÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿ +; ôEXEC_ArgVÃÄÄÄÄÄÄÄÄÄÄ´EXEC_Program³ +; ³ÀÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿ +; ôEXEC_Cur_DirectoryÃÄ´EXEC_Program³ +; ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿ +; À´EXEC_RoutineÃÄÄÄÄÄÄÄ´Build_Path_And_EXECÃÄ´EXEC_Program³ +; ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ +; +; Change List: AN000 - New code DOS 3.3 spec additions +; AC000 - Changed code DOS 3.3 spec additions +;***************************************************************************** +;***************************************************************************** + +title DOS 3.30 FORMAT EXEC Module + +IF1 + %OUT ASSEMBLING: DOS 3.3 FORMAT EXEC LOADER + %OUT +ENDIF + +code segment public para 'code' + assume cs:code +code ends + +; +;***************************************************************************** +; Include files +;***************************************************************************** +; + +.xlist +INCLUDE FORCHNG.INC +INCLUDE FORMACRO.INC +INCLUDE SYSCALL.INC +INCLUDE FOREQU.INC +.list + +; +;***************************************************************************** +; Public Data +;***************************************************************************** +; + + Public Drive_Letter_Msg + +; +;***************************************************************************** +; Public Routines +;***************************************************************************** +; + + +IF FSExec ;an018; dms;if /FS: desired + + Public EXEC_FS_Format + +ENDIF ;FSExec ;an018; dms;end /FS: conditional + + Extrn GetFSiz:near + + +; +;***************************************************************************** +; External Data Declarations +;***************************************************************************** +; + + extrn ExitStatus:Byte + extrn Fatal_Error:Byte + extrn FS_String_Buffer:Byte + extrn msgEXECFailure:Byte + extrn PSP_Segment:Word + extrn drive:byte + +; +;**************************************************************************** +; Structures +;**************************************************************************** +; + + +Exec_Block_Parms struc +Segment_Env dw 0 +Offset_Command dw 0 +Segment_Command dw 0 +Offset_FCB1 dw 0 +Segment_FCB1 dw 0 +Offset_FCB2 dw 0 +Segment_FCB2 dw 0 + +Exec_Block_Parms ends + + +; +;**************************************************************************** +; Equates +;**************************************************************************** +; + + +String_Done equ 0 +No_Error equ 0 +Error equ 1 +Stderr equ 2 +Stack_Space equ 02eh ;an000; dms; IBM addition ROM paras + +; +;**************************************************************************** +; PSP Area +;**************************************************************************** +; + +PSP segment public para 'DUMMY' + +org 2Ch +PSP_ENV_SEGMENT label word + +FCB1 equ 5Ch + +FCB2 equ 6Ch + +org 80h +Command_Line label byte + + +PSP ends + +; +;**************************************************************************** +; Data Area +;**************************************************************************** +; + +data segment public para 'DATA' + assume ds:data,es:nothing + +Exec_Block Exec_Block_Parms <> +EXEC_Path db 66 dup(0) + +Drive_Letter_Msg db "A:",0 ;Drive for exec fail message + +SP_Save dw ? ;an000; dms; +SS_Save dw ? ;an000; dms; + + +;These next two should stay togather +; --------------------------------------- + ; +Path_String db "PATH=" ; ;AN000; +Len_Path_String equ $ - Path_String ; ;AN000; + ; +;---------------------------------------- + + + + +;These should stay togather +; --------------------------------------- + ; +Search_FORMAT db "FORMAT" ; ;AC000; +Len_Search_FORMAT equ $ - Search_FORMAT ; ; ; +Search_Format_End equ $ + ; ; ; +;---------------------------------------- + + +;These next two should stay togather +; --------------------------------------- + + + + + +data ends + +code segment public para 'code' + assume cs:code,ds:data + +; +;**************************************************************************** +; Main Routine +;**************************************************************************** +; +; +; +; +; + +IF FSExec ;an018; dms;if /FS: desired + + +Procedure Exec_FS_Format ; ;AC000; + + Set_Data_Segment ; + call Set_FCB1_Drive ;an000;dms; + call Shrink ; ; ; + mov al,ExitStatus ;Setblock fail? ;AC000; + cmp al,Error ; " " " " ; ; +; $IF NE ;Nah, keep crusin! ;AN000; + JE $$IF1 + call Setup_Exec ; ; ; + call Exec_Argv ;try exec from dir BASIC loaded ; ; + mov al,ExitStatus ; ;AC000; + cmp al,Error ; ; ; +; $IF E,AND ; ;AC000; + JNE $$IF2 + call Exec_Cur_Directory ; ; ; + mov al,ExitStatus ;Try exec from cur directory ;AC000; + cmp al,Error ; ; ; +; $IF E,AND ; ;AC000; + JNE $$IF2 + call EXEC_Routine ; ; ; + mov al,ExitStatus ; ;AC000; + cmp al,Error ; ; ; +; $IF E ; ;AC000; + JNE $$IF2 + ; mov bl,FCB1 ;Get target drive from FCB + ; mov bl,Drive ;an000;dms; + push ds ;an000;dms;save ds + push si ;an000;dms;save si + mov si,PSP_Segment ;an000;dms;get psp + mov ds,si ;an000;dms;put psp in ds + assume ds:PSP ;an000;dms; + + mov si,FCB1 ;an000;dms;ptr to 1st. FCB + mov bl,byte ptr ds:[si] ;an000;dms;get drive ID + + pop si ;an000;dms;restore si + pop ds ;an000;dms;restore ds + Set_Data_Segment ;an000;dms;set segments + + cmp bl,0 ;Is it default drive? ;AN000; +; $IF E ;Yes, turn it into drive letter ;AN000; + JNE $$IF3 + push ax ;Save exit code ;AN000; + DOS_Call Get_Default_Drive ;Get the default drive ;AN000; + add al,"A" ;Turn into drive letter ;AN000; + mov Drive_Letter_Msg,al ;Save it in message ;AN000; + pop ax ;Get return code back ;AN000; +; $ELSE ;Not default, A=1 ;AN000; + JMP SHORT $$EN3 +$$IF3: + add bl,"A"-1 ;Convert to drive letter ;AN000; + mov Drive_Letter_Msg,bl ; ;AN000; +; $ENDIF ;AN000; +$$EN3: + Message msgEXECFailure ; ;AC000; +; $ELSE ; ;AN000; + JMP SHORT $$EN2 +$$IF2: + DOS_Call WaitProcess ; ;AC000; + mov ExitStatus,al ; ; ; +; $ENDIF ; ;AN000; +$$EN2: +; $ENDIF +$$IF1: + mov Fatal_Error,YES ;Not really, indicates FS used ;AN000; + ret ; ; ; + +Exec_FS_Format endp + + +; +;**************************************************************************** +; Shrink +;**************************************************************************** +; +; +; +; + + +Procedure Shrink ; ;AC000; + + mov ax,cs ;an000; dms;get code segment + mov bx,ds ;an000; dms;get data segment + sub ax,bx ;an000; dms;data seg size + mov bx,ax ;an000; dms;save paras + mov ax,offset End_Program ;Get the offset of end of loader; ; + mov cl,4 ;Div by 16 to get para's ; ; + shr ax,cl ; ; ; + add bx,ax ;an000; dms;add in code space + add bx,Stack_Space ;an000; dms;adjust for stack + add bx,11h ;an000; dms;give PSP space + mov ax,PSP_Segment + mov es,ax + assume es:nothing + + DOS_Call SetBlock ; ;AC000; +; $IF C ;If didn't work, quit ;AC000; + JNC $$IF9 + Message msgEXECFailure ; ; ; + mov ExitStatus,Error ;Bad stuff, time to quit ;AN000; +; $ENDIF ; ;AN000; +$$IF9: + ret ; ; ; + +Shrink endp ; ;AN000; + + +; +;**************************************************************************** +; Setup_Exec +;**************************************************************************** +; +; +; +; + +Procedure Setup_Exec ; ;AC000; + + Set_Data_Segment + mov ax,PSP_Segment ;Get segment of PSP ;AN000; + mov ds,ax ; " " " " ;AN000; + ; ; + assume ds:PSP + ;Setup dword pointer to command line to be passed + + mov es:Exec_Block.Segment_Command,ax ;Segment for command line ; ; + mov es:Exec_Block.Offset_Command,offset ds:Command_Line ; ; ; + + ;Setup dword pointer to first FCB to be passed + + mov es:Exec_Block.Segment_FCB1,ax ;Segment for FCB1 ; ; + mov es:Exec_Block.Offset_FCB1,offset ds:FCB1 ;Offset of FCB at 05Ch ; ; + + ;Setup dword pointer to second FCB to be passed ; ; + + mov es:Exec_Block.Segment_FCB2,ax ;Segment for FCB2 ; ; + mov es:Exec_Block.Offset_FCB2,offset ds:FCB2 ;Offset of FCB at 06Ch ; ; + + ;Setup segment of Environment string, get from PSP ; ; + + mov ax,ds:PSP_Env_Segment ; ; ; + mov es:Exec_Block.Segment_Env,ax ; ; ; + Set_Data_Segment + ret ; ; ; + + +Setup_EXEC endp ; ;AN000; + +; +;**************************************************************************** +; Exec_Argv +;**************************************************************************** +; +; Read the environment to get the Argv(0) string, which contains the drive, +; path and filename that was loaded for FORMAT.COM. This will be used to find +; the xxxxxfmt.exe, assuming that it is in the same location or path as +; FORMAT.COM +; + +Procedure EXEC_Argv ; ;AC000; + + Set_Data_Segment ;DS,ES = DATA + cld ; ; ; + mov ax,Exec_Block.Segment_Env ;Get the environment ; ; + mov ds,ax ;Get addressability ; ; + + assume ds:nothing + + xor si,si ;Start at beginning ; ; +; $DO ;Find argv(0) location ;AN000; +$$DO11: +; $DO ;Look for 0 ;AN000; +$$DO12: + inc si ;Get character ; ; + cmp byte ptr [si-1],0 ;Find string seperator? ; ; +; $ENDDO E ;Yep ;AC000; + JNE $$DO12 + inc si ;Get next char ; ; + cmp byte ptr [si-1],0 ;Are we at Argv(0)? (00?) ; ; +; $ENDDO E ;Yes if we found double 0's ;AC000; + JNE $$DO11 + add si,2 ;Skip the word count ; ; + mov di,si ;Save where string starts ; ; +; $DO ;Find length of Argv(0) string ;AN000; +$$DO15: + inc si ;Get char ; ; + cmp byte ptr [si-1],0 ;Is it the end? ; ; +; $ENDDO E ;End found if 0 found ;AC000; + JNE $$DO15 + mov cx,si ;Get number of bytes in string ; ; + sub cx,di ;Put in cx reg for rep count ; ; + mov si,di ;Point to path ; ; + mov di,offset es:EXEC_Path ;Point to where to put it ; ; + rep movsb ;Move the string ; ; + Set_Data_Segment ; ;AN000' + dec di ;Point at end of ArgV string ; ; + std ;Look backwards ;AN000; +; $DO ;Find 'FORMAT' in ARGV string ;AC000; +$$DO17: + mov cx,Len_Search_FORMAT ;Get length to compare ;AC000; + mov si,offset Search_FORMAT_End-1 ;Look at comp string from end ;AC000; + repe cmpsb ;See if same string ;AC000; +; $ENDDO E ; ;AC000; + JNE $$DO17 + mov si,offset FS_String_Buffer ; ;AN000; + inc di ;DI = replacement point-1 ;AC000; + cld ;Set direction flag back ;AN000; + mov cx,Len_FS_String_Buffer ;Length of string to move ;AN000; + rep movsb ;Build part of the path ; ; + call EXEC_Program ; ; ; + ret ; ; ; + +EXEC_ArgV endp ; ;AN000; + +; +;**************************************************************************** +; EXEC_Program +;**************************************************************************** +; +; +; +; + +Procedure EXEC_Program ; ;AC000; + + Set_Data_Segment ; ;AN000; + mov ExitStatus,No_Error ;Setup to Exec the file ; ; + mov dx,offset Exec_Path ; ; ; + mov bx,offset Exec_Block ; ; ; + mov al,0 ; ; ; + mov word ptr SP_Save,sp ;an000; dms;save sp + mov word ptr SS_Save,ss ;an000; dms;save ss + + DOS_Call Exec ; ;AC000; + + cli ;an000; dms;turn off int's + mov sp,word ptr SP_Save ;an000; dms;retrieve sp + mov ss,word ptr SS_Save ;an000; dms;retrieve ss + sti ;an000; dms;turn on int's + + +; $IF C ;CY means failure ;AC000; + JNC $$IF19 + mov ExitStatus,Error ;Set error code ; ; +; $ENDIF ; ;AN000; +$$IF19: + ret ; ; ; + +EXEC_Program endp ; ;AN000; + + +; +;**************************************************************************** +; EXEC_Routine +;**************************************************************************** +; +; +; +; + +Procedure EXEC_Routine ; ;AN000; + + Set_Data_Segment ; ;AN000; + mov ExitStatus,Error ;Assume the worst ; ; + cld ; ; ; + push ds ; ; ; + mov ax,Exec_Block.Segment_Env ;Get the environment ; ; + mov ds,ax ;Get addressability ; ; + assume ds:nothing ; + + xor si,si ;Start at beginning ; ; +; $SEARCH ; ;AC000; +$$DO21: + cmp word ptr ds:[si],0 ;End of the Evironment? ; ; +; $EXITIF E ;Reached end, no more look ;AC000; + JNE $$IF21 + ; ; ; +; $ORELSE ;Look for 'PATH=' in environment;AN000; + JMP SHORT $$SR21 +$$IF21: + mov di,offset Path_String ; " " " " ;AC000; + mov cx,Len_Path_String ; " " " " ;AC000; + repe cmpsb ; " " " " ;AC000; +; $LEAVE E ;Found if EQ ;AC000; + JE $$EN21 +; $ENDLOOP ;Found PATH in environment ;AC000; + JMP SHORT $$DO21 +$$EN21: + call Build_Path_And_Exec ; ;AN000; +; $ENDSRCH ; ; ; +$$SR21: + pop ds ; ; ; + ret ; ; ; + +EXEC_Routine endp + +; +;**************************************************************************** +; Build_Path_For_EXEC +;**************************************************************************** +; +; +; +; + +Procedure Build_Path_And_Exec ; ;AN000; + +; $DO ; ;AC000; +$$DO27: + cmp byte ptr ds:[si],0 ;All path entries done? ; ; +; $IF NE ; ;AC000; + JE $$IF28 + mov di,offset EXEC_Path ;Point at where to put path ; ; + mov byte ptr es:[di],0 ;End path just in case ; ; +; $DO ; ;AC000; +$$DO29: + cmp byte ptr ds:[si],0 ;End of Path? ; ; +; $LEAVE E ; ;AC000; + JE $$EN29 + cmp byte ptr ds:[si],';' ;End of entry? ; ; +; $if e ;yes ;an000; dms; + JNE $$IF31 + inc si ;point to next character ;an000; dms; + jmp EXIT_BPE_LOOP ;exit loop ;an000; dms; +; $endif ; ;an000; dms; +$$IF31: + movsb ;Put char in path string ; ; +; $ENDDO ; ;AN000; + JMP SHORT $$DO29 +$$EN29: + +EXIT_BPE_LOOP: ; ;an000; dms; + ;Path filled in,get backslash ; ; + cmp byte ptr ds:[si-1],0 ;Any path there? ; ; +; $IF NE ; ;AC000; + JE $$IF34 + ;Nope ; ; + cmp byte ptr ds:[si-1],"\" ;Need a backslash? ; ; +; $IF NE ; ;AC000; + JE $$IF35 + mov byte ptr es:[di],"\" ;Yes, put one in ; ; + inc di ;Line it up for next stuff ; ; + inc si ; ; ; +; $ENDIF ; ;AN000; +$$IF35: + push si ;Save place in path + push ds ;Save segment for environment ;AN000; + push es ;Xchange ds/es ;an000; dms; + pop ds ; ;an000; dms; + mov si,offset FS_String_Buffer ;Fill in filename ; ; + mov cx, Len_FS_String_Buffer ; ; ; + rep movsb ; ; ; + call Exec_Program ; ; ; + cmp ExitStatus,No_Error ;E if EXEC okay ;AN000; + pop ds ;Get Env segment back ; ; + pop si ;Get place in path back +; $ENDIF ;E if all paths done ;AN000; +$$IF34: +; $ENDIF ;E if all paths done ;AN000; +$$IF28: +; $ENDDO E ;Exit if E ;AN000; + JNE $$DO27 + ret ; ;AN000; + +Build_Path_And_EXEC Endp ; ;AN000; + + + +; +;**************************************************************************** +; Exec_Cur_Directory +;**************************************************************************** +; +; +; +; + +Procedure Exec_Cur_Directory ; ;AC000; + + Set_Data_Segment ; ;AN000; + mov si,offset FS_String_Buffer ;Setup path for current dir ; ; + mov di,offset EXEC_Path ; ; ; + mov cx,Len_FS_String_Buffer ; ; ; + rep movsb ; ; ; + call EXEC_Program ; ; ; + ret ; ; ; + +EXEC_Cur_Directory endp ; ;AN000; + +;========================================================================= +; Set_FCB1_Drive : This routine sets the 1st. byte of the FCB1, +; the drive identifier, to the default drive. +;========================================================================= + +Procedure Set_FCB1_Drive ;an000;dms;set drive ID + + push ds ;an000;dms;save ds + push si ;an000;dms;save si + + mov si,PSP_Segment ;an000;dms;get segment of PSP + mov ds,si ;an000;dms;put it in ds + assume ds:PSP ;an000;dms; + mov si,FCB1 ;an000;dms;ptr to FCB1 + mov byte ptr ds:[si],00h ;an000;dms;set drive ID to + ; default drive + pop si ;an000;dms;restore si + pop ds ;an000;dms;restore ds + Set_Data_Segment ;an000;dms;set up segmentation + ret ;an000;dms; + +Set_FCB1_Drive endp ;an000;dms; + +ENDIF ;FSExec ;an018; dms;end /FS: conditional + ; assembly + +public End_Program +End_Program label byte + +code ends + end + \ No newline at end of file diff --git a/v4.0/src/CMD/FORMAT/FORINIT.ASM b/v4.0/src/CMD/FORMAT/FORINIT.ASM new file mode 100644 index 0000000..f4fd274 --- /dev/null +++ b/v4.0/src/CMD/FORMAT/FORINIT.ASM @@ -0,0 +1,1255 @@ + +; + + +;***************************************************************************** +;***************************************************************************** +;UTILITY NAME: FORMAT.COM +; +;MODULE NAME: FORINIT.SAL +; +; +; +; ÚÄÄÄÄÄÄÄÄÄÄÄ¿ +; ³ Main_Init ³ +; ÀÄÂÄÄÄÄÄÄÄÄÄÙ +; ³ +; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +; ôInit_Input_OutputÃÄÄÄÄ´Preload_Messages³ +; ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +; ³ ôCheck_For_FS_SwitchÃÄÄ´Parse_For_FS_Switch³ +; ³ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +; ³ ³ À´EXEC_FS_Format³ +; ³ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +; ³ À´Parse_Command_Line ÃÄÄÄ´Interpret_Parse³ +; ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +; ôValidate_Target_DriveôCheck_Target_Drive³ +; ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +; ³ ôCheck_For_Network³ +; ³ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +; ³ À´Check_Translate_Drive³ +; ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿ +; À´Hook_CNTRL_C³ +; ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ +; +; +; Change List: AN000 - New code DOS 3.3 spec additions +; AC000 - Changed code DOS 3.3 spec additions +;***************************************************************************** +;***************************************************************************** + +data segment public para 'DATA' + + +Command_Line db NO +PSP_Segment dw 0 + +;These should stay togather +; --------------------------------------- ; ;AN000; +FS_String_Buffer db 13 dup(" ") ; ;AN000; +FS_String_End db "FMT.EXE",0 ; ;AN000; +Len_FS_String_End equ $ - FS_String_End ; ;AN000; + ; ;AN000; +;---------------------------------------- + +Vol_Label_Count db 80h ;an000; dms;max. string length +Vol_Label_Len db 00h ;an000; dms;len. entered +Vol_Label_Buffer db 80h dup(0) ; ;AN000; +Vol_Label_Buffer_Length equ $ - Vol_Label_Buffer ; ;AN000; + +Command_Line_Buffer db 80h dup(0) ; ;AN000; +Command_Line_Length equ $ - Command_Line_Buffer ; ;AN000; +Fatal_Error db 0 ; ;AN000; + +Command_Old_Ptr dw ? + +data ends + +code segment public para 'CODE' + assume cs:code,ds:data,es:data +code ends + +; +;***************************************************************************** +; Include files +;***************************************************************************** +; + +.xlist +INCLUDE FORCHNG.INC +INCLUDE FORMACRO.INC +INCLUDE SYSCALL.INC +INCLUDE IOCTL.INC +INCLUDE FOREQU.INC +INCLUDE FORPARSE.INC +INCLUDE FORSWTCH.INC +.list + +; +;***************************************************************************** +; Public Data +;***************************************************************************** +; + + Public FS_String_Buffer + Public Command_Line + Public Fatal_Error + Public Vol_Label_Count + Public Vol_Label_Buffer + Public PSP_Segment + Public Command_Old_Ptr + + +; +;***************************************************************************** +; Public Routines +;***************************************************************************** +; + + + Public Main_Init + +; +;***************************************************************************** +; External Routine Declarations +;***************************************************************************** +; + + Extrn Main_Routine:Near + Extrn SysLoadMsg:Near + Extrn Get_11_Characters:Near + Extrn ControlC_Handler:Near + Extrn SysDispMsg:Near + Extrn SysLoadMsg:Near + +IF FSExec ;/FS: conditional assembly ;an018; dms; + + Extrn EXEC_FS_Format:Near + +ENDIF ;/FS: conditional assembly end ;an018;dms; + + Extrn GetDeviceParameters:Near +; +;***************************************************************************** +; External Data Declarations +;***************************************************************************** +; + + Extrn SwitchMap:Word + Extrn ExitStatus:Byte + Extrn Drive:Byte + Extrn DriveLetter:Byte + Extrn TranSrc:Byte + Extrn TrackCnt:Word + Extrn NumSectors:Word + Extrn BIOSFile:Byte + Extrn DOSFile:Byte + Extrn CommandFile:Byte + Extrn MsgNeedDrive:Byte + Extrn MsgBadVolumeID:Byte + Extrn MsgBadDrive:Byte + Extrn MsgAssignedDrive:Byte + Extrn MsgNetDrive:Byte + Extrn Parse_Error_Msg:Byte + Extrn Extended_Error_Msg:Byte + Extrn SizeMap:Byte + Extrn MsgSameSwitch:Byte + Extrn Org_AX:word ;an000; dms;AX on prog. entry + Extrn DeviceParameters:Byte ;an000; dms; + Extrn FAT_Flag:Byte ;an000; dms; + Extrn Sublist_MsgParse_Error:Dword ;an000; dms; + + +code segment public para 'CODE' + +;***************************************************************************** +;Routine name: Main_Init +;***************************************************************************** +; +;Description: Main control routine for init section +; +;Called Procedures: Message (macro) +; Check_DOS_Version +; Init_Input_Output +; Validate_Target_Drive +; Hook_CNTRL_C +; +;Input: None +; +;Output: None +; +;Change History: Created 5/1/87 MT +; +;Psuedocode +; --------- +; +; Get PSP segment +; Fatal_Error = NO +; Setup I/O (CALL Init_Input_Output) +; IF !Fatal_Error +; Check target drive letter (CALL Validate_Target_Drive) +; IF !Fatal_Error +; Set up Control Break (CALL Hook_CNTRL_C) +; IF !Fatal_Error +; CALL Main_Routine +; ENDIF +; ENDIF +; ENDIF +; Exit program +;***************************************************************************** + +Procedure Main_Init ; ;AN000; + + + Set_Data_Segment ;Set DS,ES to Data segment ;AN000; + DOS_Call GetCurrentPSP ;Get PSP segment address + mov PSP_Segment,bx ;Save it for later + mov Fatal_Error,No ;Init the error flag ;AN000; + call Init_Input_Output ;Setup messages and parse ;AN000; + cmp Fatal_Error,Yes ;Error occur? ;AN000; +; $IF NE ;Nope, keep going ;AN000; + JE $$IF1 + call Validate_Target_Drive ;Check drive letter ;AN000; + cmp Fatal_Error,Yes ;Error occur? ;AN000; +; $IF NE ;Nope, keep going ;AN000; + JE $$IF2 + call Hook_CNTRL_C ;Set CNTRL -Break hook ;AN000; + cmp Fatal_Error,Yes ;Error occur? ;AN000; +; $IF NE ;Nope, keep going ;AN000; + JE $$IF3 + call Main_Routine ;Go do the real program ;AN000; +; $ENDIF ; ;AN000; +$$IF3: +; $ENDIF ; ;AN000; +$$IF2: +; $ENDIF ; ;AN000; +$$IF1: + mov al,ExitStatus ;Get Errorlevel ;AN000; + DOS_Call Exit ;Exit program ;AN000; + int 20h ;If other exit fails ;AN000; + +Main_Init endp ; ;AN000; + +;***************************************************************************** +;Routine name: Init_Input_Output +;***************************************************************************** +; +;Description: Initialize messages, Parse command line, allocate memory as +; needed. If there is a /FS switch, go handle it first as +; syntax of IFS format may be different from FAT format. +; +;Called Procedures: Preload_Messages +; Parse_For_FS_Switch +; Parse_Command_Line +; +;Change History: Created 4/1/87 MT +; +;Input: PSP command line at 81h and length at 80h +; Fatal_Error = No +; +;Output: Fatal_Error = YES/NO +; +;Psuedocode +;---------- +; +; Load messages (CALL Preload_Messages) +; IF !Fatal_Error +; See if EXEC another file system (CALL Parse_For_FS_Switch) +; IF !FATAL_Error (in this case means FS was found and exec'd) +; CALL Parse_Command_Line +; IF !Fatal_Error +; CALL Interpret_Parse +; ENDIF +; ENDIF +; ENDIF +; ret +;***************************************************************************** + +Procedure Init_Input_Output ; ;AN000; + + Set_Data_Segment ;Set DS,ES to Data segment ;AN000; + call Preload_Messages ;Load up message retriever ;AN000; + +IF FSExec ;/FS: conditional assembly ;an018; dms; + + cmp Fatal_Error,YES ;Quit? ;AN000; +; $IF NE ;Nope, keep going ;AN000; + JE $$IF7 + call Check_For_FS_Switch ;Specify FS other than FAT? ;AN000; + +ENDIF ;/FS: conditional assembly end ;an018;dms; + + cmp Fatal_Error,YES ;drive is invalid for format? ;an000; +; $if ne ;no ;an000; + JE $$IF8 + call Parse_Command_Line ;Parse in command line input ;AN000; + cmp Fatal_Error,YES ;Quit? ;AN000; +; $IF NE ;Nope, keep going ;AN000; + JE $$IF9 + call Determine_FAT_Non_FAT;see if drive was non_FAT ;an000; + call Check_For_Invalid_Drive;Drive joined? ;an000; +; $ENDIF ; ;AN000; +$$IF9: +; $ENDIF ; ;AN000; +$$IF8: + +IF FSExec ;/FS: conditional assembly ;an018; dms; + +; $ENDIF ; ;an000; +$$IF7: + +ENDIF ;/FS: conditional assembly end ;an018;dms; + + ret ; ;AN000; + +Init_Input_Output endp ; ;AN000; + +;***************************************************************************** +;Routine name: Preload_Messages +;***************************************************************************** +; +;Description: Preload messages using common message retriever routines. +; +;Called Procedures: SysLoadMsg +; +; +;Change History: Created 5/1/87 MT +; +;Input: Fatal_Error = NO +; +;Output: Fatal_Error = YES/NO +; +;Psuedocode +;---------- +; +; Preload All messages (Call SysLoadMsg) +; IF error +; Display SysLoadMsg error message +; Fatal_Error = YES +; ENDIF +; ret +;***************************************************************************** + +Procedure Preload_Messages ; ;AN000; + ; + Set_Data_Segment ;Set DS,ES to Data segment ;AN000; + call SysLoadMsg ;Preload the messages ;AN000; +; $IF C ;Error? ;AN000; + JNC $$IF13 + call SysDispMsg ;Display preload msg ;AN000; + mov Fatal_Error, YES ;Indicate error exit ;AN000; +; $ENDIF ; ;AN000; +$$IF13: + ret ; ;AN000; + +Preload_Messages endp ; ;AN000; + + + + +IF FSExec ;/FS: conditional assembly ;an018; dms; + + +;***************************************************************************** +;Routine name: Check_For_FS_Switch +;***************************************************************************** +; +;Description: Parse to see if /FS switch entered, and if so, go EXEC the +; asked for file system. Set Fatal_Error = YES if FS found +; If we do find /FS, we need to build a string of xxxxxfmt.exe,0 +; where xxxxx is the first 5 characters or less of /FS:xxxxx +; +;Called Procedures: Parse_For_FS_Switch +; EXEC_FS_Format +; +;Change History: Created 6/21/87 MT +; +;Input: Fatal_Error = NO +; +;Output: Fatal_Error = YES/NO +; Exit_Status set +; +;Psuedocode +;---------- +; +; Parse for /FS switch (CALL Parse_For_FS_Switch) +; IF !FATAL_ERROR +; IF /FS found +; Point at what was entered on /FS:xxxxx +; DO +; LEAVE end of entered string +; Got good char, move into path +; ENDDO already got 5 chars (max in xxxxxfmt.exe) +; Tack on the rest of the string (fmt.exe,0) +; Go exec the needed format (CALL EXEC_FS_Format) +; ENDIF +; ENDIF +; ret +;***************************************************************************** + +Procedure Check_For_FS_Switch ; ;AN000; + ;AN000; + Set_Data_Segment ;Set DS,ES to Data segment ;AN000; + call Parse_For_FS_Switch ;See if /FS entered ;AN000; + cmp Fatal_Error,YES ;Bad stuff entered?? ;AN000; +; $IF NE ;Nope, cruise onward ;AN000; + JE $$IF15 + cmp Switch_String_Buffer.Switch_Pointer,offset Switch_FS_Control.Keyword ; ;AN000; +; $IF E ;We got the switch ;AN000; + JNE $$IF16 + mov Switch_FS_Control.Keyword,20h ;an000; dms;remove switch from table + test SwitchMap,Switch_FS ;Have this already? ;AN002; +; $IF Z ;Nope ;AN002; + JNZ $$IF17 + push ds ;Get addressibility ;AN000; + pop es ; " " " " ;AN000; + ; + assume ds:nothing,es:data ; ;AN000; + ; + mov ax,Switch_String_Buffer.Switch_String_Seg ;Get the entered FS ;AN000; + mov ds,ax ; ;AN000; + mov si,es:Switch_String_Buffer.Switch_String_Off ; ;AN000; + mov cx,FS_String_Max_Length ; ;AN000; + mov di,offset es:FS_String_Buffer ; ;AN000; +; $DO ;Move whatever user entered ;AN000; +$$DO18: + cmp byte ptr [si],ASCIIZ_End ;End of the string? ;AN000; +; $LEAVE E ;Yep ;AN000; + JE $$EN18 + movsb ;Put character in buffer ;AN000; + dec cx ;Dec character counter + cmp cx,0 ;Nope, reached max # chars? ;AN000; +; $ENDDO E ;Yes ;AN000; + JNE $$DO18 +$$EN18: + Set_Data_Segment ;Set DS,ES to Data segment ;AN000; + mov cx,Len_FS_String_End ;Tack the FMT.EXE onto it ;AN000; + mov si,offset es:FS_String_End ;DI still points at string ;AN000; + rep movsb ;We now have Asciiz path! ;AN000; + call EXEC_FS_Format ;Go try to EXEC it..... ;AN000; +; $ELSE ; ;AN002; + JMP SHORT $$EN17 +$$IF17: + Message msgSameSwitch ; ;AN002; + mov Fatal_Error,Yes ; ;AN002; +; $ENDIF ; ;AN002; +$$EN17: +; $ENDIF ; ;AN000; +$$IF16: +; $ENDIF ; ;AN000; +$$IF15: + ret ; ;AN000; + +Check_For_FS_Switch endp ; ;AN000; + +;***************************************************************************** +;Routine name: Parse_For_FS_Switch +;***************************************************************************** +; +;Description: Copy the command line. Parse the new command line (Parse routines +; destroy the data being parsed, so need to work on copy so that +; complete command line can be passed to child format). +; The only thing we care about is if the /FS: switch exists, so +; parse until end of command line found. If there was an error, +; and it occurred on the /FS switch, then give parse error, +; otherwise ignore the parse error, because it might be something +; file system specific that doesn't meet DOS syntax rules. Also +; check for drive letter, as it is alway required. +; +;Called Procedures: Message (macro) +; SysLoadMsg +; Preload_Error +; SysParse +; +;Change History: Created 5/1/87 MT +; +;Input: Command line at 80h in PSP +; Fatal_Error = NO +; PSP_Segment +; +;Output: Fatal_Error = YES/NO +; +;Psuedocode +;---------- +; Copy command line to buffer +; DO +; Parse command line (Call SysParse) +; LEAVE end of parse +; ENDDO found /FS +; IF drive letter not found (This assumes drive letter before switches) +; Tell user +; Fatal_Error = YES +; ENDIF +; ret +;***************************************************************************** + +Procedure Parse_For_FS_Switch ; ;AN000; + ; + Set_Data_Segment ;Set DS,ES to Data segment ;AN000; + mov Drive_Letter_Buffer.Drive_Number,Init ; ;AN000; + mov cx,PSP_Segment ;Get segment of PSP ;AN000; + mov ds,cx ; " " " " ;AN000; + assume ds:nothing ; + ; + mov si,Command_Line_Parms ;Point at command line ;AN000; + mov di,offset data:Command_Line_Buffer ;Where to put a copy of it ;AN000; + mov cx,Command_Line_Length ;How long was input? ;AN000; + repnz movsb ;Copy it ;AN000; + Set_Data_Segment ;Set DS,ES to Data segment ;AN000; + xor cx,cx ; ;AN000; + xor dx,dx ;Required for SysParse call ;AN000; + mov si,offset Command_Line_Buffer ;Pointer to parse line ;AN000; + mov di,offset Switch_FS_Table ;Pointer to control table ;AN000; +; $DO ;Setup parse call ;AN000; +$$DO25: + call SysParse ;Go parse ;AN000; + cmp ax,End_Of_Parse ;Check for end of parse ;AN000; +; $LEAVE E,OR ;Exit if it is end, or ;AN000; + JE $$EN25 + cmp ax,Operand_Missing ; exit if positional missing ;AN000; +; $LEAVE E ;In other words, no drive letter;AN000; + JE $$EN25 + cmp Switch_String_Buffer.Switch_Pointer,offset Switch_FS_Control.Keyword ;AN000; +; $ENDDO E ;Exit if we find /FS ;AN000; + JNE $$DO25 +$$EN25: + cmp Drive_Letter_Buffer.Drive_Type,Type_Drive ;Check for drive letter found;AN000; +; $IF NE ;Did we not find one? ;AN000; + JE $$IF28 + MESSAGE msgNeedDrive ;Must enter drive letter ;AN000; + mov Fatal_Error,Yes ;Indicate error on exit ;AN000; +; $ENDIF ; ;AN000; +$$IF28: + ret ; ;AN000; + +Parse_For_FS_Switch endp ; ;AN000; + + +ENDIF ;/FS: conditional assembly end ;an018;dms; + + +;***************************************************************************** +;Routine name: Parse_Command_Line +;***************************************************************************** +; +;Description: Parse the command line. Check for errors, and display error and +; exit program if found. Use parse error messages except in case +; of no parameters, which has its own message +; +;Called Procedures: Message (macro) +; SysParse +; Interpret_Parse +; +;Change History: Created 5/1/87 MT +; +;Input: Fatal_Error = NO +; PSP_Segment +; +;Output: Fatal_Error = YES/NO +; +; +;Psuedocode +;---------- +; +; Assume Fatal_Error = NO on entry +; SEARCH +; EXITIF Fatal_Error = YES,OR (This can be set by Interpret_Parse) +; Parse command line (CALL SysParse) +; EXITIF end of parsing command line +; Figure out last thing parsed (Call Interpret_Parse) +; ORELSE +; See if parse error +; LEAVE parse error,OR +; See what was parsed (Call Interpret_Parse) +; LEAVE if interpret error such as bad volume label +; ENDLOOP +; Display parse error message and print error operand +; Fatal_Error = YES +; ENDSRCH +; ret +;***************************************************************************** + +Procedure Parse_Command_Line ; ;AN000; + + Set_Data_Segment ;Set DS,ES to Data segment ;AN000; + push ds + mov cx,PSP_Segment ;Get segment of PSP ;AN000; + mov ds,cx ; " " " " ;AN000; + + assume ds:nothing,es:data + + xor cx,cx ;Parse table @DI ;AN000; + xor dx,dx ;Parse line @SI ;AN000; + mov si,Command_Line_Parms ;Pointer to parse line ;AN000; + mov word ptr es:Command_Old_Ptr,si + mov di,offset es:Command_Line_Table ;Pointer to control table ;AN000; +; $SEARCH ;Loop until all parsed ;AN000; +$$DO30: + cmp es:Fatal_Error,Yes ;Interpret something bad? ;AN000; +; $EXITIF E,OR ;If so, don't parse any more ;AN000; + JE $$LL31 + call SysParse ;Go parse ;AN000; + cmp ax,End_Of_Parse ;Check for end of parse ;AN000; +; $EXITIF E ;Is it? ;AN000; + JNE $$IF30 +$$LL31: + ;All done ;AN000; +; $ORELSE ;Not end ;AN000; + JMP SHORT $$SR30 +$$IF30: + cmp ax,0 ;Check for parse error ;AN000; +; $LEAVE NE ;Stop if there was one ;AN000; + JNE $$EN30 + mov word ptr es:Command_Old_Ptr,si + call Interpret_Parse ;Go find what we parsed ;AN000; +; $ENDLOOP ;Parse error, see what it was ;AN000; + JMP SHORT $$DO30 +$$EN30: + mov byte ptr ds:[si],0 + push di + push ax + mov di,offset es:Sublist_MsgParse_Error + mov ax,word ptr es:Command_Old_Ptr + mov word ptr es:[di+2],ax + mov word ptr es:[di+4],ds + pop ax + pop di + PARSE_MESSAGE ;Display parse error ;AN000; + mov es:Fatal_Error,YES ;Indicate death! ;AN000; +; $ENDSRCH ; ;AN000; +$$SR30: + pop ds ; ;AN000; + ret ; ;AN000; + +Parse_Command_Line endp ; ;AN000; + +;***************************************************************************** +;Routine name: Interpret_Parse +;***************************************************************************** +; +;Description: Set the SwitchMap field with the switches found on the +; command line. Get the drive letter. /FS will be handled before +; here, will not be seen in this parse or accepted. Also, if /V +; see if volume label entered and verify it is good, setting up +; FCB for later create +; +;Called Procedures: Get_11_Characters +; +;Change History: Created 5/1/87 MT +; +;Input: Fatal_Error = NO +; +;Output: SwitchMap set +; DriveLetter set +; DriveNum set A=0,B=1 etc... +; Command_Line = YES/NO +; Fatal_Error = YES/NO +; +;Psuedocode +;---------- +; +; IF Drive letter parsed +; Drive = Parsed drive number -1 +; DriveLetter = (Parsed drive number - 1) +'A' +; ENDIF +; IF /1 +; or SwitchMap,Switch_1 +; ENDIF +; IF /4 +; or SwitchMap,Switch_4 +; ENDIF +; IF /8 +; or SwitchMap,Switch_8 +; ENDIF +; IF /S +; or SwitchMap,Switch_S +; ENDIF +; IF /BACKUP +; or SwitchMap,Switch_BACKUP +; ENDIF +; IF /B +; or SwitchMap,Switch_B +; ENDIF +; IF /T +; or SwitchMap,Switch_T +; TrackCnt = entered value +; ENDIF +; IF /N +; or SwitchMap,Switch_N +; NumSectors = entered value +; ENDIF +; IF /SELECT +; or SwitchMap,Switch_SELECT +; ENDIF +; IF /V +; or SwitchMap,Switch_V +; IF string entered +; Build ASCIIZ string for next call (CALL Build_String) +; Verify DBCS and setup FCB (CALL Get_11_Characters) +; Command_Line = YES +; IF error +; Invalid label message +; Fatal_Error = YES +; ENDIF +; ENDIF +; ENDIF +; IF /AUTOTEST +; or SwitchMap,Switch_AUTOTEST +; ENDIF +; +; IF /F +; or SwitchMap,Switch_F +; or Size_Map,Item_Tag +; ENDIF +; IF /Z (only if assembled) +; or SwitchMap,Switch_Z +; ENDIF +; ret +;***************************************************************************** + +Procedure Interpret_Parse ; ;AN000; + + push ds ;Save segment ;AN000; + push si ;Restore SI for parser ;AN000; + push cx ; ;AN000; + push di ; + Set_Data_Segment ;Set DS,ES to Data segment ;AN000; + cmp byte ptr Drive_Letter_Buffer.Drive_Type,Type_Drive ;Have drive letter? ;AN000; +; $IF E ;Yes, save info ;AN000; + JNE $$IF36 + mov al,Drive_Letter_Buffer.Drive_Number ;Get drive entered ;AN000; + dec al ;Make it 0 based ;AN000; + mov Drive,al ; " " " " ;AN000; + add al,'A' ;Make it a drive letter ;AN000; + mov DriveLetter,al ;Save it ;AN000; +; $ENDIF ; ;AN000; +$$IF36: + cmp Switch_Buffer.Switch_Pointer,offset Switch_1_Control.Keyword ;;AN000; +; $IF E ; ;AN000; + JNE $$IF38 + mov Switch_1_Control.Keyword,20h ;an000; dms;remove switch from table + or SwitchMap,Switch_1 ; ;AN000; +; $ENDIF ; ;AN000; +$$IF38: + cmp Switch_Buffer.Switch_Pointer,offset Switch_4_Control.Keyword ;;AN000; +; $IF E ; ;AN000; + JNE $$IF40 + mov Switch_4_Control.Keyword,20h ;an000; dms;remove switch from table + or SwitchMap,Switch_4 ; ;AN000; +; $ENDIF ; ;AN000; +$$IF40: + cmp Switch_Buffer.Switch_Pointer,offset Switch_8_Control.Keyword ;;AN000; +; $IF E ; ;AN000; + JNE $$IF42 + mov Switch_8_Control.Keyword,20h ;an000; dms;remove switch from table + or SwitchMap,Switch_8 ; ;AN000; +; $ENDIF ; ;AN000; +$$IF42: + cmp Switch_Buffer.Switch_Pointer,offset Switch_S_Control.Keyword ;;AN000; +; $IF E ; ;AN000; + JNE $$IF44 + mov Switch_S_Control.Keyword,20h ;an000; dms;remove switch from table + or SwitchMap,Switch_S ; ;AN000; +; $ENDIF ; ;AN000; +$$IF44: + cmp Switch_Buffer.Switch_Pointer,offset Switch_Backup_Control.Keyword ;AN000; +; $IF E ; ;AN000; + JNE $$IF46 + mov Switch_Backup_Control.Keyword,20h ;an000; dms;remove switch from table + or SwitchMap,Switch_Backup ; ;AN000; +; $ENDIF ; ;AN000; +$$IF46: + cmp Switch_Buffer.Switch_Pointer,offset Switch_Select_Control.Keyword ;AN000; +; $IF E ; ;AN000; + JNE $$IF48 + mov Switch_Select_Control.Keyword,20h ;an000; dms;remove switch from table + or SwitchMap,Switch_Select ; ;AN000; +; $ENDIF ; ;AN000; +$$IF48: + cmp Switch_Buffer.Switch_Pointer,offset Switch_B_Control.Keyword ;AN000; +; $IF E ; ;AN000; + JNE $$IF50 + mov Switch_B_Control.Keyword,20H + or SwitchMap,Switch_B ; ;AN000; +; $ENDIF ; ;AN000; +$$IF50: + cmp Switch_Num_Buffer.Switch_Num_Pointer,offset es:Switch_T_Control.Keyword ;AN000; +; $IF E ; ;AN000; + JNE $$IF52 + mov Switch_T_Control.Keyword,20h ;an000; dms;remove switch from table + mov Switch_Num_Buffer.Switch_Num_Pointer,0 ;Init for next switch ;AN008; + test SwitchMap,Switch_T ;Don't allow if switch already ;AN002; +; $IF Z ; entered ;AN002; + JNZ $$IF53 + or SwitchMap,Switch_T ; ;AN000; + mov ax,Switch_Num_Buffer.Switch_Number_Low ;Get entered tracks ;AN000; + mov TrackCnt,ax ;1024 or less, so always dw ;AN000; +; $ELSE ; ;AN002; + JMP SHORT $$EN53 +$$IF53: + Message msgSameSwitch ; ;AN002; + mov Fatal_Error,Yes ; ;AN002; +; $ENDIF ; ;AN000; +$$EN53: +; $ENDIF ; ;AN002; +$$IF52: + cmp Switch_Num_Buffer.Switch_Num_Pointer,offset Switch_N_Control.Keyword ;AN000; +; $IF E ; ;AN000; + JNE $$IF57 + mov Switch_N_Control.Keyword,20h ;an000; dms;remove switch from table + mov Switch_Num_Buffer.Switch_Num_Pointer,0 ;Init for next switch ;AN008; + test SwitchMap,Switch_N ;Make sure switch not already ;AN002; +; $IF Z ; entered ;AN002; + JNZ $$IF58 + or SwitchMap,Switch_N ; ;AN000; + mov ax,Switch_Num_Buffer.Switch_Number_Low ;Get entered tracks ;AN000; + xor ah,ah ;clear high byte ;an000; + mov NumSectors,ax ;Save tracks per sector ;AN000; +; $ELSE ; ;AN002; + JMP SHORT $$EN58 +$$IF58: + Message msgSameSwitch ; ;AN002; + mov Fatal_Error,Yes ; ;AN002; +; $ENDIF ; ;AN000; +$$EN58: +; $ENDIF ; ;AN002; +$$IF57: + cmp Switch_String_Buffer.Switch_String_Pointer,offset Switch_V_Control.Keyword ;AN000; +; $IF E ;If /v and haven't already done ;AN000; + JNE $$IF62 + mov Switch_String_Buffer.Switch_String_Pointer,0 ;Init for next switch ;AN008; + mov Switch_V_Control.Keyword,20h ;an000; dms;remove switch from table + test SwitchMap,Switch_V ; it - Only allow one /V entry ;AN002; +; $IF Z ; ;AN002; + JNZ $$IF63 + or SwitchMap,Switch_V ;Set /v indicator ;AN000; + mov si,Switch_String_Buffer.Switch_String_Seg ;Get string address ;;AN000; + mov ds,si ; ;AN000; + + assume ds:nothing + + mov si,es:Switch_String_Buffer.Switch_String_Off ; ;AN000; + cmp byte ptr ds:[si],None ;Is there a string there? ;AN000; +; $IF NE ;Yep ;AN000; + JE $$IF64 + cld ; ;AN000; + mov di,offset es:Vol_Label_Buffer ;Point at buffer to move string;AN000; + mov cx,Label_Length+1 ;Max length of string ;AN000; + rep movsb ;This will copy string & always ;AN000; + ; leave ASCIIZ end in buffer, ; ; + ; which is init'd to 13 dup(0) ; ; + mov si,offset es:Vol_Label_Buffer ;Point at string ;AN000; + Set_Data_Segment ;Set DS,ES to Data segment ;AN000; + mov Command_Line,YES ;Set flag indicating vol label ;AN000; + call Get_11_Characters ;Check DBCS and build FCB ;AN000; +; $IF C ;Bad DBCS setup ;AN000; + JNC $$IF65 + Message msgBadVolumeID ;Tell user ;AN000; + mov es:Fatal_Error,YES ;Indicate time to quit ;AN000; +; $ENDIF ; ;AN000; +$$IF65: +; $ENDIF ; ;AN000; +$$IF64: +; $ELSE ; ;AN002; + JMP SHORT $$EN63 +$$IF63: + Message msgSameSwitch ; ;AN002; + mov Fatal_Error,Yes ; ;AN002; +; $ENDIF ; ;AN002; +$$EN63: +; $ENDIF ; ;AN000; +$$IF62: + cmp Switch_Buffer.Switch_Pointer,offset Switch_Autotest_Control.Keyword ;AN000; +; $IF E ; ;AN000; + JNE $$IF71 + mov Switch_Autotest_Control.Keyword,20h ;an000; dms;remove switch from table + or SwitchMap,Switch_Autotest ; ;AN000; +; $ENDIF ; ;AN000; +$$IF71: + +IF ShipDisk + + cmp Switch_Buffer.Switch_Pointer,offset Switch_Z_Control.Keyword ;an000; dms;/Z switch? +; $IF E ; ;an000; dms;yes + JNE $$IF73 + mov Switch_Z_Control.Keyword,20h ;an000; dms;remove switch from table + or SwitchMap,Switch_Z ; ;an000; dms;signal switch found +; $ENDIF ; ;an000; dms; +$$IF73: + +ENDIF + + cmp Switch_String_Buffer.Switch_Pointer,offset Switch_F_Control.Keyword ; ;AN000; +; $IF E ; ;AN000; + JNE $$IF75 + mov Switch_F_Control.Keyword,20h ;an000; dms;remove switch from table + mov Switch_String_Buffer.Switch_Pointer,0 ;an000; dms; clear out ptr for next iteration + mov Switch_Num_Buffer.Switch_Num_Pointer,0 ;Init for next switch ;AN008; + test SwitchMap,Switch_F ; it - do this because SysParse ;AN002; +; $IF Z ; reuses string buffer each time;AN002; + JNZ $$IF76 + or SwitchMap,Switch_F ; ;AN000; + mov al,Switch_String_Buffer.Switch_String_Item_Tag ; Indicate what size;AN000; + or SizeMap,al ; ;AN000; +; $ELSE ; ;AN002; + JMP SHORT $$EN76 +$$IF76: + Message msgSameSwitch ; ;AN002; + mov Fatal_Error,Yes ; ;AN002; +; $ENDIF ; ;AN002; +$$EN76: +; $ENDIF ; ;AN000; +$$IF75: + pop di ;Restore parse regs ;AN000; + pop cx ; ;AN000; + pop si ; ;AN000; + pop ds ; ;AN000; + ret ; ;AN000; + +Interpret_Parse endp ; ;AN000; + + + +;***************************************************************************** +;Routine name: Validate_Target_Drive +;***************************************************************************** +; +;Description: Control routine for validating the specified format target drive. +; If any of the called routines find an error, they will print +; message and terminate program, without returning to this routine +; +;Called Procedures: Check_Target_Drive +; Check_For_Network +; Check_Translate_Drive +; +;Change History: Created 5/1/87 MT +; +;Input: Fatal_Error = NO +; +;Output: Fatal_Error = YES/NO +; +;Psuedocode +;---------- +; +; CALL Check_Target_Drive +; IF !Fatal_Error +; CALL Check_For_Network +; IF !Fatal_Error +; CALL Check_Translate_Drive +; ENDIF +; ENDIF +; ret +;***************************************************************************** + +Procedure Validate_Target_Drive ; ;AN000; + ; + call Check_Target_Drive ;See if valid drive letter ;AN000; + cmp Fatal_Error,YES ;Can we continue? ;AN000; +; $IF NE ;Yep ;AN000; + JE $$IF80 + call Check_For_Network ;See if Network drive letter ;AN000; + cmp Fatal_Error,YES ;Can we continue? ;AN000; +; $IF NE ;Yep ;AN000; + JE $$IF81 + call Check_Translate_Drive ;See if Subst, Assigned ;AN000; +; $ENDIF ;- Fatal_Error passed back ;AN000; +$$IF81: +; $ENDIF ; ;AN000; +$$IF80: + ret ; ;AN000; + +Validate_Target_Drive endp ; ;AN000; + +;***************************************************************************** +;Routine name: Check_Target_Drive +;***************************************************************************** +; +;Description: Check to see if valid DOS drive by checking if drive is +; removable. If error, the drive is invalid. Save default +; drive info. +; +;Called Procedures: Message (macro) +; +;Change History: Created 5/1/87 MT +; +;Input: Fatal_Error = NO +; +;Output: BIOSFile = default drive letter +; DOSFile = default drive letter +; CommandFile = default drive letter +; Fatal_Error = YES/NO +; +;Psuedocode +;---------- +; +; Get default drive (INT 21h, AH = 19h) +; Convert it to drive letter +; Save into BIOSFile,DOSFile,CommandFile +; See if drive removable (INT 21h, AX=4409h IOCtl) +; IF error - drive invalid +; Display Invalid drive message +; Fatal_Error= YES +; ENDIF +; ret +;***************************************************************************** + +Procedure Check_Target_Drive ; ;AN000; + ; + DOS_Call Get_Default_Drive ;Find the current drive ;AC000; + add al,'A' ;Convert to drive letter ; ; + mov BIOSFile,al ;Put it into path strings ; ; + mov DOSFile,al ; " " " " ; ; + mov CommandFile,al ; " " " " ; ; + mov bl,Drive ;Set up for next call ;AN000; + inc bl ;A=1,B=2 for IOCtl call ;AN000; + mov al,09h ;See if drive is local ;AC000; + DOS_Call IOCtl ;-this will fail if bad drive ;AC000; +; $IF C ;CY means invalid drive ;AC000; + JNC $$IF84 + Extended_Message ;Print message ;AC000; + mov Fatal_Error,Yes ;Indicate error ;AN000; +; $ENDIF ; ;AN000; +$$IF84: + ret ;And we're outa here ;AN000; + +Check_Target_Drive endp ; ;AN000; + +;***************************************************************************** +;Routine name: Check_For_Network +;***************************************************************************** +; +;Description: See if target drive isn't local, or if it is a shared drive. If +; so, exit with error message. The IOCtl call is not checked for +; an error because it is called previously in another routine, and +; invalid drive is the only error it can generate. That condition +; would not get this far +; +;Called Procedures: Message (macro) +; +;Change History: Created 5/1/87 MT +; +;Input: Drive +; Fatal_Error = NO +; +;Output: Fatal_Error = YES/NO +; +;Psuedocode +;---------- +; See if drive is local (INT 21h, AX=4409 IOCtl) +; IF not local +; Display network message +; Fatal_ERROR = YES +; ELSE +; IF 8000h bit set on return +; Display assign message +; Fatal_Error = YES +; ENDIF +; ENDIF +; ret +;***************************************************************************** + +Procedure Check_For_Network ; ;AN000; + ; + mov bl,Drive ;Drive is 0=A, 1=B ; ; + inc bl ;Get 1=A, 2=B for IOCtl call ; ; + mov al,09h ;See if drive is local or remote;AC000; + DOS_CALL IOCtl ;We will not check for error ;AC000; + test dx,Net_Check ;if (x & 1200H)(redir or shared); ; +; $IF NZ ;Found a net drive ;AC000; + JZ $$IF86 + Message MsgNetDrive ;Tell 'em ;AC000; + mov Fatal_Error,Yes ;Indicate bad stuff ;AN000; +; $ELSE ;Local drive, now check assign ;AN000; + JMP SHORT $$EN86 +$$IF86: + test dx,Assign_Check ;8000h bit is bad news ; ; +; $IF NZ ;Found it ;AC000; + JZ $$IF88 + Message MsgAssignedDrive ;Tell error ;AC000; + mov Fatal_Error,Yes ;Indicate bad stuff ;AN000; +; $ENDIF ; ;AN000; +$$IF88: +; $ENDIF ; ;AN000; +$$EN86: + ret ; ;AN000; + +Check_For_Network endp ; ;AN000; + +;***************************************************************************** +;Routine name: Check_Translate_Drive +;***************************************************************************** +; +;Description: Do a name translate call on the drive letter to see if it is +; assigned by SUBST or ASSIGN +; +;Called Procedures: Message (macro) +; +;Change History: Created 5/1/87 MT +; +;Input: Drive +; Fatal_Error = NO +; +;Output: Fatal_Error = YES/NO +; +;Psuedocode +;---------- +; Put drive letter in ASCIIZ string "d:\",0 +; Do name translate call (INT 21) +; IF drive not same +; Display assigned message +; Fatal_Error = YES +; ENDIF +; ret +;***************************************************************************** + +Procedure Check_Translate_Drive ; ;AN000; + ; + mov bl,Drive ;Get drive ; ; + add byte ptr [TranSrc],bl ;Make string "d:\" ; ; + mov si,offset TranSrc ;Point to translate string ; ; + push ds ;Set ES=DS (Data segment) ; ; + pop es ; " " " " ; ; + mov di,offset Command_Line_Buffer ;Point at output buffer ; ; + DOS_Call xNameTrans ;Get real path ;AC000; + mov bl,byte ptr [TranSrc] ;Get drive letter from path ; ; + cmp bl,byte ptr Command_Line_Buffer ;Did drive letter change? ; ; +; $IF NE ;If not the same, it be bad ;AC000; + JE $$IF91 + Message MsgAssignedDrive ;Tell user ;AC000; + mov Fatal_Error,Yes ;Setup error flag ;AN000; +; $ENDIF ; ;AN000; +$$IF91: + ret ; ;AN000; + +Check_Translate_Drive endp ; ;AN000; + +;***************************************************************************** +;Routine name: Hook_CNTRL_C +;***************************************************************************** +; +;Description: Change the interrupt handler for INT 13h to point to the +; ControlC_Handler routine +; +;Called Procedures: None +; +;Change History: Created 4/21/87 MT +; +;Input: None +; +;Output: None +; +;Psuedocode +;---------- +; +; Point at ControlC_Handler routine +; Set interrupt handler (INT 21h, AX=2523h) +; ret +;***************************************************************************** + +Procedure Hook_CNTRL_C ; ;AN000; + ; + mov al,23H ;Specify CNTRL handler ; ; + mov dx, offset ControlC_Handler ;Point at it ; ; + push ds ;Save data seg ; ; + push cs ;Point to code segment ; ; + pop ds ; ; ; + DOS_Call Set_Interrupt_Vector ;Set the INT 23h handler ;AC000; + pop ds ;Get Data degment back ; ; + ret ; ;AN000; + +Hook_CNTRL_C endp ; ;AN000; + +;========================================================================= +; Check_For_Invalid_Drive : This routine checks the AX received by +; FORMAT on its entry. This value will +; tell us if we are attempting to format +; a JOINED drive. +; +; Inputs : Org_AX - AX on entry to FORMAT +; +; Outputs : Fatal_Error - Yes if AL contained FFh +;========================================================================= + +Procedure Check_For_Invalid_Drive ;an000; dms; + + push ax ;an000; dms;save ax + cmp FAT_Flag,Yes ;an000; dms;FAT system? +; $if e ;an000; dms;yes + JNE $$IF93 + mov ax,Org_AX ;an000; dms;get its org. value + cmp al,0ffh ;an000; dms;Invalid drive? +; $if e ;an000; dms;yes + JNE $$IF94 + mov Fatal_Error,YES ;an000; dms;flag an error + mov ax,Invalid_Drive;an000; dms;error message + Extended_Message ;an000; dms;tell error +; $endif ;an000; dms; +$$IF94: +; $endif ;an000; dms; +$$IF93: + pop ax ;an000; dms; + ret ;an000; dms; + +Check_For_Invalid_Drive endp ;an000; dms; + + +;========================================================================= +; Determine_FAT_Non_FAT - This routine determines whether or +; not a device is formatted to a FAT +; specification versus a Non-FAT +; specification. +; +; Inputs : DX - Pointer to device parameters buffer +; +; Outputs : DeviceParameters - buffer containing BPB. +; +; Date : 11/6/87 +;========================================================================= + +Procedure Determine_FAT_Non_FAT ;an012; dms; + + push ax ;an012; dms;save regs + push dx ;an012; dms; + + lea dx, deviceParameters ;an012; dms;point to buffer + mov deviceParameters.DP_SpecialFunctions, 0 ;an012; dms;get default BPB + call GetDeviceParameters ;an012; dms;make the call +; $if nc ;an012; dms;no error occurred + JC $$IF97 + cmp byte ptr DeviceParameters.DP_BPB.BPB_NumberOfFATS,00h ;an012; dms;non-FAT system? +; $if e ;an012; dms;yes + JNE $$IF98 + mov FAT_Flag,No ;an012; dms;signal system non-FAT + mov ax,5f07h ;an012; dms;allow access to disk + mov dl,Drive ;an012; dms;get 0 based driver number + int 21h ;an012; dms;allow access to the drive +; $else ;an012; dms;FAT system + JMP SHORT $$EN98 +$$IF98: + mov FAT_Flag,Yes ;an012; dms;flag FAT system +; $endif ;an012; dms; +$$EN98: +; $endif ;an012; dms; +$$IF97: + + pop dx ;an012; dms;restore regs + pop ax ;an012; dms; + + ret ;an012; dms; + +Determine_FAT_Non_FAT endp ;an012; dms; + + + + +code ends + end + + \ No newline at end of file diff --git a/v4.0/src/CMD/FORMAT/FORLABEL.ASM b/v4.0/src/CMD/FORMAT/FORLABEL.ASM new file mode 100644 index 0000000..a7d46a1 --- /dev/null +++ b/v4.0/src/CMD/FORMAT/FORLABEL.ASM @@ -0,0 +1,771 @@ + +; +;***************************************************************************** +;***************************************************************************** +; +;UTILITY NAME: FORMAT.COM +; +;MODULE NAME: FORLABEL.SAL +; +; Interpret_Parse +; | +;* | +;³ÚÄÄÄÄÄ¿ÚÄÄÄÄÄÄÄÄÄÄÄÄÄ¿|ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +;À´VolIDôGet_New_LabelÃÄ´Get_11_CharactersôChange_Blanks³ +; ÀÄÄÄÄÄÙÀÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ÚÄÄÄÄÄÄÄÄÄÄÄ¿ +; ôSkip_Blanks³ +; ³ÀÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +; ôCheck_DBCS_OverrunôCheck_DBCS_Character³ +; ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +; À´Copy_FCB_String³ +; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +;***************************************************************************** +;***************************************************************************** + +data segment public para 'DATA' +data ends + +code segment public para 'CODE' + assume cs:code,ds:data +code ends + +.xlist +INCLUDE FORCHNG.INC +INCLUDE FORMACRO.INC +INCLUDE SYSCALL.INC +INCLUDE FOREQU.INC +INCLUDE FORSWTCH.INC +.list + +; +;***************************************************************************** +; Equates +;***************************************************************************** +; + +None equ 0 +StdIn equ 0 +StdOut equ 1 +StdErr equ 2 +Tab equ 09h +Label_Buffer_length equ 80h +Create_Worked equ 0 ;an024; + + +; +;***************************************************************************** +; External Data Declarations +;***************************************************************************** +; + + Extrn SwitchMap:Word + Extrn Switch_String_Buffer:Byte + Extrn VolFCB:Byte + Extrn MsgBadCharacters:Byte + Extrn MsgLabelPrompt:Byte + Extrn MsgBadVolumeID:Byte + Extrn MsgCRLF:Byte + Extrn VolNam:Byte + Extrn Vol_Label_Count:Byte + Extrn VolDrive:Byte + Extrn Drive:Byte + Extrn Command_Line:Byte + Extrn Vol_Label_Buffer:Byte + Extrn DelDrive:Byte + Extrn DelFCB:Byte + +code segment public para 'CODE' + +;************************************************************************************************ +;Routine name Volid +;************************************************************************************************ +; +;Description: Get volume id from command line /V:xxxxxxx if it is there, or +; else prompt user for volume label, parse the input. At this +; point setup the FCB and create the volume label. If failure, +; prompt user that they entered bad input, and try again. +; +; Note: This routine in 3.30 and prior used to check for /V +; switch. Volume labels are always required now, so /V +; is ignored, except to get volume label on command line. +; +;Called Procedures: Message (macro) +; Get_New_Label +; +;Change History: Created 5/1/87 MT +; +;Input: Switch_V +; Command_Line = YES/NO +; +;Output: None +; +;Psuedocode +;---------- +; +; Save registers +; IF /V switch entered +; IF /v:xxxxx form not entered +; CALL Get_New_Label ;Return string in Volume_Label +; ENDIF +; ELSE +; CALL Get_New_Label ;Return string in Volume_Label +; ENDIF +; DO +; Create volume label +; LEAVE Create Ok +; Display Bad Character message +; CALL Get_New_Label ;Return string in Volume_Label +; ENDDO +; Restore registers +; ret +;***************************************************************************** + +Procedure Volid ; ;AN000; + + push ds ;Save registers ;AN000; + push si ; " " " " ;AN000; + test SwitchMap,Switch_V ;Was /V entered ;AN000; +; $IF NZ ;Yes, see if label entered also ;AN000; + JZ $$IF1 + cmp Command_Line,YES ;Is there a string there? ;AN000; +; $IF NE ;Nope ;AN000; + JE $$IF2 + call Get_New_Label ;Go get volume label from user ;AN000; +; $ENDIF ; ;AN000; +$$IF2: +; $ELSE ;Label not entered on cmd line ;AN000; + JMP SHORT $$EN1 +$$IF1: + call Get_New_Label ;Go get label from user ;AN000; +; $ENDIF ; ;AN000; +$$EN1: + mov dl,drive ;Get drive number A=0 ;AN000; + inc dl ;Make it 1 based ;AN000; + mov DelDrive,dl ;Put into FCBs ;AN000; + mov VolDrive,dl ; ;AN000; + mov dx,offset DelFCB ;Point at FCB to delete label ;AN000; + DOS_Call FCB_Delete ;Do the delete ;AN000; + mov dx,offset VolFCB ;Point at FCB for create ;AN000; + DOS_CALL FCB_Create ;Go create it ;AN000; + cmp dl,Create_Worked ;See if the create worked ;an024; +; $IF E ;an024; + JNE $$IF6 + mov dx,offset VolFCB ;Point to the FCB created ;an022; dms; + DOS_Call FCB_Close ;Close the newly created FCB ;an022; dms; +; $ENDIF ;an024; +$$IF6: + + pop si ;Restore registers ;AN000; + pop ds ; " " " " ;AN000; + ret ; ;AN000; + +Volid endp ; ;AN000; + +;***************************************************************************** +;Routine name: Get_New_Label +;***************************************************************************** +; +;Description: Prompts, inputs and verifies a volume label string. Continues +; to prompt until valid vol label is input +; +;Called Procedures: Message (macro) +; Build_String +; Get_11_Characters +; +;Change History: Created 3/18/87 MT +; +;Input: None +; +;Output: Volume_Label holds +; +;Psuedocode +;---------- +; +; DO +; Display new volume label prompt +; Input vol label +; IF No error (NC) +; Build Asciiz string with label, pointer DS:SI (CALL Build_String) +; Call Get_11_Characters (Error returned CY) +; ENDIF +; LEAVE no error (NC) +; Display label error +; ENDDO +; ret +;***************************************************************************** + +Procedure Get_New_Label ; ;AN000; + +; $DO ;Loop until we get good one ;AN000; +$$DO8: + Message msgLabelPrompt ;Prompt to input Vol label ;AN000; + mov ax,(Std_Con_Input_Flush shl 8) + 0 ;an000; dms;clean out input + int 21h ;an000; dms; + mov dx,offset Vol_Label_Count ;an000; dms;beginning of buffer + mov ah,Std_Con_String_Input ;an000; dms;get input + int 21h ;an000; dms; + mov ax,(Std_Con_Input_Flush shl 8) + 0 ;an000; dms; clean out input + int 21h ;an000; dms; +; $IF NC ;Read ok if NC, Bad sets CY ;AN000; + JC $$IF9 + mov si,offset Vol_Label_Buffer ;Get pointer to string ;AN000; + call Get_11_Characters ;Handle DBCS stuff on input ;AN000; +; $ENDIF ;Ret CY if error ;AN000; +$$IF9: +; $LEAVE NC ;Done if NC ;AN000; + JNC $$EN8 + Message MsgCRLF ;next line ;an020; dms; + Message msgBadVolumeID ;Tell user error ;AN000; +; $ENDDO ;Try again ;AN000; + JMP SHORT $$DO8 +$$EN8: + Message MsgCRLF ;an000; dms;next line + ret ; ;AN000; + +Get_New_Label endp ; ;AN000; + +;***************************************************************************** +;Routine name: Get_11_Characters +;***************************************************************************** +; +;Description: Handle DBCS considerations, and build FCB to create vol label +; +; +;Called Procedures: Change_Blanks +; Skip_Blanks +; Check_DBCS_Overrun +; Copy_FCB_String +; +;Change History: Created 5/12/87 MT +; +;Input: DS:SI = Asciiz string containing volume label input +; Command_Line = YES/NO +; +;Output: Volname will contain an 8.3 volume label in FCB +; CY set on invalid label +; +;Psuedocode +;---------- +; Save regs used +; Scan line replacing all DBCS blanks with SBCS (CALL_Change_Blanks) +; Skip over leading blanks (Call Skip_Blanks) +; IF leading blanks ,AND +; IF Command line +; Indicate invalid label (STC) +; ELSE +; See if DBCS character at 11th byte (CALL Check_DBCS_Overrun) +; IF DBCS character at 11th byte +; Indicate invalid label (STC) +; ELSE +; Put string into FCB (CALL Copy_FCB_STRING) +; CLC +; ENDIF +; ENDIF +; Restore regs +; ret +;***************************************************************************** + +Procedure Get_11_Characters ; ;AN000; + + call Change_Blanks ;Change DBCS blanks to SBCS ;AN000; + call Skip_Blanks ;Skip over leading blanks ;AN000; +; $IF C,AND ;Find leading blanks? ;AN000; + JNC $$IF13 + cmp Command_Line,YES ;Is this command line input? ;AN000; +; $IF E ;Yes ;AN000; + JNE $$IF13 + stc ;Indicate error (CY set) ;AN000; +; $ELSE ;Leading blanks ok ;AN000; + JMP SHORT $$EN13 +$$IF13: + call Check_DBCS_Overrun ;Is DBCS char at 11th byte? ;AN000; +; $IF C ;Yes ;AN000; + JNC $$IF15 + stc ;Indicate invalid label ;AN000; +; $ELSE ;No, good characters ;AN000; + JMP SHORT $$EN15 +$$IF15: + call Copy_FCB_String ;Put string into FCB ;AN000; + clc ;Indicate everything A-OK! ;AN000; +; $ENDIF ; ;AN000; +$$EN15: +; $ENDIF ; ;AN000; +$$EN13: + ret ; ;AN000; + +Get_11_Characters endp ; ;AN000; + +;***************************************************************************** +;Routine name: Change_Blanks +;***************************************************************************** +; +;Description: Replace all DBCS blanks with SBCS blanks, end string with +; Asciiz character if one doesn't already exist +; +;Called Procedures: Check_DBCS_Character +; +;Change History: Created 6/12/87 MT +; +;Input: DS:SI = String containing volume label input +; +;Output: DS:SI = ASCIIZ string with all DBCS blanks replaced with 2 SBCS blanks +; +; +;Psuedocode +;---------- +; +; Save pointer to string +; DO +; LEAVE End of string (0) +; See if DBCS character (Check_DBCS_Character) +; IF CY (DBCS char found) +; IF first byte DBCS blank, AND +; IF second byte DBCS blank +; Convert to SBCS blanks +; ENDIF +; Point to next byte to compensate for DBCS character +; ENDIF +; ENDDO +; Tack on ASCIIZ character to string +; Restore pointer to string +; +;***************************************************************************** + +Procedure Change_Blanks ; ;AN000; + + push si ;Save pointer to string ;AN000; + push cx ; ;AN000; + push ax ; ;AN000; + xor cx,cx ; ;AN000; +; $DO ;Do while not CR ;AN000; +$$DO19: + cmp byte ptr [si],Asciiz_End ;Is it end of string? ;AN000; +; $LEAVE E,OR ;All done if so ;AN000; + JE $$EN19 + cmp byte ptr [si],CR ;Is it CR? ;AN000; +; $LEAVE E,OR ;Exit if yes,end of label ;AN000; + JE $$EN19 + inc cx ;Count the character ;AN000; + cmp cx,Label_Buffer_Length ;Reached max chars? (80h) ;AN000; +; $LEAVE E ;Exit if so ;AN000; + JE $$EN19 + mov al,byte ptr [si] ;Get char to test for DBCS ;AN000; + call Check_DBCS_Character ;Test for dbcs lead byte ;AN000; +; $IF C ;We have a lead byte ;AN000; + JNC $$IF21 + cmp byte ptr [si],DBCS ;Is it a lead blank? ;AN000; +; $IF E,AND ;If a dbcs char ;AN000; + JNE $$IF22 + cmp byte ptr [si+1],DBCS_Blank ;Is it an Asian blank? ;AN000; +; $IF E ;If an Asian blank ;AN000; + JNE $$IF22 + mov byte ptr [si+1],Blank ;set up moves ;AN000; + mov byte ptr [si],Blank ; to replace ;AN000; +; $ENDIF ; ;AN000; +$$IF22: + inc si ;Point to dbcs char ;AN000; +; $ENDIF ;End lead byte test ;AN000; +$$IF21: + inc si ;Point to si+1 ;AN000; +; $ENDDO ;End do while ;AN000; + JMP SHORT $$DO19 +$$EN19: + mov byte ptr [si],Asciiz_End ;Mark end of string ;AN000; + pop ax ;Restore regs ;AN000; + pop cx ; ;AN000; + pop si ; ;AN000; + ret ;return to caller ;AN000; + +Change_Blanks endp ; ;AN000; + +;***************************************************************************** +;Routine name: Skip_Blanks +;***************************************************************************** +; +;Description: Scan ASCIIZ string for leading blanks, return pointer to first +; non-blank character. Set CY if blanks found +; +;Called Procedures: None +; +;Change History: Created 6/12/87 MT +; +;Input: DS:SI = ASCIIZ string containing volume label input +; +;Output: DS:SI = Input string starting at first non-blank character +; CY set if blanks found +; +; +; +;Psuedocode +;---------- +; +; Save original pointer, DI register +; DO +; Look at character from string +; LEAVE End of string (0) +; IF character is blank,OR +; IF character is tab +; INC pointer (SI) +; Indicate blank +; ELSE +; Indicate non-blank +; ENDIF +; ENDDO non-blank +; Get back pointer +; Cmp string pointer to original pointer +; IF NE +; STC +; ELSE +; CLC +; ENDIF +; ret +;***************************************************************************** + +Procedure Skip_Blanks ; ;AN000; + + push di ;Preserve DI, just in case ;AN000; + push si ;Save pointer to string ;AN000; +; $DO ;Look at entire ASCIIZ string ;AN000; +$$DO26: + cmp byte ptr [si],ASCIIZ_End ;End of string? ;AN000; +; $LEAVE E ;Yep, exit loop ;AN000; + JE $$EN26 + cmp byte ptr [si],Blank ;Find a blank? ;AN000; +; $IF E,OR ;Yes ;AN000; + JE $$LL28 + cmp byte ptr [si],TAB ;Is it tab? ;AN000; +; $IF E ;Yes ;AN000; + JNE $$IF28 +$$LL28: + inc si ;Bump pointer to next character ;AN000; + clc ;Indicate found blank ;AN000; +; $ELSE ;Not blank or tab ;AN000; + JMP SHORT $$EN28 +$$IF28: + stc ;Force exit ;AN000; +; $ENDIF ; ;AN000; +$$EN28: +; $ENDDO C ;Go look at next character ;AN000; + JNC $$DO26 +$$EN26: + pop di ;Get back original pointer ;AN000; + cmp di,si ;Are they the same? ;AN000; +; $IF NE ;If not equal blanks were found ;AN000; + JE $$IF32 + stc ;Set CY ;AN000; +; $ELSE ;No leading blanks found ;AN000; + JMP SHORT $$EN32 +$$IF32: + clc ;Clear CY ;AN000; +; $ENDIF ; ;AN000; +$$EN32: + pop di ;Restore DI ;AN000; + ret ; ;AN000; + +Skip_Blanks endp ; ;AN000; + + +;***************************************************************************** +;Routine name: Copy_FCB_String +;***************************************************************************** +; +;Description: Build an 11 character string in the FCB from ASCIIZ string +; If nothing entered, than terminated with 0. Also add drive +; number in FCB +; +;Called Procedures: None +; +;Change History: Created 6/12/87 MT +; +;Input: DS:SI = String containing volume label input +; +;Output: VOLNAM is filled in with Volume label string +; +; +; +;Psuedocode +;---------- +; +; Save regs +; Init VolNam to blanks +; DO +; LEAVE if character is end of ASCIIZ string +; Mov character to FCB +; Inc counter +; ENDDO all 11 chars done +; Restore regs +;***************************************************************************** + +Procedure Copy_FCB_String ; ;AN000; + + push di ; ;AN000; + push cx ; ;AN000; + push si ;Save pointer to string ;AN000; + cld ;Set string direction to up ;AN000; + mov di,offset Volnam ;Init FCB field to blanks ;AN000; + mov al,Blank ; " " " " ;AN000; + mov cx,Label_Length ; " " " " ;AN000; + rep stosb ; " " " " ;AN000; + pop si ;Get back pointer to string ;AN000; + mov di,offset VolNam ;Point at FCB field ;AN000; + xor cx,cx ;Init counter ;AN000; +; $DO ;Copy characters over ;AN000; +$$DO35: + cmp byte ptr [si],ASCIIZ_End ;End of String? ;AN000; +; $LEAVE E ;Yes, don't copy - leave blanks ;AN000; + JE $$EN35 + movsb ;Nope, copy character ;AN000; + inc cx ;Bump up count ;AN000; + cmp cx,Label_Length ;Have we moved 11? ;AN000; +; $ENDDO E ;Quit if so ;AN000; + JNE $$DO35 +$$EN35: + pop cx ; ;AN000; + pop di ; ;AN000; + ret ; ;AN000; + +Copy_FCB_String endp ; ;AN000; + + +;***************************************************************************** +;Routine name: Check_DBCS_Overrun +;***************************************************************************** +; +;Description: Check 11th byte, if the string is that long, to see +; if it is a DBCS character that is split down the middle. Must +; scan entire string to properly find DBCS characters, due to +; the fact a second byte of a DBCS character can fall into +; the range of the first byte environment vector, and thus look +; like a DBCS char when it really isn't +; +;Called Procedures: Check_DBCS_Character +; +;Change History: Created 6/12/87 MT +; +;Input: DS:SI = String containing volume label input +; +;Output: CY set if DBCS character at bytes 11-12 in string +; +;***************************************************************************** + +Procedure Check_DBCS_Overrun ; ;AN000; + + push si ;Save pointer ;AN000; + push ax ;Save registers ;AN000; + push cx ; " " " " ;AN000; + mov cx,si ;Get start of string ;AN000; + add cx,Label_Length ;Find where to check for overrun;AN000; + +Check_DBCS_OverRun_Cont: ;Scan string for DBCS chars ;AN000; + + cmp byte ptr [si],ASCIIZ_End ;End of string? ;AN000; + je DBCS_Good_Exit ;Yep ;AN000; + + mov al,[si] ;Get character for routine ;AN000; + call Check_DBCS_Character ;See if DBCS leading character ;AN000; +; $if c ;DBCS if CY set ;AN000; + JNC $$IF38 + inc si ;Next byte to handle DBCS ;AN000; + cmp si,cx ;Is DBCS char spanning 11-12? ;AN000; +; $if e ;truncate string + JNE $$IF39 + mov byte ptr [si-1],20h;blank it out + mov byte ptr [si],20h ;blank it out + jmp DBCS_Good_Exit ;exit +; $endif ; +$$IF39: +; $else ;Not DBCS character ;an000; dms; + JMP SHORT $$EN38 +$$IF38: + mov al,[si] ;Get character for routine ;an000; dms; + call Scan_For_Invalid_Char ;See if invalid vol ID char ;an000; dms; + jc DBCS_Bad_Exit ;Bad char entered - exit ;an000; dms; +; $endif ; ;an000; dms; +$$EN38: + + inc si ;Point to next character ;an000; dms; + jmp Check_DBCS_OverRun_Cont ;Continue looping ;an000; dms; + +DBCS_Good_Exit: + ;an000; dms; + clc ;Signal no error ;an000; dms; + jmp DBCS_Exit ;Exit routine ;an000; dms; + +DBCS_Bad_Exit: ;an000; dms; + + stc ;Signal error ;an000; dms; + +DBCS_Exit: ;an000; dms; + + pop cx ;Restore registers ;AN000; + pop ax ; " " " " ;AN000; + pop si ;Restore string pointer ;AN000; + ret ; ;AN000; + +Check_DBCS_Overrun endp ; ;AN000; + +;***************************************************************************** +;Routine name: Check_DBCS_Character +;***************************************************************************** +; +;Description: Check if specified byte is in ranges of DBCS vectors +; +;Called Procedures: None +; +;Change History: Created 6/12/87 MT +; +;Input: AL = Character to check for DBCS lead character +; DBCS_Vector = YES/NO +; +;Output: CY set if DBCS character +; DBCS_VECTOR = YES +; +; +;Psuedocode +;---------- +; Save registers +; IF DBCS vector not found +; Get DBCS environmental vector (INT 21h +; Point at first set of vectors +; ENDIF +; SEARCH +; LEAVE End of DBCS vectors +; EXITIF Character > X1,AND (X1,Y1) are environment vectors +; EXITIF Character < Y1 +; STC (DBCS character) +; ORELSE +; Inc pointer to next set of vectors +; ENDLOOP +; CLC (Not DBCS character) +; ENDSRCH +; Restore registers +; ret +;***************************************************************************** + +Procedure Check_DBCS_Character ; ;AN000; + + push ds ;Save registers ;AN000; + push si ; " " " " ;AN000; + push ax ; " " " " ;AN000; + push ds ; " " " " ;AN000; + pop es ;Establish addressability ;AN000; + cmp byte ptr es:DBCS_VECTOR,Yes ;Have we set this yet? ;AN000; + push ax ;Save input character ;AN000; +; $IF NE ;Nope ;AN000; + JE $$IF43 + mov al,0 ;Get DBCS environment vectors ;AN000; + DOS_Call Hongeul ; " " " " ;AN000; + mov byte ptr es:DBCS_VECTOR,YES ;Indicate we've got vector ;AN000; + mov es:DBCS_Vector_Off,si ;Save the vector ;AN000; + mov ax,ds ; ;AN000; + mov es:DBCS_Vector_Seg,ax ; ;AN000; +; $ENDIF ; for next time in ;AN000; +$$IF43: + pop ax ;Restore input character ;AN000; + mov si,es:DBCS_Vector_Seg ;Get saved vector pointer ;AN000; + mov ds,si ; ;AN000; + mov si,es:DBCS_Vector_Off ; ;AN000; +; $SEARCH ;Check all the vectors ;AN000; +$$DO45: + cmp word ptr ds:[si],End_Of_Vector ;End of vector table? ;AN000; +; $LEAVE E ;Yes, done ;AN000; + JE $$EN45 + cmp al,ds:[si] ;See if char is in vector ;AN000; +; $EXITIF AE,AND ;If >= to lower, and ;AN000; + JNAE $$IF45 + cmp al,ds:[si+1] ; =< than higher range ;AN000; +; $EXITIF BE ; then DBCS character ;AN000; + JNBE $$IF45 + stc ;Set CY to indicate DBCS ;AN000; +; $ORELSE ;Not in range, check next ;AN000; + JMP SHORT $$SR45 +$$IF45: + add si,DBCS_Vector_Size ;Get next DBCS vector ;AN000; +; $ENDLOOP ;We didn't find DBCS char ;AN000; + JMP SHORT $$DO45 +$$EN45: + clc ;Clear CY for exit ;AN000; +; $ENDSRCH ; ;AN000; +$$SR45: + pop ax ;Restore registers ;AN000; + pop si ; " " " " ;AN000; + pop ds ;Restore data segment ;AN000; + ret ; ;AN000; + +Check_DBCS_Character endp ; ;AN000; + +;========================================================================= +; Scan_For_Invalid_Char : This routine scans the bad character table +; to determine if the referenced character is +; invalid. +; +; Inputs : Bad_Char_Table - Table of bad characters +; Bad_Char_Table_Len - Length of table +; AL - Character to be searched for +; +; Outputs : CY - Bad character +; NC - Character good +;========================================================================= + +Procedure Scan_For_Invalid_Char ;an000; dms; + + push ax ;an000; dms;save ax + push cx ;an000; dms;save cx + push di ;an000; dms;save di + + lea di,Bad_Char_Table ;an000; dms;point to bad character table + mov cx,Bad_Char_Table_Len ;an000; dms;get its length + repnz scasb ;an000; dms;scan the table + cmp cx,0000h ;an000; dms;did we find the character +; $if e ;an000; dms;no - a good character + JNE $$IF51 + clc ;an000; dms;flag a good character +; $else ;an000; dms;yes - a bad character + JMP SHORT $$EN51 +$$IF51: + stc ;an000; dms;flag a bad character +; $endif ;an000; dms; +$$EN51: + + pop di ;an000; dms;restore di + pop cx ;an000; dms;restore cx + pop ax ;an000; dms;restore ax + + ret ;an000; dms; + +Scan_For_Invalid_Char endp ;an000; dms; + + +code ends + +data segment public para 'DATA' + +Bad_Char_Table label byte ;an000; dms;table of invalid vol ID chars + db "*" + db "?" + db "[" + db "]" + db ":" + db "<" + db "|" + db ">" + db "+" + db "=" + db ";" + db "," + db "/" + db "\" + db '.' + db '"' + db " " +Bad_Char_Table_Len equ $-Bad_Char_Table;an000; dms;length of table + +DBCS_Vector_Off dw 0 ; +DBCS_Vector_Seg dw 0 ; + +data ends + end + \ No newline at end of file diff --git a/v4.0/src/CMD/FORMAT/FORMACRO.INC b/v4.0/src/CMD/FORMAT/FORMACRO.INC new file mode 100644 index 0000000..63f17cf --- /dev/null +++ b/v4.0/src/CMD/FORMAT/FORMACRO.INC @@ -0,0 +1,102 @@ + + + + + + + +; +;****************************************************************************** +; Message Macro Definitions +;****************************************************************************** +; + + EXTRN Display_Interface:near + + +;----------------------------------------------------------------------------- + +Message macro Message_Name ; ;AN000; + ; + mov dx,offset data:Message_Name ; ;AN000; + call Display_Interface ; ;AN000; + endm ; ;AN000; + +;----------------------------------------------------------------------------- + +Parse_Message macro ; ;AN000; + + ; + push ds + mov dx,data + mov ds,dx + mov word ptr Parse_Error_Msg,ax ; ;AN000; + mov dx,offset Parse_Error_Msg ; ;AN000; + call Display_Interface ; ;AN000; + pop ds ; + endm ; ;AN000; + +;----------------------------------------------------------------------------- + +Extended_Message macro ; ;AN000; + ; + + push ds + mov dx,data + mov ds,dx + mov word ptr Extended_Error_Msg,ax ; ;AN000; + mov dx,offset data:Extended_Error_Msg ; ;AN000; + call Display_Interface ; ;AN000; + pop ds + endm ; ;AN000; + +; +;***************************************************************************** +; General Macro's +;***************************************************************************** +; + +Procedure macro Proc_Name + +Public Proc_Name +Proc_Name proc + + endm +;----------------------------------------------------------------------------- + +DOS_Call macro Function + + mov ah,Function + int 21h + + endm +;----------------------------------------------------------------------------- + +Popff macro + + jmp $+3 + iret + push cs + call $-2 + + endm + + +;----------------------------------------------------------------------------- + +Set_Data_Segment macro + + push ax + mov ax,data ;Point to data segment + mov ds,ax ; + push ds + pop es + pop ax + +assume ds:data,es:data + + endm + + + + \ No newline at end of file diff --git a/v4.0/src/CMD/FORMAT/FORMAT.ASM b/v4.0/src/CMD/FORMAT/FORMAT.ASM new file mode 100644 index 0000000..c9034d7 --- /dev/null +++ b/v4.0/src/CMD/FORMAT/FORMAT.ASM @@ -0,0 +1,4509 @@ +page 84,132 +; +; SCCSID = @(#)format.asm 1.26 85/10/20 +; SCCSID = @(#)format.asm 1.26 85/10/20 +;*************************************************************** +; +; 86-DOS FORMAT DISK UTILITY +; +; This routine formats a new disk,clears the FAT and DIRECTORY then +; optionally copies the SYSTEM and COMMAND.COM to this new disk +; +; SYNTAX: FORMAT [drive][/switch1][/switch2]...[/switch16] +; +; Regardless of the drive designator , the user will be prompted to +; insert the diskette to be formatted. +; +;*************************************************************** + +; 5/12/82 ARR Mod to ask for volume ID +; 5/19/82 ARR Fixed rounding bug in CLUSCAL: +; REV 1.5 +; Added rev number message +; Added dir attribute to DELALL FCB +; REV 2.00 +; Redone for 2.0 +; REV 2.10 +; 5/1/83 ARR Re-do to transfer system on small memory systems +; REV 2.20 +; 6/17/83 system size re-initialization bug -- mjb001 +; Rev 2.25 +; 8/31/83 16-bit fat insertion +; Rev 2.26 +; 11/2/83 MZ fix signed compare problems for bad sectors +; Rev 2.27 +; 11/8/83 EE current directories are always saved and restored +; Rev 2.28 +; 11/9/83 NP Printf and changed to an .EXE file +; Rev 2.29 +; 11/11/83 ARR Fixed ASSIGN detection to use NameTrans call to see +; if drive letter remapped. No longer IBM only +; Rev 2.30 +; 11/13/83 ARR SS does NOT = CS, so all use of BP needs CS override +; Rev 2.31 +; 12/27/83 ARR REP STOSB instruction at Clean: changed to be +; sure ES = CS. + + + + +code segment public para 'CODE' +code ends + + + +data segment public para 'DATA' +data ends + +End_Of_Memory segment public para 'BUFFERS' +End_Of_Memory ends + + +code segment public para 'CODE' + + assume cs:code,ds:nothing,es:nothing + +;------------------------------------------------------------------------------- +; Define as public for debugging + +; procedures + public GetSize + public AddToSystemSize + public Phase1Initialisation + public SetStartSector + public SetfBigFat + public Phase2Initialisation + public DiskFormat + public BadSector + public DisplayCurrentTrack + public WriteFileSystem + public Done + public CurrentLogicalSector + public PrintErrorAbort + public GetDeviceParameters + public SetDeviceParameters + public Multiply_32_Bits + + public START + public FatAllocated + public MEMERRJ + public MEM_OK + public RDFRST + public NEEDSYS + public INITCALL + public SWITCHCHK + public SYSLOOP + public FRMTPROB + public GETTRK + public TRKFND + public CLRTEST + public CMPTRKS + public BadClus +; public DoBig +; public DoSet + public DRTFAT + public CLEARED + public LOUSE + public LOUSEP + public FATWRT + public SYSOK + public STATUS + public REPORTC + public ONCLUS + public MORE + public FEXIT + public SYSPRM + public fexitJ + public DoPrompt + public TARGPRM + public IsRemovable + public CheckRemove + public IsRemove + public NotRemove + public DSKPRM + public GOPRNIT + public crlf + public PrintString + public std_printf + public READDOS + public RDFILS + public FILESDONE + public CLSALL + public GOTBIOS + public GOTDOS + public CLSALLJ + public GOTCOM + public WRITEDOS + public GOTALLBIO + public BIOSDONE + public GOTNDOS + public PARTDOS + public GOTALLDOS + public DOSDONE + public PARTCOM + public GOTALLCOM + public COMDONE + public MAKEFIL + public CheckMany + public CLOSETARG + public IOLOOP + public GOTTARG + public GSYS + public TESTSYS + public GETOFFS +; public TESTSYSDISK ; dcl 8/23/86 + public SETBIOS + public BIOSCLS + public SETBIOSSIZ + public DOSOPNOK + public DOSCLS + public SETDOSSIZ + public GotComHand + public COMCLS + public SETCOMSIZ + public GETFSIZ + public READFILE + public WRITEFILE + public FILIO + public NORMIO + public IORETP + public IORET + public NORMALIZE + public GotDeviceParameters + public LoadSectorTable + public NotBigTotalSectors + public NotBig + public FormatLoop + public FormatDone + public ContinueFormat + public ReportBadTrack + public NoMoreTracks + public WriteDIRloop + public Main_Routine + public ControlC_Handler + +; bytes + public fBigFat + public formatError + public ROOTSTR + public DBLFLG + public DRIVE + public FILSTAT + public USERDIRS + public VOLFCB + public VOLNAM + public TRANSRC + public TRANDST + public INBUFF + public driveLetter + public systemDriveLetter + public CommandFile + public ExitStatus + public VolDrive + public DelFCB + public DelDrive + +; words + public startSector + public fatSpace + public firstHead + public firstCylinder + public tracksLeft + public tracksPerDisk + public sectorsInRootDirectory + public directorySector + public printStringPointer + public MSTART + public MSIZE + public TempHandle + public BEGSEG + public SWITCHMAP + public SWITCHCOPY + public FAT + public CLUSSIZ + public SECSIZ + public SYSTRKS + public SECTORS + public currentHead + public currentCylinder + public PercentComplete + public Formatted_Tracks_High + public Formatted_Tracks_Low + +; other + public deviceParameters + public Disk_Access + public formatPacket +;------------------------------------------------------------------------------- + +data segment public para 'DATA' + extrn msgAssignedDrive:byte + extrn msgBadDosVersion:byte + extrn msgDirectoryWriteError:byte + extrn msgFormatComplete:byte + extrn msgFormatNotSupported:byte + extrn msgFATwriteError:byte + extrn msgInvalidDeviceParameters:byte + extrn msgLabelPrompt:byte + extrn msgNeedDrive:byte + extrn msgNoSystemFiles:byte + extrn msgNetDrive:byte + extrn msgInsertDisk:byte + extrn msgHardDiskWarning:byte + extrn msgSystemTransfered:byte + extrn msgFormatAnother?:byte + extrn msgBadCharacters:byte + extrn msgBadDrive:byte + extrn msgInvalidParameter:byte + extrn msgParametersNotSupported:byte + extrn msgReInsertDisk:byte + extrn msgInsertDosDisk:byte + extrn msgFormatFailure:byte + extrn ContinueMsg:Byte + extrn msgNotSystemDisk:byte + extrn msgDiskUnusable:byte + extrn msgOutOfMemory:byte + extrn msgCurrentTrack:byte + extrn msgWriteProtected:byte + extrn msgInterrupt:byte + extrn msgCRLF:byte + extrn Fatal_Error:Byte + extrn Read_Write_Relative:Byte + extrn PSP_Segment:Word + extrn Parse_Error_Msg:Byte + extrn Extended_Error_Msg:Byte + extrn MsgVerify:Byte + +data ends + + +debug equ 0 + .xlist + INCLUDE VERSIONA.INC + INCLUDE DOSMAC.INC + INCLUDE SYSCALL.INC + INCLUDE ERROR.INC + INCLUDE DPB.INC + INCLUDE CPMFCB.INC + INCLUDE DIRENT.INC + INCLUDE CURDIR.INC + INCLUDE PDB.INC + INCLUDE BPB.INC + INCLUDE FOREQU.INC + INCLUDE FORMACRO.INC + INCLUDE IOCTL.INC + INCLUDE FORSWTCH.INC + INCLUDE SYSVAR.INC + .list + + +;------------------------------------------------------------------------------- +; And this is the actual data + +data segment public para 'DATA' + public deviceParameters + public bios + public dos + public command + public FAT_Flag + +validSavedDeviceParameters db 0 +savedDeviceParameters a_DeviceParameters <> +deviceParameters a_DeviceParameters <> + +Disk_Access A_DiskAccess_Control <> ;an000; dms; + +formatPacket a_FormatPacket <> +RWPacket a_TrackReadWritePacket <> +RW_TRF_Area db 512 dup(0) + +startSector dw ? +fatSpace dd ? +fBigFat db FALSE + +firstHead dw ? +firstCylinder dw ? +tracksLeft dw ? +tracksPerDisk dw ? + +Formatted_Tracks_Low dw 0 +Formatted_Tracks_High dw 0 + + +public NumSectors ,TrackCnt +NumSectors dw 0FFFFh +TrackCnt dw 0FFFFh +PercentComplete dw 0FFFFh ;Init non-zero so msg will display first time + +public Old_Dir +Old_Dir db FALSE + +public fLastChance +fLastChance db FALSE ; Flags reinvocation from + ; LastChanceToSaveIt. Used by DSKPRM + +sectorsInRootDirectory dw ? + +directorySector dd 0 + +formatError db 0 + +printStringPointer dw 0 + +; Exit status defines +ExitStatus db 0 +ExitOK equ 0 +ExitCtrlC equ 3 +ExitFatal equ 4 +ExitNo equ 5 +ExitDriveNotReady equ 6 ;an017; dms;drive not ready error +ExitWriteProtect equ 7 ;an017; dms;write protect error + +ROOTSTR DB ? + DB ":\",0 +DBLFLG DB 0 ;Initialize flags to zero +IOCNT DD ? +MSTART DW ? ; Start of sys file buffer (para#) +MSIZE DW ? ; Size of above in paragraphs +TempHandle DW ? +FILSTAT DB ? ; In memory status of files + ; XXXXXX00B BIOS not in + ; XXXXXX01B BIOS partly in + ; XXXXXX10B BIOS all in + ; XXXX00XXB DOS not in + ; XXXX01XXB DOS partly in + ; XXXX10XXB DOS all in + ; XX00XXXXB COMMAND not in + ; XX01XXXXB COMMAND partly in + ; XX10XXXXB COMMAND all in + +USERDIRS DB DIRSTRLEN+3 DUP(?) ; Storage for users current directory + +Paras_Per_Fat dw 0000h ;an000;holds fat para count +Fat_Init_Value dw 0000h ;an000;initializes the FAT + +bios a_FileStructure <> +BiosAttributes EQU attr_hidden + attr_system + attr_read_only + +dos a_FileStructure <> +DosAttributes EQU attr_hidden + attr_system + attr_read_only + +command a_FileStructure <> +CommandAttributes EQU 0 +CommandFile DB "X:\COMMAND.COM",0 +CommandFile_Buffer DB 127 dup(0) ;an000;allow room for copy + +Command_Com DB "COMMAND.COM",0 + +VOLFCB DB -1,0,0,0,0,0,8 +VOLDRIVE DB 0 +VOLNAM DB " " + DB 8 + DB 26 DUP(?) + +DelFCB DB -1,0,0,0,0,0,8 +DelDRIVE DB 0 +DelNAM DB "???????????" + DB 8 + DB 26 DUP(?) + +TRANSRC DB "A:CON",0,0 ; Device so we don't hit the drive +TRANDST DB "A:\",0,0,0,0,0,0,0,0,0,0 + +BEGSEG DW ? +SWITCHMAP DW ? +SWITCHCOPY DW ? +FAT DW ? + DW ? +CLUSSIZ DW ? +SECSIZ DW ? +SYSTRKS DW ? +SECTORS DW ? +INBUFF DB 80,0 + DB 80 DUP(?) + + +drive db 0 +driveLetter db "x" +systemDriveLetter db "x" + +CTRL_BREAK_VECTOR dd ? ;ac010; dms;Holds CTRL-Break + ; vector + +Command_Path dd ? ;an011; dms;hold pointer to + ; COMMAND's path + +Comspec_ID db "COMSPEC=",00 ;an011; dms;Comspec target + + +Environ_Segment dw ? ;an011; dms;hold segment of + ; environ. vector +;======== Disk Table ========== ;an012; dms; +;Used if NumberOfFATs in BPB +;is 0. + +DiskTable dw 0, 32680, 0803h, 512, 0 + dw 4h, 0000h, 0402h, 512, Fbig + dw 8h, 0000h, 0803h, 512, Fbig + dw 10h, 0000h, 1004h, 512, Fbig + dw 20h, 0000h, 2005h, 512, Fbig + +public Org_AX ;an000; dms;make it known +Org_AX dw ? ;an000; dms;AX on entry + +Cluster_Boundary_Adj_Factor dw ? ;an000; dms; +Cluster_Boundary_SPT_Count dw ? ;an000; dms; +Cluster_Boundary_Flag db False ;an000; dms; +Cluster_Boundary_Buffer_Seg dw ? ;an000; dms; + +Relative_Sector_Low dw ? ;an000; dms; +Relative_Sector_High dw ? ;an000; dms; + +FAT_Flag db ? ;an000; dms; +Tracks_To_Format dw ? ;an015; dms; +Track_Count dw ? ;an015; dms; +Format_End db FALSE ;an015; dms; + +public Msg_Allocation_Unit_Val + +Msg_Allocation_Unit_Val dd ? ;an019; dms; + + +data ends + +;For FORPROC and FORMES modules + + public secsiz,clussiz,inbuff + + PUBLIC crlf,std_printf + + public switchmap,drive,driveLetter,fatSpace + public fBigFat, PrintString,currentHead,currentCylinder + extrn CheckSwitches:near,LastChanceToSaveIt:near + extrn Volid:near + extrn WriteBootSector:near,OemDone:near + extrn AccessDisk:near + extrn Main_Init:near + extrn Read_Disk:near + extrn Write_Disk:near + +data segment public para 'DATA' + extrn BiosFile:byte,DosFile:byte +data ends + +;For FORPROC module + + EXTRN FormatAnother?:near,Yes?:near,REPORT:NEAR,USER_STRING:NEAR +data segment public para 'DATA' + extrn syssiz:dword,biosiz:dword +data ends + +DOSVER_LOW EQU 0300H+20 +DOSVER_HIGH EQU 0300H+20 + +RECLEN EQU fcb_RECSIZ+7 +RR EQU fcb_RR+7 + +PSP_Environ equ 2ch ;an011; dms;location of + ; environ. segment + ; in PSP + +Fbig equ 0ffh ;an000; dms;flag for big FAT + +START: + xor bx,bx ; ;AN000; + push bx ; ;AN000; + Set_Data_Segment ; ;AC000; + mov Org_AX,ax ;an000; dms;save ax on entry + jmp Main_Init ; ;AC000; + + +Main_Routine: ; ;AN000; +; Set memory requirements + mov bx,PSP_Segment ;Shrink to free space for FAT ;AC000; + mov es,bx ; ;AC000; + mov bx,End_Of_Memory ; ;AC000; + sub bx,PSP_Segment ; ;AC000; + DOS_Call Setblock ; ;AC000; + + call Get_Disk_Access ;an014; dms; + cmp Disk_Access.DAC_Access_Flag,0ffh ;an014; dms;is access already allowed? +; $if ne ;an014; dms;no, don't change status + JE $$IF1 + lea dx,Disk_Access ;an014; dms;point to parm block + mov Disk_Access.DAC_Access_Flag,01h ;an014; dms;signal disk access + call Set_Disk_Access_On_Off ;an014;dms;allow disk access +; $endif ;an014; dms; +$$IF1: + + CALL Phase1Initialisation + jnc FatAllocated + + Message msgFormatFailure ; ;AC000; + jmp Fexit + +MEMERR: + mov ax, seg data + mov ds, ax + Message msgOutOfMemory ; ;AC000; + ;call PrintString + JMP FEXIT + +FatAllocated: + + TEST SWITCHMAP,SWITCH_S + JZ INITCALL + MOV BX,0FFFFH + MOV AH,ALLOC + INT 21H + OR BX,BX + JZ MEMERRJ ;No memory + MOV [MSIZE],BX + MOV AH,ALLOC + INT 21H + JNC MEM_OK +MEMERRJ: + JMP MEMERR ;No memory + +MEM_OK: + MOV [MSTART],AX + +RDFRST: + mov bios.fileSizeInParagraphs,0 ;mjb001 initialize file size + mov dos.fileSizeInParagraphs,0 ;mjb001 ... + mov command.fileSizeInParagraphs,0 ;mjb001 ... + CALL READDOS ;Read BIOS and DOS + JNC INITCALL ;OK -- read next file +NEEDSYS: + CALL SYSPRM ;Prompt for system disk + JMP RDFRST ;Try again + +INITCALL: + CALL Phase2Initialisation + +SWITCHCHK: + MOV DX,SWITCHMAP + MOV SWITCHCOPY,DX + +SYSLOOP: + ;Must intialize for each iteration + + MOV WORD PTR SYSSIZ,0 + MOV WORD PTR SYSSIZ+2,0 + MOV BYTE PTR DBLFLG,0 + mov ExitStatus, ExitOK + MOV DX,SWITCHCOPY + MOV SWITCHMAP,DX ;Restore original Switches +; DiskFormat will handle call for new disk + CALL DISKFORMAT ;Format the disk + JNC GETTRK +FRMTPROB: + + test SwitchMap,Switch_Select ;an017; dms;SELECT option? +; $if z ;an017; dms;no - display message + JNZ $$IF3 + Message msgFormatFailure ; ;AC000; + mov ExitStatus, ExitFatal ;an017; dms; +; $endif ;an017; dms; +$$IF3: + CALL MORE ;See if more disks to format + JMP SHORT SYSLOOP + +;Mark any bad sectors in the FATs +;And keep track of how many bytes there are in bad sectors + +GETTRK: + CALL BADSECTOR ;Do bad track fix-up + JC FRMTPROB ;Had an error in Formatting - can't recover + CMP AX,0 ;Are we finished? + JNZ TRKFND ;No - check error conditions + JMP DRTFAT ;Yes +TRKFND: + mov bx,word ptr Relative_Sector_Low ;get the low word of the sector ;an000; dms; + CMP BX,STARTSECTOR ;Are any sectors in the system area bad? + JAE CLRTEST ; MZ 2.26 unsigned compare + Message msgDiskUnusable ; ;AC000; + JMP FRMTPROB ;Bad disk -- try again +CLRTEST: + MOV SECTORS,AX ;Save the number of sectors on the track + TEST SWITCHMAP,SWITCH_S ;If system requested calculate size + JZ BAD100 + CMP BYTE PTR DBLFLG,0 ;Have we already calculated System space? + JNZ CMPTRKS ;Yes -- all ready for the compare + INC BYTE PTR DBLFLG ;No -- set the flag + CALL GETBIOSIZE ; Get the size of the BIOS + MOV DX,WORD PTR SYSSIZ+2 + MOV AX,WORD PTR SYSSIZ + MOV WORD PTR BIOSIZ+2,DX + MOV WORD PTR BIOSIZ,AX + CALL GETDOSSIZE + CALL GETCMDSIZE + MOV DX,WORD PTR BIOSIZ+2 + MOV AX,WORD PTR BIOSIZ + DIV deviceParameters.DP_BPB.BPB_BytesPerSector + ADD AX,STARTSECTOR + MOV SYSTRKS,AX ;Space FAT,Dir,and system files require +CMPTRKS: + mov bx,word ptr Relative_Sector_Low ;get the low word of the sector ;an000; dms; + CMP BX,SYSTRKS + JA BAD100 ; MZ 2.26 unsigned compare + mov ExitStatus, ExitFatal + Message msgNotSystemDisk ; ;AC000; + AND SWITCHMAP,NOT SWITCH_S ;Turn off system transfer switch + MOV WORD PTR SYSSIZ+2,0 ;No system to transfer + MOV WORD PTR SYSSIZ,0 ;No system to transfer +BAD100: + + CMP deviceParameters.DP_DeviceType, DEV_HARDDISK ;an000; dms;hard disk? +; $if e ;an000; dms; yes + JNE $$IF5 + call Get_Bad_Sector_Hard ;an000; dms;see if a sector is bad +; $else ;an000; dms;floppy disk + JMP SHORT $$EN5 +$$IF5: + call Get_Bad_Sector_Floppy ;an000; dms;mark entire track bad +; $endif ;an000; dms; +$$EN5: + + JMP GETTRK + +; Inputs: BX = Cluster number +; Outputs: The given cluster is marked as invalid +; Zero flag is set if the cluster was already marked bad +; Registers modified: DX,SI +; No other registers affected + +;========================================================================= +; BADCLUS : Marks off a bad cluster in the FAT +; If a cluster has already been marked bad it +; will return with ZR. +; +; Inputs : DX:AX - Cluster Number +; +; Outputs : Cluster is marked invalid +; ZR set if cluster already marked bad +;========================================================================= + +BadClus proc near ;an000; mark bad clusters + + push di ;an000; save affected regs + push ax + push bx + push cx + push dx + push es + + mov es, word ptr fatSpace + 2 ;an005; obtain seg of FAT + CMP fBigFat,TRUE ;an005; 16 bit fat? +; $if ne ;an005; no - 12-bit fat + JE $$IF8 + push ax ;an000; save ax - contains low cluster number + mov si,dx ;an000; pick up high word of cluster + mov di,ax ;an000; pick up low word of cluster + mov cx,2 ;an000; divide by 2 + call Divide_32_Bits ;an000; 32 bit divide + + add ax,di ;an000; add in low word of result + adc dx,si ;an000; pick up low word carry + ;cluster = cluster * 1.5 + add ax,word ptr fatspace ;an005; add 0 + adc dx,0 ;an000; pick up carry + + mov bx,dx ;an000; get high word for adjust + mov cx,es ;an005; place seg in ax + call BadClus_Address_Adjust ;an000; adjust segment offset + mov es,cx ;an000; new segment + mov si,ax ;an000; new offset + + MOV DX,0FF7h ;an005; bad cluster flag + MOV AX,0FFFh ;an005; mask value + + pop cx ;an000; restore ax in cx - low cluster number + test cx,1 ;an000; is old clus num odd? +; $if nz ;an005; yes + JZ $$IF9 + mov cl,4 ;an005; set shift count + SHL AX,cl ;an005; get only 12 bits - fff0 + mov cl,4 ;an005; set shift count + SHL DX,cl ;an005; get 12 bits - ff70 +; $endif ;an005; +$$IF9: +; $else ;an005; 16-bit fats here + JMP SHORT $$EN8 +$$IF8: + xor si,si ;an005; clear si + mov bx,dx ;an000; get high word for multiply + mov cx,2 ;an000; multiply by 2 + call Multiply_32_Bits ;an000; 32 bit multiply + ; due to 2 bytes per + ; FAT cell. This gives + ; us an offset into the + ; FAT. + + mov cx,es ;an005; place seg in cx + call BadClus_Address_Adjust ;an000; adjust segment:offset + mov es,cx ;an000; new segment + mov si,ax ;an000; new offset + + MOV DX,0FFF7h ;an005; bad cluster value + MOV AX,0FFFFh ;an005; mask value +; $endif +$$EN8: + + MOV CX,es:[SI] ;an005; get contents of fat cell + AND CX,AX ;an005; make it 12 or 16 bit + ; depending on value in AX + NOT AX ;an005; set AX to 0 + AND es:[SI],AX ;an005; clear FAT entry + OR es:[SI],DX ;an005; flag it a bad cluster + CMP DX,CX ; return op == badval; + + pop es + pop dx + pop cx + pop bx + pop ax + pop di + return + +badclus endp + +DRTFAT: + TEST SWITCHMAP,SWITCH_S ;If system requested, calculate size + JZ CLEARED + CMP BYTE PTR DBLFLG,0 ;Have we already calculated System space? + JNZ CLEARED ;Yes + INC BYTE PTR DBLFLG ;No -- set the flag + CALL GETSIZE ;Calculate the system size +CLEARED: + call Ctrl_Break_Save ;ac010; dms;save CTRL-Break + call Set_Ctrl_Break + CALL WriteFileSystem + + JNC FATWRT + + +LOUSE: + + call Reset_Ctrl_Break ;ac010; dms;restore CTRL-Break + Message msgDiskUnusable ; ;AC000; + JMP FRMTPROB + +LOUSEP: + POP DS + JMP LOUSE + +FATWRT: + + PUSH DS + MOV DL,DRIVE + INC DL + MOV AH,GET_DPB + INT 21H + CMP AL,-1 + JZ LOUSEP ;Something BAD has happened + MOV [BX.dpb_next_free],0 ; Reset allocation to start of disk + MOV [BX.dpb_free_cnt],-1 ; Force free space to be computed + POP DS + TEST SWITCHMAP,SWITCH_S ;System desired + JZ STATUS + mov al, drive + call AccessDisk ; note what is current logical drive + CALL WRITEDOS ;Write the BIOS & DOS + JNC SYSOK + Message msgNotSystemDisk ; ;AC000; + MOV WORD PTR SYSSIZ+2,0 ;No system transfered + MOV WORD PTR SYSSIZ,0 ;No system transfered + JMP SHORT STATUS + +SYSOK: + + + test SwitchMap,(Switch_Select or SWITCH_AUTOTEST) ;Don't display if EXEC'd by ;AN000; +; $IF Z ; Select ;AN000; + JNZ $$IF13 + Message msgSystemTransfered ; ;AC000; +; $ENDIF ;AN000; +$$IF13: +STATUS: + + call Reset_Ctrl_Break ;ac010; dms;restore CTRL-Break + + CALL CRLF + + + + + MOV AH,DISK_RESET + INT 21H + CALL DONE ;Final call to OEM module + JNC REPORTC + JMP FRMTPROB ;Report an error + +REPORTC: + +; +;TEMP FIX for /AUTOTEST +; + test SwitchMap,(Switch_Autotest or Switch_8) ;TEMP +; $IF Z + JNZ $$IF15 + CALL VOLID +; $ENDIF +$$IF15: + test SwitchMap,(Switch_Select or SWITCH_AUTOTEST) ;Need to shut down the report? ;AN000; +; $IF Z ;If exec'd by Select, we do ;AN000; + JNZ $$IF17 + CALL REPORT ;Print report +; $ENDIF ; ;AN000; +$$IF17: + CALL MORE ;See if more disks to format + JMP SYSLOOP ;If we returned from MORE then continue + +;****************************************** +; Calculate the size in bytes of the system rounded up to sector and +; cluster boundries, Answer in SYSSIZ + +GetSize proc near + call GetBioSize + call GetDosSize + call GetCmdSize + return +GetSize endp + +GetBioSize proc near + MOV AX,WORD PTR bios.fileSizeInBytes + MOV DX,WORD PTR bios.fileSizeInBytes+2 + CALL AddToSystemSize + return +GetBioSize endp + +GetDosSize proc near + MOV AX,WORD PTR dos.fileSizeInBytes + MOV DX,WORD PTR dos.fileSizeInBytes+2 + CALL AddToSystemSize + return +GetDosSize endp + +GetCmdSize proc near + MOV AX,WORD PTR command.fileSizeInBytes + MOV DX,WORD PTR command.fileSizeInBytes+2 + call AddToSystemSize + return +GetCmdSize endp + +;Calculate the number of sectors used for the system +PUBLIC AddToSystemSize +AddToSystemSize proc near + push bx + DIV deviceParameters.DP_BPB.BPB_BytesPerSector + OR DX,DX + JZ FNDSIZ0 + INC AX ; Round up to next sector +FNDSIZ0: + PUSH AX + XOR DX,DX + xor bx,bx + mov bl, deviceParameters.DP_BPB.BPB_SectorsPerCluster + div bx + POP AX + OR DX,DX + JZ ONCLUS + SUB DX, bx + NEG DX + ADD AX,DX ; Round up sector count to cluster + ; boundry +ONCLUS: + MUL deviceParameters.DP_BPB.BPB_BytesPerSector + ADD WORD PTR SYSSIZ,AX + ADC WORD PTR SYSSIZ+2,DX + pop bx + return +AddToSystemSize endp + +MORE: + + mov Formatted_Tracks_Low,0 ;Reinit the track counter ;AN000; + mov Formatted_Tracks_High,0 ; in case of another format ;AN000; + test SwitchMap,(Switch_Select or SWITCH_AUTOTEST) ;Don't display if EXEC'd by ;AN000; + jnz ExitProgram ; Select ;AN000; + + CMP deviceParameters.DP_DeviceType, DEV_HARDDISK + je ExitProgram + test SwitchMap,(SWITCH_Select or SWITCH_AUTOTEST) ;If exec'd from select, then;AN000; + jnz ExitProgram ; don't give user choice ;AN000; + CALL FormatAnother? ;Get yes or no response + JC ExitProgram + CALL CRLF + JMP CRLF + + +FEXIT: + Set_Data_Segment ;Make sure have addressability ;AN000; + mov ExitStatus,ExitFatal + +ExitProgram: + test validSavedDeviceParameters, 0ffH + jz DoNotRestoreDeviceParameters + mov savedDeviceParameters.DP_SpecialFunctions, TRACKLAYOUT_IS_GOOD + lea dx, savedDeviceParameters + call SetDeviceParameters +DoNotRestoreDeviceParameters: + + call Format_Access_Wrap_Up ;determine access status ;an000; dms;determine access status + mov al,ExitStatus ;Get Errorlevel ;AN000; + DOS_Call Exit ;Exit program ;AN000; + int 20h ;If other exit fails ;AN000; + +; Prompt the user for a system diskette in the default drive +SYSPRM: + MOV AH,GET_DEFAULT_DRIVE ;Will find out the default drive + INT 21H ;Default now in AL + MOV BL,AL + INC BL ; A = 1 + ADD AL,41H ;Now in Ascii + MOV systemDriveLetter,AL ;Text now ok + CALL IsRemovable + JNC DoPrompt +; +; Media is non-removable. Switch sys disk to drive A. Check, though, to see +; if drive A is removable too. +; + MOV AL,"A" + MOV BYTE PTR [systemDriveLetter],AL + MOV [BiosFile],AL + MOV [DosFile],AL + MOV [CommandFile],AL + MOV BX,1 + CALL IsRemovable + JNC DoPrompt + Message msgNoSystemFiles ; ;AC000; +fexitJ: + JMP FEXIT + +DoPrompt: + mov al, systemDriveLetter + sub al, 'A' + call AccessDisk + Message msgInsertDOSDisk ; ;AC000; + Message ContinueMsg + ;lea dx, ptr_msgInsertDosDisk + ;CALL std_printf ;Print first line + CALL USER_STRING ;Wait for a key + CALL CRLF + call crlf + return + +TARGPRM: + mov al, drive + call AccessDisk + Message MsgInsertDisk ; ;AC000; + Message ContinueMsg ; + ;lea DX, ptr_msgInsertDisk + ;CALL std_printf ;Print first line + CALL USER_STRING ;Wait for a key + CALL CRLF + return + +; +; Determine if the drive indicated in BX is removable or not. +; +; Inputs: BX has drive (0=def, 1=A) +; Outputs: Carry clear +; Removable +; Carry set +; not removable +; Registers modified: none + +IsRemovable: + SaveReg + MOV AX,(IOCTL SHL 8) OR 8 ; Rem media check + INT 21H + JNC CheckRemove + MOV AX,(IOCTL SHL 8) + 9 ; Is it a NET drive? + INT 21h + JC NotRemove ; Yipe, say non-removable + TEST DX,1000h + JNZ NotRemove ; Is NET drive, say non-removeable + JMP IsRemove ; Is local, say removable +CheckRemove: + TEST AX,1 + JNZ NotRemove +IsRemove: + CLC + RestoreReg + return +NotRemove: + STC + RestoreReg + return + + +; DiSKPRoMpt: +; +; This routine prompts for the insertion of the correct diskette +; into the Target drive, UNLESS we are being re-entrantly invoked +; from LastChanceToSaveIt. If the target is a Hardisk we issue a +; warning message. +; +; INPUTS: +; deviceParameters.DP_DeviceType +; fLastChance +; +; OUTPUTS: +; Prompt string +; fLastChance := FALSE +; +; Registers affected: +; Flags +; +DSKPRM: + CMP fLastChance,TRUE + JE PrmptRet + + CMP deviceParameters.DP_DeviceType, DEV_HARDDISK + jne goprnit + Message msgHardDiskWarning ; ;AC000; + ;lea dx, ptr_msgHardDiskWarning + ;call std_printf + CALL Yes? + jnc OkToFormatHardDisk + mov ExitStatus, ExitNo + jmp ExitProgram + +OkToFormatHardDisk: + CALL CRLF + CALL CRLF + return + +GOPRNIT: + mov al, drive + call AccessDisk + Message msgInsertDisk ; ;AC000; + Message ContinueMsg ; + ;lea dx,ptr_msgInsertDisk + ;CALL std_printf + CALL USER_STRING ;Wait for any key + CALL CRLF + CALL CRLF + +PrmptRet: + mov fLastChance, FALSE + return + + +;------------------------------------------------------------------------------- + +ControlC_Handler: + mov ax, seg data + mov ds, ax + Message msgInterrupt ; ;AC000; + mov ExitStatus, ExitCtrlC + jmp ExitProgram + + +crlf: + ;lea dx, msgCRLF + mov dx,offset msgCRLF ;CR,LF added to message ;AC000; +PrintString: + ;mov printStringPointer, dx + ;lea dx, PrintStringPointer + +std_printf: + ;push dx + ;call printf + call Display_Interface ; ;AC000; + return + +;------------------------------------------------------------------------------- + + +;**************************************** +;Copy IO.SYS, MSDOS.SYS and COMMAND.COM into data area. +; Carry set if problems + +READDOS: + push ax ;save regs ;an025; dms; + push bx ; ;an025; dms; + push es ; ;an025; dms; + + mov ah,Get_In_Vars ;Find out boot drive ;an025; dms; + int 21h ; ;an025; dms; + mov al,byte ptr es:[bx].SysI_Boot_Drive ;get 1 based drive ID ;an025; dms; + add al,40h ;Make it ASCII ;an025; dms; + mov [BiosFile],al ;Stuff it in file specs. ;an025; dms; + mov [DosFile],al ; ;an025; dms; + mov [CommandFile],al ; ;an025; dms; + + pop es ;restore regs ;an025; dms; + pop bx ; ;an025; dms; + pop ax ; ;an025; dms; + + call Get_BIOS ; dcl 8/23/86 + JNC RDFILS + return + +RDFILS: + MOV BYTE PTR [FILSTAT],0 + MOV BX,[bios.fileHandle] + MOV AX,[MSTART] + MOV DX,AX + ADD DX,[MSIZE] ; CX first bad para + MOV [bios.fileStartSegment],AX + MOV CX,[bios.fileSizeInParagraphs] + ADD AX,CX + CMP AX,DX + JBE GOTBIOS + MOV BYTE PTR [FILSTAT],00000001B ; Got part of BIOS + MOV SI,[MSIZE] + XOR DI,DI + CALL DISIX4 + push ds + MOV DS,[bios.fileStartSegment] + assume ds:nothing + CALL READFILE + pop ds + assume ds:data + JC CLSALL + XOR DX,DX + MOV CX,DX + MOV AX,(LSEEK SHL 8) OR 1 + INT 21H + MOV WORD PTR [bios.fileOffset],AX + MOV WORD PTR [bios.fileOffset+2],DX +FILESDONE: + CLC +CLSALL: + PUSHF +; CALL COMCLS ; dcl 8/23/86 + call FILE_CLS ; dcl 8/23/86 + POPF + return + +GOTBIOS: + MOV BYTE PTR [FILSTAT],00000010B ; Got all of BIOS + push es + LES SI,[bios.fileSizeInBytes] + MOV DI,ES + pop es + push ds + MOV DS,[bios.fileStartSegment] + assume ds:nothing + CALL READFILE + pop ds + assume ds:data + JC CLSALL + + push ax ; dcl 8/23/86 + push dx ; dcl 8/23/86 + call File_Cls ; dcl 8/23/86 + call Get_DOS ; dcl 8/23/86 + pop dx ; dcl 8/23/86 + pop ax ; dcl 8/23/86 + + JNC Found_IBMDOS ;mt 12/8/86 P894 + return ;mt 12/8/86 + +Found_IBMDOS: ;mt 12/8/86 + + MOV BX,[dos.fileHandle] + MOV [dos.fileStartSegment],AX + CMP AX,DX ; No room left? + JZ CLSALL ; Yes + MOV CX,[dos.fileSizeInParagraphs] + ADD AX,CX + CMP AX,DX + JBE GOTDOS + OR BYTE PTR [FILSTAT],00000100B ; Got part of DOS + SUB DX,[dos.fileStartSegment] + MOV SI,DX + XOR DI,DI + CALL DISIX4 + push ds + MOV DS,[dos.fileStartSegment] + assume ds:nothing + CALL READFILE + pop ds + assume ds:data + JC CLSALL + XOR DX,DX + MOV CX,DX + MOV AX,(LSEEK SHL 8) OR 1 + INT 21H + MOV WORD PTR [dos.fileOffset],AX + MOV WORD PTR [dos.fileOffset+2],DX + JMP FILESDONE + +GOTDOS: + OR BYTE PTR [FILSTAT],00001000B ; Got all of DOS + push es + LES SI,[dos.fileSizeInBytes] + MOV DI,ES + pop es + push ds + MOV DS,[dos.fileStartSegment] + assume ds:nothing + CALL READFILE + pop ds + assume ds:data + +CLSALLJ: JNC NOTCLSALL ;PTM P894 mt 12/8/86 + jmp clsall ; + +NotCLSALL: + push ax ; dcl 8/23/86 + + push dx ; dcl 8/23/86 + call File_cls ; dcl 8/23/86 + call Get_Command_Path ;ac011; dms; get path of + ; COMMAND.COM + call Get_COMMAND ;ac011; dms; Point to COMMAND + ; and read it + pop dx ; dcl 8/23/86 + pop ax ; dcl 8/23/86 + + JNC Found_COMMAND ;mt 12/8/86 P894 + return ;mt 12/8/86 + +Found_COMMAND: ;mt 12/8/86 + MOV BX,[command.fileHandle] + MOV [command.fileStartSegment],AX + CMP AX,DX ; No room left? + JZ CLSALLJ ; Yes + MOV CX,[command.fileSizeInParagraphs] + ADD AX,CX + CMP AX,DX + JBE GOTCOM + OR BYTE PTR [FILSTAT],00010000B ; Got part of COMMAND + SUB DX,[command.fileStartSegment] + MOV SI,DX + XOR DI,DI + CALL DISIX4 + push ds + MOV DS,[command.fileStartSegment] + assume ds:nothing + CALL READFILE + pop ds + assume ds:data + JC CLSALLJ + XOR DX,DX + MOV CX,DX + MOV AX,(LSEEK SHL 8) OR 1 + INT 21H + MOV WORD PTR [command.fileOffset],AX + MOV WORD PTR [command.fileOffset+2],DX + JMP FILESDONE + +GOTCOM: + OR BYTE PTR [FILSTAT],00100000B ; Got all of COMMAND + push es + LES SI,[command.fileSizeInBytes] + MOV DI,ES + pop es + push ds + MOV DS,[command.fileStartSegment] + assume ds:nothing + CALL READFILE + pop ds + assume ds:data + JMP CLSALL + +;************************************************** +;Write BIOS DOS COMMAND to the newly formatted disk. + +ASSUME DS:DATA +WRITEDOS: + MOV CX,BiosAttributes + MOV DX,OFFSET BiosFile + push es + LES SI,[bios.fileSizeInBytes] + MOV DI,ES + pop es + CALL MAKEFIL + retc + + MOV [TempHandle],BX + TEST BYTE PTR FILSTAT,00000010B + JNZ GOTALLBIO + call Get_BIOS ; dcl 8/23/86 + jnc Got_WBIOS ;mt 12/8/86 P894 + ret + +Got_WBIOS: + + push es + LES SI,[bios.fileOffset] + MOV DI,ES + pop es + MOV WORD PTR [IOCNT],SI + MOV WORD PTR [IOCNT+2],DI + MOV BP,OFFSET bios + CALL GOTTARG + retc + JMP SHORT BIOSDONE + +GOTALLBIO: + push es + LES SI,[bios.fileSizeInBytes] + MOV DI,ES + pop es + push ds + MOV DS,[bios.fileStartSegment] + assume ds:nothing + CALL WRITEFILE + pop ds + assume ds:data +BIOSDONE: + MOV BX,[TempHandle] + MOV CX,bios.fileTime + MOV DX,bios.fileDate + CALL CLOSETARG + MOV CX,DosAttributes + MOV DX,OFFSET DosFile + push es + LES SI,[dos.fileSizeInBytes] + MOV DI,ES + pop es + CALL MAKEFIL + retc + +GOTNDOS: + MOV [TempHandle],BX + TEST BYTE PTR FILSTAT,00001000B + JNZ GOTALLDOS + call Get_DOS ; dcl 8/23/86 + jnc Got_WDOS ;mt 12/8/86 P894 + ret + +Got_WDOS: + MOV BP,OFFSET dos + TEST BYTE PTR FILSTAT,00000100B + JNZ PARTDOS + MOV WORD PTR [dos.fileOffset],0 + MOV WORD PTR [dos.fileOffset+2],0 + CALL GETSYS3 + retc + JMP SHORT DOSDONE + +PARTDOS: + push es + LES SI,[dos.fileOffset] + MOV DI,ES + pop es + MOV WORD PTR [IOCNT],SI + MOV WORD PTR [IOCNT+2],DI + CALL GOTTARG + retc + JMP SHORT DOSDONE + +GOTALLDOS: + push es + LES SI,[dos.fileSizeInBytes] + MOV DI,ES + pop es + push ds + MOV DS,[dos.fileStartSegment] + assume ds:nothing + CALL WRITEFILE + pop ds + assume ds:data +DOSDONE: + MOV BX,[TempHandle] + MOV CX,dos.fileTime + MOV DX,dos.fileDate + CALL CLOSETARG + MOV CX,CommandAttributes + call Command_Root ;an011; dms;adjust path for + ;COMMAND.COM creation + MOV DX,OFFSET CommandFile + push es + LES SI,[command.fileSizeInBytes] + MOV DI,ES + pop es + CALL MAKEFIL + retc + + MOV [TempHandle],BX + TEST BYTE PTR FILSTAT,00100000B + JNZ GOTALLCOM + call Get_COMMAND ; dcl 8/23/86 + jnc Got_WCOM ;mt 12/8/86 P894 + ret + +Got_WCOM: + MOV BP,OFFSET command + TEST BYTE PTR FILSTAT,00010000B + JNZ PARTCOM + MOV WORD PTR [command.fileOffset],0 + MOV WORD PTR [command.fileOffset+2],0 + CALL GETSYS3 + retc + JMP SHORT COMDONE + +PARTCOM: + push es + LES SI,[command.fileOffset] + MOV DI,ES + pop es + MOV WORD PTR [IOCNT],SI + MOV WORD PTR [IOCNT+2],DI + CALL GOTTARG + retc + JMP SHORT COMDONE + +GOTALLCOM: + push es + LES SI,[command.fileSizeInBytes] + MOV DI,ES + pop es + push ds + MOV DS,[command.fileStartSegment] + assume ds:nothing + CALL WRITEFILE + pop ds + assume ds:data +COMDONE: + MOV BX,[TempHandle] + MOV CX,command.fileTime + MOV DX,command.fileDate + CALL CLOSETARG +;**************************************************************** +; I don't see the need for the following code!! - RS 3.20 +; CMP BYTE PTR [FILSTAT],00101010B +; JZ NOREDOS +;RDFRST2: +; CALL READDOS ; Start back with BIOS +; JNC NOREDOS +; CALL SYSPRM ;Prompt for system disk +; JMP RDFRST2 ;Try again +;NOREDOS: +;**************************************************************** + CLC + return + +;********************************************* +; Create a file on target disk +; CX = attributes, DX points to name +; DI:SI is size file is to have +; +; There is a bug in DOS 2.00 and 2.01 having to do with writes +; from the end of memory. In order to circumvent it this routine +; must create files with the length in DI:SI +; +; On return BX is handle, carry set if problem + +MAKEFIL: + MOV BX,DX + PUSH WORD PTR [BX] + MOV AL,DriveLetter + MOV [BX],AL + MOV AH,CREAT + INT 21H + POP WORD PTR [BX] + MOV BX,AX + JC CheckMany + MOV CX,DI + MOV DX,SI + MOV AX,LSEEK SHL 8 + INT 21H ; Seek to eventual EOF + XOR CX,CX + MOV AH,WRITE + INT 21H ; Set size of file to position + XOR CX,CX + MOV DX,CX + MOV AX,LSEEK SHL 8 + INT 21H ; Seek back to start + return + +; +; Examine error code in AX to see if it is too-many-open-files. +; If it is, we abort right here. Otherwise we return. +; +CheckMany: + CMP AX,error_too_many_open_files + retnz + Extended_Message ; ;AC006; + JMP FEXIT + +;********************************************* +; Close a file on the target disk +; CX/DX is time/date, BX is handle + +CLOSETARG: + MOV AX,(FILE_TIMES SHL 8) OR 1 + INT 21H + MOV AH,CLOSE + INT 21H + return + +;**************************************** +; Transfer system files +; BP points to data structure for file involved +; offset is set to current amount read in +; Start set to start of file in buffer +; TempHandle is handle to write to on target + +IOLOOP: + MOV AL,[systemDriveLetter] + CMP AL,[DriveLetter] + JNZ GOTTARG + MOV AH,DISK_RESET + INT 21H + CALL TARGPRM ;Get target disk + +GOTTARG: +ASSUME DS:DATA +;Enter here if some of file is already in buffer, IOCNT must be set +; to size already in buffer. + MOV BX,[TempHandle] + MOV SI,WORD PTR [IOCNT] + MOV DI,WORD PTR [IOCNT+2] + push ds + MOV DS,ds:[BP.fileStartSegment] + assume ds:nothing + CALL WRITEFILE ; Write next part + pop ds + assume ds:data + retc + + push es + LES AX,ds:[BP.fileOffset] + CMP AX,WORD PTR ds:[BP.fileSizeInBytes] + JNZ GETSYS3 + MOV AX,ES + CMP AX,WORD PTR ds:[BP.fileSizeInBytes+2] + JNZ GETSYS3 + pop es + return ; Carry clear from CMP + +GETSYS3: +;Enter here if none of file is in buffer + pop es + MOV AH,DISK_RESET + INT 21H + MOV AX,[MSTART] ;Furthur IO done starting here + MOV ds:[BP.fileStartSegment],AX ;point to start of buffer + MOV AL,[systemDriveLetter] ;see if we have system disk + CMP AL,[DriveLetter] + JNZ TESTSYS +GSYS: + MOV AH,DISK_RESET + INT 21H + CALL SYSPRM ;Prompt for system disk +TESTSYS: +; CALL TESTSYSDISK ; dcl 8/23/86 + JC GSYS + MOV BX,word ptr DS:[BP.fileHandle] ; CS over ARR 2.30 + push es + LES DX,dword ptr DS:[BP.fileOffset] ; CS over ARR 2.30 + MOV CX,ES + pop es + PUSH DX + MOV AX,LSEEK SHL 8 + INT 21H + POP DX + push es + LES SI,dword ptr DS:[BP.fileSizeInBytes] ; CS over ARR 2.30 + MOV DI,ES ;put high word in di + pop es + SUB SI,DX ;get low word value + SBB DI,CX ; DI:SI is #bytes to go + PUSH DI + PUSH SI + ADD SI,15 ;round up 1 para + ADC DI,0 ;pick up carry + CALL DISID4 ;div 16 to get para count + MOV AX,SI ;put para count in ax + POP SI ;restore bytes remaining + POP DI ;restore bytes remaining + CMP AX,[MSIZE] ;enough memory to read remainder? + JBE GOTSIZ2 ;yes + MOV SI,[MSIZE] + XOR DI,DI + CALL DISIX4 +GOTSIZ2: + MOV WORD PTR [IOCNT],SI ;save byte count for read + MOV WORD PTR [IOCNT+2],DI + push ds + MOV DS,[MSTART] + assume ds:nothing + CALL READFILE + pop ds + assume ds:data + JNC GETOFFS + CALL CLSALL + JMP GSYS +GETOFFS: + XOR DX,DX ;clear dx + MOV CX,DX ;clear cx + MOV AX,(LSEEK SHL 8) OR 1 + INT 21H + MOV WORD PTR DS:[BP.fileOffset],AX ; CS over ARR 2.30 + MOV WORD PTR DS:[BP.fileOffset+2],DX ; CS over ARR 2.30 +;;;;;; CALL CLSALL + JMP IOLOOP + +;************************************************* +; Test to see if correct system disk. Open handles + +CRET12: + STC + return + +;TESTSYSDISK: ; dcl 8/23/86 +Get_BIOS: ; dcl 8/23/86 + MOV AX,OPEN SHL 8 + MOV DX,OFFSET BiosFile + INT 21H + JNC SETBIOS +; call CheckMany ; dcl 8/23/86 + jmp CheckMany ; dcl 8/23/86 + +SETBIOS: + MOV [Bios.fileHandle],AX + MOV BX,AX + CALL GETFSIZ + CMP [bios.fileSizeInParagraphs],0 + JZ SETBIOSSIZ + CMP [bios.fileSizeInParagraphs],AX + JZ SETBIOSSIZ +BIOSCLS: + MOV AH,CLOSE + MOV BX,[Bios.fileHandle] + INT 21H +; JMP CRET12 ; dcl 8/23/86 + ret + +SETBIOSSIZ: + MOV [bios.fileSizeInParagraphs],AX + MOV WORD PTR [bios.fileSizeInBytes],SI + MOV WORD PTR [bios.fileSizeInBytes+2],DI + MOV [bios.fileDate],DX + MOV [bios.fileTime],CX + clc + ret ; dcl 8/23/86 + +Get_DOS: ; dcl 8/23/86 + MOV AX,OPEN SHL 8 + MOV DX,OFFSET DosFile + INT 21H + JNC DOSOPNOK +; call CheckMany ; dcl 8/23/86 +; JMP BIOSCLS ; dcl 8/23/86 Checkmany no ret. + jmp CheckMany ; dcl 8/23/86 + +DOSOPNOK: + MOV [dos.fileHandle],AX + MOV BX,AX + CALL GETFSIZ + CMP [dos.fileSizeInParagraphs],0 + JZ SETDOSSIZ + CMP [dos.fileSizeInParagraphs],AX + JZ SETDOSSIZ + +DOSCLS: + MOV AH,CLOSE + MOV BX,[dos.fileHandle] + INT 21H +; JMP BIOSCLS ; dcl 8/23/86 + ret ; dcl 8/23/86 + +SETDOSSIZ: + MOV [dos.fileSizeInParagraphs],AX + MOV WORD PTR [dos.fileSizeInBytes],SI + MOV WORD PTR [dos.fileSizeInBytes+2],DI + MOV [dos.fileDate],DX + MOV [dos.fileTime],CX + clc + ret ; dcl 8/23/86 + + + +Get_COMMAND: + MOV AX,OPEN SHL 8 + MOV DX,OFFSET CommandFile + INT 21H + JNC GotComHand +; call CheckMany ; dcl 8/23/86 +; JMP DosCls ; dcl 8/23/86 + jmp Checkmany ; dcl 8/23/86 + +GotComHand: + MOV [command.fileHandle],AX + MOV BX,AX + CALL GETFSIZ + CMP [command.fileSizeInParagraphs],0 + JZ SETCOMSIZ + CMP [command.fileSizeInParagraphs],AX + JZ SETCOMSIZ +COMCLS: + MOV AH,CLOSE + MOV BX,[command.fileHandle] + INT 21H +; JMP DOSCLS ; dcl 8/23/86 + ret ; dcl 8/23/86 + +SETCOMSIZ: + MOV [command.fileSizeInParagraphs],AX + MOV WORD PTR [command.fileSizeInBytes],SI + MOV WORD PTR [command.fileSizeInBytes+2],DI + MOV [command.fileDate],DX + MOV [command.fileTime],CX + CLC + return + +FILE_CLS: ; dcl 8/23/86 + MOV AH,CLOSE ; dcl 8/23/86 + INT 21H ; dcl 8/23/86 + ret ; dcl 8/23/86 + +;******************************************* +; Handle in BX, return file size in para in AX +; File size in bytes DI:SI, file date in DX, file +; time in CX. + +GETFSIZ: + MOV AX,(LSEEK SHL 8) OR 2 + XOR CX,CX + MOV DX,CX + INT 21H + MOV SI,AX + MOV DI,DX + ADD AX,15 ; Para round up + ADC DX,0 + AND DX,0FH ; If the file is larger than this it + ; is bigger than the 8086 address + ; space! + MOV CL,12 + SHL DX,CL + MOV CL,4 + SHR AX,CL + OR AX,DX + PUSH AX + MOV AX,LSEEK SHL 8 + XOR CX,CX + MOV DX,CX + INT 21H + MOV AX,FILE_TIMES SHL 8 + INT 21H + POP AX + return + +;******************************************** +; Read/Write file +; DS:0 is Xaddr +; DI:SI is byte count to I/O +; BX is handle +; Carry set if screw up +; +; I/O SI bytes +; I/O 64K - 1 bytes DI times +; I/O DI bytes + + +READFILE: +; Must preserve AX,DX + PUSH AX + PUSH DX + PUSH BP + MOV BP,READ SHL 8 + CALL FILIO + POP BP + POP DX + POP AX + return + +WRITEFILE: + PUSH BP + MOV BP,WRITE SHL 8 + CALL FILIO + POP BP + return + +FILIO: + XOR DX,DX + MOV CX,SI + JCXZ K64IO + MOV AX,BP + INT 21H + retc + ADD DX,AX + CMP AX,CX ; If not =, AX= 4086) +; +Phase1Initialisation proc near + +; Get device parameters + lea dx, deviceParameters + mov deviceParameters.DP_SpecialFunctions, 0 + call GetDeviceParameters + jnc GotDeviceParameters + Message msgFormatNotSupported ; ;AC000; + ;lea dx, ptr_msgFormatNotSupported + ;call std_printf + jmp fexit +GotDeviceParameters: + +; Save the device parameters for when we exit + lea si, deviceParameters + lea di, savedDeviceParameters + mov cx, size a_DeviceParameters + push ds + pop es + rep movsb + +; Ensure that there is a valid number of sectors in the track table + mov savedDeviceParameters.DP_TrackTableEntries, 0 + mov validSavedDeviceParameters, 1 + +; Initialise this to zero to know if CheckSwitches defined the track layout + mov deviceParameters.DP_TrackTableEntries, 0 + + call Set_BPB_Info ;an000; dms; Check to see if we are on + ; FAT system. If not set BPB to proper + ; values for format. +SetMTsupp: + +; Check switches against parameters and use switches to modify device parameters + call CheckSwitches + retc + +IF ShipDisk + + test SwitchMap,Switch_Z ;an000; dms;1 sector/cluster disk? +; $if nz ;an000; dms;yes + JZ $$IF19 + mov DeviceParameters.DP_BPB.BPB_SectorsPerCluster,01h ;an000; dms;set BPB accordingly + call Calc_Small_Fat ;an000; dms;calc FAT size +; $endif ;an000; dms; +$$IF19: + +ENDIF + + + cmp deviceParameters.DP_TrackTableEntries, 0 + jne TrackLayoutSet ; There is a good track layout + +; Store sector table info + mov cx, deviceParameters.DP_BPB.BPB_SectorsPerTrack + mov deviceParameters.DP_TrackTableEntries, cx + mov ax, 1 + mov bx, deviceParameters.DP_BPB.BPB_bytesPerSector + lea di, deviceParameters.DP_SectorTable +LoadSectorTable: + stosw + xchg ax, bx + stosw + xchg ax, bx + inc ax + loop LoadSectorTable +TrackLayoutSet: + +; +; directorySector = malloc( Bytes Per Sector ) +; + mov bx, deviceParameters.DP_BPB.BPB_BytesPerSector + add bx, 0fH + shr bx, 1 + shr bx, 1 + shr bx, 1 + shr bx, 1 + mov ah, Alloc + int 21H + retc + mov word ptr directorySector+2, ax + xor ax,ax + mov word ptr directorySector, ax + +; +; fatSpace = malloc( Bytes Per Sector * Sectors Per FAT ) +; + mov ax, deviceParameters.DP_BPB.BPB_BytesPerSector + add ax, 0fH + shr ax, 1 + shr ax, 1 + shr ax, 1 + shr ax, 1 + mul deviceParameters.DP_BPB.BPB_SectorsPerFAT + mov Paras_Per_Fat,ax ;AN005;128k FAT + mov bx,ax + mov ah,Alloc + int 21H + retc + mov word ptr fatSpace+2,ax + xor ax,ax + mov word ptr fatSpace,ax + + call SetStartSector + call SetfBigFat + + clc + return + +Phase1Initialisation endp + +;------------------------------------------------------------------------------- + +SetStartSector proc near + +; startSector = number of reserved sectors +; + number of FAT Sectors ( Number of FATS * Sectors Per FAT ) +; + number of directory sectors ( 32* Root Entries / bytes Per Sector ) +; ( above is rounded up ) + +; Calculate the number of directory sectors + mov ax, deviceParameters.DP_BPB.BPB_RootEntries + mov bx, size dir_entry + mul bx + add ax, deviceParameters.DP_BPB.BPB_bytesPerSector + dec ax + xor dx,dx + div deviceParameters.DP_BPB.BPB_bytesPerSector + mov sectorsInRootDirectory,ax + mov startSector, ax + +; Calculate the number of FAT sectors + mov ax, deviceParameters.DP_BPB.BPB_SectorsPerFAT + mul deviceParameters.DP_BPB.BPB_numberOfFATs +; Add in the number of boot sectors + add ax, deviceParameters.DP_BPB.BPB_ReservedSectors + add startSector, ax + + return + +SetStartSector endp + +;------------------------------------------------------------------------------- + +SetfBigFat proc near +; +; fBigFat = ( ( (Total Sectors - Start Sector) / Sectors Per Cluster) >= 4086 ) +; + cmp deviceParameters.DP_BPB.BPB_BigTotalSectors+2,0 ; > 32mb part? ;AN000; +; $IF NE ;Yes, big FAT ;AC000; + JE $$IF21 + mov fBigFat, TRUE ;Set flag ;AN000; +; $ELSE ;Nope, < 32,b ;AC000; + JMP SHORT $$EN21 +$$IF21: + mov ax,deviceParameters.DP_BPB.BPB_BigTotalSectors ;Assume this used ;AN000; + cmp ax,0 ;Was this field used? ;AN000; +; $IF E ;Nope, use the other sector field;AN000; + JNE $$IF23 + mov ax, deviceParameters.DP_BPB.BPB_TotalSectors ; ;AC000; + ;** Fix for PTM PCDOS P51 +; $ENDIF ; ;AN000; +$$IF23: + sub ax,startSector ;Get sectors in data area + xor dx,dx + xor bx,bx + mov bl,deviceParameters.DP_BPB.BPB_sectorsPerCluster + div bx ;Get total clusters + cmp ax,BIG_FAT_THRESHOLD ;Is clusters >= 4086? +; $IF AE + JNAE $$IF25 + mov fBigFAT,TRUE ;16 bit FAT if >=4096 + ;** END fix for PTM PCDOS P51 +; $ENDIF +$$IF25: +; $ENDIF +$$EN21: + return + +SetfBigFat endp + +;------------------------------------------------------------------------------- +; +; Phase2Initialisation: +; Use device parameters to build information that will be +; required for each format +; +; Algorithm: +; Calculate first head/cylinder to format +; Calculate number of tracks to format +; Calculate the total bytes on the disk and save for later printout +; First initialise the directory buffer +; +Phase2Initialisation proc near + +; Calculate first track/head to format (round up - kludge) + mov ax, deviceParameters.DP_BPB.BPB_HiddenSectors + mov dx, deviceParameters.DP_BPB.BPB_HiddenSectors + 2 + add ax, deviceParameters.DP_BPB.BPB_SectorsPerTrack + adc dx, 0 + dec ax + sbb dx, 0 + div deviceParameters.DP_BPB.BPB_SectorsPerTrack + xor dx,dx + div deviceParameters.DP_BPB.BPB_Heads + mov firstCylinder, ax + mov firstHead, dx + +; Calculate the total number of tracks to be formatted (round down - kludge) + mov ax, deviceParameters.DP_BPB.BPB_TotalSectors + xor dx,dx +; if (TotalSectors == 0) then use BigTotalSectors + or ax,ax + jnz NotBigTotalSectors + mov ax, deviceParameters.DP_BPB.BPB_BigTotalSectors + mov dx, deviceParameters.DP_BPB.BPB_BigTotalSectors + 2 + +NotBigTotalSectors: + div deviceParameters.DP_BPB.BPB_SectorsPerTrack + mov tracksPerDisk, ax + +; Initialise the directory buffer +; Clear out the Directory Sector before any information is inserted. + mov cx, deviceParameters.DP_BPB.BPB_BytesPerSector + les di, directorySector + xor ax,ax + rep stosb + + mov ax, deviceParameters.DP_BPB.BPB_BytesPerSector + xor dx, dx + mov bx, size dir_entry + div bx + mov cx, ax + + les bx, directorySector +; If Old_Dir = TRUE then put the first letter of each directory entry must be 0E5H + xor al, al + cmp old_Dir, TRUE + jne StickE5 + mov al, 0e5H +StickE5: + mov es:[bx], al + add bx, size dir_entry + loop stickE5 + + ret + +Phase2Initialisation endp + +;------------------------------------------------------------------------------- +; +; SetDeviceParameters: +; Set the device parameters +; +; Input: +; drive +; dx - pointer to device parameters +; +SetDeviceParameters proc near + + mov ax, (IOCTL shl 8) or GENERIC_IOCTL + mov bl, drive + inc bl + mov cx, (RAWIO shl 8) or SET_DEVICE_PARAMETERS + int 21H + return + +SetDeviceParameters endp + +;------------------------------------------------------------------------------- +; +; GetDeviceParameters: +; Get the device parameters +; +; Input: +; drive +; dx - pointer to device parameters +; +GetDeviceParameters proc near + + mov ax, (IOCTL shl 8) or GENERIC_IOCTL + mov bl, drive + inc bl + mov cx, (RAWIO shl 8) or GET_DEVICE_PARAMETERS + int 21H + return + +GetDeviceParameters endp + +;------------------------------------------------------------------------------- +; +; DiskFormat: +; Format the tracks on the disk +; Since we do our SetDeviceParameters here, we also need to +; detect the legality of /N /T if present and abort with errors +; if not. +; This routine stops as soon as it encounters a bad track +; Then BadSector is called to report the bad track, and it continues +; the format +; +; Algorithm: +; Initialise in memory FAT +; current track = first +; while not done +; if format track fails +; DiskFormatErrors = true +; return +; next track + +DiskFormat proc near + + +; +; Initialise fatSpace +; + + + push es + + call Fat_Init ;an000; initialize the FAT + + mov di, word ptr fatspace+2 ;an000; get segment of FAT + mov es, di ;an000; place it in es + mov di, word ptr fatSpace ;Should be 0 + mov al, deviceParameters.DP_BPB.BPB_MediaDescriptor + mov ah, 0ffH + stosw + mov ax, 00ffH + test fBigFat, TRUE + jz NotBig + mov ax, 0ffffH +NotBig: stosw + pop es + +; don't bother to do the formatting if /c was given + test switchmap, SWITCH_C + jz Keep_Going + jmp FormatDone ;FormatDone is to far away + +Keep_Going: +foofoo = INSTALL_FAKE_BPB or TRACKLAYOUT_IS_GOOD + mov deviceParameters.DP_SpecialFunctions, foofoo + lea dx, deviceParameters + + call SetDeviceParameters + + call Cluster_Buffer_Allocate ;an000; dms;get room for retry buffer + + call Prompt_User_For_Disk ;an016; dms; + + test switchmap,switch_8 ; DCL 5/12/86 avoid Naples AH=18h + jnz stdBpB ; lackof support for 8 sectors/track + + ; DCL 5/12/86 + ; Always do the STATUS_FOR_FORMAT test, as we don't know if the machine + ; has this support. For 3.2 /N: & /T: were not documented & therefore + ; not fully supported thru the ROM of Aquarius & Naples & Royal Palm + + ;test SwitchMap, SWITCH_N or SWITCH_T ; IF ( /N or /T ) ;; DCL 5/12/86 + ;jz StdBPB + ; THEN check if + ; supported + mov formatPacket.FP_SpecialFunctions, STATUS_FOR_FORMAT + mov ax, (IOCTL shl 8) or GENERIC_IOCTL + mov bl, drive + inc bl + mov cx, (RAWIO shl 8) or FORMAT_TRACK + lea dx, formatPacket + int 21H + ; switch ( FormatStatusCall) + + ;cmp FormatPacket.FP_SpecialFunctions, Format_No_ROM_Support + ;jb NTSupported ; 0 returned from IBMBIO + ;ja IllegalComb ; 2 returned - ROM Support + ; Illegal Combination! + cmp FormatPacket.FP_SpecialFunctions,0 + je NTSupported + cmp FormatPacket.FP_SpecialFunctions,2 +; $IF E ; ;AC000; + JNE $$IF28 + Message msgInvalidParameter ; ;AC000; + mov Fatal_Error,Yes ;Indicate quittin'type err! ;AN000; +; $ELSE ; ; ; + JMP SHORT $$EN28 +$$IF28: + cmp FormatPacket.FP_SpecialFunctions,3 ; ; ; +; $IF E ; ;AC000; + JNE $$IF30 + mov ax,Error_Not_Ready ;flag not ready ;an000;dms; + call CheckError ; set error level ;an017; dms; + jmp FrmtProb ; exit program ;an017; dms; +; $ELSE ; DCL No ROM support is okay ; ; + JMP SHORT $$EN30 +$$IF30: + ; except for /N: & /T: ; ; + test SwitchMap, SWITCH_N or SWITCH_T ; DCL 5/12/86 ; ; +; $IF NZ ; ;AC000; + JZ $$IF32 + Message msgParametersNotSupported ; ;AC000; + mov Fatal_Error,Yes ;Indicate quittin'type err! ;AN000; +; $ENDIF ; ;AN000; +$$IF32: +; $ENDIF ; ;AN000; +$$EN30: +; $ENDIF ; ;AN000; +$$EN28: + cmp Fatal_Error,Yes ; ;AN000; + jne StdBPB ; ;AN000; + jmp Fexit +; +; We have the support to carry out the FORMAT +; +NTSupported: +StdBPB: + ;call DSKPRM ; prompt user for disk ;; DCL 5/12/86 + mov FormatPacket.FP_SpecialFunctions, 0 + mov ax, firstHead + mov formatPacket.FP_Head, ax + mov ax, firstCylinder + mov formatPacket.FP_Cylinder, ax + mov cx, tracksPerDisk + mov tracksLeft, cx + mov Format_End,False ;an015; dms;flag not at end of format + call Calc_Max_Tracks_To_Format ;an015; dms;max track count for FormatTrack call +FormatLoop: + call Format_Loop ;an015; dms;Format until CY occurs + + cmp Format_End,True ;an015; dms;End of Format? +; $if e ;an015; dms;yes + JNE $$IF36 + mov FormatError,0 ;an015; dms;signal good format + clc ;an015; dms;clear CY +; $else ;an015; dms;bad format + JMP SHORT $$EN36 +$$IF36: + call CheckError ;an015; dms;determine type of error +; $if nc ;an015; dms; + JC $$IF38 + call LastChanceToSaveIt ;an015; dms;acceptable error? +; $if c ;an015; dms;yes + JNC $$IF39 + mov FormatError,1 ;an015; dms;signal error type + clc ;an015; dms;clear CY +; $else ;an015; dms;not acceptable error + JMP SHORT $$EN39 +$$IF39: + call SetStartSector ;an015; dms;start from scratch + call SetFBigFat ;an015; dms; + push ax ;an015; dms; + call Phase2Initialisation ;an015; dms; + clc ;an015; dms; + pop ax ;an015; dms; + jmp DiskFormat ;an015; dms;try again +; $endif ;an015; dms; +$$EN39: +; $endif ;an015; dms; +$$IF38: +; $endif ;an015; dms; +$$EN36: + return + +FormatDone: + mov FormatError,0 + clc + return + +DiskFormat endp + + +;------------------------------------------------------------------------------- +; +; BadSector: +; Reports the bad sectors. +; Reports the track where DiskFormat stopped. +; From then on it formats until it reaches a bad track, or end, +; and reports that. +; +; Output: +; Carry: set --> fatal error +; if Carry not set +; ax - The number of consecutive bad sectors encountered +; ax == 0 --> no more bad sectors +; bx - The logical sector number of the first bad sector +; +; Algorithm: +; if DiskFormatErrors +; DiskFormatErrors = false +; return current track +; else +; next track +; while not done +; if format track fails +; return current track +; next track +; return 0 + +BadSector proc near + + +; don't bother to do the formatting if /c was given + test switchmap, SWITCH_C + jnz NoMoreTracks + + test formatError, 0ffH + jz ContinueFormat + mov formatError, 0 + jmp ReportBadTrack + +ContinueFormat: + call Adj_Track_Count ;an015; dms;decrease track counter + call NextTrack ;an015; dms;adjust head and cylinder + cmp Format_End,True ;an015; dms;end of format? +; $if ne ;an015; dms;no + JE $$IF44 + call Format_Loop ;an015; dms;format until CY + cmp Format_End,True ;an015; dms;end of format? +; $if ne ;an015; dms;no + JE $$IF45 + call CheckError ;an015; dms;must be error - which error? +; $if nc ;an015; dms;non-fatal error? + JC $$IF46 + call CurrentLogicalSector ;an015; dms;yes - get position + mov ax,DeviceParameters.DP_BPB.BPB_SectorsPerTrack ;an015; dms; set track size + clc ;an015; dms;signal O.K. to continue +; $endif ;an015; dms; +$$IF46: +; $else ;an015; dms; + JMP SHORT $$EN45 +$$IF45: + jmp NoMoreTracks ;an015; dms;end of format +; $endif ;an015; dms; +$$EN45: +; $else ;an015; dms; + JMP SHORT $$EN44 +$$IF44: + jmp NoMoreTracks ;an015; dms;end of format +; $endif ;an015; dms; +$$EN44: + return ;an015; dms; + +ReportBadTrack: + call CurrentLogicalSector + mov ax, deviceParameters.DP_BPB.BPB_SectorsPerTrack + clc + return + +NoMoreTracks: + test SwitchMap,(Switch_Select or SWITCH_AUTOTEST) ;Don't display done msg;AN000; +; $IF Z ; if EXEC'd by SELECT ;AN000; + JNZ $$IF52 + Message msgFormatComplete ; ;AC000; +; $ENDIF ; ;AN000; +$$IF52: + mov ax, 0 + clc + return + +BadSector endp + + + +;------------------------------------------------------------------------------- + +data segment public para 'DATA' + +;ptr_msgCurrentTrack dw offset msgCurrentTrack +currentHead dw 0 +currentCylinder dw 0 + +data ends + +;========================================================================= +; Calc_Current_Head_Cyl : Obtain the current head and cylinder of the +; track being formatted. +; +; Inputs: FP_Cylinder - Cylinder of track being formatted +; FP_Head - Head of track being formatted +;========================================================================= + +Procedure Calc_Current_Head_Cyl ;an000; dms; + + push cx ;an000; dms;save cx + mov cx,FormatPacket.FP_Cylinder ;an000; dms;get current cylinder + mov CurrentCylinder,cx ;an000; dms;put into variable + mov cx,FormatPacket.FP_Head ;an000; dms;get current head + mov CurrentHead,cx ;an000; dms;put into variable + pop cx ;an000; dms;restore cx + ret ;an000; dms; + +Calc_Current_Head_Cyl endp ;an000; dms; + + +DisplayCurrentTrack proc near + + push dx ; ;AN000; + push cx ; ;AN000; + push ax ;an015; dms; + + mov ax,Tracks_To_Format ;an015; dms;get track count + + add Formatted_Tracks_Low,ax ;Indicate formatted a track ;AN000; + adc Formatted_Tracks_High,0 ; ;AN000; + mov ax,Formatted_Tracks_Low ; ;AN000; + mov bx,Formatted_Tracks_High ; ;AN000; + mov cx,100 ;Make integer calc for div ;AN000; + call Multiply_32_Bits ; BX:AX = (Cyl * Head *100) ;AN000; + mov dx,bx ;Set up divide ;AN000; + div TracksPerDisk ;% = (Cyl * Head *100)/ # tracks;AN000; + cmp ax,PercentComplete ;Only print message when change ;AN000; +; $IF NE ;To avoid excess cursor splat ;AN000; + JE $$IF54 + mov PercentComplete,ax ;Save it if changed ;AN000; + Message msgCurrentTrack ; ;AC000; +; $ENDIF ; +$$IF54: + pop ax ;an015; dms; + pop cx ;Restore register ;AN000; + pop dx ; ;AN000; + return + +DisplayCurrentTrack endp + + +;------------------------------------------------------------------------------- +; CheckError: +; Input: +; ax - extended error code +; Ouput: +; carry set if error is fatal +; Message printed if Not Ready or Write Protect +; +CheckError proc near + cmp ax, error_write_protect + je WriteProtectError + cmp ax, error_not_ready + je NotReadyError + cmp currentCylinder, 0 + jne CheckRealErrors + cmp currentHead, 0 + je BadTrackZero + +CheckRealErrors: + cmp ax, error_CRC + je JustABadTrack + cmp ax, error_sector_not_found + je JustABadTrack + cmp ax, error_write_fault + je JustABadTrack + cmp ax, error_read_fault + je JustABadTrack + cmp ax, error_gen_failure + je JustABadTrack + + stc + ret + +JustABadTrack: + clc + ret + +WriteProtectError: + + test SwitchMap,Switch_SELECT ;an017; dms;SELECT option? +; $if z ;an017; dms;no - display messages + JNZ $$IF56 + Message msgCRLF ; ;AC006; + Message msgCRLF ; ;AC006; + Extended_Message ; ;AC006; +; $else ;an017; dms;yes - set error level + JMP SHORT $$EN56 +$$IF56: + mov ExitStatus,ExitWriteProtect ;an017; dms;signal write protect error +; $endif ;an017; dms; +$$EN56: + + stc ;an017; dms;signal fatal error + ret ;an017; dms;return to caller + +NotReadyError: + test SwitchMap,Switch_SELECT ;an017; dms; SELECT option? +; $if z ;an017; dms; no - display messages + JNZ $$IF59 + Message msgCRLF ; ;AC006; + Message msgCRLF ; ;AC006; + Extended_Message ; ;AC006; +; $else ;an017; dms;yes - set error level + JMP SHORT $$EN59 +$$IF59: + mov ExitStatus,ExitDriveNotReady ;an017; dms;signal drive not ready +; $endif ;an017; dms; +$$EN59: + stc + ret + + +BadTrackZero: + Message msgDiskUnusable ; ;AC000; + stc + ret + +CheckError endp + +;------------------------------------------------------------------------------- +; WriteFileSystem: +; Write the boot sector and FATs out to disk +; Clear the directory sectors to zero +; + +WriteFileSystem proc near + + + call WriteBootSector + retc + + Set_Data_Segment ;Set DS,ES = DATA ;AN000; +; Write out each of the FATs + push ds ;ac005; dms;save ds + xor cx, cx + mov cl, es:deviceParameters.DP_BPB.BPB_numberOfFATs ; ;AC000; + mov dx, es:deviceParameters.DP_BPB.BPB_ReservedSectors ; ;AC000; + mov al, es:drive ; ;AC000; + mov bx,word ptr es:FatSpace+2 ;Get segment of memory Fat ;AC000; + mov ds,bx ; ;AN000; + mov bx,word ptr es:FatSpace ; ;AN000; + + mov si,bx ;ac005; dms;set up for add. calc + call SEG_ADJ ;ac005; dms;get adjusted seg:off + mov bx,si ;ac005; dms;get new off + assume ds:nothing,es:data ; ;AN000; + +; $do ;ac005; dms;while FATS > 0 +$$DO62: + cmp cx,00 ;ac005; dms;FATS remaining? +; $leave e ;ac005; dms;no + JE $$EN62 + push bx ;ac005; dms;save FAT offset + push ds ;ac005; dms;save FAT segment + push cx ;ac005; dms;save FAT count + push dx ;ac005; dms;reserved FAT sector + call WRITE_FAT ;ac005; dms;write the FAT + pop dx ;ac005; dms;get 1st. FAT sector + pop cx ;ac005; dms;get FAT count + pop ds ;ac005; dms;restore FAT segment + pop bx ;ac005; dms;restore FAT offset +; $if c ;ac005; dms;an error occurred + JNC $$IF64 + Message msgFATwriteError;ac005; dms;say why failed + jmp FEXIT ;ac005; dms;exit format +; $endif ;ac005; dms; +$$IF64: + add dx, es:deviceParameters.DP_BPB.BPB_SectorsPerFAT ; ;AC000; + dec cx ;ac005; dms;decrease FAT count +; $enddo ;ac005; dms; + JMP SHORT $$DO62 +$$EN62: + + pop ds ;ac005; dms;restore ds + assume ds:data ;ac005; dms; + + +; Clear the directory + +; Now write the initialised directory sectors out to disk + mov ax, es:deviceParameters.DP_BPB.BPB_SectorsPerFAT ; ;AC000; + xor dx,dx + push bx ;an000; dms;save bx + xor bx,bx ;an000; dms;clear bx + mov bl,es:DeviceParameters.DP_BPB.BPB_NumberOfFATs ;an000; dms;get FAT count + mul bx ;an000; dms;get total FAT sectors + pop bx ;an000; dms;restore bx + + mov dx, es:deviceParameters.DP_BPB.BPB_ReservedSectors ; ;AC000; + add dx, ax + mov cx, es:sectorsInRootDirectory ; ;AC000; +WriteDIRloop: + push cx + push dx + mov al, es:drive ; ;AC000; + mov cx, 1 + lds bx, es:directorySector ; ;AC000; + + assume ds:nothing,es:data ; ;AN000; + +;Assume dir is alway contined in first 32mb of partition + + mov es:Read_Write_Relative.Start_Sector_High,0 ; ;AC000; + Call Write_Disk ; ;AN000; + jnc Dir_OK ; ;AC000; + Message msgDirectoryWriteError ; ;AC000; + jmp FExit ; ;AN000; +Dir_OK: ; ;AN000; + pop dx + add dx, 1 + pop cx + loop WriteDIRLoop + + Set_Data_Segment ;Set DS to DATA segment ;AN000; +; Ok, we can tell the device driver that we are finished formatting + mov savedDeviceParameters.DP_TrackTableEntries, 0 + mov savedDeviceParameters.DP_SpecialFunctions, TRACKLAYOUT_IS_GOOD + lea dx, savedDeviceParameters + call SetDeviceParameters + + MOV AH,DISK_RESET ; Flush any directories in + INT 21H ; buffers + + return + + +WriteFileSystem endp + +;========================================================================= +; WRITE_FAT : This routine writes the logical sector count requested. +; It will write a maximum of 40h sectors. If more +; than 40h exists it will continue looping until +; all sectors have been written. +; +; Inputs : AL - Drive letter +; DS:BX - Segment:offset of transfer address +; CX - Sector count +; DX - 1st. sector +; +; Outputs : Logical sectors written +;========================================================================= + +procedure write_fat + + mov cx, es:deviceParameters.DP_BPB.BPB_SectorsPerFAT ; ;AC000; + +; $do ;an000;while sectors left +$$DO67: + cmp cx,00h ;an000;any sectors? +; $leave e ;an000;no + JE $$EN67 + + cmp cx,40h +; $if a ;an000;yes + JNA $$IF69 + push cx ;an000;save cx + mov cx,40h + push ax ;an000;save ax + call write_disk ;an000;write it + pop ax ;an000;restore ax + pop cx ;an000;restore cx + jc Write_Exit ;an000;exit if fail + mov si,8000h + call seg_adj ;an000;adjust segment + mov bx,si ;an000;new offset + add dx,40h + sub cx,40h +; $else ;an000;< 64k + JMP SHORT $$EN69 +$$IF69: + push ax ;an000;save ax + call write_disk ;an000;write it + pop ax ;an000;restore ax + xor cx,cx ;an000;set cx to 0 - last read +; $endif +$$EN69: +; $enddo + JMP SHORT $$DO67 +$$EN67: + + Write_Exit: + + ret + +write_fat endp + +;========================================================================= +; SEG_ADJ : This routine adjusts the segment:offset to prevent +; address wrap. +; +; Inputs : SI - Offset to adjust segment with +; DS - Segment to be adjusted +; +; Outputs : SI - New offset +; DS - Adjusted segment +;========================================================================= + +procedure seg_adj + + push ax + push cx + push dx + mov ax,si ;an000;get offset + mov bx,0010h ;an000;16 + xor dx,dx ;an000;clear dx + div bx ;an000;get para count +; $if c ;an000;overflow? + JNC $$IF73 + adc bx,0 ;an000;pick it up +; $endif ;an000; +$$IF73: + mov bx,ds ;an000;get seg + add bx,ax ;an000;adjust for paras + mov ds,bx ;an000;save new seg + mov si,dx ;an000;new offset + pop dx + pop cx + pop ax + ret + +seg_adj endp + +;------------------------------------------------------------------------------- +; format is done... so clean up the disk! +; +Done proc near + + + call OemDone + return + +Done endp + +;------------------------------------------------------------------------------- +; CurrentLogicalSector: +; Get the current logical sector number +; +; Input: +; current track = tracksPerDisk - tracksLeft +; SectorsPerTrack +; +; Output: +; BX = logical sector number of the first sector in the track we +; just tried to format +; +CurrentLogicalSector proc near + + push ax ;an000; dms;save regs + push bx ;an000; dms; + push dx ;an000; dms; + + mov ax, tracksPerDisk + sub ax, tracksLeft + xor dx,dx ;an000; dms;clear dx + mul deviceParameters.DP_BPB.BPB_SectorsPerTrack + mov word ptr Relative_Sector_High,dx ;an000; dms;save high word of sector # + mov word ptr Relative_Sector_Low,ax ;an000; dms;save low word of sector # + + pop dx ;an000; dms;restore regs + pop bx ;an000; dms; + pop ax ;an000; dms; + + return + +CurrentLogicalSector endp + +;------------------------------------------------------------------------------- +; PrintErrorAbort: +; Print an error message and abort +; +; Input: +; dx - Pointer to error message string +; +PrintErrorAbort proc near + + push dx + call crlf + pop dx + call PrintString + + jmp fexit + +PrintErrorAbort endp + + + + +;***************************************************************************** +;Routine name: Multiply_32_Bits +;***************************************************************************** +; +;Description: A real sleazy 32 bit x 16 bit multiply routine. Works by adding +; the 32 bit number to itself for each power of 2 contained in the +; 16 bit number. Whenever a bit that is set in the multiplier (CX) +; gets shifted to the bit 0 spot, it means that that amount has +; been multiplied so far, and it should be added into the total +; value. Take the example CX = 12 (1100). Using the associative +; rule, this is the same as CX = 8+4 (1000 + 0100). The +; multiply is done on this principle - whenever a bit that is set +; is shifted down to the bit 0 location, the value in BX:AX is +; added to the running total in DI:SI. The multiply is continued +; until CX = 0. The routine will exit with CY set if overflow +; occurs. +; +; +;Called Procedures: None +; +;Change History: Created 7/23/87 MT +; +;Input: BX:AX = 32 bit number to be multiplied +; CX = 16 bit number to be multiplied. (Must be even number) +; +;Output: BX:AX = output. +; CY set if overflow +; +;Psuedocode +;---------- +; +; Point at ControlC_Handler routine +; Set interrupt handler (INT 21h, AX=2523h) +; ret +;***************************************************************************** + +Public Multiply_32_Bits +Multiply_32_Bits proc ; ;AN000; + + push di ; ;AN000; + push si ; ;AN000; + xor di,di ;Init result to zero + xor si,si ; + cmp cx,0 ;Multiply by 0? ;AN000; +; $IF NE ;Keep going if not ;AN000; + JE $$IF75 +; $DO ;This works by adding the result;AN000; +$$DO76: + test cx,1 ;Need to add in sum of this bit?;AN000; +; $IF NZ ;Yes ;AN000; + JZ $$IF77 + add si,ax ;Add in the total so far for ;AN000; + adc di,bx ; this bit multiplier (CY oflow);AN000; +; $ELSE ;Don't split multiplier ;AN000; + JMP SHORT $$EN77 +$$IF77: + clc ;Force non exit ;AN000; +; $ENDIF ; ;AN000; +$$EN77: +; $LEAVE C ;Leave on overflow ;AN000; + JC $$EN76 + shr cx,1 ;See if need to multiply value ;AN000; + cmp cx,0 ;by 2 ;AN000; +; $LEAVE E ;Done if cx shifted down to zero;AN000; + JE $$EN76 + add ax,ax ;Each time cx is shifted, add ;AN000; + adc bx,bx ;value to itself (Multiply * 2) ;AN000; +; $ENDDO C ;CY set on overflow ;AN000; + JNC $$DO76 +$$EN76: +; $IF NC ;If no overflow, add in DI:SI ;AN000; + JC $$IF83 + mov ax,si ; which contains the original ;AN000; + mov bx,di ; value if odd, 0 if even. This ;AN000; + clc ;Set no overflow flag ;AN000; +; $ENDIF ; ;AN000; +$$IF83: +; $ELSE ; + JMP SHORT $$EN75 +$$IF75: + xor ax,ax ; + xor bx,bx ; +; $ENDIF ;Multiply by 0 ;AN000; +$$EN75: + pop si ; ;AN000; + pop di ; ;AN000; + ret ; ;AN000; + +Multiply_32_Bits endp + + +;========================================================================= +; Divide_32_Bits - This routine will perform 32bit division +; +; Inputs : SI:DI - value to be divided +; CX - divisor +; +; Outputs : SI:DI - result +; CX - remainder +;========================================================================= + +Procedure Divide_32_Bits ;an000; dms; + + push ax ;an000; dms;save regs + push bx ;an000; dms; + push dx ;an000; dms; + + xor dx,dx ;an000; dms;clear dx + mov ax,si ;an000; dms;get high word + div cx ;an000; dms;get high word result + mov si,ax ;an000; dms;save high word result + + mov ax,di ;an000; dms;get low word + div cx ;an000; dms;get low word result + mov di,ax ;an000; dms;save low word result + mov cx,dx ;an000; dms;pick up remainder + + pop dx ;an000; dms;restore regs + pop bx ;an000; dms; + pop ax ;an000; dms; + + ret ;an000; dms; + +Divide_32_Bits endp ;an000; dms; + + + + +;========================================================================= +; FAT_INIT: This routine initializes the FAT based on the +; number of paragraphs. +; +; +; input - fatspace +; fatspace+2 +; paras_per_fat +; fat_init_value +; output - fat space is initialized +; +;========================================================================= +Public Fat_Init +Fat_Init proc near + + push es + push di + push ax + push bx + push cx + mov di, word ptr FatSpace+2 ;Get segment of Fat space ;AC000; + mov es,di ; ;AN000; + mov di, word ptr FatSpace ; ;AN000; + mov bx,Paras_Per_Fat ;an000;get number of paras + mov ax,fat_init_value ;an000; + push dx ;an000;save bx + mov dx,es ;an000;grab es into dx +; $do +$$DO87: + cmp bx,0 ;an000;do while bx not = 0 +; $leave e ;an000;exit if 0 + JE $$EN87 + mov cx,10h ;an000;word move of paragraph + rep stosb ;an000;move the data to FAT + xor di,di ;an000;offset always init to 0 + inc dx ;an000;next paragraph + mov es,dx ;an000;put next para in es + dec bx ;an000;loop iteration counter +; $enddo ;an000; + JMP SHORT $$DO87 +$$EN87: + pop dx ;an000; + pop cx ;an000; + pop bx ;an000; + pop ax ;an000; + pop di ;an000; + pop es ;an000; + + ret ;an000; + +Fat_Init endp ;an000; + + +;========================================================================= +; Ctrl_Break_Write : This routine takes the control break request +; an returns. In essence, it disables the CTRL-BREAK. +; This routine is used during the writing of the +; FAT, DIR, and SYSTEM. +;========================================================================= + +Ctrl_Break_Write: ;ac010; dms; + + iret ;ac010; dms;return to caller + + +;========================================================================= +; Ctrl_Break_Save : This routine gets the current vector of +; INT 23h and saves it in CTRL_BREAK_VECTOR. +; +; Inputs : none +; +; Outputs : CTRL_BREAK_VECTOR - holds address of INT 23h routine +;========================================================================= + +Ctrl_Break_Save proc near ;ac010; dms; + + push es ;ac010; dms;save es + push bx ;ac010; dms;save bx + push ax ;ac010; dms;save ax + + mov ax,3523h ;ac010; dms;get CTRL-BREAK + ; interrupt vector + int 21h ;ac010; dms; + + mov word ptr Ctrl_Break_Vector,bx ;ac010; dms;get vector offset + mov word ptr Ctrl_Break_Vector+2,es ;ac010; dms;get vector segment + + pop ax ;ac010; dms;restore ax + pop bx ;ac010; dms;restore bx + pop es ;ac010; dms;restore es + + ret ;ac010; dms; + + +Ctrl_Break_Save endp ;ac010; dms; + + +;========================================================================= +; Set_Ctrl_Break : This routine sets the CTRL-Break vector to one +; defined by the user. +; +; Inputs : none +; +; Outputs : CTRL_BREAK_VECTOR - holds address of INT 23h routine +;========================================================================= + +Set_Ctrl_Break proc near ;ac010; dms; + + push ds ;ac010; dms;save ds + push ax ;ac010; dms;save ax + push bx ;ac010; dms;save bx + push dx ;ac010; dms;save dx + + push cs ;ac010; dms;swap cs with ds + pop ds ;an000; dms;point to code seg + + mov dx,offset Ctrl_Break_Write ;ac010; dms;get interrupt vec. + mov ax,2523h ;ac010; dms;set CTRL-BREAK + ; interrupt vector + int 21h ;ac010; dms; + + pop dx ;ac010; dms;restore dx + pop bx ;ac010; dms;restore bx + pop ax ;ac010; dms;restore ax + pop ds ;ac010; dms;restore ds + + ret ;ac010; dms; + + +Set_Ctrl_Break endp ;ac010; dms; + + +;========================================================================= +; Reset_Ctrl_Break : This routine resets the CTRL-Break vector to that +; originally defined. +; +; Inputs : CTRL_BREAK_VECTOR - holds address of INT 23h routine +; +; Outputs : none +;========================================================================= + +Reset_Ctrl_Break proc near ;ac010; dms; + + push ds ;ac010; dms;save ds + push ax ;ac010; dms;save ax + push bx ;ac010; dms;save bx + push dx ;ac010; dms;save ds + + mov ax,word ptr Ctrl_Break_Vector+2 ;ac010; dms;get seg. of vector + mov bx,word ptr Ctrl_Break_Vector ;ac010; dms;get off. of vector + mov ds,ax ;ac010; dms;get seg. + mov dx,bx ;ac010; dms;get off. + mov ax,2523h ;ac010; dms;set CTRL-BREAK + ; interrupt vector + int 21h ;ac010; dms; + + pop dx ;ac010; dms;restore dx + pop bx ;ac010; dms;restore bx + pop ax ;ac010; dms;restore ax + pop ds ;ac010; dms;restore ds + + ret ;ac010; dms; + + +Reset_Ctrl_Break endp ;ac010; dms; + +;========================================================================= +; Get_Command_Path : This routine finds the path where +; COMMAND.COM resides based on the +; environmental vector. Once the +; path is found it is copied to +; CommandFile. +; +; Inputs : Exec_Block.Segment_Env - Segment of environmental vector +; Comspec_ID - "COMSPEC=" +; +; Outputs : CommandFile - Holds path to COMMAND.COM +;========================================================================= + +Procedure Get_Command_Path ;an011; dms; + + push ds ;an011; dms;save ds + push es ;an011; dms;save es + + Set_Data_Segment ;an011; dms; DS,ES = Data + call Get_PSP_Parms ;an011; dms; gets PSP info. + cld ;an011; dms; clear direction + mov ax,es:Environ_Segment ;an011; dms; get seg. of + ; environ. vector + mov ds,ax ;an011; dms; put it in DS + assume ds:nothing ;an011; dms; + xor si,si ;an011; dms; clear si + mov bx,si ;an011; dms; save si + mov di,offset Comspec_ID ;an011; dms; point to target + mov cx,127 ;an011; dms; loop 127 times +; $do ;an011; dms; while cx not 0 +$$DO90: + ; and target not found + cmp cx,00h ;an011; dms; end of env.? +; $leave e ;an011; dms; yes + JE $$EN90 + + push cx ;an011; dms; save cx + mov cx,0008h ;an011; dms; loop 8 times + repe cmpsb ;an011; dms; "COMSPEC=" ? + pop cx ;an011; dms; restore cx +; $if z ;an011; dms; yes + JNZ $$IF92 + push di ;an011; dms; save di + mov di,offset es:CommandFile ;an011; dms + lodsb ;an011; dms; priming read + mov dl,al ;an011; dms; prepare for capitalization + call Cap_Char ;an011; dms; capitalize character in DL + cmp dl,es:CommandFile ;an011; dms;COMSPEC same as default drive? +; $if e ;an000; dms; yes + JNE $$IF93 +; $do ;an011; dms; while AL not = 0 +$$DO94: + cmp al,00h ;an011; dms; at end? +; $leave e ;an011; dms; yes + JE $$EN94 + stosb ;an011; dms; save it + lodsb ;an011; dms; get character +; $enddo + JMP SHORT $$DO94 +$$EN94: +; $endif ;an011; dms; +$$IF93: + pop di ;an011; dms; restore di + mov cx,0ffffh ;an011; dms; flag target found +; $endif ;an011; dms; +$$IF92: + + cmp cx,0ffffh ;an011; dms; target found? +; $leave e ;an011; dms; yes + JE $$EN90 + + mov di,offset Comspec_ID ;an011; dms; point to target + mov si,bx ;an011; dms; restore si + inc si ;an011; dms; point to next byte + mov bx,si ;an011; dms; save si + + dec cx ;an011; dms; decrease counter +; $enddo ;an011; dms; + JMP SHORT $$DO90 +$$EN90: + + pop es ;an011; dms; restore es + pop ds ;an011; dms; restore ds + + ret ;an011; dms; + +Get_Command_Path endp ;an011; dms; + + +; +;**************************************************************************** +; Get_PSP_Parms +;**************************************************************************** +; +; +; +; + +Procedure Get_PSP_Parms ; ;AC000; + + Set_Data_Segment + mov ax,PSP_Segment ;Get segment of PSP ;AN000; + mov ds,ax ; " " " " ;AN000; + ; ; + assume ds:nothing + ;Setup segment of Environment string, get from PSP ; ; + + mov ax,ds:PSP_Environ ; ; ; + mov es:Environ_Segment,ax ; ; ; + Set_Data_Segment + ret ; ; ; + + +Get_PSP_Parms endp ; ;AN000; + + +;========================================================================= +; Command_Root : This routine sets up CommandFile so that the +; COMMAND.COM will be written to the root. +; It does this by copying at offset 3 of CommandFile +; the literal COMMAND.COM. This effectively +; overrides the original path, but maintains the +; drive letter that is to be written to. +; +; Inputs : CommandFile - Holds full path to default COMMAND.COM +; Outputs : CommandFile - Holds modified path to new COMMAND.COM +; on target drive. +;========================================================================= + +Procedure Command_Root ;an011; dms; + + push ds ;an011; dms; save ds + push es ;an011; dms; save es + push di ;an011; dms; save di + push si ;an011; dms; save si + push cx ;an011; dms; save cx + Set_Data_Segment ;an011; + + mov di,offset CommandFile+3 ;an011; dms; point to path + ; past drive spec + mov si,offset Command_Com ;an011; dms; holds the literal + ; COMMAND.COM + mov cx,000ch ;an011; dms; len. of literal + rep movsb ;an011; dms; move it + + pop cx ;an011; dms; restore cx + pop si ;an011; dms; restore si + pop di ;an011; dms; restore di + pop es ;an011; dms; restore es + pop ds ;an011; dms; restore ds + + ret ;an011; dms; + +Command_Root endp ;an011; dms; + + +;========================================================================= +; Set_BPB_Info : When we have a FAT count of 0, we must calculate +; certain parts of the BPB. The following code +; will do just that. +; +; Inputs : DeviceParameters +; +; Outputs : BPB information +;========================================================================= + +Procedure Set_BPB_Info ;an012; dms;calc new BPB + + Set_Data_Segment ;an012; dms;set up addressibility + cmp DeviceParameters.DP_BPB.BPB_NumberOfFats,00h ;an012; dms;see if we have 0 FATS specified +; $if e ;an012; dms;yes, 0 FATS specified + JNE $$IF101 + call Scan_Disk_Table ;an012; dms;access disk table + mov bl,byte ptr ds:[si+8] ;an012; dms;get FAT type + mov cx,word ptr ds:[si+4] ;an012; dms;get sectors/cluster + mov dx,word ptr ds:[si+6] ;an012; dms;number of entries for the root DIR + + mov DeviceParameters.DP_BPB.BPB_RootEntries,dx ;an012; dms;save root entries + mov DeviceParameters.DP_BPB.BPB_SectorsPerCluster,ch ;an012; dms;save sectors/cluster + mov DeviceParameters.DP_BPB.BPB_BytesPerSector,0200h ;an012; dms;save bytes/sector + mov DeviceParameters.DP_BPB.BPB_ReservedSectors,0001h ;an012; dms;save reserved sectors + mov DeviceParameters.DP_BPB.BPB_NumberOfFats,02h ;an012; dms;FAT count + + cmp bl,FBIG ;an012; dms;Big FAT? +; $if e ;an012; dms;yes + JNE $$IF102 + call Calc_Big_FAT ;an012; dms;calc big FAT info +; $else ;an012; dms; + JMP SHORT $$EN102 +$$IF102: + call Calc_Small_FAT ;an012; dms;calc small FAT info +; $endif ;an012; dms; +$$EN102: +; $endif ;an012; dms; +$$IF101: + + ret ;an012; dms; + +Set_BPB_Info endp ;an012; dms; + + + +;========================================================================= +; Scan_Disk_Table : Scans the table containing information on +; the disk's attributes. When it finds the +; applicable data, it returns a pointer in +; DS:SI for reference by the calling proc. +; +; Inputs : DiskTable - Contains data about disk types +; +; Outputs : DS:SI - Points to applicable disk data +;========================================================================= + +Procedure Scan_Disk_Table ;an012; dms; + + cmp DeviceParameters.DP_BPB.BPB_TotalSectors,00h ;an012; dms;small disk? +; $if ne ;an012; dms;yes + JE $$IF106 + mov dx,00h ;an012; dms;set high to 0 + mov ax,word ptr DeviceParameters.DP_BPB.BPB_TotalSectors ;an012; dms;get sector count +; $else ;an012; dms; + JMP SHORT $$EN106 +$$IF106: + mov dx,word ptr DeviceParameters.DP_BPB.BPB_BigTotalSectors[+2] ;an012; dms;get high count + mov ax,word ptr DeviceParameters.DP_BPB.BPB_BigTotalSectors[+0] ;an012; dms;get low count +; $endif ;an012; dms; +$$EN106: + + mov si,offset DiskTable ;an012; dms;point to disk data +Scan: + + cmp dx,word ptr ds:[si] ;an012; dms;below? + jb Scan_Disk_Table_Exit ;an012; dms;yes, exit + ja Scan_Next ;an012; dms;no, continue + cmp ax,word ptr ds:[si+2] ;an012; dms;below or equal? + jbe Scan_Disk_Table_Exit ;an012; dms;yes, exit + +Scan_Next: + + add si,5*2 ;an012; dms;adjust pointer + jmp Scan ;an012; dms;continue scan + +Scan_Disk_Table_Exit: + + ret ;an012; dms; + +Scan_Disk_Table endp ;an012; dms; + + + +;========================================================================= +; Calc_Big_FAT : Calculates the sectors per FAT for a 16 bit FAT. +; +; Inputs : DeviceParameters.DP_BPB.BPB_BigTotalSectors or +; DeviceParameters.DP_BPB.BPB_TotalSectors +; +; Outputs : DeviceParameters.DP_BPB.BPB_SectorsPerFat +;========================================================================= + +Procedure Calc_Big_FAT ;an012; dms; + + cmp DeviceParameters.DP_BPB.BPB_TotalSectors,00h ;an012; dms;small disk? +; $if ne ;an012; dms;yes + JE $$IF109 + mov dx,00h ;an012; dms;set high to 0 + mov ax,word ptr DeviceParameters.DP_BPB.BPB_TotalSectors ;an012; dms;get sector count +; $else ;an012; dms; + JMP SHORT $$EN109 +$$IF109: + mov dx,word ptr DeviceParameters.DP_BPB.BPB_BigTotalSectors[+2] ;an012; dms;get high count + mov ax,word ptr DeviceParameters.DP_BPB.BPB_BigTotalSectors[+0] ;an012; dms;get low count +; $endif ;an012; dms; +$$EN109: + + mov cl,04h ;an012; dms;16 DIR entries per sector + push dx ;an012; dms;save total sectors (high) + mov dx,DeviceParameters.DP_BPB.BPB_RootEntries ;an012; dms;get root entry count + shr dx,cl ;an012; dms;divide by 16 + sub ax,dx ;an012; dms; + pop dx ;an012; dms;restore dx + sbb dx,0 ;an012; dms; + sub ax,1 ;an012; dms;AX = T - R - D + sbb dx,0 ;an012; dms; + mov bl,02h ;an012; dms; + mov bh,DeviceParameters.DP_BPB.BPB_SectorsPerCluster ;an012; dms;get sectors per cluster + add ax,bx ;an012; dms;AX = T-R-D+256*SPC+2 + adc dx,0 ;an012; dms; + sub ax,1 ;an012; dms;AX = T-R-D+256*SPC+1 + sbb dx,0 ;an012; dms; + div bx ;an012; dms; sec/FAT = CEIL((TOTAL-DIR-RES)/ + ; (256*SECPERCLUS+2) + mov word ptr DeviceParameters.DP_BPB.BPB_SectorsPerFAT,ax ;an012; dms;Sectors/cluster + ret ;an012; dms; + +Calc_Big_FAT endp ;an012; dms; + + +;========================================================================= +; Calc_Small_FAT: Calculates the sectors per FAT for a 12 bit FAT. +; +; Inputs : DeviceParameters.DP_BPB.BPB_BigTotalSectors or +; DeviceParameters.DP_BPB.BPB_TotalSectors +; +; Outputs : DeviceParameters.DP_BPB.BPB_SectorsPerFat +;========================================================================= + +Procedure Calc_Small_FAT ;an012; dms; + + cmp DeviceParameters.DP_BPB.BPB_TotalSectors,00h ;an012; dms;small disk? +; $if ne ;an012; dms;yes + JE $$IF112 + mov dx,00h ;an012; dms;set high to 0 + mov ax,word ptr DeviceParameters.DP_BPB.BPB_TotalSectors ;an012; dms;get sector count +; $else ;an012; dms; + JMP SHORT $$EN112 +$$IF112: + mov dx,word ptr DeviceParameters.DP_BPB.BPB_BigTotalSectors[+2] ;an012; dms;get high count + mov ax,word ptr DeviceParameters.DP_BPB.BPB_BigTotalSectors[+0] ;an012; dms;get low count +; $endif ;an012; dms; +$$EN112: + + xor bx,bx ;an012; dms;clear bx + mov bl,DeviceParameters.DP_BPB.BPB_SectorsPerCluster ;an012; dms;get sectors/cluster + div bx ;an012; dms; +; now multiply by 3/2 + mov bx,3 ;an012; dms; + mul bx ;an012; dms;div by log 2 of sectors/cluster + mov bx,2 ;an012; dms; + div bx ;an012; dms; + xor dx,dx ;an012; dms; +; now divide by 512 + mov bx,512 ;an012; dms; + div bx ;an012; dms; + inc ax ;an012; dms; +; dx:ax contains number of FAT sectors necessary + mov DeviceParameters.DP_BPB.BPB_SectorsPerFAT,ax ;an012; dms;save sectors/FAT + ret ;an012; dms; + +Calc_Small_FAT endp ;an012; dms; + +;========================================================================= +; Get_Bad_Sector_Hard : Determine the bad sector. +; +; Inputs : Head of failing track +; Cylinder of failing track +; Relative_Sector_Low - 1st. sector in track +; Relative_Sector_High +; +; Cluster_Boundary_Adj_Factor - The number of sectors +; that are to be read +; at one time. +; Cluster_Boundary_SPT_Count - Used by Calc_Cluster_Boundary +; to track how many sectors +; have been read. +; Cluster_Boundary_Flag - True (Use cluster buffer) +; - False (Use internal buffer) +; Cluster_Boundary_Buffer_Seg - Segment of buffer +; +; Outputs : Marked cluster as bad +;========================================================================= + +Procedure Get_Bad_Sector_Hard ;an000; dms; + + push cx ;an000; dms;save cx + mov cx,0001h ;an000; dms;set counter to start at 1 + mov Cluster_Boundary_SPT_Count,00h ;an000; dms;clear sector counter + mov Cluster_Boundary_Adj_Factor,01h ;an000; dms;default value +; $do ;an000; dms;while sectors left +$$DO115: + cmp cx,DeviceParameters.DP_BPB.BPB_SectorsPerTrack ;an000; dms;at end? +; $leave a ;an000; dms;yes,exit + JA $$EN115 + push cx ;an000; dms;save cx + + cmp Cluster_Boundary_Flag,True ;an000; dms;full buffer there? +; $if e ;an000; dms;yes + JNE $$IF117 + call Calc_Cluster_Boundary ;an000; dms;see if on boundary + mov ax,Cluster_Boundary_Buffer_Seg + mov word ptr RWPacket.TRWP_TransferAddress[0],0 ;an000; dms;point to transfer area + mov word ptr RWPacket.TRWP_TransferAddress[2],ax ;an000; dms; +; $else ;an000; dms;default to internal buffer + JMP SHORT $$EN117 +$$IF117: + mov word ptr RWPacket.TRWP_TransferAddress[0],offset RW_TRF_Area ;an000; dms;point to transfer area + mov word ptr RWPacket.TRWP_TransferAddress[2],DS ;an000; dms; +; $endif ;an000; dms; +$$EN117: + + call Verify_Structure_Set_Up ;an019; dms; set up verify vars + + mov ax,(IOCTL shl 8) or GENERIC_IOCTL ;an000; dms; + xor bx,bx ;an000; dms;clear bx + mov bl,drive ;an000; dms;get drive + inc bl ;an000; dms;adjust it + mov cx,(IOC_DC shl 8) or READ_TRACK ;an000; dms;read track + lea dx,RWPacket ;an000; dms;point to parms + int 21h ;an000; dms; + + pop cx ;an000; dms;restore cx + + push cx ;an000; dms;save cx + +; $if c ;an000; dms;an error occurred + JNC $$IF120 + call Calc_Cluster_Position ;an000; dms;determine which cluster + call BadClus ;an000; dms;mark the cluster as bad +; $endif ;an000; dms; +$$IF120: + + pop cx ;an000; dms;restore cx + + add cx,Cluster_Boundary_Adj_Factor ;an000; dms;adjust loop counter + mov ax,Cluster_Boundary_Adj_Factor ;an000; dms;get adjustment factor + xor dx,dx ;an000; dms;clear dx + add ax,Relative_Sector_Low ;an000; dms;add in low word + adc dx,Relative_Sector_High ;an000; dms;pick up carry in high word + mov Relative_Sector_Low,ax ;an000; dms;save low word + mov Relative_Sector_High,dx ;an000; dms;save high word + + +; $enddo ;an000; dms; + JMP SHORT $$DO115 +$$EN115: + + pop cx ;an000; dms;restore cx + + ret ;an000; dms; + +Get_Bad_Sector_Hard endp ;an000; dms; + + +;========================================================================= +; Verify_Structure_Set_Up : Set up the fields for the Read IOCTL +; to verify the sectors in a failing +; track. Also, it displays the +; message notifying the user of the +; sectors it is verifying. +;========================================================================= + +Procedure Verify_Structure_Set_Up ;an019; dms;set up verify structure + + mov RWPacket.TRWP_SpecialFunctions,00h ;an000; dms;reset special functions + + mov ax,FormatPacket.FP_Head ;an000; dms;get current head + mov RWPacket.TRWP_Head,ax ;an000; dms;get current head + + mov ax,FormatPacket.FP_Cylinder ;an000; dms;get current cylinder + mov RWPacket.TRWP_Cylinder,ax ;an000; dms;get current cylinder + + dec cx ;an000; dms;make sector 0 based + mov RWPacket.TRWP_FirstSector,cx ;an000; dms;get sector to read + + mov ax,Cluster_Boundary_Adj_Factor ;an000; dms;get # of sectors to read + mov RWPacket.TRWP_SectorsToReadWrite,ax ;an000; dms;read only # sector(s) + + call Calc_Cluster_Position ;an019; dms;determine cluster number + mov word ptr Msg_Allocation_Unit_Val[+2],dx ;an019; dms;save high word of cluster + mov word ptr Msg_Allocation_Unit_Val[+0],ax ;an019; dms;save low word of cluster + message MsgVerify + + ret + +Verify_Structure_Set_Up endp ;an019; dms; + + +;========================================================================= +; Get_Bad_Sector_Floppy : This routine marks an entire track as bad +; since it is a floppy disk. +; +; Inputs : Relative_Sector_Low - first sector +; +; Outputs : FAT marked with bad sectors +;========================================================================= + +Procedure Get_Bad_Sector_Floppy ;an000; dms; + + push bx ;an000; dms;save regs + push cx ;an000; dms; + + mov cx,DeviceParameters.DP_BPB.BPB_SectorsPerTrack ;an000; dms;get sectors/track +; $do ;an000; dms;while sectors left +$$DO123: + cmp cx,00 ;an000; dms;at end +; $leave e ;an000; dms;yes + JE $$EN123 + push bx ;an000; dms;save bx we destroy it + push cx ;an000; dms;save cx we destroy it + call Calc_Cluster_Position ;an000; dms;get cluster position + call BadClus ;an000; dms;mark it as bad + pop cx ;an000; dms;restore regs + pop bx ;an000; dms; + dec cx ;an000; dms;decrease loop counter + inc Relative_Sector_Low ;an000; dms;next sector +; $enddo ;an000; dms; + JMP SHORT $$DO123 +$$EN123: + + pop cx ;an000; dms;restore regs + pop bx ;an000; dms; + + ret ;an000; dms; + +Get_Bad_Sector_Floppy endp ;an000; dms; + + +;========================================================================= +; Calc_Cluster_Position : This routine calculates which cluster the +; failing sector falls in. +; +; Inputs : Relative_Sector_High - high word of sector position +; Relative_Sector_Low - low word of sector position +; +; Outputs : DX:AX - Cluster position +;========================================================================= +Procedure Calc_Cluster_Position ;an000; dms; + + push cx ;an000; dms;save regs + push di ;an000; dms; + push si ;an000; dms; + + xor dx,dx ;an000; dms;clear high word + mov dx,word ptr Relative_Sector_High ;an000; dms;get the high sector word + mov ax,word ptr Relative_Sector_Low ;an000; dms;get the low sector word + sub ax,StartSector ;an000; dms;get relative sector # + sbb dx,0 ;an000; dms;pick up borrow + + mov si,dx ;an000; dms;get high word + mov di,ax ;an000; dms;get low word + xor cx,cx ;an000; dms;clear cx + mov cl,DeviceParameters.DP_BPB.BPB_SectorsPerCluster ;an000; dms;get sectors/cluster + call Divide_32_Bits ;an000; dms;32 bit division + + mov dx,si ;an000; dms;get high word of result + mov ax,di ;an000; dms;get low word of result + add ax,2 ;an000; dms;adjust for cluster bias + adc dx,0 ;an000; dms;pick up carry + + pop si ;an000; dms;restore regs + pop di ;an000; dms; + pop cx ;an000; dms; + + ret ;an000 ;dms; + +Calc_Cluster_Position endp ;an000; dms; + + +;========================================================================= +; Cap_Char : This routine will capitalize the character passed in +; DL. +; +; Inputs : DL - Character to be capitalized +; +; Outputs : DL - Capitalized character +;========================================================================= + +Procedure Cap_Char ;an011; dms; + + push ax ;an011; dms;save ax + mov ax,6520h ;an011; dms;capitalize character + int 21h ;an011; dms; + pop ax ;an011; dms;restore ax + ret ;an011; dms; + +Cap_Char endp ;an011; dms; + +;========================================================================= +; Set_Disk_Access_On_Off: This routine will either turn access on or off +; to a disk depending on the contents of the +; buffer passed in DX. +; +; Inputs : DX - pointer to buffer +; +;========================================================================= + +Procedure Set_Disk_Access_On_Off ;an014; dms; + + push ax ;an014; dms;save regs + push bx ;an014; dms; + push cx ;an014; dms; + push dx ;an014; dms; + + xor bx,bx ;an014; dms;clear bx + mov bl,Drive ;an014; dms;get driver number + inc bl ;an014; dms;make it 1 based + call IsRemovable ;an014; dms;see if removable media +; $if c ;an014; dms;not removable + JNC $$IF126 + mov ax,(IOCTL shl 8) or Generic_IOCTL ;an014; dms;generic ioctl + xor bx,bx ;an014; dms;clear bx + mov bl,Drive ;an014; dms;get drive letter + inc bl ;an014; dms;make it 1 based + mov cx,(RAWIO shl 8) or Set_Access_Flag ;an014; dms;allow access to disk + int 21h ;an014; dms; +; $endif ;an014; dms; +$$IF126: + + pop dx ;an014; dms;restore regs + pop cx ;an014; dms; + pop bx ;an014; dms; + pop ax ;an014; dms; + + ret ;an014; dms; + +Set_Disk_Access_On_Off endp ;an014; dms; + + +;========================================================================= +; Get_Disk_Access : This routine will determine the access state of +; the disk. +; +; Inputs : DX - pointer to buffer +; Outputs : Disk_Access.DAC_Access_Flag - 0ffh signals access allowed +; to the disk previously. +; +;========================================================================= + +Procedure Get_Disk_Access ;an014; dms; + + push ax ;an014; dms;save regs + push bx ;an014; dms; + push cx ;an014; dms; + push dx ;an014; dms; + + xor bx,bx ;an014; dms;clear bx + mov bl,Drive ;an014; dms;get driver number + inc bl ;an014; dms;make it 1 based + call IsRemovable ;an014; dms;see if removable media +; $if c ;an014; dms;not removable + JNC $$IF128 + mov ax,(IOCTL shl 8) or Generic_IOCTL ;an014; dms;generic ioctl + xor bx,bx ;an014; dms;clear bx + mov bl,Drive ;an014; dms;get drive letter + inc bl ;an014; dms;make it 1 based + mov cx,(RAWIO shl 8) or Get_Access_Flag ;an014; dms;determine disk access + lea dx,Disk_Access ;an014; dms;point to parm list + int 21h ;an014; dms; + cmp Disk_Access.DAC_Access_Flag,01h ;an014; dms;access is currently allowed? +; $if e ;an014; dms;yes + JNE $$IF129 + mov Disk_Access.DAC_Access_Flag,0ffh ;an014; dms;signal access is currently allowed +; $endif ;an014; dms; +$$IF129: +; $endif ;an014; dms; +$$IF128: + + pop dx ;an014; dms;restore regs + pop cx ;an014; dms; + pop bx ;an014; dms; + pop ax ;an014; dms; + + ret ;an014; dms; + +Get_Disk_Access endp ;an014; dms; + +;========================================================================= +; Calc_Cluster_Boundary : This routine will determine where, within a +; cluster, a sector resides. +; +; Inputs : Relative_Sector_Low - Sector +; Relative_Sector_High +; +; Outputs : Cluster_Boundary_Adj_Factor - The number of sectors +; remaining in the cluster. +; Cluster_Boundary_SPT_Count - The count of sectors +; having been accessed for +; a track. +;========================================================================= + +Procedure Calc_Cluster_Boundary ;an000; dms; + + push ax ;an000; dms;save regs + push bx ;an000; dms; + push cx ;an000; dms; + push dx ;an000; dms; + push si ;an000; dms; + push di ;an000; dms; + + xor dx,dx ;an000; dms;clear high word + mov dx,word ptr Relative_Sector_High ;an000; dms;get the high sector word + mov ax,word ptr Relative_Sector_Low ;an000; dms;get the low sector word + sub ax,StartSector ;an000; dms;get relative sector # + sbb dx,0 ;an000; dms;pick up borrow + + mov si,dx ;an000; dms;get high word + mov di,ax ;an000; dms;get low word + xor cx,cx ;an000; dms;clear cx + mov cl,DeviceParameters.DP_BPB.BPB_SectorsPerCluster ;an000; dms;get sectors/cluster + call Divide_32_Bits ;an000; dms;32 bit division + + or cx,cx ;an000; dms;see if remainder exists +; $if nz ;an000; dms;remainder exists + JZ $$IF132 + xor bx,bx ;an021; dms; + mov bl,DeviceParameters.DP_BPB.BPB_SectorsPerCluster ;an021; dms;get sectors/cluster + sub bx,cx ;an021; dms;get number of sectors to read + mov Cluster_Boundary_Adj_Factor,bx ;ac021; dms;remainder = sector count +; $else ;an000; dms;no remainder + JMP SHORT $$EN132 +$$IF132: + xor bx,bx ;an000; dms;clear bx + mov bl,DeviceParameters.DP_BPB.BPB_SectorsPerCluster ;an000; dms;get sectors/cluster + mov Cluster_Boundary_Adj_Factor,bx ;an000; dms;get sectors/cluster +; $endif ;an000; dms; +$$EN132: + + mov ax,Cluster_Boundary_SPT_Count ;an000; dms;get current sector count + xor dx,dx ;an000; dms;clear high word + add ax,Cluster_Boundary_Adj_Factor ;an000; dms;get next sector count + cmp ax,DeviceParameters.DP_BPB.BPB_SectorsPerTrack ;an000; dms;exceeded sectors/track? +; $if a ;an000; dms;yes + JNA $$IF135 + mov ax,DeviceParameters.DP_BPB.BPB_SectorsPerTrack ;an000; dms;only use difference + sub ax,Cluster_Boundary_SPT_Count ;an000; dms;get next sector count + mov Cluster_Boundary_Adj_Factor,ax ;an000; dms; +; $endif ;an000; dms; +$$IF135: + + mov ax,Cluster_Boundary_SPT_Count ;an000; dms;get sector count + xor dx,dx ;an000; dms;clear high word + add ax,Cluster_Boundary_Adj_Factor ;an000; dms;get new sector count + mov Cluster_Boundary_SPT_Count,ax ;an000; dms;save it + + pop di ;an000; dms;restore regs + pop si ;an000; dms; + pop dx ;an000; dms;restore regs + pop cx ;an000; dms; + pop bx ;an000; dms; + pop ax ;an000; dms; + + ret ;an000; dms; + +Calc_Cluster_Boundary endp ;an000; dms; + +;========================================================================= +; Cluster_Buffer_Allocate : This routine will allocate a buffer +; based on a cluster's size. If enough +; space does not exist, a cluster will +; be redefined to a smaller size for +; purposes of sector retries. +; +; Inputs : DeviceParameters.DP_BPB.BPB_BytesPerSector +; DeviceParameters.DP_BPB.BPB_SectorsPerCluster +; +; Outputs : Cluster_Boundary_Flag - True (space available) +; False(not enough space) +; Cluster_Boundary_Buffer_Seg - Pointer to buffer +;========================================================================= + +Procedure Cluster_Buffer_Allocate ;an000; dms; + + push ax ;an000; dms;save regs + push bx ;an000; dms; + push cx ;an000; dms; + push dx ;an000; dms; + + mov ax,(Alloc shl 8) ;an000; dms;allocate memory + mov bx,0ffffh ;an000; dms;get available memory + int 21h ;an000; dms; + + mov ax,DeviceParameters.DP_BPB.BPB_BytesPerSector ;an000; dms;get bytes/sector + xor dx,dx ;an000; dms;clear high word + xor cx,cx ;an000; dms;clear cx + mov cl,DeviceParameters.DP_BPB.BPB_SectorsPerCluster ;an000; dms;get sector count + mul cx ;an000; dms;get total byte count + mov cl,4 ;an000; dms;set up shift count + shr ax,cl ;an000; dms;divide by 16 + inc ax ;an000; dms;round up + + cmp bx,ax ;an000; dms;enough room +; $if a ;an000; dms;yes + JNA $$IF137 + mov bx,ax ;an000; dms;allocate needed memory + mov ax,(Alloc shl 8) ;an000; dms; + int 21h ;an000; dms; + mov Cluster_Boundary_Buffer_Seg,ax ;an000; dms;save pointer to buffer + mov Cluster_Boundary_Flag,True ;an000; dms;signal space available +; $else ;an000; dms;not enough room + JMP SHORT $$EN137 +$$IF137: + mov Cluster_Boundary_Flag,False ;an000; dms;signal not enough space +; $endif ;an000; dms; +$$EN137: + + pop dx ;an000; dms;restore regs + pop cx ;an000; dms; + pop bx ;an000; dms; + pop ax ;an000; dms; + + ret ;an000; dms; + +Cluster_Buffer_Allocate endp ;an000; dms; + + +;========================================================================= +; Set_CDS_Off - This routine disallows access to a +; disk if a format fails on a non-FAT +; formatted disk. +; +;========================================================================= + +Procedure Set_CDS_Off ;an000; dms; + + push ax ;an000; dms;save regs + push dx ;an000; dms; + + mov ax,5f08h ;an000; dms;reset CDS + mov dl,Drive ;an000; dms;drive to reset + int 21h ;an000; dms; + + pop dx ;an000; dms;restore regs + pop ax ;an000; dms; + + ret ;an000; dms; + +Set_CDS_Off endp ;an000; dms; + + +;========================================================================= +; Format_Access_Wrap_Up - This routine determines whether or +; not access should be allowed to the +; disk based on the exit status of +; format. +; +;========================================================================= + +Procedure Format_Access_Wrap_Up ;an000; dms; + + cmp Disk_Access.DAC_Access_Flag,0ffh ;an015; dms;access prev. allowed? +; $if ne ;an015; dms;no + JE $$IF140 + cmp ExitStatus,ExitOK ;an015; dms;good exit? +; $if ne ;an015; dms;no + JE $$IF141 + lea dx,Disk_Access ;an015; dms;point to parm block + mov Disk_Access.DAC_Access_Flag,00h ;an015; dms;signal no disk access + call Set_Disk_Access_On_Off ;an015; dms;don't allow disk access +; $else ;an015; dms;bad exit + JMP SHORT $$EN141 +$$IF141: + lea dx,Disk_Access ;an015; dms;point to parm block + mov Disk_Access.DAC_Access_Flag,01h ;an015; dms;signal disk access + call Set_Disk_Access_On_Off ;an015; dms;allow disk access +; $endif ;an015; dms; +$$EN141: +; $endif ;an015; dms; +$$IF140: + + cmp FAT_Flag,No ;an012; dms;non-FAT format? +; $if e ;an012; dms;yes + JNE $$IF145 + cmp ExitStatus,ExitOK ;an012; dms;good exit? +; $if ne ;an012; dms;no + JE $$IF146 + call Set_CDS_Off ;an012; dms;disallow FAT access +; $endif ;an012; dms; +$$IF146: +; $endif ;an012; dms; +$$IF145: + + ret ;an000; dms; + +Format_Access_Wrap_Up endp ;an000; dms; + +;========================================================================= +; BadClus_Address_Adjust - This routine adjusts the segment and +; offset to provide addressibility into +; the FAT table. +; +; Inputs : bx - high word to adjust segment for +; ax - low word to adjust segment for +; cx - segment to be adjusted +; +; Outputs : cx - new segment value +; ax - new offset value +;========================================================================= + +Procedure BadClus_Address_Adjust ;an000; dms; + + push bx ;an000; save regs + push dx ;an000; + push di ;an000; + push si ;an000; + + mov dx,cx ;an000; save segment value + mov si,bx ;an000; get high word for divide + mov di,ax ;an000; get low word for divide + xor cx,cx ;an000; clear cx + mov cl,Paragraph_Size ;an000; divide by 16 + call Divide_32_Bits ;an000; perform division + + add dx,di ;an000; adjust segment for result + mov ax,cx ;an000; pick up the remainder + mov cx,dx ;an000; pass back new segment + + pop si ;an000; restore regs + pop di ;an000; + pop dx ;an000; + pop bx ;an000; + + ret ;an000; dms; + +BadClus_Address_Adjust endp ;an000; dms; + + + +;========================================================================= +; NextTrack : This routine determines the next track to be +; formatted. +; +; Inputs : TracksLeft - # of tracks remaining +; Tracks_To_Format - # of tracks to format in 1 call +; FP_Head - disk head +; FP_Cylinder - disk cylinder +; +; Outputs : TracksLeft - # of tracks remaining +; FP_Head - disk head +; FP_Cylinder - disk cylinder +; CY - no tracks left to format +; NC - tracks left to format +;========================================================================= + +Procedure NextTrack ;an015; dms; + + + cmp TracksLeft,00 ;an015; dms;end of format? +; $if e ;an015; dms;yes + JNE $$IF149 + stc ;an015; dms;signal end of format + mov Format_End,True +; $else + JMP SHORT $$EN149 +$$IF149: + mov cx,Tracks_To_Format ;an015; dms;get max track count for call +; $do ;an015; dms;while tracks remain +$$DO151: + cmp TracksLeft,00 ;an015; dms;end of format? +; $leave e ;an015; dms;yes + JE $$EN151 + cmp cx,00 ;an015; dms;end of head/cyl. adjustment? +; $leave e ;an015; dms;yes + JE $$EN151 + inc FormatPacket.FP_Head ;an015; dms;next head + mov ax,FormatPacket.FP_Head ;an015; dms;get head for comp + cmp ax,DeviceParameters.DP_BPB.BPB_Heads ;an015; dms;exceeded head count? +; $if e ;an015; dms;yes + JNE $$IF154 + mov FormatPacket.FP_Head,00 ;an015; dms;reinit. head + inc FormatPacket.FP_Cylinder ;an015; dms;next cylinder +; $endif ;an015; dms; +$$IF154: + + dec cx ;an015; dms;decrease counter +; $enddo ;an015; dms; + JMP SHORT $$DO151 +$$EN151: + + clc ;an015; dms;clear CY +; $endif ;an015; dms; +$$EN149: + + ret ;an015; dms; + +NextTrack endp ;an015; dms; + +;========================================================================= +; Determine_Format_Type : This routine determines the type of format +; that is to occur based on the media type. +; +; Inputs : Dev_HardDisk - Media type (harddisk) +; Multi_Track_Format - EQU 02h +; Single_Track_Format - EQU 00h +; +; Outputs : FP_SpecialFunctions - Set appropriately for single +; or multi track format +;========================================================================= + +Procedure Determine_Format_Type ;an015; dms; + + cmp DeviceParameters.DP_DeviceType,Dev_HardDisk ;an015; dms;harddisk? +; $if e ;an015; dms;yes + JNE $$IF158 + mov FormatPacket.FP_SpecialFunctions,Multi_Track_Format ;an015; dms;set for multi track format +; $else ;an015; dms; + JMP SHORT $$EN158 +$$IF158: + mov FormatPacket.FP_SpecialFunctions,Single_Track_Format ;an015; dms;set for single track format +; $endif ;an015; dms; +$$EN158: + ret ;an015; dms; + +Determine_Format_Type endp ;an015; dms; + + +;========================================================================= +; FormatTrack : This routine performs multi track or single +; track formatting based on the state of the +; SpecialFunctions byte. +; +; Inputs : Tracks_To_Format - # of tracks to format in 1 call +; FormatPacket - Parms for IOCTL call +; +; Outputs : NC - formatted track(s) +; CY - error in format +; AX - extended error on CY +;========================================================================= + +Procedure FormatTrack ;an015; dms; + + mov ax,(IOCTL shl 8) or Generic_IOCTL ;an015; dms;Generic IOCTL + mov bl,drive ;an015; dms;get drive number + inc bl ;an015; dms;make it 1 based + mov cx,(RawIO shl 8) or Format_Track ;an015; dms;Format track(s) + mov dx,Tracks_To_Format ;an015; dms;get track count + mov FormatPacket.FP_TrackCount,dx ;an015; dms;put count in parms list + lea dx,FormatPacket ;an015; dms;ptr to parms + int 21h ;an015; dms; + +; $if c ;an015; dms;error? + JNC $$IF161 + mov ah,59h ;an015; dms;get extended error + xor bx,bx ;an015; dms;clear bx + int 21h ;an015; dms; + stc ;an015; dms;flag an error +; $endif ;an015; dms; +$$IF161: + + ret ;an015; dms; + +FormatTrack endp ;an015; dms; + + +;========================================================================= +; Determine_Track_Count : This routine determines the number of +; tracks to be formatted, based on whether +; or not we have a hard disk. If we have +; a hard disk we can use multi-track +; format/verify, otherwise we use the +; single track format/verify. +; +; Inputs : Device_Type - Media type +; +; Outputs : Tracks_To_Format - Max. number of tracks +; to be formatted in one +; call +;========================================================================= + +Procedure Determine_Track_Count ;an015; dms; + + cmp DeviceParameters.DP_DeviceType,Dev_HardDisk ;an015; dms;harddisk? +; $if e ;an015; dms;yes + JNE $$IF163 + call Calc_Track_Count ;an015; dms;calc Tracks_To_Format +; $else ;an015; dms;removable media + JMP SHORT $$EN163 +$$IF163: + mov Tracks_To_Format,0001h ;an015; dms;default to 1 track +; $endif ;an015; dms; +$$EN163: + + ret ;an015; dms; + +Determine_Track_Count endp ;an015;dms; + + +;========================================================================= +; Calc_Track_Count : This routine determines if we have enough tracks +; remaining to use the max. number of tracks +; in the FormatTrack call. If the tracks remaining +; to be formatted is less that the max. number of +; allowable tracks for the call, the max. number +; of allowable tracks is set to the remaining track +; count. +; +; Inputs : Track_Count - Max. number of allowable tracks to be +; formatted in 1 FormatTrack call. +; TracksLeft - Track count of remaining tracks to be +; formatted. +; +; Outputs : Tracks_To_Format - Count of the tracks to be formatted +; in the next FormatTrack call. +; +; +;========================================================================= + +Procedure Calc_Track_Count ;an015; dms; + + push ax ;an015; dms;save regs + mov ax,Track_Count ;an015; dms;max bytes to format + cmp ax,TracksLeft ;an015; dms;too many tracks? +; $if a ;an015; dms;yes + JNA $$IF166 + mov ax,TracksLeft ;an015; dms;format remaining tracks +; $endif ;an015; dms; +$$IF166: + mov Tracks_To_Format,ax ;an015; dms;save track count + + pop ax ;an015; dms; + + ret ;an015; dms; + +Calc_Track_Count endp ;an015; dms; + +;========================================================================= +; Calc_Max_Tracks_To_Format : This routine determines the maximum +; number of tracks to format at 1 time. +; +; Inputs : DeviceParameters - SectorsPerTrack +; BytesPerSector +; +; Outputs : Track_Count - Max. # of tracks to format in 1 call +; to FormatTrack +;========================================================================= + +Procedure Calc_Max_Tracks_To_Format + + push ax ;an015; dms;save regs + push bx ;an015; dms; + push dx ;an015; dms; + + mov ax,DeviceParameters.DP_BPB.BPB_SectorsPerTrack ;an015; dms;get sectors per track + mov bx,DeviceParameters.DP_BPB.BPB_BytesPerSector ;an015; dms;get byte count + xor dx,dx ;an015; dms;clear dx + mul bx ;an015; dms;get total byte count + mov bx,ax ;an015; dms;put count in bx + mov ax,Max_Format_Size ;an015; dms;max bytes to format + div bx ;an015; dms;get track count + mov Track_Count,ax + + pop dx ;an015; dms; + pop bx ;an015; dms; + pop ax ;an015; dms; + + ret + +Calc_Max_Tracks_To_Format endp + + + + + +;========================================================================= +; Format_Track_Retry : This routine performs the retry logic for +; the format multi-track. It will retry each track +; until the failing track is encountered through +; a CY condition. +; +; Inputs : none +; +; Outputs : CY - indicates either a failing track or end of format +; +; +;========================================================================= + +Procedure Format_Track_Retry + + clc ;an022; dms; clear existing CY + mov Tracks_To_Format,1 ;an015; dms; only format 1 track +; $do ;an015; dms; while we have good tracks +$$DO168: +; $leave c ;an015; dms; exit on bad track + JC $$EN168 + call FormatTrack ;an015; dms; format the track +; $if nc ;an015; dms;error? + JC $$IF170 + call DisplayCurrentTrack ;an022; dms;adjust percent counter + call Adj_Track_Count + call NextTrack ;an015; dms;calc next track +; $endif ;an015; dms; +$$IF170: +; $enddo ;an015; dms; + JMP SHORT $$DO168 +$$EN168: + + ret ;an015; dms; + +Format_Track_Retry endp ;an015; dms; + +;========================================================================= +; Format_Loop : This routine provides the main template +; for the formatting of a disk. A disk +; will be formatted as long as there are +; tracks remaining to be formatted. +; This routine can be exited on a carry +; condition; i.e., bad track, last track, etc. +; +; Inputs : none +; +; Outputs : CY - Set on exit from this routine +; AX - Possible error condition code +;========================================================================= + +Procedure Format_Loop ;an015; dms; + + clc ;an015; dms;initialize to NC +; $do ;an015; dms;while NC +$$DO173: +; $leave c ;an015; dms;exit on CY + JC $$EN173 + call Calc_Current_Head_Cyl ;an015; dms;head and cylinder calc. + call Determine_Format_Type ;an015; dms;floppy/hard media? + call Determine_Track_Count ;an015; dms;how many tracks? + call FormatTrack ;an015; dms;format track(s) +; $if c ;an015; dms;formattrack failed + JNC $$IF175 + pushf ;an015; dms;save flags + cmp DeviceParameters.DP_DeviceType,Dev_HardDisk ;an015; dms;harddisk? +; $if e ;an015; dms;yes + JNE $$IF176 + popf ;an015; dms;restore flags + call Format_Track_Retry ;an015; dms;find failing track +; $else ;an015; dms; + JMP SHORT $$EN176 +$$IF176: + popf ;an015; dms;restore flags +; $endif ;an015; dms; +$$EN176: +; $endif ;an015; dms; +$$IF175: + +; $if c ;an015; dms;format error? + JNC $$IF180 + pushf ;an015; dms;yes - save flags + push ax ;an015; dms;save return code + call CheckRealErrors ;an015; dms;check error type +; $if nc ;an015; dms;if non-fatal + JC $$IF181 + call DisplayCurrentTrack ;an015; dms;display % formatted +; $endif ;an015; dms; +$$IF181: + pop ax ;an015; dms;restore regs + popf ;an015; dms; +; $endif ;an015; dms; +$$IF180: + +; $leave c ;an015; dms;exit on CY + JC $$EN173 + + call DisplayCurrentTrack ;an015; dms;tell how much formatted + call Adj_Track_Count ;an015; dms;decrease track counter + call NextTrack ;an015; dms;adjust head and cylinder +; $enddo ;an015; dms; + JMP SHORT $$DO173 +$$EN173: + ret ;an015; dms; + +Format_Loop endp ;an015; dms; + +;========================================================================= +; Adj_Track_Count : This routine adjusts the track count by the +; number of tracks that have been formatted +; in one FormatTrack call. +; +; Inputs : TracksLeft - # of tracks remaining to be formatted +; Tracks_To_Format - Tracks formatted in 1 call +; +; Outputs : TracksLeft - # of tracks remaining to be formatted +;========================================================================= + +Procedure Adj_Track_Count ;an015; dms; + + push ax ;an015; dms; save regs + mov ax,TracksLeft ;an015; dms; get tracks remaining + sub ax,Tracks_To_Format ;an015; dms; subtract amount formatted + mov TracksLeft,ax ;an015; dms; save new tracks remaining value + pop ax ;an015; dms; restore regs + ret ;an015; dms; + +Adj_Track_Count endp ;an015; dms; + +;========================================================================= +; Prompt_User_For_Disk : This routine prompts the user for the +; disk to be formatted. An appropriate +; message is chosen based on the type +; of switch entered. If the /SELECT +; switch is entered, the disk prompt is +; issued through the INT 2fh services +; provided by SELECT. +; +; Inputs : Switchmap - Switches chosen for format +; +; Outputs : Message printed as appropriate. +;========================================================================= + +Procedure Prompt_User_For_Disk ;an016;dms; + + push ax ;an016;dms;save ax + test switchmap, (SWITCH_Backup or SWITCH_Select or SWITCH_AUTOTEST) ;Suppress prompt? ;AC000; +; $IF Z ; ;AC000; + JNZ $$IF186 + call DSKPRM ; prompt user for disk +; $ENDIF ; ;AC000; +$$IF186: + + test switchmap, (Switch_Select) ;an016;dms;/SELECT requested? +; $if nz ;an016;dms;yes + JZ $$IF188 + mov al, drive ;an016;dms;get drive to access for format + call AccessDisk ;an016;dms;access the disk + mov ax,Select_Disk_Message ;an016;dms;display disk prompt + int 2fh ;an016;dms; through INT 2fh services +; $endif ;an016;dms; +$$IF188: + pop ax ;an016;dms;restore ax + + ret ;an016;dms; + +Prompt_User_For_Disk endp ;an016;dms; + + +code ends + END START + \ No newline at end of file diff --git a/v4.0/src/CMD/FORMAT/FORMAT.LNK b/v4.0/src/CMD/FORMAT/FORMAT.LNK new file mode 100644 index 0000000..4798cf9 --- /dev/null +++ b/v4.0/src/CMD/FORMAT/FORMAT.LNK @@ -0,0 +1,8 @@ +DISPLAY.OBJ+ +FORINIT.OBJ+ +FORLABEL.OBJ+ +FORMAT.OBJ+ +FORPROC.OBJ+ +MSFOR.OBJ+ +FOREXEC.OBJ +FORMAT.exe,FORMAT.MAP; diff --git a/v4.0/src/CMD/FORMAT/FORMAT.SKL b/v4.0/src/CMD/FORMAT/FORMAT.SKL new file mode 100644 index 0000000..11f18fd --- /dev/null +++ b/v4.0/src/CMD/FORMAT/FORMAT.SKL @@ -0,0 +1,229 @@ + +:util FORMAT + +:class 1 +:use EXTEND2 ;File not found +:use EXTEND4 ;Too many open files +:use EXTEND5 ;Access denied +:use EXTEND8 ;Insufficient memory +:use EXTEND15 ;Invalid drive was specified +:use EXTEND26 ;Unknown media type + +:class A +;msgBadDosVersion +;"Incorrect DOS version",CR,LF,"$" +:use COMMON1 + +;msgCurrentTrack +;"Head: %3d Cylinder: %4d", CR, 0 +;:def 2 "Head: %1 Cylinder: %2",CR +:def 2 CR,"%1 percent of disk formatted ",CR + +;msgDataSpace +;"%l10d bytes available on disk",CR,LF,0 +:use COMMON3 + +;msgFormatComplete +;"Format complete ",CR,LF,0 +:def 4 CR,"Format complete ",CR,LF + +;msgBadSpace +;"%l10d bytes in bad sectors", CR, LF, 0 +:use COMMON5 + +;msgTotalDiskSpace +;"%l10d bytes total disk space", CR, LF, 0 +:use COMMON6 + +;msgInsertDisk +;"Insert new diskette for drive %c:",CR,LF +:def 7 "Insert new diskette for drive %1:",CR,LF + +;msgSystemSpace +;"%l10d bytes used by system", CR, LF, 0 +:use COMMON8 + +;msgReInsertDisk +;"Re-insert diskette for drive %c:",0 +:def 9 "Re-insert diskette for drive %1:",CR,LF + +;msgLabelPrompt +;"Volume label (11 characters, ENTER for none)? ",0 +:use 10 COMMON35 + +;msgFormatNotSupported +;"Format not supported on drive %c:", CR,LF,0 +:def 11 CR,"Format not supported on drive %1:", CR,LF + +;msgInvalidDeviceParameters +;"Invalid device parameters from device driver",CR,LF,0 +:def 12 CR,"Invalid device parameters from device driver",CR,LF + +;msgErrorInIOCTL +;"Error in IOCTL call", CR, LF, 0 +:def 13 CR,"Error in IOCTL call ",CR,LF + +;msgNotBlockDevice +;"Not a block device", CR, LF +:def 14 CR,"Not a block device ",CR,LF + +;msgFATwriteError +;"Error writing FAT", CR, LF, 0 +:def 15 CR,"Error writing FAT ",CR,LF + +;msgDirectoryWriteError +;"Error writing directory ", CR, LF, 0 +:def 16 CR,"Error writing directory",CR,LF + +;msgAssignedDrive +;"Cannot format an ASSIGNed, SUBSTed, or JOINed drive. ", CR, LF, 0 +:def 17 CR,"Cannot format an ASSIGNed, SUBSTed, or JOINed drive. ",CR,LF + + +;msgNoSystemFiles +;"Cannot find System Files",CR,LF,0 +:def 18 CR,"Cannot find System Files",CR,LF + + +;msgNetDrive +;"Cannot FORMAT a Network drive", CR, LF, 0 +:def 19 CR,"Cannot FORMAT a Network drive",CR,LF + +;msgBadCharacters +;"Invalid characters in volume label ", CR, LF, 0 +:use 20 COMMON21 + + +:CLASS B + +;msgParametersNotSupported +;"Parameters not supported",CR,LF,0 +:def 21 CR,"Parameters not supported",CR,LF + +;msgFormatFailure +; Note: This message must be long enough to wipe out message msgCurrentTrack +;"Format terminated ",CR,LF,0 +:def 22 CR,"Format terminated ",CR,LF + +;msgNotSystemDisk +;"Disk unsuitable for system disk", CR, LF, 0 +:def 23 CR,"Disk unsuitable for system disk",CR,LF + +;msgDiskUnusable +;"Invalid media or Track 0 bad - disk unusable", CR, LF, 0 +:def 24 CR,"Invalid media or Track 0 bad - disk unusable",CR,LF + +;msgBootWriteError +;"Unable to write BOOT", CR, LF, 0 +:def 25 CR,"Unable to write BOOT ",CR,LF + +;msgDirectoryReadError +;"Error reading directory", CR, LF, 0 +:def 26 CR,"Error reading directory",CR,LF + +;msgNeedDrive +;"No target drive specified",CR,LF,0 +:use COMMON27 + +;ContinueMsg +;Press any key to continue +:def 28 CR,"and press ENTER when ready..." + +;msgBadVolumeId +;"Invalid Volume ID", CR, LF, 0 +:def 29 CR,"Invalid Volume ID ",CR,LF + +;msgSystemTransfered +;"System transferred",CR,LF,0 +:use COMMON30 + +;msgWhatIsVolumeId? +;"Enter current Volume Label for drive %c: ", 0 +:def 31 CR,"Enter current Volume Label for drive %1: " + + +;msgIncompatibleParametersForHardDisk +;" with fixed disk", CR,LF,0 +:def 32 CR,"Parameters not compatible",CR,LF,"with fixed disk",CR,LF + +;msgPartitionTableReadError +;"Error reading partition table", CR, LF, 0 +:def 35 CR,"Error reading partition table",CR,LF + +;msgSerialNumber +:use COMMON36 + +;msgFormatBroken +;"Format Broken", CR, LF, 0 +:def 37 CR,"Format Broken",CR,LF + +;msgEXECFailure +:def 38 CR,"Format not available on drive %1",CR,LF + +;NO_SYS_MESS: +; THIS IS A SPECIAL MESSAGE WHICH IS INCLUDED IN THE "FAKE" IBMBIO.COM +; FILE PLACED ON DISKS FORMATTED /B or /R. NOTE THAT IT IS NUL TERMINATED. +;"Non-System disk or disk error",13,10,0 +:def 39 CR,"Non-System disk or disk error",CR,LF + +;msgbadpartitiontable +;"Bad Partition Table", CR, LF, 0 +:def 40 CR,"Bad Partition Table ",CR,LF + +:CLASS C + +;msgParametersNotSupportedByDrive +;"Parameters not Supported by Drive",CR, LF, 0 +:def 41 CR,"Parameters not Supported by Drive",CR,LF + +;msgCRLF +:def 42 CR,LF + +;msgInterrupt +:def 43 CR,LF,LF + +;msgInsertDosDisk db "Insert DOS disk in drive %c:", CR, LF +:def 44 CR,"Insert DOS disk in drive %1:",CR,LF + + +;msgHardDiskWarning db CR,LF +; db "WARNING, ALL DATA ON NON-REMOVABLE DISK",CR,LF +; db "DRIVE %c: WILL BE LOST!",CR,LF +; db "Proceed with Format (Y/N)?",0 +:def 45 CR,LF,"WARNING, ALL DATA ON NON-REMOVABLE DISK",CR,LF +"DRIVE %1: WILL BE LOST!",CR,LF +"Proceed with Format (Y/N)?" + +;msgFormatAnother? db "Format another (Y/N)?",0 +:def 46 CR,"Format another (Y/N)?" + +;msgPartitionTableReadError db "Error reading partition table", CR, LF, 0 +:def 47 CR,"Error reading partition table",CR,LF + +;msgPartitionTableWriteError db "Error writing partition table", CR, LF, 0 +:def 48 CR,"Error writing partition table",CR,LF + +;msgIncompatibleParametere forproc.sal not compatible", CR,LF +;"Parameters not compatible", CR,LF,0 +:def 49 CR,"Parameters not compatible", CR,LF + +;msgNumAlloc +:def 50 "%1 allocation units available on disk",CR,LF + +;msgAllocSize +:def 51 "%1 bytes in each allocation unit",CR,LF + +;msgPartitionTableWriteError +; "Error writing partition table", CR, LF, 0 +:def 52 CR, "Error writing partition table",CR,LF + +;msgSameSwitch +:def 53 CR,"Same parameter entered twice",CR,LF + +;msgBad_T_N +:def 54 CR,"Must enter both /T and /N parameters",CR,LF ;AN009; + +;MsgVerify +:def 55 CR,"Attempting to recover allocation unit %1 ",CR +:end + diff --git a/v4.0/src/CMD/FORMAT/FORMSG.INC b/v4.0/src/CMD/FORMAT/FORMSG.INC new file mode 100644 index 0000000..09ec9f2 --- /dev/null +++ b/v4.0/src/CMD/FORMAT/FORMSG.INC @@ -0,0 +1,861 @@ +; + +; +;***************************************************************************** +; Macro's +;***************************************************************************** +; + + +Define_Msg macro Message_Name ; ;AN000; + ; +Create_Msg Message_Name,Message_Number,Handle,Sublist,Count,Class,Function,Input;AN000; + ; + endm ; ;AN000; + +;----------------------------------------------------------------------------- + +Create_Msg macro Parm1,Parm2,Parm3,Parm4,Parm5,Parm6,Parm7,Parm8; ;AN000; + +Public Parm1 +Parm1 label word ; ;AN000; + dw Parm2 ; ;AN000; + dw Parm3 ; ;AN000; + dw Parm4 ; ;AN000; + dw Parm5 ; ;AN000; + db Parm6 ; ;AN000; + db Parm7 ; ;AN000; + dw Parm8 ; ;AN000; + endm ; ;AN000; + + +; +;***************************************************************************** +; External data declarations +;***************************************************************************** +; + + Extrn DriveLetter:Byte + Extrn SystemDriveLetter:Byte + Extrn CurrentHead:Byte + Extrn CurrentCylinder:Word + Extrn FdskSiz:Word + Extrn SysSiz:Word + Extrn BadSiz:Word + Extrn DataSiz:Word + Extrn Drive_Letter_Msg:Byte + Extrn PercentComplete:Byte + Extrn AllocSize:Dword + Extrn AllocNum:Word + Extrn Serial_Num_Low:Word + Extrn Serial_Num_High:Word + Extrn Command_Old_Ptr:Word + Extrn Msg_Allocation_Unit_Val:Dword + +; +;***************************************************************************** +; Publics +;***************************************************************************** +; + + + +; +;***************************************************************************** +; Message Retriever equates +;***************************************************************************** +; + +Format_Msg equ 'C' + +N_A equ 0 +Sublist_Length equ 11 +None equ 0 + +Blank equ " " +No_Function equ 0 +No_Replace equ 0 + +Msg_Ser_Class equ 0 +Ext_Err_Class equ 1 +Parse_Err_Class equ 2 +Utility_Msg_Class equ 0FFh + +Reserved equ 0 + + + + +data segment public para 'DATA' + assume ds:data + + +; +;***************************************************************************** +; Message Sublist Tables +;***************************************************************************** +; +;The following control blocks are used for messages with +;replaceable paramaters. These control blocks are used by the +;SysDispMsg routine. +; + +;--------------------------- ; +Sublist_msgCurrentTrack label dword ; ;AN000; + ; + db Sublist_Length ; ;AN000; + db Reserved ; ;AN000; + dw offset PercentComplete ; ;AN000; + dw data ; ;AN000; + db 1 ; ;AN000; + db Right_Align+Unsgn_Bin_Word ; ;AN000; + db 3 ;Max % is 100 ;AN000; + db 3 ;Min % is 0 ;AN000; + db Blank ; ;AN000; +;--------------------------- ; +Sublist_msgInsertDisk label dword ; ;AN000; +Sublist_msgReInsertDisk label dword ; ;AN000; +Sublist_MsgHardDiskWarning label dword ; +Sublist_msgFormatNotSupported label dword ; ;AN000; + + db Sublist_Length ; ;AN000; + db Reserved ; ;AN000; + dw offset DriveLetter ; ;AN000; + dw data ; ;AN000; + db 1 ; ;AN000; + db Left_Align+Char_Field_Char ; ;AN000; + db 1 ; ;AN000; + db 1 ; ;AN000; + db Blank ; ;AN000; +;--------------------------- ; +Sublist_msgInsertDOSDisk label dword ; ;AN000; + ; + db Sublist_Length ; ;AN000; + db Reserved ; ;AN000; + dw offset SystemDriveLetter; ;AN000; + dw data ; ;AN000; + db 1 ; ;AN000; + db Left_Align+Char_Field_Char ; ;AN000; + db 1 ; ;AN000; + db 1 ; ;AN000; + db Blank ; ;AN000; +;--------------------------- ; +Sublist_msgTotalDiskSpace label dword ; ;AN000; + ; + db Sublist_Length ; ;AN000; + db Reserved ; ;AN000; + dw offset FdskSiz ; ;AN000; + dw data ; ;AN000; + db 1 ; ;AN000; + db Right_Align+Unsgn_Bin_Dword ; ;AN000; + db 10 ; ;AN000; + db 10 ;4,000,000,000 limit ;AN000; + db Blank ; ;AN000; +;--------------------------- ; +Sublist_msgSystemSpace label dword ; ;AN000; + ; + db Sublist_Length ; ;AN000; + db Reserved ; ;AN000; + dw offset SysSiz ; ;AN000; + dw data ; ;AN000; + db 1 ; ;AN000; + db Right_Align+Unsgn_Bin_DWord ; ;AN000; + db 10 ; ;AN000; + db 10 ;64k*3 max ;AN000; + db Blank ; ;AN000; +;--------------------------- ; +Sublist_msgBadSpace label dword ; ;AN000; + ; + db Sublist_Length ; ;AN000; + db Reserved ; ;AN000; + dw offset BadSiz ; ;AN000; + dw data ; ;AN000; + db 1 ; ;AN000; + db Right_Align+Unsgn_Bin_DWord ; ;AN000; + db 10 ; ;AN000; + db 10 ;4,000,000,000 max ;AN000; + db Blank ; ;AN000; +;--------------------------- ; +Sublist_msgDataSpace label dword ; ;AN000; + ; + db Sublist_Length ; ;AN000; + db Reserved ; ;AN000; + dw Offset DataSiz ; ;AN000; + dw data ; ;AN000; + db 1 ; ;AN000; + db Right_Align+Unsgn_Bin_DWord ; ;AN000; + db 10 ; ;AN000; + db 10 ;4,000,000,000 max ;AN000; + db Blank ; ;AN000; +;--------------------------- ; +Sublist_msgWhatIsVolumeId? label dword ; ;AN000; + ; + db Sublist_Length ; ;AN000; + db Reserved ; ;AN000; + dw offset DriveLetter ; ;AN000; + dw data ; ;AN000; + db 1 ; ;AN000; + db Left_Align+Char_Field_Char ; ;AN000; + db 1 ; ;AN000; + db 1 ; ;AN000; + db Blank ; ;AN000; +;--------------------------- ; +Sublist_msgEXECFailure label dword ; ;AN000; + ; + db Sublist_Length ; ;AN000; + db Reserved ; ;AN000; + dw Drive_Letter_Msg ; ;AN000; + dw data ; ;AN000; + db 1 ; ;AN000; + db Left_Align+Char_Field_ASCIIZ ; ;AN000; + db 2 ; ;AN000; + db 2 ; ;AN000; + db Blank ; ;AN000; +;--------------------------- ; +Sublist_msgAllocNum label dword ; ;AN000; + ; + db Sublist_Length ; ;AN000; + db Reserved ; ;AN000; + dw offset AllocNum ; ;AN000; + dw data ; ;AN000; + db 1 ; ;AN000; + db Right_Align+Unsgn_Bin_Word ; ;AN000; + db 10 ; ;AN000; + db 10 ; ;AN000; + db Blank ; ;AN000; +;--------------------------- ; +Sublist_msgAllocSize label dword ; ;AN000; + ; + db Sublist_Length ; ;AN000; + db Reserved ; ;AN000; + dw offset AllocSize ; ;AN000; + dw data ; ;AN000; + db 1 ; ;AN000; + db Right_Align+Unsgn_Bin_DWord ; ;AN000; + db 10 ; ;AN000; + db 10 ; ;AN000; + db Blank ; ;AN000; +;--------------------------- ; +Sublist_msgSerialNumber label dword ; ;AN000; + ; + db Sublist_Length ; ;AN000; + db Reserved ; ;AN000; + dw offset Serial_Num_Low ; ;AN000; + dw data ; ;AN000; + db 1 ; ;AN000; + db Right_Align+Bin_Hex_Word ; ;AN000; + db 4 ; ;AN000; + db 4 ; ;AN000; + db '0' ;Display leading 0's ;AN000; + db Sublist_Length ; ;AN000; + db Reserved ; ;AN000; + dw offset Serial_Num_High ; ;AN000; + dw data ; ;AN000; + db 2 ; ;AN000; + db Right_Align+Bin_hex_Word ; ;AN000; + db 4 ; ;AN000; + db 4 ; ;AN000; + db '0' ; ;AN000; + +Public Sublist_MsgParse_Error +Sublist_msgParse_Error label dword ; ;AN000; + + db Sublist_Length ; ;AN000; + db Reserved ; ;AN000; + dw 0 ; ;AN000; + dw Data ; ;AN000; + db 0 ; ;AN000; + db Left_Align+Char_Field_ASCIIZ ; ;AN000; + db 20 ; ;AN000; + db 01 ; ;AN000; + db Blank ; ;AN000; +;--------------------------- ; +Sublist_MsgVerify label dword ; ;AN000; + ; + db Sublist_Length ; ;AN000; + db Reserved ; ;AN000; + dw offset Msg_Allocation_Unit_Val; ;AN000; + dw data ; ;AN000; + db 1 ; ;AN000; + db Right_Align+Unsgn_Bin_DWord; ;AN000; + db 8 ; ;AN000; + db 8 ; ;AN000; + db Blank +; +;***************************************************************************** +; Message Description Tables +;***************************************************************************** +; + +;---------------------- ; +Message_Number = 1 ; ;AN000; +Handle = No_Handle ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Input ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgBadDOSVersion ; ;AN000; +;---------------------- ; +Message_Number = 2 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = Sublist_msgCurrentTrack ; ;AN000; +Count = 1 ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Input ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgCurrentTrack ; ;AN000; +;---------------------- ; +Message_Number = 3 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = Sublist_msgDataSpace ; ;AN000; +Count = 1 ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgDataSpace ; ;AN000; +;---------------------- ; +Message_Number = 4 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Input ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgFormatComplete ; ;AN000; +;---------------------- ; +Message_Number = 5 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = Sublist_msgBadSpace ; ;AN000; +Count = 1 ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgBadSpace ; ;AN000; +;---------------------- ; +Message_Number = 6 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = Sublist_msgTotalDiskSpace ; ;AN000; +Count = 1 ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgTotalDiskSpace ; ;AN000; +;---------------------- ; +Message_Number = 7 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = Sublist_msgInsertDisk ; ;AN000; +Count = 1 ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgInsertDisk ; ;AN000; +;---------------------- ; +Message_Number = 8 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = Sublist_msgSystemSpace ; ;AN000; +Count = 1 ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgSystemSpace ; ;AN000; +;---------------------- ; +Message_Number = 9 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = Sublist_msgReInsertDisk ; ;AN000; +Count = 1 ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgReInsertDisk ; ;AN000; +;---------------------- ; +Message_Number = 10 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgLabelPrompt ; ;AN000; +;---------------------- ; +Message_Number = 11 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = Sublist_msgFormatNotSupported ; ;AN000; +Count = 1 ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgFormatNotSupported ; ;AN000; +;---------------------- ; +Message_Number = 12 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgInvalidDeviceParameters; ;AN000; +;---------------------- ; +Message_Number = 13 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgErrorInIOCTL ; ;AN000; +;---------------------- ; +Message_Number = 14 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgNotBlockDevice ; ;AN000; +;---------------------- ; +Message_Number = 15 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgFATwriteError ; ;AN000; +;---------------------- ; +Message_Number = 16 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgDirectoryWriteError ; ;AN000; +;---------------------- ; +Message_Number = 17 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgAssignedDrive ; ;AN000; +;---------------------- ; +Message_Number = 18 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgNoSystemFiles ; ;AN000; +;---------------------- ; +Message_Number = 19 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgNetDrive ; ;AN000; +;---------------------- ; +Message_Number = 20 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgBadCharacters ; ;AN000; +;---------------------- ; +Message_Number = 21 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgParametersNotSupported ; ;AN000; +;---------------------- ; +Message_Number = 22 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgFormatFailure ; ;AN000; +;---------------------- ; +Message_Number = 23 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgNotSystemDisk ; ;AN000; +;---------------------- ; +Message_Number = 24 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgDiskUnusable ; ;AN000; +;---------------------- ; +Message_Number = 25 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgBootWriteError ; ;AN000; +;---------------------- ; +Message_Number = 26 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgDirectoryReadError ; ;AN000; +;---------------------- ; +Message_Number = 27 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgNeedDrive ; ;AN000; +;---------------------- ; +Message_Number = 28 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg ContinueMsg ; ;AN000; +;---------------------- ; +Message_Number = 29 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgBadVolumeId ; ;AN000; +;---------------------- ; +Message_Number = 30 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Input ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgSystemTransfered ; ;AN000; +;---------------------- ; +Message_Number = 31 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = Sublist_msgWhatIsVolumeId? ; ;AN000; +Count = 1 ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgWhatIsVolumeId? ; ;AN000; +;---------------------- ; +Message_Number = 32 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgIncompatibleParametersForHardDisk ; ;AN000; +;---------------------- ; + +Message_Number = 33 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgWriteProtected ; ;AN000; +;---------------------- ; +Message_Number = 34 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgNotReady ; ;AN000; +;---------------------- ; + +Message_Number = 35 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgPartitionTableReadErr ; ;AN000; +;---------------------- ; +Message_Number = 36 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = Sublist_msgSerialNumber ; ;AN000; +Count = 2 ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgSerialNumber ; ;AN000; +;---------------------- ; +Message_Number = 37 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgFormatBroken ; ;AN000; +;---------------------- ; +Message_Number = 38 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = Sublist_msgEXECFailure ; ;AN000; +Count = 1 ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgEXECFailure ; ;AN000; +;---------------------- ; +Message_Number = 39 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg NO_SYS_MESS ; ;AN000; +;---------------------- ; +Message_Number = 40 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgbadpartitiontable ; ;AN000; +;---------------------- ; +Message_Number = 41 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgParametersNotSupportedByDrive ; ;AN000; +;---------------------- ; +Message_Number = 42 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgCRLF ; ;AN000; +;---------------------- ; +Message_Number = 43 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgInterrupt ; ;AN000; +;---------------------- ; +Message_Number = 44 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = Sublist_MsgInsertDOSDisk ; ;AN000; +Count = 1 ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgInsertDOSDisk ; ;AN000; +;---------------------- ; +Message_Number = 45 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = Sublist_MsgHardDiskWarning ; ;AN000; +Count = 1 ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgHardDiskWarning ; ;AN000; +;---------------------- ; +Message_Number = 46 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgFormatAnother? ; ;AN000; +;---------------------- ; +Message_Number = 47 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgPartitionTableReadError ; ;AN000; +;---------------------- ; +Message_Number = 48 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgPartitionTableWriteError ; ;AN000; +;---------------------- ; +Message_Number = 49 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgIncompatibleParameters ; ;AN000; +;---------------------- ; +Message_Number = 50 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = Sublist_MsgAllocNum ; ;AN000; +Count = 1 ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgAllocNum ; ;AN000; +;---------------------- ; +Message_Number = 51 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = Sublist_MsgAllocSize ; ;AN000; +Count = 1 ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgAllocSize ; ;AN000; +;---------------------- ; +Message_Number = 52 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgPartitionTableWriteErr ; ;AN000; +;---------------------- ; +Message_Number = 53 ; ;AN002; +Handle = STDOUT ; ;AN002; +Sublist = No_Replace ; ;AN002; +Count = N_A ; ;AN002; +Class = Utility_Msg_Class ; ;AN002; +Function = No_Function ; ;AN002; +Input = N_A ; ;AN002; + Define_Msg msgSameSwitch ; ;AN002; +;---------------------- ; +Message_Number = 54 ; ;AN009; +Handle = STDOUT ; ;AN009; +Sublist = No_Replace ; ;AN009; +Count = N_A ; ;AN009; +Class = Utility_Msg_Class ; ;AN009; +Function = No_Function ; ;AN009; +Input = N_A ; ;AN009; + Define_Msg msgBad_T_N ; ;AN009; +;---------------------- ; +Message_Number = 55 ; ;an019; dms; +Handle = STDOUT ; ;an019; dms; +Sublist = Sublist_MsgVerify ; ;an019; dms; +Count = 1 ; ;an019; dms; +Class = Utility_Msg_Class ; ;an019; dms; +Function = No_Function ; ;an019; dms; +Input = N_A ; ;an019; dms; + Define_Msg MsgVerify ; ;an019; dms; +;---------------------- ; +Message_Number = 0 ; ;AN000; +Handle = STDERR ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Ext_Err_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg Extended_Error_Msg ; ;AN000; +;---------------------- +Message_Number = 0 ; ;AN000; +Handle = STDERR ; ;AN000; +Sublist = Sublist_MsgParse_Error ; ;AN000; +Count = 1 ; ;AN000; +Class = Parse_Err_Class ; ;AN000; +Function = No_Function ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg Parse_Error_Msg ; ;AN000; +;----------------------- + + + +; +;These need to be coded as extended an parse errors, but left here to link. +; + + + +Message_Number = 70 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Input ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgOutOfMemory ; ;AN000; +;---------------------- ; +Message_Number = 71 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Input ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgBadDrive ; ;AN000; +;---------------------- ; +Message_Number = 10 ; ;AN000; +Handle = StdErr ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Parse_Err_Class ; ;AN000; +Function = No_Input ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgInvalidParameter ; ;AN000; +;---------------------- ; +Message_Number = 73 ; ;AN000; +Handle = STDOUT ; ;AN000; +Sublist = No_Replace ; ;AN000; +Count = N_A ; ;AN000; +Class = Utility_Msg_Class ; ;AN000; +Function = No_Input ; ;AN000; +Input = N_A ; ;AN000; + Define_Msg msgLoadFailure ; ;AN000; + + + + + + + + + +data ends + + diff --git a/v4.0/src/CMD/FORMAT/FORPARSE.INC b/v4.0/src/CMD/FORMAT/FORPARSE.INC new file mode 100644 index 0000000..393b425 --- /dev/null +++ b/v4.0/src/CMD/FORMAT/FORPARSE.INC @@ -0,0 +1,523 @@ +; + + + +data segment public para 'DATA' + +; +;***************************************************************************** +; Publics +;***************************************************************************** +; + + Public Drive_Letter_Buffer + Public Switch_Buffer + Public Switch_Num_Buffer + Public Switch_String_Buffer + + +; +;*************************************************************************** +; Equates +;*************************************************************************** +; + +;Match Flags + +Numeric_Value equ 8000h ; ;AN000; +Signed_Numeric_Value equ 4000h ; ;AN000; +Simple_String equ 2000h ; ;AN000; +Date_String equ 1000h ; ;AN000; +Time_String equ 0800h ; ;AN000; +Complex_List equ 0400h ; ;AN000; +Filespec equ 0200h ; ;AN000; +Drive_Only equ 0100h ; ;AN000; +Quoted_String equ 0080h ; ;AN000; +Ignore_Colon equ 0010h ; ;AN000; +Repeats_Allowed equ 0002h ; ;AN000; +Optional equ 0001h ; ;AN000; + +;Function_Flags + +File_Table_Capitalize equ 1 ; ;AN000; +Char_Table_Capitalize equ 2 ; ;AN000; +Remove_Colon equ 10h ; ;AN000; + +;Extra delimeters and EOL + +Delimiters_Only equ 1 ; ;AN000; +EOL_Or_Delimiters equ 2 ; ;AN000; + +Semi_Colon equ ";" ; ;AN000; +Tab equ 09h ; ;AN000; +Colon equ ":" ; ;AN000; + + +;Parse Errors + +No_Error equ 0 ; ;AN000; +Too_Many_Operands equ 1 ; ;AN000; +Operand_Missing equ 2 ; ;AN000; +Not_In_Switch_List equ 3 ; ;AN000; +Not_In_Keyword_List equ 4 ; ;AN000; +Out_Of_Range equ 6 ; ;AN000; +Not_In_Value_List equ 7 ; ;AN000; +Not_In_String_List equ 8 ; ;AN000; +Syntax_Error equ 9 ; ;AN000; +End_Of_Parse equ -1 ; ;AN000; + +;Return types + +Type_Reserved equ 0 ; ;AN000; +Type_Number equ 1 ; ;AN000; +Type_List_Index equ 2 ; ;AN000; +Type_String equ 3 ; ;AN000; +Type_Complex equ 4 ; ;AN000; +Type_Filespec equ 5 ; ;AN000; +Type_Drive equ 6 ; ;AN000; +Type_Date equ 7 ; ;AN000; +Type_Time equ 8 ; ;AN000; +Type_Quoted_String equ 9 ; ;AN000; + +;Other + +None equ 0 ; ;AN000; +No_Error equ 0 ; ;AN000; +Switch_Found equ 0FFFFh ; ;AN000; +Range_Ok equ 1 ; ;AN000; +Command_Line_Parms equ 81h ; ;AN000; + +; +;***************************************************************************** +; Parse Structures +;***************************************************************************** +; + +Control struc + +Match_Flags dw ? +Function_Flags dw ? +Result dw ? +Values dw ? +Num_Keywords db ? +Keyword db ? + +Control ends + +Drive_Letter_Return struc ; ;AN000; + +Drive_Type db 0 ; ;AN000; +Drive_Item_Tag db 0 ; ;AN000; +Drive_Pointer dw 0 ; ;AN000; +Drive_Number db 0 ;A=1, B=2, C=3 ;AN000; +Drive_debug db 8 dup(0) + +Drive_Letter_Return ends ; ;AN000; + +Switch_Return struc ; ;AN000; + +Switch_Type db 0 ; ;AN000; +Switch_Item_Tag db 0 ; ;AN000; +Switch_Pointer dw 0 ; ;AN000; +Switch_Debug db 4 dup(0) + +Switch_Return ends ; ;AN000; + +Switch_Num_Return struc ; ;AN000; + +Switch_Num_Type db 0 ; ;AN000; +Switch_Num_Item_Tag db 0 ; ;AN000; +Switch_Num_Pointer dw 0 ; ;AN000; +Switch_Number_Low dw 0 ; ;AN000; +Switch_Number_High dw 0 ; ;AN000; + +Switch_Num_Return ends ; ;AN000; + +Switch_String_Return struc ; ;AN000; + +Switch_String_Type db 0 ; ;AN000; +Switch_String_Item_Tag db 0 ; ;AN000; +Switch_String_Pointer dw 0 ; ;AN000; +Switch_String_Off dw 0 ; ;AN000; +Switch_String_Seg dw 0 ; ;AN000; + +Switch_String_Return ends ; ;AN000; + + +; +;************************************************************************** +; Parse tables +;************************************************************************** +; + +IF FSExec ;conditionally assemble /FS: ;an018; dms; + +Switch_FS_Table label byte ; ;AN000; + + dw Drive_Control_Definition ;Point to next level ;AN000; + db 0 ; ;AN000; + +ENDIF ;end conditional assembly /FS: ;an018; dms; + +Command_Line_Table label byte ; ;AN000; + + dw Command_Control ;Point to next level ;AN000; + db 0 ; ;AN000; + +; +;************************************************************************** +;Define Positionals, Switches and Keywords +;************************************************************************** +; + + +IF FSExec ;conditionally assemble /FS: ;an018; dms; + +Drive_Control_Definition label byte ; ;AN000; + + db 1,1 ;Only drive letter posistional ;AN000; + dw Positional_Control ;Pointer to control table ;AN000; + db 1 ;1 switch ;AN000; + dw Switch_FS_Control ; ;AN000; + db None ;No Keywords (maxk) ;AN000; + +ENDIF ;end conditional assembly /FS: ;an018; dms; + +Command_Control label byte ; ;AN000; + + db 1,1 ;Only drive letter posistional ;AN000; + dw Positional_Control ;Pointer to control table ;AN000; +IF ShipDisk + db 13 ;if /Z switch needed ;an000; dms; +ELSE + db 12 ; ;AC001; +ENDIF + dw Switch_V_Control ;Without quotes AN000; + dw Switch_S_Control ; ;AN000; + dw Switch_4_Control ; ;AN000; + dw Switch_1_Control ; ;AN000; + dw Switch_8_Control ; ;AN000; + dw Switch_B_Control ; ;AN000; + dw Switch_T_Control ; ;AN000; + dw Switch_N_Control ; ;AN000; + dw Switch_Select_Control ; ;AN000; + dw Switch_Backup_Control ; ;AN000; + dw Switch_Autotest_Control ; ;AN000; + dw Switch_F_Control ; ;AC001; +IF ShipDisk + dw Switch_Z_Control ;1 sector/cluster switch ;an000; dms; +ENDIF + db None ;No Keywords (maxk) ;AN000; + +; +;************************************************************************** +;Control Tables +;************************************************************************** +; + +Positional_Control label byte ; ;AN000; + + dw Drive_Only ;Match_Flag ;AN000; + dw None ;No function flags ;AN000; + dw Drive_Letter_Buffer ;Where it will be returned ;AN000; + dw No_Value ;No value ranges defined ;AN000; + db None ;No defined switches/keywords ;AN000; + +IF FSExec ;conditionally assemble /FS: ;an018; dms; + +Switch_FS_Control label byte + dw Simple_String ;/FS:xxxxx ;AN000; + dw File_Table_Capitalize ;Make it uppercase ;AN000; + dw Switch_String_Buffer ; ;AN000; + dw No_Value ; ;AN000; + db 1 ; ;AN000; + db "/FS",0 ; ;AN000; + +ENDIF ;end conditional assembly /FS: ;an018; dms; + +Switch_V_Control label byte ; ;AN000; + + dw Simple_String+Quoted_String+Optional ;/v:xxxxxxxx ;AN000; + dw File_Table_Capitalize ; ;AN000; + dw Switch_String_Buffer ; ;AN000; + dw No_Value ; ;AN000; + db 1 ; ;AN000; + db "/V",0 ; ;AN000; + +Switch_S_Control label byte ; ;AN000; + + dw None ; ;AN000; + dw None ; ;AN000; + dw Switch_Buffer ; ;AN000; + dw No_Value ; ;AN000; + db 1 ; ;AN000; + db "/S",0 ; ;AN000; + +Switch_4_Control label byte ; ;AN000; + + dw None ; ;AN000; + dw None ; ;AN000; + dw Switch_Buffer ; ;AN000; + dw No_Value ; ;AN000; + db 1 ; ;AN000; + db "/4",0 ; ;AN000; + +Switch_1_Control label byte ; ;AN000; + + dw None ; ;AN000; + dw None ; ;AN000; + dw Switch_Buffer ; ;AN000; + dw No_Value ; ;AN000; + db 1 ; ;AN000; + db "/1",0 ; ;AN000; + +Switch_8_Control label byte ; ;AN000; + + dw None ; ;AN000; + dw None ; ;AN000; + dw Switch_Buffer ; ;AN000; + dw No_Value ; ;AN000; + db 1 ; ;AN000; + db "/8",0 ; ;AN000; + +Switch_B_Control label byte ; ;AN000; + + dw None ; ;AN000; + dw None ; ;AN000; + dw Switch_Buffer ; ;AN000; + dw No_Value ; ;AN000; + db 1 ; ;AN000; + db "/B",0 ; ;AN000; + +Switch_T_Control label byte ; ;AN000; + + dw Numeric_Value ; ;AN000; + dw None ; ;AN000; + dw Switch_Num_Buffer ; ;AN000; + dw Switch_T_Value ; ;AN000; + db 1 ; ;AN000; + db "/T",0 ; ;AN000; + +Switch_N_Control label byte ; ;AN000; + + dw Numeric_Value ; ;AN000; + dw None ; ;AN000; + dw Switch_Num_Buffer ; ;AN000; + dw Switch_N_Value ; ;AN000; + db 1 ; ;AN000; + db "/N",0 ; ;AN000; + +Switch_Select_Control label byte ; ;AN000; + + dw None ; ;AN000; + dw None ; ;AN000; + dw Switch_Buffer ; ;AN000; + dw No_Value ; ;AN000; + db 1 ; ;AN000; + db "/SELECT",0 ; ;AN000; + +Switch_Backup_Control label byte ; ;AN000; + + dw None ; ;AN000; + dw None ; ;AN000; + dw Switch_Buffer ; ;AN000; + dw No_Value ; ;AN000; + db 1 ; ;AN000; + db "/BACKUP",0 ; ;AN000; + +Switch_Autotest_Control label byte ; ;AN000; + + dw None ; ;AN000; + dw None ; ;AN000; + dw Switch_Buffer ; ;AN000; + dw No_Value ; ;AN000; + db 1 ; ;AN000; + db "/AUTOTEST",0 ; ;AN000; + +Switch_F_Control label byte ; ;AN001; + dw Simple_String ;/F:xxxxx ;AN001; + dw File_Table_Capitalize ;Make it uppercase ;AN001; + dw Switch_String_Buffer ; ;AN001; + dw Switch_Size_Value ; ;AN001; + db 1 ; ;AN001; + db "/F",0 ; ;AN001; + +IF ShipDisk + +Switch_Z_Control label byte ;control structure for /Z ;an000; dms; + dw None ; ;an000; dms; + dw None ; ;an000; dms; + dw Switch_Buffer ; ;an000; dms; + dw No_Value ; ;an000; dms; + db 1 ; ;an000; dms; + db "/Z",0 ; ;an000; dms; + +ENDIF + +; +;************************************************************************ +; PARSE Value Lists +;************************************************************************ +; + +Switch_T_Value label byte ; ;AN000; + + db 1 ;Range only ;ANOOO; + db 1 ;1 range ;ANOOO; + db Range_OK ;Item_Tag ;ANOOO; + dd 1 ;1 is low bound ;ANOOO; + dd 1024 ;2**10 is max ;AN000; + +Switch_N_Value label byte ; ;AN000; + + db 1 ;Range only ;ANOOO; + db 1 ;1 range ;ANOOO; + db Range_OK ;Item_Tag ;ANOOO; + dd 1 ;1 is low bound ;ANOOO; + dd 64 ;2**6 is max ;AN000; + +Switch_Size_Value label byte ; ;AN001; + + db 3 ;Look for strings ;AN001; + db 0 ;No ranges ;AN001; + db 0 ;No numerics ;AN001; + db 27 ;16 possible strings ;AN001; + db Size_160 ; ;AN001; + dw String_160k_1 ;/F:160 ;AN001; + db Size_160 ; ;AN001; + dw String_160k_2 ;/F:160K ;AN001; + db Size_160 ; ;AN001; + dw String_160k_3 ;/F:160KB ;AN001; + db Size_180 ; ;AN001; + dw String_180k_1 ;/F:180 ;AN001; + db Size_180 ; ;AN001; + dw String_180k_2 ;/F:180K ;AN001; + db Size_180 ; ;AN001; + dw String_180k_3 ;/F:180KB ;AN001; + db Size_320 ; ;AN001; + dw String_320k_1 ;/F:320 ;AN001; + db Size_320 ; ;AN001; + dw String_320k_2 ;/F:320K ;AN001; + db Size_320 ; ;AN001; + dw String_320k_3 ;/F:320KB ;AN001; + db Size_360 ; ;AN001; + dw String_360k_1 ;/F:360 ;AN001; + db Size_360 ; ;AN001; + dw String_360k_2 ;/F:360K ;AN001; + db Size_360 ; ;AN001; + dw String_360k_3 ;/F:360KB ;AN001; + db Size_720 ; ;AN001; + dw String_720k_1 ;/F:720 ;AN001; + db Size_720 ; ;AN001; + dw String_720k_2 ;/F:720K ;AN001; + db Size_720 ; ;AN001; + dw String_720k_3 ;/F:720KB ;AN001; + db Size_1200 ; ;AN001; + dw String_1200k_1 ;/F:1200 ;AN001; + db Size_1200 ; ;AN001; + dw String_1200k_2 ;/F:1200K ;AN001; + db Size_1200 ; ;AN001; + dw String_1200k_3 ;/F:1200KB ;AN001; + db Size_1200 ; ;AN001; + dw String_1200k_4 ;/F:1.2 ;AN001; + db Size_1200 ; ;AN001; + dw String_1200k_5 ;/F:1.2M ;AN001; + db Size_1200 ; ;AN001; + dw String_1200k_6 ;/F:1.2MB ;AN001; + db Size_1440 ; ;AN001; + dw String_1440k_1 ;/F:1440 ;AN001; + db Size_1440 ; ;AN001; + dw String_1440k_2 ;/F:1440K ;AN001; + db Size_1440 ; ;AN001; + dw String_1440k_3 ;/F:1440KB ;AN001; + db Size_1440 ; ;AN001; + dw String_1440k_4 ;/F:1.44 ;AN001; + db Size_1440 ; ;AN001; + dw String_1440k_5 ;/F:1.44M ;AN001; + db Size_1440 ; ;AN001; + dw String_1440k_6 ;/F:1.44MB ;AN001; + + +No_Value label byte ; ;AN000; + db 0 ; ;AN000; + +; +;***************************************************************************** +; Data Area for value lists +;***************************************************************************** +; + +; +;The following are a list of the allowed strings for the /F:xxxxx switch. +; + +String_160k_1 db "160" ,Asciiz_End ; ;AN001; +String_160k_2 db "160K" ,Asciiz_End ; ;AN001; +String_160k_3 db "160KB" ,Asciiz_End ; ;AN001; +String_180k_1 db "180" ,Asciiz_End ; ;AN001; +String_180k_2 db "180K" ,Asciiz_End ; ;AN001; +String_180k_3 db "180KB" ,Asciiz_End ; ;AN001; +String_320k_1 db "320" ,Asciiz_End ; ;AN001; +String_320k_2 db "320K" ,Asciiz_End ; ;AN001; +String_320k_3 db "320KB" ,Asciiz_End ; ;AN001; +String_360k_1 db "360" ,Asciiz_End ; ;AN001; +String_360k_2 db "360K" ,Asciiz_End ; ;AN001; +String_360k_3 db "360KB" ,Asciiz_End ; ;AN001; +String_720k_1 db "720" ,Asciiz_End ; ;AN001; +String_720k_2 db "720K" ,Asciiz_End ; ;AN001; +String_720k_3 db "720KB" ,Asciiz_End ; ;AN001; +String_1200k_1 db "1200" ,Asciiz_End ; ;AN001; +String_1200k_2 db "1200K",Asciiz_End ; ;AN001; +String_1200k_3 db "1200KB",Asciiz_End ; ;AN001; +String_1200k_4 db "1.2" ,Asciiz_End ; ;AN001; +String_1200k_5 db "1.2M" ,Asciiz_End ; ;AN001; +String_1200k_6 db "1.2MB" ,Asciiz_End ; ;AN001; +String_1440k_1 db "1440" ,Asciiz_End ; ;AN001; +String_1440k_2 db "1440K",Asciiz_End ; ;AN001; +String_1440k_3 db "1440KB",Asciiz_End ; ;AN001; +String_1440k_4 db "1.44",Asciiz_End ; ;AN001; +String_1440k_5 db "1.44M",Asciiz_End ; ;AN001; +String_1440k_6 db "1.44MB",Asciiz_End ; ;AN001; + +; +;************************************************************************ +; PARSE Return Buffers +;************************************************************************ +; + +Drive_Letter_Buffer Drive_Letter_Return <> ;Example of structure ;AN000; +Switch_Buffer Switch_Return <> ; ;AN000; +Switch_Num_Buffer Switch_Num_Return <> ; ;AN000; +Switch_String_Buffer Switch_String_Return <> ; ;AN000; + +data ends + +; +;***************************************************************************** +; SysParse Routines +;***************************************************************************** +; + + +code segment public para 'CODE' + assume cs:code,ds:Data + +FarSW equ Not_Include ;AN000; +DateSW equ Not_Include ; ;AN000; +TimeSW equ Not_Include ; ;AN000; +FileSW equ Do_Include ; ;AN000; +CAPSW equ Do_Include ; ;AN000; +CmpxSW equ Not_Include ; ;AN000; +NumSW equ Do_Include ; ;AN000; +KeySW equ Not_Include ; ;AN000; +SwSW equ Do_Include ; ;AN000; +Val1SW equ DO_Include ; ;AN000; +Val2SW equ Not_Include ; ;AN000; +Val3SW equ Do_Include ; ;AN001; +DrvSW equ Do_Include ; ;AN000; +QusSW equ Do_Include ; ;AN000; + +INCLUDE PARSE.ASM ; ;AN000; + + +code ends diff --git a/v4.0/src/CMD/FORMAT/FORPROC.ASM b/v4.0/src/CMD/FORMAT/FORPROC.ASM new file mode 100644 index 0000000..bbf139a --- /dev/null +++ b/v4.0/src/CMD/FORMAT/FORPROC.ASM @@ -0,0 +1,521 @@ +; SCCSID = @(#)forproc.asm 1.2 85/07/25 +; +.xlist +.xcref +BREAK MACRO subtitle + SUBTTL subtitle + PAGE +ENDM + + INCLUDE FORCHNG.INC + INCLUDE SYSCALL.INC + INCLUDE FOREQU.INC + INCLUDE FORMACRO.INC + INCLUDE FORSWTCH.INC + INCLUDE IOCTL.INC +.cref +.list +data segment public para 'DATA' +data ends + +code segment public para 'CODE' + assume cs:code,ds:data + + PUBLIC FormatAnother?,Yes?,REPORT,USER_STRING + public fdsksiz,badsiz,syssiz,datasiz,biosiz + public AllocSize,AllocNum + + extrn std_printf:near,crlf:near,PrintString:near + extrn Multiply_32_Bits:near + extrn AddToSystemSize:near + +data segment public para 'DATA' + extrn driveLetter:byte + extrn msgInsertDisk:byte + extrn msgFormatAnother?:byte + extrn msgTotalDiskSpace:byte + extrn msgSystemSpace:byte + extrn msgBadSpace:byte + extrn msgDataSpace:byte + extrn Read_Write_Relative:byte + extrn msgAllocSize:byte + extrn MsgAllocNum:Byte + extrn deviceParameters:byte + extrn bios:byte + extrn dos:byte + extrn command:byte + extrn Serial_Num_Low:Word + extrn Serial_Num_High:Word + extrn msgSerialNumber:Byte + extrn SwitchMap:Word + + + extrn inbuff:byte + +fdsksiz dd 0 + +syssiz dd 0 +biosiz dd 0 + +badsiz dd 0 + +datasiz dd 0 + +AllocSize dd 0 ; ;AN000; +AllocNum dw 0 ; ;AN000; + dw offset driveLetter +data ends + +FormatAnother? proc near +; Wait for key. If yes return carry clear, else no. Insures +; explicit Y or N answer. + Message msgFormatAnother? ; ;AC000; + CALL Yes? + JNC WAIT20 + JZ WAIT20 + CALL CRLF + JMP SHORT FormatAnother? +WAIT20: ; ;AC000; + RET ; ;AC000; +FormatAnother? endp + +;***************************************************************************** +;Routine name:Yes? +;***************************************************************************** +; +;Description: Validate that input is valid Y/N for the country dependent info +; Wait for key. If YES return carry clear,else carry set. +; If carry is set, Z is set if explicit NO, else key was not Yes or No. +; +;Called Procedures: Message (macro) +; User_String +; +;Change History: Created 4/32/87 MT +; +;Input: None +; +;Output: CY = 0 Yes is entered +; CY = 1, Z = No +; CY = 1, NZ = other +; +;Psuedocode +;---------- +; +; Get input (CALL USER STRING) +; IF got character +; Check for country dependent Y/N (INT 21h, AX=6523h Get Ext Country) +; IF Yes +; clc +; ELSE (No) +; IF No +; stc +; Set Zero flag +; ELSE (Other) +; stc +; Set NZ +; ENDIF +; ENDIF +; ELSE (nothing entered) +; stc +; Set NZ flag +; ENDIF +; ret +;***************************************************************************** + +Procedure YES? ; ;AN000; + + call User_String ;Get character ; ; +; $IF NZ ;Got one if returned NZ ;AC000; + JZ $$IF1 + mov al,23h ;See if it is Y/N ;AN000; + mov dl,[InBuff+2] ;Get character ;AN000; + DOS_Call GetExtCntry ;Get country info call ;AN000; + cmp ax,Found_Yes ;Which one? ;AC000; +; $IF E ;Got a Yes ;AC000; + JNE $$IF2 + clc ;Clear CY for return ;AN000; +; $ELSE ;Not a Yes ;AN000; + JMP SHORT $$EN2 +$$IF2: + cmp ax,Found_No ;Is it No? ;AC000; +; $IF E ;Yep ;AN000; + JNE $$IF4 + stc ;Set CY for return ;AC000; +; $ELSE ;Something else we don't want ;AN000; + JMP SHORT $$EN4 +$$IF4: + xor al,al ;Set NZ flag for ret ;AC000; + cmp al,1 ; " " " " ;AC000; + stc ;And CY flag for good measure ;AN000; +; $ENDIF ; ;AN000; +$$EN4: +; $ENDIF ; ;AN000; +$$EN2: +; $ELSE ;No char found at all ;AN000; + JMP SHORT $$EN1 +$$IF1: + xor al,al ;Set NZ flag for ret ;AN000; + cmp al,1 ; " " " " ;AN000; + stc ;And CY flag for good measure ;AN000; +; $ENDIF ; ;AN000; +$$EN1: + ret ; ; ; + +Yes? endp ; ;AN000; + + +USER_STRING: +; Get a string from user. Z is set if user typed no chars (imm CR) +; We need to flush a second time to get rid of incoming Kanji characters also. + MOV AX,(STD_CON_INPUT_FLUSH SHL 8) + 0 ; Clean out input + INT 21H + MOV DX,OFFSET INBUFF + MOV AH,STD_CON_STRING_INPUT + INT 21H + MOV AX,(STD_CON_INPUT_FLUSH SHL 8) + 0 ; Clean out input + INT 21H + CMP BYTE PTR [INBUFF+1],0 + RET + +;********************************************* +; Make a status report including the following information: +; Total disk capacity +; Total system area used +; Total bad space allocated +; Total data space available +; Number of allocation units +; Size of allocation units + +REPORT: + call crlf + + call Calc_System_Space ;an013; dms;calc system space + call Calc_Total_Addressible_Space ;an013; dms;calc total space + + Message msgTotalDiskSpace ; ;AC000; + ;call std_printf + cmp WORD PTR SYSSIZ,0 + JNZ SHOWSYS + cmp WORD PTR SYSSIZ+2,0 + JZ CHKBAD +SHOWSYS: + Message msgSystemSpace ; ;AC000; + ;CALL std_printf ;Report space used by system +CHKBAD: + cmp WORD PTR BADSIZ,0 + JNZ SHOWBAD + cmp WORD PTR BADSIZ+2,0 + JZ SHOWDATA +SHOWBAD: + Message msgBadSpace ; ;AC000; + ;call std_printf +SHOWDATA: + + + MOV CX,WORD PTR Fdsksiz + MOV BX,WORD PTR Fdsksiz+2 + SUB CX,WORD PTR BADSIZ + SBB BX,WORD PTR BADSIZ+2 + SUB CX,WORD PTR SYSSIZ + SBB BX,WORD PTR SYSSIZ+2 + MOV word ptr datasiz,CX + MOV word ptr datasiz+2,BX + Message msgDataSpace ; ;AC000; + ;call std_printf + + call crlf ; ;AN000; + mov ax,deviceParameters.DP_BPB.BPB_BytesPerSector ; ;AN000; + mov cl,deviceParameters.DP_BPB.BPB_SectorsPerCluster ; ;AN000; + xor ch,ch ; ;AN000; + mul cx ;Get bytes per alloc ;AN000; + + mov word ptr AllocSize,ax ;Save allocation size ;AN000; + mov word ptr AllocSize+2,dx ; for message ;AN000; + Message msgAllocSize ;Print size of cluster ;AN000; + call Get_Free_Space ;an013; dms;get disk space + + mov word ptr AllocNum,bx ;Put result in msg ;AN000; + Message msgAllocNum ; = cluster/disk ;AN000; + call crlf ; ;AN000; + test switchmap, SWITCH_8 ;If 8 tracks, don't display ;AN027; + jnz NOSERIALNUMBER ;serial number ;AN027; + Message msgSerialNumber ;Spit out serial number ;AN000; + call crlf ; +NOSERIALNUMBER: ;AN027; + RET ; + +;***************************************************************************** +;Routine name: Read_Disk +;***************************************************************************** +; +;description: Read in data using Generic IOCtl +; +;Called Procedures: None +; +; +;Change History: Created 5/13/87 MT +; +;Input: AL = Drive number (0=A) +; DS:BX = Transfer address +; CX = Number of sectors +; Read_Write_Relative.Start_Sector_High = Number of sectors high +; DX = logical sector number low +; +;Output: CY if error +; AH = INT 25h error code +; +;Psuedocode +;---------- +; Save registers +; Setup structure for function call +; Read the disk (AX=440Dh, CL = 6Fh) +; Restore registers +; ret +;***************************************************************************** + +Procedure Read_Disk ; ;AN000; + + ;This is setup for INT 25h right;AN000; + ;Change it to Read relative sect;AN000; + push bx ;Save registers ;AN000; + push cx ; ;AN000; + push dx ; ;AN000; + push si ; ;AN000; + push di ; ;AN000; + push bp ; ;AN000; + push es ; ;AN000; + push ds ; + mov si,data ; ;AN000; + mov es,si ; ;AN000; + + assume es:data,ds:nothing ; ;AN000; + + mov es:Read_Write_Relative.Buffer_Offset,bx ;Get transfer buffer add;AN000; + mov bx,ds ; ;AN000; + mov es:Read_Write_Relative.Buffer_Segment,bx ;Get segment ;AN000; + mov bx,data ;Point DS at parameter list ;AN000; + mov ds,bx ; ;AN000; + + assume ds:data,es:data + + mov Read_Write_Relative.Number_Sectors,cx ;Number of sec to read ;AN000; + mov Read_Write_Relative.Start_Sector_Low,dx ;Start sector ;AN000; + mov bx,offset Read_Write_Relative ; ;AN000; + mov cx,0FFFFh ;Read relative sector ;AN000; + INT 25h ;Do the read ;AN000; + pop dx ;Throw away flags on stack ;AN000; + pop ds ; + pop es ; ;AN000; + pop bp ; ;AN000; + pop di ; ;AN000; + pop si ; ;AN000; + pop dx ;Restore registers ;AN000; + pop cx ; ;AN000; + pop bx ; ;AN000; + ret ; ;AN000; + + +Read_Disk endp ; ;AN000; + +;***************************************************************************** +;Routine name: Write_Disk +;***************************************************************************** +; +;description: Write Data using Generic IOCtl +; +;Called Procedures: None +; +; +;Change History: Created 5/13/87 MT +; +;Input: AL = Drive number (0=A) +; DS:BX = Transfer address +; CX = Number of sectors +; Read_Write_Relative.Start_Sector_High = Number of sectors high +; DX = logical sector number low +; +;Output: CY if error +; AH = INT 26h error code +; +;Psuedocode +;---------- +; Save registers +; Setup structure for function call +; Write to disk (AX=440Dh, CL = 4Fh) +; Restore registers +; ret +;***************************************************************************** + +Procedure Write_Disk ; ;AN000; + + + ;This is setup for INT 26h right + ;Change it to Read relative sect + + push bx ;Save registers ;AN000; + push cx ; ;AN000; + push dx ; ;AN000; + push si ; ;AN000; + push di ; ;AN000; + push bp ; ;AN000; + push es ; ;AN000; + push ds ; + mov si,data ; ;AN000; + mov es,si ; ;AN000; + + assume es:data,ds:nothing ; ;AN000; + + mov es:Read_Write_Relative.Buffer_Offset,bx ;Get transfer buffer add;AN000; + mov bx,ds ; ;AN000; + mov es:Read_Write_Relative.Buffer_Segment,bx ;Get segment ;AN000; + mov bx,data ;Point DS at parameter list ;AN000; + mov ds,bx ; ;AN000; + + assume ds:data,es:data + + mov Read_Write_Relative.Number_Sectors,cx ;Number of sec to write ;AN000; + mov Read_Write_Relative.Start_Sector_Low,dx ;Start sector ;AN000; + mov bx,offset Read_Write_Relative ; ;AN000; + mov cx,0FFFFh ;Write relative sector ;AN000; + INT 26h ;Do the write ;AN000; + pop dx ;Throw away flags on stack ;AN000; + pop ds ; ;AN000; + pop es ; ;AN000; + pop bp ; ;AN000; + pop di ; ;AN000; + pop si ; ;AN000; + pop dx ;Restore registers ;AN000; + pop cx ; ;AN000; + pop bx ; ;AN000; + ret ; ;AN000; + +Write_Disk endp ; ;AN000; + +;========================================================================= +; Calc_Total_Addressible_Space : Calculate the total space that is +; addressible on the the disk by DOS. +; +; Inputs : none +; +; Outputs : Fdsksiz - Size in bytes of the disk +;========================================================================= + +Procedure Calc_Total_Addressible_Space ;an013; dms; + + push ax ;an013; dms;save affected regs + push dx ;an013; dms; + push bx ;an013; dms; + + call Get_Free_Space ;an013; dms;get free disk space + + push bx ;an013; dms;save avail. cluster + push dx ;an013; dms;save total. cluster + + mov ax,dx ;an013; dms;get total clusters + + xor bx,bx ;an013; dms;clear bx + xor cx,cx ;an013; dms;clear cx + mov cl,DeviceParameters.DP_BPB.BPB_SectorsPerCluster ;an013; dms;get total sectors + call Multiply_32_Bits ;an013; dms;multiply + + xor cx,cx ;an013; dms;clear cx + mov cx,DeviceParameters.DP_BPB.BPB_BytesPerSector ;an013; dms;get total bytes + call Multiply_32_Bits ;an013; dms; multiply + + mov word ptr Fdsksiz,ax ;an013; dms;save high word + mov word ptr Fdsksiz+2,bx ;an013; dms;save low word + + pop dx ;an000; dms;get total clusters + pop bx ;an000; dms;get avail clusters + + mov ax,dx ;an013; dms;get total clusters + sub ax,bx ;an013; dms;get bad clusters + + xor bx,bx ;an013; dms;clear bx + xor cx,cx ;an013; dms;clear cx + mov cl,DeviceParameters.DP_BPB.BPB_SectorsPerCluster ;an013; dms;get total sectors + call Multiply_32_Bits ;an013; dms;multiply + + xor cx,cx ;an013; dms;clear cx + mov cx,DeviceParameters.DP_BPB.BPB_BytesPerSector ;an013; dms;get total bytes + call Multiply_32_Bits ;an013; dms; multiply + + sub ax,word ptr syssiz ;an013; dms;account for system + sbb bx,word ptr syssiz+2 ;an013; dms;size + + mov word ptr Badsiz,ax ;an013; dms;save high word + mov word ptr Badsiz+2,bx ;an013; dms;save low word + + pop bx ;an013; dms; + pop dx ;an013; dms;restore regs + pop ax ;an013; dms; + + ret ;an013; dms; + +Calc_Total_Addressible_Space endp ;an013; dms; + + +;========================================================================= +; Get_Free_Space : Get the free space on the disk. +; +; Inputs : none +; +; Outputs : BX - Available space in clusters +; DX - Total space in clusters +;========================================================================= + +Procedure Get_Free_Space ;an013; dms; + + xor ax,ax ;an013; dms;clear ax + mov ah,36h ;an013; dms;Get disk free space + mov dl,driveletter ;an013; dms;get drive letter + sub dl,"A" ;an013; dms;get 0 based number + inc dl ;an013; dms;make it 1 based + int 21h ;an013; dms; + ret ;an013; dms; + +Get_Free_Space endp ;an013; dms; + +;========================================================================= +; Calc_System_Space : This routine calculates the space occupied by +; the system on the disk. +; +; Inputs : DOS.FileSizeInBytes +; BIOS.FileSizeInBytes +; Command.FileSizeInBytes +; +; Outputs : SysSiz - Size of the system +;========================================================================= + +Procedure Calc_System_Space ;an013; dms; + + push ax ;an013; dms;save regs + push dx ;an013; dms; + + mov word ptr SysSiz+0,00h ;an013; dms;clear variable + mov word ptr SysSiz+2,00h ;an013; dms; + + mov ax,word ptr [DOS.FileSizeInBytes+0] ;an013; dms;get low word + mov dx,word ptr [DOS.FileSizeInBytes+2] ;an013; dms;get high word + call AddToSystemSize ;an013; dms;add in values + + mov ax,word ptr [BIOS.FileSizeInBytes+0] ;an013; dms;get bios size + mov dx,word ptr [BIOS.FileSizeInBytes+2] ;an013; dms; + call AddToSystemSize ;an013; dms;add in values + + mov ax,word ptr [COMMAND.FileSizeInBytes+0] ;an013; dms;get command size + mov dx,word ptr [COMMAND.FileSizeInBytes+2] ;an013; dms; + call AddToSystemSize ;an013; dms;add in values + + pop dx ;an013; dms;restore regs + pop ax ;an013; dms; + + ret ;an013; dms; + +Calc_System_Space endp ;an013; dms; + + + +code ends + end + \ No newline at end of file diff --git a/v4.0/src/CMD/FORMAT/FORSWTCH.INC b/v4.0/src/CMD/FORMAT/FORSWTCH.INC new file mode 100644 index 0000000..a795395 --- /dev/null +++ b/v4.0/src/CMD/FORMAT/FORSWTCH.INC @@ -0,0 +1,38 @@ +; +;FORMAT Pre-defined switches + SWITCH_S EQU 0001h ; System transfer + SWITCH_V EQU 0002h ; Volume ID prompt + SWITCH_BACKUP EQU 0004h + SWITCH_C EQU 0008h + SWITCH_T EQU 0010h + SWITCH_N EQU 0020h + SWITCH_1 EQU 0040h + SWITCH_4 EQU 0080h + SWITCH_8 EQU 0100h + SWITCH_B EQU 0200h + SWITCH_SELECT EQU 0400h + SWITCH_AUTOTEST EQU 0800h + SWITCH_F EQU 1000h + SWITCH_FS EQU 2000h + +IF ShipDisk + + SWITCH_Z EQU 4000h ;an000; dms;1 sector/cluster switch + +ENDIF + +; +; The following is a list of equates to define each IBM defined diskette size +; for use with the /F switch + + +Size_160 equ 0001h ;Flag settings for size switch ;AN000; +Size_180 equ 0002h ; ;AN000; +Size_320 equ 0004h ; ;AN000; +Size_360 equ 0008h ; ;AN000; +Size_720 equ 0010h ; ;AN000; +Size_1200 equ 0020h ; ;AN000; +Size_1440 equ 0040h ; ;AN000; + + + diff --git a/v4.0/src/CMD/FORMAT/MAKEFILE b/v4.0/src/CMD/FORMAT/MAKEFILE new file mode 100644 index 0000000..17742c4 --- /dev/null +++ b/v4.0/src/CMD/FORMAT/MAKEFILE @@ -0,0 +1,55 @@ +#************************ makefile for cmd\format ************************* + +msg =..\..\messages +dos =..\..\dos +inc =..\..\inc +hinc =..\..\h +boot =..\..\boot + +# +####################### dependencies begin here. ######################### +# + +all: format.com + +boot.cl1: + copy $(boot)\boot.cl1 + +format.ctl: format.skl $(msg)\$(COUNTRY).msg + +display.obj: display.asm forequ.inc formsg.inc formacro.inc makefile \ + format.ctl format.cl1 format.cl2 format.cla $(inc)\sysmsg.inc \ + $(inc)\msgserv.asm \ + format.clb format.clc formacro.inc + +forexec.obj: forexec.asm forequ.inc makefile $(inc)\syscall.inc \ + formacro.inc + +forlabel.obj: forlabel.asm forequ.inc formacro.inc makefile \ + $(inc)\syscall.inc $(inc)\ioctl.inc $(inc)\dosmac.inc \ + forswtch.inc + +format.obj: format.asm $(inc)\dosmac.inc $(inc)\bpb.inc \ + $(inc)\dirent.inc $(inc)\dpb.inc $(inc)\curdir.inc \ + $(inc)\cpmfcb.inc $(inc)\pdb.inc makefile \ + $(inc)\error.inc $(inc)\syscall.inc $(inc)\ioctl.inc \ + forequ.inc formacro.inc forswtch.inc + +forinit.obj: forinit.asm forequ.inc formacro.inc makefile \ + $(inc)\syscall.inc $(inc)\ioctl.inc forparse.inc \ + forswtch.inc $(inc)\parse.asm $(inc)\psdata.inc + +msfor.obj: msfor.asm $(inc)\dosmac.inc $(inc)\syscall.inc $(inc)\bpb.inc \ + $(inc)\dirent.inc boot.cl1 $(inc)\ioctl.inc \ + $(inc)\boot.inc $(inc)\boot11.inc makefile \ + $(inc)\bootform.inc filesize.inc forequ.inc formacro.inc forswtch.inc + +forproc.obj: forproc.asm $(inc)\syscall.inc makefile forequ.inc \ + formacro.inc forswtch.inc + + +format.com: format.obj forproc.obj msfor.obj forexec.obj display.obj \ + forinit.obj forlabel.obj + link @format.lnk + convert format.exe + del format.exe 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