summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/FORMAT
diff options
context:
space:
mode:
authorGravatar Mark Zbikowski2024-04-25 21:24:10 +0100
committerGravatar Microsoft Open Source2024-04-25 22:32:27 +0000
commit2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch)
tree80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/CMD/FORMAT
parentMerge pull request #430 from jpbaltazar/typoptbr (diff)
downloadms-dos-main.tar.gz
ms-dos-main.tar.xz
ms-dos-main.zip
MZ is back!HEADmain
Diffstat (limited to 'v4.0/src/CMD/FORMAT')
-rw-r--r--v4.0/src/CMD/FORMAT/DISPLAY.ASM177
-rw-r--r--v4.0/src/CMD/FORMAT/FILESIZE.INC6
-rw-r--r--v4.0/src/CMD/FORMAT/FORCHNG.INC135
-rw-r--r--v4.0/src/CMD/FORMAT/FOREQU.INC115
-rw-r--r--v4.0/src/CMD/FORMAT/FOREXEC.ASM637
-rw-r--r--v4.0/src/CMD/FORMAT/FORINIT.ASM1255
-rw-r--r--v4.0/src/CMD/FORMAT/FORLABEL.ASM771
-rw-r--r--v4.0/src/CMD/FORMAT/FORMACRO.INC102
-rw-r--r--v4.0/src/CMD/FORMAT/FORMAT.ASM4509
-rw-r--r--v4.0/src/CMD/FORMAT/FORMAT.LNK8
-rw-r--r--v4.0/src/CMD/FORMAT/FORMAT.SKL229
-rw-r--r--v4.0/src/CMD/FORMAT/FORMSG.INC861
-rw-r--r--v4.0/src/CMD/FORMAT/FORPARSE.INC523
-rw-r--r--v4.0/src/CMD/FORMAT/FORPROC.ASM521
-rw-r--r--v4.0/src/CMD/FORMAT/FORSWTCH.INC38
-rw-r--r--v4.0/src/CMD/FORMAT/MAKEFILE55
-rw-r--r--v4.0/src/CMD/FORMAT/MSFOR.ASM1936
17 files changed, 11878 insertions, 0 deletions
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 @@
1;
2
3;*****************************************************************************
4;*****************************************************************************
5;UTILITY NAME: FORMAT.COM
6;
7;MODULE NAME: DISPLAY.ASM
8;
9;
10; Change List: AN000 - New code DOS 3.3 spec additions
11; AC000 - Changed code DOS 3.3 spec additions
12;*****************************************************************************
13;*****************************************************************************
14
15
16;
17;*****************************************************************************
18; Define Segment ordering
19;*****************************************************************************
20;
21
22
23.SEQ ;
24
25PSP segment public para 'DUMMY'
26PSP ends
27
28data segment public para 'DATA' ;
29Public Test_Data_Start
30Test_Data_Start label byte
31data ends ;
32
33stack segment para stack
34 db 62 dup ("-Stack!-") ; (362-80h) is the additionsal IBM ROM
35 assume ss:stack
36stack ends
37
38
39code segment public para 'CODE' ;
40 assume cs:code,ds:data ;
41code ends
42
43End_Of_Memory segment public para 'BUFFERS' ;
44Public Test_End
45Test_End label byte
46End_Of_Memory ends ;
47
48
49;
50;*****************************************************************************
51; INCLUDE FILES
52;*****************************************************************************
53;
54
55.xlist
56INCLUDE FORCHNG.INC
57INCLUDE FOREQU.INC
58INCLUDE FORMSG.INC
59INCLUDE SYSMSG.INC
60.list
61
62;
63;*****************************************************************************
64; Message Services
65;*****************************************************************************
66;
67
68
69MSG_UTILNAME <FORMAT>
70
71
72data segment public para 'DATA'
73Msg_Services <MSGDATA>
74data ends
75
76code segment public para 'CODE'
77Msg_Services <NEARmsg>
78Msg_Services <LOADmsg>
79Msg_Services <DISPLAYmsg,CHARmsg,NUMmsg>
80Msg_Services <FORMAT.CLA,FORMAT.CLB,FORMAT.CLC,FORMAT.CL1,FORMAT.CL2,FORMAT.CTL>
81code ends
82
83;
84;*****************************************************************************
85; Public Declarations
86;*****************************************************************************
87;
88
89 Public SysDispMsg
90 Public SysLoadMsg
91
92
93;
94;***************************************************************************
95; Message Structures
96;***************************************************************************
97;
98
99
100Message_Table struc ; ;AN000;
101 ;
102Entry1 dw 0 ; ;AN000;
103Entry2 dw 0 ; ;AN000;
104Entry3 dw 0 ; ;AN000;
105Entry4 dw 0 ; ;AN000;
106Entry5 db 0 ; ;AN000;
107Entry6 db 0 ; ;AN000;
108Entry7 dw 0 ; ;AN000;
109 ;
110Message_Table ends ; ;AN000;
111
112
113
114code segment public para 'CODE'
115;*****************************************************************************
116;Routine name&gml Display_Interface
117;*****************************************************************************
118;
119;DescriptioN&gml Save all registers, set up registers required for SysDispMsg
120; routine. This information is contained in a message description
121; table pointed to by the DX register. Call SysDispMsg, then
122; restore registers. This routine assumes that the only time an
123; error will be returned is if an extended error message was
124; requested, so it will ignore error returns
125;
126;Called Procedures: Message (macro)
127;
128;Change History&gml Created 4/22/87 MT
129;
130;Input&gml ES&gmlDX = pointer to message description
131;
132;Output&gml None
133;
134;Psuedocode
135;----------
136;
137; Save all registers
138; Setup registers for SysDispMsg from Message Description Tables
139; CALL SysDispMsg
140; Restore registers
141; ret
142;*****************************************************************************
143
144Public Display_Interface
145Display_Interface proc ; ;AN000;
146
147 push ds ; ;AN000;
148 push ax ;Save registers ;AN000;
149 push bx ; " " " " ;AN000;
150 push cx ; " " " " ;AN000;
151 push dx ; " " " " ;AN000;
152 push si ; " " " " ;AN000;
153 push di ; " " " " ;AN000;
154 mov di,dx ;Change pointer to table ;AN000;
155 mov dx,data ;Point to data segment
156 mov ds,dx ;
157 mov ax,[di].Entry1 ;Message number ;AN000;
158 mov bx,[di].Entry2 ;Handle ;AN000;
159 mov si,[di].Entry3 ;Sublist ;AN000;
160 mov cx,[di].Entry4 ;Count ;AN000;
161 mov dh,[di].Entry5 ;Class ;AN000;
162 mov dl,[di].Entry6 ;Function ;AN000;
163 mov di,[di].Entry7 ;Input ;AN000;
164 call SysDispMsg ;Display the message ;AN000;
165 pop di ;Restore registers ;AN000;
166 pop si ; " " " " ;AN000;
167 pop dx ; " " " " ;AN000;
168 pop cx ; " " " " ;AN000;
169 pop bx ; " " " " ;AN000;
170 pop ax ; " " " " ;AN000;
171 pop ds ; ;AN000;
172 ret ;All done ;AN000;
173
174Display_Interface endp ; ;AN000;
175code ends
176 end
177
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 @@
1
2 %out ..filesize.inc
3
4BIOS_SIZE equ 35000 ;actually
5DOS_SIZE equ 37000 ;actually
6 \ 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 @@
1.xlist
2;
3;
4;*****************************************************************************
5;* *
6;* Change list to FORMAT modules *
7;* *
8;* Lines are tagged ANxxx for new, ACxxx for changed *
9;* --------------------------------------------------------------------------*
10;* 000 - DOS 4.00 Spec additions and DCR's thru unit/function test *
11;* Date: 8/3/87 Developer: MT *
12;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
13;* 001 - DOS 4.00 DCR D146 Add support for /F switch *
14;* Date: 8/13/87 Developer: MT *
15;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
16;* 002 - DOS 4.00 DCR D166 Add logic to detect that switches entered *
17;* multiple times, and print error message *
18;* Date: 8/13/87 Developer: MT *
19;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
20;* 003 - DOS 4.00 PTM P233 Do not allow Cntrl-Break when writing file *
21;* system out, only during the actual format *
22;* Date: 8/14/87 Developer: MT *
23;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
24;* 004 - DOS 4.00 PTM P229 Volume serial number displayed in reverse word *
25;* order from command.com and diskcopy. Reverse order of words *
26;* Date: 8/17/87 Developer: MT *
27;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
28;* 005 - DOS 4.00 DCR D64 Enable for 128k FAT *
29;* Date: 8/19/87 Developer: DMS *
30;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
31;* 006 - DOS 4.00 PTM P320 Not detecting write protect. Needed to use *
32;* extended error messages *
33;* Date 8/20/87 Developer: MT *
34;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
35;* 007 - DOS 4.00 PTM P170 Straighten out the switch check logic to allow *
36;* /B with all diskette formats, add /B/S check, and remove /V/B *
37;* check except for /8 sectored diskettes (old dir and boot record *
38;* Date 8/21/87 Developer: MT *
39;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
40;* 008 - DOS 4.00 PTM P402 Fields that determine switch type not cleared, *
41;* so switches got checked multiple times, causing error *
42;* Date 8/23/87 Developer: MT , DS *
43;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
44;* 009 - DOS 4.00 PTM P341 Check to make sure /N entered with /T *
45;* Date 8/23/87 Developer: MT *
46;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
47;* 010 - DOS 4.00 PTM P233 Capture the CTRL-BREAK interrupt and disable *
48;* it during the writing of the FAT, DIR, and SYSTEM. *
49;* Date 8/25/87 Developer: DMS *
50;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
51;* 012 - DOS 4.00 DCR 200 If the NumberOfFATs field of the BPB is 0 we need *
52;* to calculate various values in the BPB to be used by FORMAT. *
53;* Date 9/10/87 Developer: DMS *
54;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
55;* 013 - DOS 4.00 DCR 208 Set FORMAT in order that the space available it *
56;* reports is consistent with DIR. *
57;* Date 9/11/87 Developer: DMS *
58;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
59;* 014 - DOS 4.00 PTM 1535 Allow access to a non-formatted disk. *
60;* Date 10/15/87 Developer: DMS *
61;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
62;* 015 - DOS 4.00 DCR 390 Multi-Track format of hard media *
63;* Date 12/9/87 Developer: DMS *
64;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
65;* 016 - DOS 4.00 DCR 395 SELECT message support. Use INT 2Fh, function *
66;* ADC1h to print FORMAT disk prompt from SELECT. *
67;* Date 12/14/87 Developer: DMS *
68;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
69;* 017 - DOS 4.00 PTM 3125 SELECT message support. Disable write protect *
70;* message under SELECT option. Addition of exit codes 6 (Drive Not *
71;* Ready" and 7 (Write Protect). *
72;* Date 1/14/88 Developer: DMS *
73;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
74;* 018 - DOS 4.00 PTM 3130 Provide for conditional assembly of the /FS: *
75;* code, since it is not being shipped with DOS 4.00. *
76;* Date 1/26/88 Developer: DMS *
77;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
78;* 019 - DOS 4.00 PTM 3994 FORMAT now has a "heartbeat" when it verifies *
79;* bad sectors. By doing so the user knows the FORMAT is still *
80;* proceeding well. Without this heartbeat, an AT appears to hang *
81;* when the sectors are being verified. This is caused by the slow *
82;* head resets on an AT. *
83;* Date 3/25/88 Developer: DMS *
84;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
85;* 020 - DOS 4.00 PTM 4058 When an invalid Volume ID is entered at the *
86;* volume prompt, FORMAT should go to the next line so that the *
87;* user can see the invalid volume id. *
88;* Date 3/29/88 Developer: DMS *
89;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
90;* 021 - DOS 4.00 PTM 4081 FORMAT was marking the incorrect cluster as *
91;* bad under certain situations. This caused that sector to fail *
92;* when read or written to. *
93;* Date 3/31/88 Developer: DMS *
94;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
95;* 022 - DOS 4.00 PTM 4180 FORMAT was not performing an FCB Close after *
96;* it had done an FCB Create. This caused the change line counter *
97;* to go "haywire". Also a bug was found in the FORMAT retry logic. *
98;* FORMAT was never entering the retry logic because of a CY flag *
99;* always existing on entry to the routine. *
100;* Date 4/15/88 Developer: DMS *
101;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
102;* 023 - DOS 4.00 DCR 524 FORMAT must accept a blank or carriage return to *
103;* allow for a blank volume label. *
104;* Date 4/19/88 Developer: DRM *
105;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
106;* 024 - DOS 4.00 PTM 4487 FORMAT trys to get the A: drive when formatting *
107;* drive B: and then hitting enter for the volume label. There is a *
108;* problem with FCB Close but logic was also changed in FORLABEL.SAL *
109;* to eliminate this condition. *
110;* Date 4/26/88 Developer: DRM *
111;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
112;* 025 - DOS 4.00 PTM 4539 FORMAT accesses the default disk instead of the *
113;* boot disk when the default disk is different than the boot disk. *
114;* This is incorrect behavior because the user could receive a system *
115;* other than what they wanted. *
116;* Date 4/28/88 Developer: DMS *
117;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
118;* 026 - DOS 4.00 PTM 4805 FORMAT A: /B gives invalid bad byte count and *
119;* FORMAT A: /F:160 on an 1.2 Mb drive gives parm error. *
120;* Date 5/10/88 Developer: DMS *
121;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
122;* 027 - DOS 4.00 PTM 4913 FORMAT A: /B displays the serial number of the *
123;* diskette but never writes it to the diskette. Format will no *
124;* display the serial number when formatting with /8. *
125;* Date 5/19/88 Developer: DRM *
126;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
127;* 028 - DOS 4.00 PTM 5023 FORMAT puts just the N of NO NAME in the volume *
128;* label of the boot record. This is corrected in IBMFOR.SAL by *
129;* setting up the CX register correctly. *
130;* Date 6/09/88 Developer: DRM *
131;*****************************************************************************
132;* Note: This is file FORCHNG.INC for updating purposes *
133;*****************************************************************************
134.list
135
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 @@
1; ; ; ;
2
3NO equ 0
4YES equ not NO
5FSExec equ NO ;an018; dms;conditional assembly
6ShipDisk equ NO ;an000; dms;ship disk flag
7
8Boot_ID equ 0AA55h
9DOS_Found equ 0
10
11Not_Include equ 0
12Do_Include equ 1
13
14INIT equ 0
15
16FAT12_File_System equ 01h
17FAT16_File_System equ 04h
18New_File_System equ 06h
19
20FS_String_Max_Length equ 5
21
22Paragraph_Size equ 16 ; ;AN005;
23Len_FS_String_Buffer equ 13
24
25Net_Check equ 1200h
26Assign_Check equ 8000h
27
28Found_Yes equ 1
29Found_No equ 0
30
31Asciiz_End equ 0
32DBCS equ 81h
33DBCS_Blank equ 40h
34DBCS_Vector_Size equ 2
35End_Of_Vector equ 0
36
37
38Blank equ " "
39
40Label_Length equ 11
41CR equ 13
42
43DBCS_VECTOR equ NO
44
45;Limits
46BIG_FAT_THRESHOLD equ 4086
47
48;-------------------------------------------------------------------------------
49
50
51
52
53
54DRNUM EQU 5CH
55
56
57
58; Exit status defines
59ExitOK equ 0
60ExitCtrlC equ 3
61ExitFatal equ 4
62ExitNo equ 5
63
64
65;-------------------------------------------------------------------------------
66; These are the data structures which we will need
67
68
69Media_ID struc
70Media_ID_Info_Level dw 0
71Media_ID_Serial_Number dd 0
72Media_ID_Volume_Label db 11 dup(" ")
73Media_ID_File_System db 8 dup(" ")
74Media_ID ends
75
76
77Relative_Sector_Buffer struc ; ;AN000;
78
79Start_Sector_Low dw ? ;Low word of RBA sector ;AN000;
80Start_Sector_High dw ? ;High word of RBA sector ;AN000;
81Number_Sectors dw ? ;Number of sectors ;AN000;
82Buffer_Offset dw ? ;Address of data buffer ;AN000;
83Buffer_Segment dw ? ; ;AN000;
84
85Relative_Sector_Buffer ends ; ;AN000;
86
87
88;Per system file data structure
89
90a_FileStructure struc
91fileHandle DW ?
92fileSizeInParagraphs DW ?
93fileSizeInBytes DD ?
94fileOffset DD ?
95fileStartSegment DW ?
96fileDate DW ?
97fileTime DW ?
98a_FileStructure ends
99
100;-------------------------------------------------------------------------------
101
102LOGBOOTSECT equ 1
103Set_Drv_Owner equ 0Fh ; IOCTL subfunction
104Custom_Media equ 0F0H ; Media byte for custom format
105Dual_8_Media equ 0FFh ; Dual sided 8 sectored
106Single_8_Media equ 0FEh ; Single sided 8 sectored
107Dual_9_Media equ 0FDh ; Dual sided 9 sectored
108Single_9_Media equ 0FCh ; Single sided 9 sectored
109Dual_15_Media equ 0F9h ; Dual sided 15 sectored
110Fixed_Disk equ 0F8h ; Fixed Disk
111Invalid_Drive equ 000Fh ; Extended error 15
112Max_Format_Size equ 0FFFFh ; Max bytes to Format ;an015; dms;
113Multi_Track_Format equ 02h ; Multi-track format ;an015; dms;
114Single_Track_Format equ 00h ; Single track format ;an015; dms;
115Select_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 @@
1page ,132 ;
2;
3
4;*****************************************************************************
5;*****************************************************************************
6;UTILITY NAME: FORMAT.COM
7;
8;MODULE NAME: FOREXEC.SAL
9;
10;
11;
12; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
13; ³EXEC_FS_FORMAT³
14; ÀÄÂÄÄÄÄÄÄÄÄÄÄÄÄÙ
15; ³
16; ³ÚÄÄÄÄÄÄ¿
17; ôShrink³
18; ³ÀÄÄÄÄÄÄÙ
19; ³ÚÄÄÄÄÄÄÄÄÄÄ¿
20; ôSetup_EXEC³
21; ³ÀÄÄÄÄÄÄÄÄÄÄÙ
22; ³ÚÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿
23; ôEXEC_ArgVÃÄÄÄÄÄÄÄÄÄÄ´EXEC_Program³
24; ³ÀÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ
25; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿
26; ôEXEC_Cur_DirectoryÃÄ´EXEC_Program³
27; ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ
28; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿
29; À´EXEC_RoutineÃÄÄÄÄÄÄÄ´Build_Path_And_EXECÃÄ´EXEC_Program³
30; ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ
31;
32; Change List: AN000 - New code DOS 3.3 spec additions
33; AC000 - Changed code DOS 3.3 spec additions
34;*****************************************************************************
35;*****************************************************************************
36
37title DOS 3.30 FORMAT EXEC Module
38
39IF1
40 %OUT ASSEMBLING: DOS 3.3 FORMAT EXEC LOADER
41 %OUT
42ENDIF
43
44code segment public para 'code'
45 assume cs:code
46code ends
47
48;
49;*****************************************************************************
50; Include files
51;*****************************************************************************
52;
53
54.xlist
55INCLUDE FORCHNG.INC
56INCLUDE FORMACRO.INC
57INCLUDE SYSCALL.INC
58INCLUDE FOREQU.INC
59.list
60
61;
62;*****************************************************************************
63; Public Data
64;*****************************************************************************
65;
66
67 Public Drive_Letter_Msg
68
69;
70;*****************************************************************************
71; Public Routines
72;*****************************************************************************
73;
74
75
76IF FSExec ;an018; dms;if /FS: desired
77
78 Public EXEC_FS_Format
79
80ENDIF ;FSExec ;an018; dms;end /FS: conditional
81
82 Extrn GetFSiz:near
83
84
85;
86;*****************************************************************************
87; External Data Declarations
88;*****************************************************************************
89;
90
91 extrn ExitStatus:Byte
92 extrn Fatal_Error:Byte
93 extrn FS_String_Buffer:Byte
94 extrn msgEXECFailure:Byte
95 extrn PSP_Segment:Word
96 extrn drive:byte
97
98;
99;****************************************************************************
100; Structures
101;****************************************************************************
102;
103
104
105Exec_Block_Parms struc
106Segment_Env dw 0
107Offset_Command dw 0
108Segment_Command dw 0
109Offset_FCB1 dw 0
110Segment_FCB1 dw 0
111Offset_FCB2 dw 0
112Segment_FCB2 dw 0
113
114Exec_Block_Parms ends
115
116
117;
118;****************************************************************************
119; Equates
120;****************************************************************************
121;
122
123
124String_Done equ 0
125No_Error equ 0
126Error equ 1
127Stderr equ 2
128Stack_Space equ 02eh ;an000; dms; IBM addition ROM paras
129
130;
131;****************************************************************************
132; PSP Area
133;****************************************************************************
134;
135
136PSP segment public para 'DUMMY'
137
138org 2Ch
139PSP_ENV_SEGMENT label word
140
141FCB1 equ 5Ch
142
143FCB2 equ 6Ch
144
145org 80h
146Command_Line label byte
147
148
149PSP ends
150
151;
152;****************************************************************************
153; Data Area
154;****************************************************************************
155;
156
157data segment public para 'DATA'
158 assume ds:data,es:nothing
159
160Exec_Block Exec_Block_Parms <>
161EXEC_Path db 66 dup(0)
162
163Drive_Letter_Msg db "A:",0 ;Drive for exec fail message
164
165SP_Save dw ? ;an000; dms;
166SS_Save dw ? ;an000; dms;
167
168
169;These next two should stay togather
170; ---------------------------------------
171 ;
172Path_String db "PATH=" ; ;AN000;
173Len_Path_String equ $ - Path_String ; ;AN000;
174 ;
175;----------------------------------------
176
177
178
179
180;These should stay togather
181; ---------------------------------------
182 ;
183Search_FORMAT db "FORMAT" ; ;AC000;
184Len_Search_FORMAT equ $ - Search_FORMAT ; ; ;
185Search_Format_End equ $
186 ; ; ;
187;----------------------------------------
188
189
190;These next two should stay togather
191; ---------------------------------------
192
193
194
195
196
197data ends
198
199code segment public para 'code'
200 assume cs:code,ds:data
201
202;
203;****************************************************************************
204; Main Routine
205;****************************************************************************
206;
207;
208;
209;
210;
211
212IF FSExec ;an018; dms;if /FS: desired
213
214
215Procedure Exec_FS_Format ; ;AC000;
216
217 Set_Data_Segment ;
218 call Set_FCB1_Drive ;an000;dms;
219 call Shrink ; ; ;
220 mov al,ExitStatus ;Setblock fail? ;AC000;
221 cmp al,Error ; " " " " ; ;
222; $IF NE ;Nah, keep crusin! ;AN000;
223 JE $$IF1
224 call Setup_Exec ; ; ;
225 call Exec_Argv ;try exec from dir BASIC loaded ; ;
226 mov al,ExitStatus ; ;AC000;
227 cmp al,Error ; ; ;
228; $IF E,AND ; ;AC000;
229 JNE $$IF2
230 call Exec_Cur_Directory ; ; ;
231 mov al,ExitStatus ;Try exec from cur directory ;AC000;
232 cmp al,Error ; ; ;
233; $IF E,AND ; ;AC000;
234 JNE $$IF2
235 call EXEC_Routine ; ; ;
236 mov al,ExitStatus ; ;AC000;
237 cmp al,Error ; ; ;
238; $IF E ; ;AC000;
239 JNE $$IF2
240 ; mov bl,FCB1 ;Get target drive from FCB
241 ; mov bl,Drive ;an000;dms;
242 push ds ;an000;dms;save ds
243 push si ;an000;dms;save si
244 mov si,PSP_Segment ;an000;dms;get psp
245 mov ds,si ;an000;dms;put psp in ds
246 assume ds:PSP ;an000;dms;
247
248 mov si,FCB1 ;an000;dms;ptr to 1st. FCB
249 mov bl,byte ptr ds:[si] ;an000;dms;get drive ID
250
251 pop si ;an000;dms;restore si
252 pop ds ;an000;dms;restore ds
253 Set_Data_Segment ;an000;dms;set segments
254
255 cmp bl,0 ;Is it default drive? ;AN000;
256; $IF E ;Yes, turn it into drive letter ;AN000;
257 JNE $$IF3
258 push ax ;Save exit code ;AN000;
259 DOS_Call Get_Default_Drive ;Get the default drive ;AN000;
260 add al,"A" ;Turn into drive letter ;AN000;
261 mov Drive_Letter_Msg,al ;Save it in message ;AN000;
262 pop ax ;Get return code back ;AN000;
263; $ELSE ;Not default, A=1 ;AN000;
264 JMP SHORT $$EN3
265$$IF3:
266 add bl,"A"-1 ;Convert to drive letter ;AN000;
267 mov Drive_Letter_Msg,bl ; ;AN000;
268; $ENDIF ;AN000;
269$$EN3:
270 Message msgEXECFailure ; ;AC000;
271; $ELSE ; ;AN000;
272 JMP SHORT $$EN2
273$$IF2:
274 DOS_Call WaitProcess ; ;AC000;
275 mov ExitStatus,al ; ; ;
276; $ENDIF ; ;AN000;
277$$EN2:
278; $ENDIF
279$$IF1:
280 mov Fatal_Error,YES ;Not really, indicates FS used ;AN000;
281 ret ; ; ;
282
283Exec_FS_Format endp
284
285
286;
287;****************************************************************************
288; Shrink
289;****************************************************************************
290;
291;
292;
293;
294
295
296Procedure Shrink ; ;AC000;
297
298 mov ax,cs ;an000; dms;get code segment
299 mov bx,ds ;an000; dms;get data segment
300 sub ax,bx ;an000; dms;data seg size
301 mov bx,ax ;an000; dms;save paras
302 mov ax,offset End_Program ;Get the offset of end of loader; ;
303 mov cl,4 ;Div by 16 to get para's ; ;
304 shr ax,cl ; ; ;
305 add bx,ax ;an000; dms;add in code space
306 add bx,Stack_Space ;an000; dms;adjust for stack
307 add bx,11h ;an000; dms;give PSP space
308 mov ax,PSP_Segment
309 mov es,ax
310 assume es:nothing
311
312 DOS_Call SetBlock ; ;AC000;
313; $IF C ;If didn't work, quit ;AC000;
314 JNC $$IF9
315 Message msgEXECFailure ; ; ;
316 mov ExitStatus,Error ;Bad stuff, time to quit ;AN000;
317; $ENDIF ; ;AN000;
318$$IF9:
319 ret ; ; ;
320
321Shrink endp ; ;AN000;
322
323
324;
325;****************************************************************************
326; Setup_Exec
327;****************************************************************************
328;
329;
330;
331;
332
333Procedure Setup_Exec ; ;AC000;
334
335 Set_Data_Segment
336 mov ax,PSP_Segment ;Get segment of PSP ;AN000;
337 mov ds,ax ; " " " " ;AN000;
338 ; ;
339 assume ds:PSP
340 ;Setup dword pointer to command line to be passed
341
342 mov es:Exec_Block.Segment_Command,ax ;Segment for command line ; ;
343 mov es:Exec_Block.Offset_Command,offset ds:Command_Line ; ; ;
344
345 ;Setup dword pointer to first FCB to be passed
346
347 mov es:Exec_Block.Segment_FCB1,ax ;Segment for FCB1 ; ;
348 mov es:Exec_Block.Offset_FCB1,offset ds:FCB1 ;Offset of FCB at 05Ch ; ;
349
350 ;Setup dword pointer to second FCB to be passed ; ;
351
352 mov es:Exec_Block.Segment_FCB2,ax ;Segment for FCB2 ; ;
353 mov es:Exec_Block.Offset_FCB2,offset ds:FCB2 ;Offset of FCB at 06Ch ; ;
354
355 ;Setup segment of Environment string, get from PSP ; ;
356
357 mov ax,ds:PSP_Env_Segment ; ; ;
358 mov es:Exec_Block.Segment_Env,ax ; ; ;
359 Set_Data_Segment
360 ret ; ; ;
361
362
363Setup_EXEC endp ; ;AN000;
364
365;
366;****************************************************************************
367; Exec_Argv
368;****************************************************************************
369;
370; Read the environment to get the Argv(0) string, which contains the drive,
371; path and filename that was loaded for FORMAT.COM. This will be used to find
372; the xxxxxfmt.exe, assuming that it is in the same location or path as
373; FORMAT.COM
374;
375
376Procedure EXEC_Argv ; ;AC000;
377
378 Set_Data_Segment ;DS,ES = DATA
379 cld ; ; ;
380 mov ax,Exec_Block.Segment_Env ;Get the environment ; ;
381 mov ds,ax ;Get addressability ; ;
382
383 assume ds:nothing
384
385 xor si,si ;Start at beginning ; ;
386; $DO ;Find argv(0) location ;AN000;
387$$DO11:
388; $DO ;Look for 0 ;AN000;
389$$DO12:
390 inc si ;Get character ; ;
391 cmp byte ptr [si-1],0 ;Find string seperator? ; ;
392; $ENDDO E ;Yep ;AC000;
393 JNE $$DO12
394 inc si ;Get next char ; ;
395 cmp byte ptr [si-1],0 ;Are we at Argv(0)? (00?) ; ;
396; $ENDDO E ;Yes if we found double 0's ;AC000;
397 JNE $$DO11
398 add si,2 ;Skip the word count ; ;
399 mov di,si ;Save where string starts ; ;
400; $DO ;Find length of Argv(0) string ;AN000;
401$$DO15:
402 inc si ;Get char ; ;
403 cmp byte ptr [si-1],0 ;Is it the end? ; ;
404; $ENDDO E ;End found if 0 found ;AC000;
405 JNE $$DO15
406 mov cx,si ;Get number of bytes in string ; ;
407 sub cx,di ;Put in cx reg for rep count ; ;
408 mov si,di ;Point to path ; ;
409 mov di,offset es:EXEC_Path ;Point to where to put it ; ;
410 rep movsb ;Move the string ; ;
411 Set_Data_Segment ; ;AN000'
412 dec di ;Point at end of ArgV string ; ;
413 std ;Look backwards ;AN000;
414; $DO ;Find 'FORMAT' in ARGV string ;AC000;
415$$DO17:
416 mov cx,Len_Search_FORMAT ;Get length to compare ;AC000;
417 mov si,offset Search_FORMAT_End-1 ;Look at comp string from end ;AC000;
418 repe cmpsb ;See if same string ;AC000;
419; $ENDDO E ; ;AC000;
420 JNE $$DO17
421 mov si,offset FS_String_Buffer ; ;AN000;
422 inc di ;DI = replacement point-1 ;AC000;
423 cld ;Set direction flag back ;AN000;
424 mov cx,Len_FS_String_Buffer ;Length of string to move ;AN000;
425 rep movsb ;Build part of the path ; ;
426 call EXEC_Program ; ; ;
427 ret ; ; ;
428
429EXEC_ArgV endp ; ;AN000;
430
431;
432;****************************************************************************
433; EXEC_Program
434;****************************************************************************
435;
436;
437;
438;
439
440Procedure EXEC_Program ; ;AC000;
441
442 Set_Data_Segment ; ;AN000;
443 mov ExitStatus,No_Error ;Setup to Exec the file ; ;
444 mov dx,offset Exec_Path ; ; ;
445 mov bx,offset Exec_Block ; ; ;
446 mov al,0 ; ; ;
447 mov word ptr SP_Save,sp ;an000; dms;save sp
448 mov word ptr SS_Save,ss ;an000; dms;save ss
449
450 DOS_Call Exec ; ;AC000;
451
452 cli ;an000; dms;turn off int's
453 mov sp,word ptr SP_Save ;an000; dms;retrieve sp
454 mov ss,word ptr SS_Save ;an000; dms;retrieve ss
455 sti ;an000; dms;turn on int's
456
457
458; $IF C ;CY means failure ;AC000;
459 JNC $$IF19
460 mov ExitStatus,Error ;Set error code ; ;
461; $ENDIF ; ;AN000;
462$$IF19:
463 ret ; ; ;
464
465EXEC_Program endp ; ;AN000;
466
467
468;
469;****************************************************************************
470; EXEC_Routine
471;****************************************************************************
472;
473;
474;
475;
476
477Procedure EXEC_Routine ; ;AN000;
478
479 Set_Data_Segment ; ;AN000;
480 mov ExitStatus,Error ;Assume the worst ; ;
481 cld ; ; ;
482 push ds ; ; ;
483 mov ax,Exec_Block.Segment_Env ;Get the environment ; ;
484 mov ds,ax ;Get addressability ; ;
485 assume ds:nothing ;
486
487 xor si,si ;Start at beginning ; ;
488; $SEARCH ; ;AC000;
489$$DO21:
490 cmp word ptr ds:[si],0 ;End of the Evironment? ; ;
491; $EXITIF E ;Reached end, no more look ;AC000;
492 JNE $$IF21
493 ; ; ;
494; $ORELSE ;Look for 'PATH=' in environment;AN000;
495 JMP SHORT $$SR21
496$$IF21:
497 mov di,offset Path_String ; " " " " ;AC000;
498 mov cx,Len_Path_String ; " " " " ;AC000;
499 repe cmpsb ; " " " " ;AC000;
500; $LEAVE E ;Found if EQ ;AC000;
501 JE $$EN21
502; $ENDLOOP ;Found PATH in environment ;AC000;
503 JMP SHORT $$DO21
504$$EN21:
505 call Build_Path_And_Exec ; ;AN000;
506; $ENDSRCH ; ; ;
507$$SR21:
508 pop ds ; ; ;
509 ret ; ; ;
510
511EXEC_Routine endp
512
513;
514;****************************************************************************
515; Build_Path_For_EXEC
516;****************************************************************************
517;
518;
519;
520;
521
522Procedure Build_Path_And_Exec ; ;AN000;
523
524; $DO ; ;AC000;
525$$DO27:
526 cmp byte ptr ds:[si],0 ;All path entries done? ; ;
527; $IF NE ; ;AC000;
528 JE $$IF28
529 mov di,offset EXEC_Path ;Point at where to put path ; ;
530 mov byte ptr es:[di],0 ;End path just in case ; ;
531; $DO ; ;AC000;
532$$DO29:
533 cmp byte ptr ds:[si],0 ;End of Path? ; ;
534; $LEAVE E ; ;AC000;
535 JE $$EN29
536 cmp byte ptr ds:[si],';' ;End of entry? ; ;
537; $if e ;yes ;an000; dms;
538 JNE $$IF31
539 inc si ;point to next character ;an000; dms;
540 jmp EXIT_BPE_LOOP ;exit loop ;an000; dms;
541; $endif ; ;an000; dms;
542$$IF31:
543 movsb ;Put char in path string ; ;
544; $ENDDO ; ;AN000;
545 JMP SHORT $$DO29
546$$EN29:
547
548EXIT_BPE_LOOP: ; ;an000; dms;
549 ;Path filled in,get backslash ; ;
550 cmp byte ptr ds:[si-1],0 ;Any path there? ; ;
551; $IF NE ; ;AC000;
552 JE $$IF34
553 ;Nope ; ;
554 cmp byte ptr ds:[si-1],"\" ;Need a backslash? ; ;
555; $IF NE ; ;AC000;
556 JE $$IF35
557 mov byte ptr es:[di],"\" ;Yes, put one in ; ;
558 inc di ;Line it up for next stuff ; ;
559 inc si ; ; ;
560; $ENDIF ; ;AN000;
561$$IF35:
562 push si ;Save place in path
563 push ds ;Save segment for environment ;AN000;
564 push es ;Xchange ds/es ;an000; dms;
565 pop ds ; ;an000; dms;
566 mov si,offset FS_String_Buffer ;Fill in filename ; ;
567 mov cx, Len_FS_String_Buffer ; ; ;
568 rep movsb ; ; ;
569 call Exec_Program ; ; ;
570 cmp ExitStatus,No_Error ;E if EXEC okay ;AN000;
571 pop ds ;Get Env segment back ; ;
572 pop si ;Get place in path back
573; $ENDIF ;E if all paths done ;AN000;
574$$IF34:
575; $ENDIF ;E if all paths done ;AN000;
576$$IF28:
577; $ENDDO E ;Exit if E ;AN000;
578 JNE $$DO27
579 ret ; ;AN000;
580
581Build_Path_And_EXEC Endp ; ;AN000;
582
583
584
585;
586;****************************************************************************
587; Exec_Cur_Directory
588;****************************************************************************
589;
590;
591;
592;
593
594Procedure Exec_Cur_Directory ; ;AC000;
595
596 Set_Data_Segment ; ;AN000;
597 mov si,offset FS_String_Buffer ;Setup path for current dir ; ;
598 mov di,offset EXEC_Path ; ; ;
599 mov cx,Len_FS_String_Buffer ; ; ;
600 rep movsb ; ; ;
601 call EXEC_Program ; ; ;
602 ret ; ; ;
603
604EXEC_Cur_Directory endp ; ;AN000;
605
606;=========================================================================
607; Set_FCB1_Drive : This routine sets the 1st. byte of the FCB1,
608; the drive identifier, to the default drive.
609;=========================================================================
610
611Procedure Set_FCB1_Drive ;an000;dms;set drive ID
612
613 push ds ;an000;dms;save ds
614 push si ;an000;dms;save si
615
616 mov si,PSP_Segment ;an000;dms;get segment of PSP
617 mov ds,si ;an000;dms;put it in ds
618 assume ds:PSP ;an000;dms;
619 mov si,FCB1 ;an000;dms;ptr to FCB1
620 mov byte ptr ds:[si],00h ;an000;dms;set drive ID to
621 ; default drive
622 pop si ;an000;dms;restore si
623 pop ds ;an000;dms;restore ds
624 Set_Data_Segment ;an000;dms;set up segmentation
625 ret ;an000;dms;
626
627Set_FCB1_Drive endp ;an000;dms;
628
629ENDIF ;FSExec ;an018; dms;end /FS: conditional
630 ; assembly
631
632public End_Program
633End_Program label byte
634
635code ends
636 end
637 \ 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 @@
1
2;
3
4
5;*****************************************************************************
6;*****************************************************************************
7;UTILITY NAME: FORMAT.COM
8;
9;MODULE NAME: FORINIT.SAL
10;
11;
12;
13; ÚÄÄÄÄÄÄÄÄÄÄÄ¿
14; ³ Main_Init ³
15; ÀÄÂÄÄÄÄÄÄÄÄÄÙ
16; ³
17; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
18; ôInit_Input_OutputÃÄÄÄÄ´Preload_Messages³
19; ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
20; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
21; ³ ôCheck_For_FS_SwitchÃÄÄ´Parse_For_FS_Switch³
22; ³ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
23; ³ ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
24; ³ ³ À´EXEC_FS_Format³
25; ³ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
26; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
27; ³ À´Parse_Command_Line ÃÄÄÄ´Interpret_Parse³
28; ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
29; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
30; ôValidate_Target_DriveôCheck_Target_Drive³
31; ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
32; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
33; ³ ôCheck_For_Network³
34; ³ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
35; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
36; ³ À´Check_Translate_Drive³
37; ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
38; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿
39; À´Hook_CNTRL_C³
40; ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ
41;
42;
43; Change List: AN000 - New code DOS 3.3 spec additions
44; AC000 - Changed code DOS 3.3 spec additions
45;*****************************************************************************
46;*****************************************************************************
47
48data segment public para 'DATA'
49
50
51Command_Line db NO
52PSP_Segment dw 0
53
54;These should stay togather
55; --------------------------------------- ; ;AN000;
56FS_String_Buffer db 13 dup(" ") ; ;AN000;
57FS_String_End db "FMT.EXE",0 ; ;AN000;
58Len_FS_String_End equ $ - FS_String_End ; ;AN000;
59 ; ;AN000;
60;----------------------------------------
61
62Vol_Label_Count db 80h ;an000; dms;max. string length
63Vol_Label_Len db 00h ;an000; dms;len. entered
64Vol_Label_Buffer db 80h dup(0) ; ;AN000;
65Vol_Label_Buffer_Length equ $ - Vol_Label_Buffer ; ;AN000;
66
67Command_Line_Buffer db 80h dup(0) ; ;AN000;
68Command_Line_Length equ $ - Command_Line_Buffer ; ;AN000;
69Fatal_Error db 0 ; ;AN000;
70
71Command_Old_Ptr dw ?
72
73data ends
74
75code segment public para 'CODE'
76 assume cs:code,ds:data,es:data
77code ends
78
79;
80;*****************************************************************************
81; Include files
82;*****************************************************************************
83;
84
85.xlist
86INCLUDE FORCHNG.INC
87INCLUDE FORMACRO.INC
88INCLUDE SYSCALL.INC
89INCLUDE IOCTL.INC
90INCLUDE FOREQU.INC
91INCLUDE FORPARSE.INC
92INCLUDE FORSWTCH.INC
93.list
94
95;
96;*****************************************************************************
97; Public Data
98;*****************************************************************************
99;
100
101 Public FS_String_Buffer
102 Public Command_Line
103 Public Fatal_Error
104 Public Vol_Label_Count
105 Public Vol_Label_Buffer
106 Public PSP_Segment
107 Public Command_Old_Ptr
108
109
110;
111;*****************************************************************************
112; Public Routines
113;*****************************************************************************
114;
115
116
117 Public Main_Init
118
119;
120;*****************************************************************************
121; External Routine Declarations
122;*****************************************************************************
123;
124
125 Extrn Main_Routine:Near
126 Extrn SysLoadMsg:Near
127 Extrn Get_11_Characters:Near
128 Extrn ControlC_Handler:Near
129 Extrn SysDispMsg:Near
130 Extrn SysLoadMsg:Near
131
132IF FSExec ;/FS: conditional assembly ;an018; dms;
133
134 Extrn EXEC_FS_Format:Near
135
136ENDIF ;/FS: conditional assembly end ;an018;dms;
137
138 Extrn GetDeviceParameters:Near
139;
140;*****************************************************************************
141; External Data Declarations
142;*****************************************************************************
143;
144
145 Extrn SwitchMap:Word
146 Extrn ExitStatus:Byte
147 Extrn Drive:Byte
148 Extrn DriveLetter:Byte
149 Extrn TranSrc:Byte
150 Extrn TrackCnt:Word
151 Extrn NumSectors:Word
152 Extrn BIOSFile:Byte
153 Extrn DOSFile:Byte
154 Extrn CommandFile:Byte
155 Extrn MsgNeedDrive:Byte
156 Extrn MsgBadVolumeID:Byte
157 Extrn MsgBadDrive:Byte
158 Extrn MsgAssignedDrive:Byte
159 Extrn MsgNetDrive:Byte
160 Extrn Parse_Error_Msg:Byte
161 Extrn Extended_Error_Msg:Byte
162 Extrn SizeMap:Byte
163 Extrn MsgSameSwitch:Byte
164 Extrn Org_AX:word ;an000; dms;AX on prog. entry
165 Extrn DeviceParameters:Byte ;an000; dms;
166 Extrn FAT_Flag:Byte ;an000; dms;
167 Extrn Sublist_MsgParse_Error:Dword ;an000; dms;
168
169
170code segment public para 'CODE'
171
172;*****************************************************************************
173;Routine name: Main_Init
174;*****************************************************************************
175;
176;Description: Main control routine for init section
177;
178;Called Procedures: Message (macro)
179; Check_DOS_Version
180; Init_Input_Output
181; Validate_Target_Drive
182; Hook_CNTRL_C
183;
184;Input: None
185;
186;Output: None
187;
188;Change History: Created 5/1/87 MT
189;
190;Psuedocode
191; ---------
192;
193; Get PSP segment
194; Fatal_Error = NO
195; Setup I/O (CALL Init_Input_Output)
196; IF !Fatal_Error
197; Check target drive letter (CALL Validate_Target_Drive)
198; IF !Fatal_Error
199; Set up Control Break (CALL Hook_CNTRL_C)
200; IF !Fatal_Error
201; CALL Main_Routine
202; ENDIF
203; ENDIF
204; ENDIF
205; Exit program
206;*****************************************************************************
207
208Procedure Main_Init ; ;AN000;
209
210
211 Set_Data_Segment ;Set DS,ES to Data segment ;AN000;
212 DOS_Call GetCurrentPSP ;Get PSP segment address
213 mov PSP_Segment,bx ;Save it for later
214 mov Fatal_Error,No ;Init the error flag ;AN000;
215 call Init_Input_Output ;Setup messages and parse ;AN000;
216 cmp Fatal_Error,Yes ;Error occur? ;AN000;
217; $IF NE ;Nope, keep going ;AN000;
218 JE $$IF1
219 call Validate_Target_Drive ;Check drive letter ;AN000;
220 cmp Fatal_Error,Yes ;Error occur? ;AN000;
221; $IF NE ;Nope, keep going ;AN000;
222 JE $$IF2
223 call Hook_CNTRL_C ;Set CNTRL -Break hook ;AN000;
224 cmp Fatal_Error,Yes ;Error occur? ;AN000;
225; $IF NE ;Nope, keep going ;AN000;
226 JE $$IF3
227 call Main_Routine ;Go do the real program ;AN000;
228; $ENDIF ; ;AN000;
229$$IF3:
230; $ENDIF ; ;AN000;
231$$IF2:
232; $ENDIF ; ;AN000;
233$$IF1:
234 mov al,ExitStatus ;Get Errorlevel ;AN000;
235 DOS_Call Exit ;Exit program ;AN000;
236 int 20h ;If other exit fails ;AN000;
237
238Main_Init endp ; ;AN000;
239
240;*****************************************************************************
241;Routine name: Init_Input_Output
242;*****************************************************************************
243;
244;Description: Initialize messages, Parse command line, allocate memory as
245; needed. If there is a /FS switch, go handle it first as
246; syntax of IFS format may be different from FAT format.
247;
248;Called Procedures: Preload_Messages
249; Parse_For_FS_Switch
250; Parse_Command_Line
251;
252;Change History: Created 4/1/87 MT
253;
254;Input: PSP command line at 81h and length at 80h
255; Fatal_Error = No
256;
257;Output: Fatal_Error = YES/NO
258;
259;Psuedocode
260;----------
261;
262; Load messages (CALL Preload_Messages)
263; IF !Fatal_Error
264; See if EXEC another file system (CALL Parse_For_FS_Switch)
265; IF !FATAL_Error (in this case means FS was found and exec'd)
266; CALL Parse_Command_Line
267; IF !Fatal_Error
268; CALL Interpret_Parse
269; ENDIF
270; ENDIF
271; ENDIF
272; ret
273;*****************************************************************************
274
275Procedure Init_Input_Output ; ;AN000;
276
277 Set_Data_Segment ;Set DS,ES to Data segment ;AN000;
278 call Preload_Messages ;Load up message retriever ;AN000;
279
280IF FSExec ;/FS: conditional assembly ;an018; dms;
281
282 cmp Fatal_Error,YES ;Quit? ;AN000;
283; $IF NE ;Nope, keep going ;AN000;
284 JE $$IF7
285 call Check_For_FS_Switch ;Specify FS other than FAT? ;AN000;
286
287ENDIF ;/FS: conditional assembly end ;an018;dms;
288
289 cmp Fatal_Error,YES ;drive is invalid for format? ;an000;
290; $if ne ;no ;an000;
291 JE $$IF8
292 call Parse_Command_Line ;Parse in command line input ;AN000;
293 cmp Fatal_Error,YES ;Quit? ;AN000;
294; $IF NE ;Nope, keep going ;AN000;
295 JE $$IF9
296 call Determine_FAT_Non_FAT;see if drive was non_FAT ;an000;
297 call Check_For_Invalid_Drive;Drive joined? ;an000;
298; $ENDIF ; ;AN000;
299$$IF9:
300; $ENDIF ; ;AN000;
301$$IF8:
302
303IF FSExec ;/FS: conditional assembly ;an018; dms;
304
305; $ENDIF ; ;an000;
306$$IF7:
307
308ENDIF ;/FS: conditional assembly end ;an018;dms;
309
310 ret ; ;AN000;
311
312Init_Input_Output endp ; ;AN000;
313
314;*****************************************************************************
315;Routine name: Preload_Messages
316;*****************************************************************************
317;
318;Description: Preload messages using common message retriever routines.
319;
320;Called Procedures: SysLoadMsg
321;
322;
323;Change History: Created 5/1/87 MT
324;
325;Input: Fatal_Error = NO
326;
327;Output: Fatal_Error = YES/NO
328;
329;Psuedocode
330;----------
331;
332; Preload All messages (Call SysLoadMsg)
333; IF error
334; Display SysLoadMsg error message
335; Fatal_Error = YES
336; ENDIF
337; ret
338;*****************************************************************************
339
340Procedure Preload_Messages ; ;AN000;
341 ;
342 Set_Data_Segment ;Set DS,ES to Data segment ;AN000;
343 call SysLoadMsg ;Preload the messages ;AN000;
344; $IF C ;Error? ;AN000;
345 JNC $$IF13
346 call SysDispMsg ;Display preload msg ;AN000;
347 mov Fatal_Error, YES ;Indicate error exit ;AN000;
348; $ENDIF ; ;AN000;
349$$IF13:
350 ret ; ;AN000;
351
352Preload_Messages endp ; ;AN000;
353
354
355
356
357IF FSExec ;/FS: conditional assembly ;an018; dms;
358
359
360;*****************************************************************************
361;Routine name: Check_For_FS_Switch
362;*****************************************************************************
363;
364;Description: Parse to see if /FS switch entered, and if so, go EXEC the
365; asked for file system. Set Fatal_Error = YES if FS found
366; If we do find /FS, we need to build a string of xxxxxfmt.exe,0
367; where xxxxx is the first 5 characters or less of /FS:xxxxx
368;
369;Called Procedures: Parse_For_FS_Switch
370; EXEC_FS_Format
371;
372;Change History: Created 6/21/87 MT
373;
374;Input: Fatal_Error = NO
375;
376;Output: Fatal_Error = YES/NO
377; Exit_Status set
378;
379;Psuedocode
380;----------
381;
382; Parse for /FS switch (CALL Parse_For_FS_Switch)
383; IF !FATAL_ERROR
384; IF /FS found
385; Point at what was entered on /FS:xxxxx
386; DO
387; LEAVE end of entered string
388; Got good char, move into path
389; ENDDO already got 5 chars (max in xxxxxfmt.exe)
390; Tack on the rest of the string (fmt.exe,0)
391; Go exec the needed format (CALL EXEC_FS_Format)
392; ENDIF
393; ENDIF
394; ret
395;*****************************************************************************
396
397Procedure Check_For_FS_Switch ; ;AN000;
398 ;AN000;
399 Set_Data_Segment ;Set DS,ES to Data segment ;AN000;
400 call Parse_For_FS_Switch ;See if /FS entered ;AN000;
401 cmp Fatal_Error,YES ;Bad stuff entered?? ;AN000;
402; $IF NE ;Nope, cruise onward ;AN000;
403 JE $$IF15
404 cmp Switch_String_Buffer.Switch_Pointer,offset Switch_FS_Control.Keyword ; ;AN000;
405; $IF E ;We got the switch ;AN000;
406 JNE $$IF16
407 mov Switch_FS_Control.Keyword,20h ;an000; dms;remove switch from table
408 test SwitchMap,Switch_FS ;Have this already? ;AN002;
409; $IF Z ;Nope ;AN002;
410 JNZ $$IF17
411 push ds ;Get addressibility ;AN000;
412 pop es ; " " " " ;AN000;
413 ;
414 assume ds:nothing,es:data ; ;AN000;
415 ;
416 mov ax,Switch_String_Buffer.Switch_String_Seg ;Get the entered FS ;AN000;
417 mov ds,ax ; ;AN000;
418 mov si,es:Switch_String_Buffer.Switch_String_Off ; ;AN000;
419 mov cx,FS_String_Max_Length ; ;AN000;
420 mov di,offset es:FS_String_Buffer ; ;AN000;
421; $DO ;Move whatever user entered ;AN000;
422$$DO18:
423 cmp byte ptr [si],ASCIIZ_End ;End of the string? ;AN000;
424; $LEAVE E ;Yep ;AN000;
425 JE $$EN18
426 movsb ;Put character in buffer ;AN000;
427 dec cx ;Dec character counter
428 cmp cx,0 ;Nope, reached max # chars? ;AN000;
429; $ENDDO E ;Yes ;AN000;
430 JNE $$DO18
431$$EN18:
432 Set_Data_Segment ;Set DS,ES to Data segment ;AN000;
433 mov cx,Len_FS_String_End ;Tack the FMT.EXE onto it ;AN000;
434 mov si,offset es:FS_String_End ;DI still points at string ;AN000;
435 rep movsb ;We now have Asciiz path! ;AN000;
436 call EXEC_FS_Format ;Go try to EXEC it..... ;AN000;
437; $ELSE ; ;AN002;
438 JMP SHORT $$EN17
439$$IF17:
440 Message msgSameSwitch ; ;AN002;
441 mov Fatal_Error,Yes ; ;AN002;
442; $ENDIF ; ;AN002;
443$$EN17:
444; $ENDIF ; ;AN000;
445$$IF16:
446; $ENDIF ; ;AN000;
447$$IF15:
448 ret ; ;AN000;
449
450Check_For_FS_Switch endp ; ;AN000;
451
452;*****************************************************************************
453;Routine name: Parse_For_FS_Switch
454;*****************************************************************************
455;
456;Description: Copy the command line. Parse the new command line (Parse routines
457; destroy the data being parsed, so need to work on copy so that
458; complete command line can be passed to child format).
459; The only thing we care about is if the /FS: switch exists, so
460; parse until end of command line found. If there was an error,
461; and it occurred on the /FS switch, then give parse error,
462; otherwise ignore the parse error, because it might be something
463; file system specific that doesn't meet DOS syntax rules. Also
464; check for drive letter, as it is alway required.
465;
466;Called Procedures: Message (macro)
467; SysLoadMsg
468; Preload_Error
469; SysParse
470;
471;Change History: Created 5/1/87 MT
472;
473;Input: Command line at 80h in PSP
474; Fatal_Error = NO
475; PSP_Segment
476;
477;Output: Fatal_Error = YES/NO
478;
479;Psuedocode
480;----------
481; Copy command line to buffer
482; DO
483; Parse command line (Call SysParse)
484; LEAVE end of parse
485; ENDDO found /FS
486; IF drive letter not found (This assumes drive letter before switches)
487; Tell user
488; Fatal_Error = YES
489; ENDIF
490; ret
491;*****************************************************************************
492
493Procedure Parse_For_FS_Switch ; ;AN000;
494 ;
495 Set_Data_Segment ;Set DS,ES to Data segment ;AN000;
496 mov Drive_Letter_Buffer.Drive_Number,Init ; ;AN000;
497 mov cx,PSP_Segment ;Get segment of PSP ;AN000;
498 mov ds,cx ; " " " " ;AN000;
499 assume ds:nothing ;
500 ;
501 mov si,Command_Line_Parms ;Point at command line ;AN000;
502 mov di,offset data:Command_Line_Buffer ;Where to put a copy of it ;AN000;
503 mov cx,Command_Line_Length ;How long was input? ;AN000;
504 repnz movsb ;Copy it ;AN000;
505 Set_Data_Segment ;Set DS,ES to Data segment ;AN000;
506 xor cx,cx ; ;AN000;
507 xor dx,dx ;Required for SysParse call ;AN000;
508 mov si,offset Command_Line_Buffer ;Pointer to parse line ;AN000;
509 mov di,offset Switch_FS_Table ;Pointer to control table ;AN000;
510; $DO ;Setup parse call ;AN000;
511$$DO25:
512 call SysParse ;Go parse ;AN000;
513 cmp ax,End_Of_Parse ;Check for end of parse ;AN000;
514; $LEAVE E,OR ;Exit if it is end, or ;AN000;
515 JE $$EN25
516 cmp ax,Operand_Missing ; exit if positional missing ;AN000;
517; $LEAVE E ;In other words, no drive letter;AN000;
518 JE $$EN25
519 cmp Switch_String_Buffer.Switch_Pointer,offset Switch_FS_Control.Keyword ;AN000;
520; $ENDDO E ;Exit if we find /FS ;AN000;
521 JNE $$DO25
522$$EN25:
523 cmp Drive_Letter_Buffer.Drive_Type,Type_Drive ;Check for drive letter found;AN000;
524; $IF NE ;Did we not find one? ;AN000;
525 JE $$IF28
526 MESSAGE msgNeedDrive ;Must enter drive letter ;AN000;
527 mov Fatal_Error,Yes ;Indicate error on exit ;AN000;
528; $ENDIF ; ;AN000;
529$$IF28:
530 ret ; ;AN000;
531
532Parse_For_FS_Switch endp ; ;AN000;
533
534
535ENDIF ;/FS: conditional assembly end ;an018;dms;
536
537
538;*****************************************************************************
539;Routine name: Parse_Command_Line
540;*****************************************************************************
541;
542;Description: Parse the command line. Check for errors, and display error and
543; exit program if found. Use parse error messages except in case
544; of no parameters, which has its own message
545;
546;Called Procedures: Message (macro)
547; SysParse
548; Interpret_Parse
549;
550;Change History: Created 5/1/87 MT
551;
552;Input: Fatal_Error = NO
553; PSP_Segment
554;
555;Output: Fatal_Error = YES/NO
556;
557;
558;Psuedocode
559;----------
560;
561; Assume Fatal_Error = NO on entry
562; SEARCH
563; EXITIF Fatal_Error = YES,OR (This can be set by Interpret_Parse)
564; Parse command line (CALL SysParse)
565; EXITIF end of parsing command line
566; Figure out last thing parsed (Call Interpret_Parse)
567; ORELSE
568; See if parse error
569; LEAVE parse error,OR
570; See what was parsed (Call Interpret_Parse)
571; LEAVE if interpret error such as bad volume label
572; ENDLOOP
573; Display parse error message and print error operand
574; Fatal_Error = YES
575; ENDSRCH
576; ret
577;*****************************************************************************
578
579Procedure Parse_Command_Line ; ;AN000;
580
581 Set_Data_Segment ;Set DS,ES to Data segment ;AN000;
582 push ds
583 mov cx,PSP_Segment ;Get segment of PSP ;AN000;
584 mov ds,cx ; " " " " ;AN000;
585
586 assume ds:nothing,es:data
587
588 xor cx,cx ;Parse table @DI ;AN000;
589 xor dx,dx ;Parse line @SI ;AN000;
590 mov si,Command_Line_Parms ;Pointer to parse line ;AN000;
591 mov word ptr es:Command_Old_Ptr,si
592 mov di,offset es:Command_Line_Table ;Pointer to control table ;AN000;
593; $SEARCH ;Loop until all parsed ;AN000;
594$$DO30:
595 cmp es:Fatal_Error,Yes ;Interpret something bad? ;AN000;
596; $EXITIF E,OR ;If so, don't parse any more ;AN000;
597 JE $$LL31
598 call SysParse ;Go parse ;AN000;
599 cmp ax,End_Of_Parse ;Check for end of parse ;AN000;
600; $EXITIF E ;Is it? ;AN000;
601 JNE $$IF30
602$$LL31:
603 ;All done ;AN000;
604; $ORELSE ;Not end ;AN000;
605 JMP SHORT $$SR30
606$$IF30:
607 cmp ax,0 ;Check for parse error ;AN000;
608; $LEAVE NE ;Stop if there was one ;AN000;
609 JNE $$EN30
610 mov word ptr es:Command_Old_Ptr,si
611 call Interpret_Parse ;Go find what we parsed ;AN000;
612; $ENDLOOP ;Parse error, see what it was ;AN000;
613 JMP SHORT $$DO30
614$$EN30:
615 mov byte ptr ds:[si],0
616 push di
617 push ax
618 mov di,offset es:Sublist_MsgParse_Error
619 mov ax,word ptr es:Command_Old_Ptr
620 mov word ptr es:[di+2],ax
621 mov word ptr es:[di+4],ds
622 pop ax
623 pop di
624 PARSE_MESSAGE ;Display parse error ;AN000;
625 mov es:Fatal_Error,YES ;Indicate death! ;AN000;
626; $ENDSRCH ; ;AN000;
627$$SR30:
628 pop ds ; ;AN000;
629 ret ; ;AN000;
630
631Parse_Command_Line endp ; ;AN000;
632
633;*****************************************************************************
634;Routine name: Interpret_Parse
635;*****************************************************************************
636;
637;Description: Set the SwitchMap field with the switches found on the
638; command line. Get the drive letter. /FS will be handled before
639; here, will not be seen in this parse or accepted. Also, if /V
640; see if volume label entered and verify it is good, setting up
641; FCB for later create
642;
643;Called Procedures: Get_11_Characters
644;
645;Change History: Created 5/1/87 MT
646;
647;Input: Fatal_Error = NO
648;
649;Output: SwitchMap set
650; DriveLetter set
651; DriveNum set A=0,B=1 etc...
652; Command_Line = YES/NO
653; Fatal_Error = YES/NO
654;
655;Psuedocode
656;----------
657;
658; IF Drive letter parsed
659; Drive = Parsed drive number -1
660; DriveLetter = (Parsed drive number - 1) +'A'
661; ENDIF
662; IF /1
663; or SwitchMap,Switch_1
664; ENDIF
665; IF /4
666; or SwitchMap,Switch_4
667; ENDIF
668; IF /8
669; or SwitchMap,Switch_8
670; ENDIF
671; IF /S
672; or SwitchMap,Switch_S
673; ENDIF
674; IF /BACKUP
675; or SwitchMap,Switch_BACKUP
676; ENDIF
677; IF /B
678; or SwitchMap,Switch_B
679; ENDIF
680; IF /T
681; or SwitchMap,Switch_T
682; TrackCnt = entered value
683; ENDIF
684; IF /N
685; or SwitchMap,Switch_N
686; NumSectors = entered value
687; ENDIF
688; IF /SELECT
689; or SwitchMap,Switch_SELECT
690; ENDIF
691; IF /V
692; or SwitchMap,Switch_V
693; IF string entered
694; Build ASCIIZ string for next call (CALL Build_String)
695; Verify DBCS and setup FCB (CALL Get_11_Characters)
696; Command_Line = YES
697; IF error
698; Invalid label message
699; Fatal_Error = YES
700; ENDIF
701; ENDIF
702; ENDIF
703; IF /AUTOTEST
704; or SwitchMap,Switch_AUTOTEST
705; ENDIF
706;
707; IF /F
708; or SwitchMap,Switch_F
709; or Size_Map,Item_Tag
710; ENDIF
711; IF /Z (only if assembled)
712; or SwitchMap,Switch_Z
713; ENDIF
714; ret
715;*****************************************************************************
716
717Procedure Interpret_Parse ; ;AN000;
718
719 push ds ;Save segment ;AN000;
720 push si ;Restore SI for parser ;AN000;
721 push cx ; ;AN000;
722 push di ;
723 Set_Data_Segment ;Set DS,ES to Data segment ;AN000;
724 cmp byte ptr Drive_Letter_Buffer.Drive_Type,Type_Drive ;Have drive letter? ;AN000;
725; $IF E ;Yes, save info ;AN000;
726 JNE $$IF36
727 mov al,Drive_Letter_Buffer.Drive_Number ;Get drive entered ;AN000;
728 dec al ;Make it 0 based ;AN000;
729 mov Drive,al ; " " " " ;AN000;
730 add al,'A' ;Make it a drive letter ;AN000;
731 mov DriveLetter,al ;Save it ;AN000;
732; $ENDIF ; ;AN000;
733$$IF36:
734 cmp Switch_Buffer.Switch_Pointer,offset Switch_1_Control.Keyword ;;AN000;
735; $IF E ; ;AN000;
736 JNE $$IF38
737 mov Switch_1_Control.Keyword,20h ;an000; dms;remove switch from table
738 or SwitchMap,Switch_1 ; ;AN000;
739; $ENDIF ; ;AN000;
740$$IF38:
741 cmp Switch_Buffer.Switch_Pointer,offset Switch_4_Control.Keyword ;;AN000;
742; $IF E ; ;AN000;
743 JNE $$IF40
744 mov Switch_4_Control.Keyword,20h ;an000; dms;remove switch from table
745 or SwitchMap,Switch_4 ; ;AN000;
746; $ENDIF ; ;AN000;
747$$IF40:
748 cmp Switch_Buffer.Switch_Pointer,offset Switch_8_Control.Keyword ;;AN000;
749; $IF E ; ;AN000;
750 JNE $$IF42
751 mov Switch_8_Control.Keyword,20h ;an000; dms;remove switch from table
752 or SwitchMap,Switch_8 ; ;AN000;
753; $ENDIF ; ;AN000;
754$$IF42:
755 cmp Switch_Buffer.Switch_Pointer,offset Switch_S_Control.Keyword ;;AN000;
756; $IF E ; ;AN000;
757 JNE $$IF44
758 mov Switch_S_Control.Keyword,20h ;an000; dms;remove switch from table
759 or SwitchMap,Switch_S ; ;AN000;
760; $ENDIF ; ;AN000;
761$$IF44:
762 cmp Switch_Buffer.Switch_Pointer,offset Switch_Backup_Control.Keyword ;AN000;
763; $IF E ; ;AN000;
764 JNE $$IF46
765 mov Switch_Backup_Control.Keyword,20h ;an000; dms;remove switch from table
766 or SwitchMap,Switch_Backup ; ;AN000;
767; $ENDIF ; ;AN000;
768$$IF46:
769 cmp Switch_Buffer.Switch_Pointer,offset Switch_Select_Control.Keyword ;AN000;
770; $IF E ; ;AN000;
771 JNE $$IF48
772 mov Switch_Select_Control.Keyword,20h ;an000; dms;remove switch from table
773 or SwitchMap,Switch_Select ; ;AN000;
774; $ENDIF ; ;AN000;
775$$IF48:
776 cmp Switch_Buffer.Switch_Pointer,offset Switch_B_Control.Keyword ;AN000;
777; $IF E ; ;AN000;
778 JNE $$IF50
779 mov Switch_B_Control.Keyword,20H
780 or SwitchMap,Switch_B ; ;AN000;
781; $ENDIF ; ;AN000;
782$$IF50:
783 cmp Switch_Num_Buffer.Switch_Num_Pointer,offset es:Switch_T_Control.Keyword ;AN000;
784; $IF E ; ;AN000;
785 JNE $$IF52
786 mov Switch_T_Control.Keyword,20h ;an000; dms;remove switch from table
787 mov Switch_Num_Buffer.Switch_Num_Pointer,0 ;Init for next switch ;AN008;
788 test SwitchMap,Switch_T ;Don't allow if switch already ;AN002;
789; $IF Z ; entered ;AN002;
790 JNZ $$IF53
791 or SwitchMap,Switch_T ; ;AN000;
792 mov ax,Switch_Num_Buffer.Switch_Number_Low ;Get entered tracks ;AN000;
793 mov TrackCnt,ax ;1024 or less, so always dw ;AN000;
794; $ELSE ; ;AN002;
795 JMP SHORT $$EN53
796$$IF53:
797 Message msgSameSwitch ; ;AN002;
798 mov Fatal_Error,Yes ; ;AN002;
799; $ENDIF ; ;AN000;
800$$EN53:
801; $ENDIF ; ;AN002;
802$$IF52:
803 cmp Switch_Num_Buffer.Switch_Num_Pointer,offset Switch_N_Control.Keyword ;AN000;
804; $IF E ; ;AN000;
805 JNE $$IF57
806 mov Switch_N_Control.Keyword,20h ;an000; dms;remove switch from table
807 mov Switch_Num_Buffer.Switch_Num_Pointer,0 ;Init for next switch ;AN008;
808 test SwitchMap,Switch_N ;Make sure switch not already ;AN002;
809; $IF Z ; entered ;AN002;
810 JNZ $$IF58
811 or SwitchMap,Switch_N ; ;AN000;
812 mov ax,Switch_Num_Buffer.Switch_Number_Low ;Get entered tracks ;AN000;
813 xor ah,ah ;clear high byte ;an000;
814 mov NumSectors,ax ;Save tracks per sector ;AN000;
815; $ELSE ; ;AN002;
816 JMP SHORT $$EN58
817$$IF58:
818 Message msgSameSwitch ; ;AN002;
819 mov Fatal_Error,Yes ; ;AN002;
820; $ENDIF ; ;AN000;
821$$EN58:
822; $ENDIF ; ;AN002;
823$$IF57:
824 cmp Switch_String_Buffer.Switch_String_Pointer,offset Switch_V_Control.Keyword ;AN000;
825; $IF E ;If /v and haven't already done ;AN000;
826 JNE $$IF62
827 mov Switch_String_Buffer.Switch_String_Pointer,0 ;Init for next switch ;AN008;
828 mov Switch_V_Control.Keyword,20h ;an000; dms;remove switch from table
829 test SwitchMap,Switch_V ; it - Only allow one /V entry ;AN002;
830; $IF Z ; ;AN002;
831 JNZ $$IF63
832 or SwitchMap,Switch_V ;Set /v indicator ;AN000;
833 mov si,Switch_String_Buffer.Switch_String_Seg ;Get string address ;;AN000;
834 mov ds,si ; ;AN000;
835
836 assume ds:nothing
837
838 mov si,es:Switch_String_Buffer.Switch_String_Off ; ;AN000;
839 cmp byte ptr ds:[si],None ;Is there a string there? ;AN000;
840; $IF NE ;Yep ;AN000;
841 JE $$IF64
842 cld ; ;AN000;
843 mov di,offset es:Vol_Label_Buffer ;Point at buffer to move string;AN000;
844 mov cx,Label_Length+1 ;Max length of string ;AN000;
845 rep movsb ;This will copy string & always ;AN000;
846 ; leave ASCIIZ end in buffer, ; ;
847 ; which is init'd to 13 dup(0) ; ;
848 mov si,offset es:Vol_Label_Buffer ;Point at string ;AN000;
849 Set_Data_Segment ;Set DS,ES to Data segment ;AN000;
850 mov Command_Line,YES ;Set flag indicating vol label ;AN000;
851 call Get_11_Characters ;Check DBCS and build FCB ;AN000;
852; $IF C ;Bad DBCS setup ;AN000;
853 JNC $$IF65
854 Message msgBadVolumeID ;Tell user ;AN000;
855 mov es:Fatal_Error,YES ;Indicate time to quit ;AN000;
856; $ENDIF ; ;AN000;
857$$IF65:
858; $ENDIF ; ;AN000;
859$$IF64:
860; $ELSE ; ;AN002;
861 JMP SHORT $$EN63
862$$IF63:
863 Message msgSameSwitch ; ;AN002;
864 mov Fatal_Error,Yes ; ;AN002;
865; $ENDIF ; ;AN002;
866$$EN63:
867; $ENDIF ; ;AN000;
868$$IF62:
869 cmp Switch_Buffer.Switch_Pointer,offset Switch_Autotest_Control.Keyword ;AN000;
870; $IF E ; ;AN000;
871 JNE $$IF71
872 mov Switch_Autotest_Control.Keyword,20h ;an000; dms;remove switch from table
873 or SwitchMap,Switch_Autotest ; ;AN000;
874; $ENDIF ; ;AN000;
875$$IF71:
876
877IF ShipDisk
878
879 cmp Switch_Buffer.Switch_Pointer,offset Switch_Z_Control.Keyword ;an000; dms;/Z switch?
880; $IF E ; ;an000; dms;yes
881 JNE $$IF73
882 mov Switch_Z_Control.Keyword,20h ;an000; dms;remove switch from table
883 or SwitchMap,Switch_Z ; ;an000; dms;signal switch found
884; $ENDIF ; ;an000; dms;
885$$IF73:
886
887ENDIF
888
889 cmp Switch_String_Buffer.Switch_Pointer,offset Switch_F_Control.Keyword ; ;AN000;
890; $IF E ; ;AN000;
891 JNE $$IF75
892 mov Switch_F_Control.Keyword,20h ;an000; dms;remove switch from table
893 mov Switch_String_Buffer.Switch_Pointer,0 ;an000; dms; clear out ptr for next iteration
894 mov Switch_Num_Buffer.Switch_Num_Pointer,0 ;Init for next switch ;AN008;
895 test SwitchMap,Switch_F ; it - do this because SysParse ;AN002;
896; $IF Z ; reuses string buffer each time;AN002;
897 JNZ $$IF76
898 or SwitchMap,Switch_F ; ;AN000;
899 mov al,Switch_String_Buffer.Switch_String_Item_Tag ; Indicate what size;AN000;
900 or SizeMap,al ; ;AN000;
901; $ELSE ; ;AN002;
902 JMP SHORT $$EN76
903$$IF76:
904 Message msgSameSwitch ; ;AN002;
905 mov Fatal_Error,Yes ; ;AN002;
906; $ENDIF ; ;AN002;
907$$EN76:
908; $ENDIF ; ;AN000;
909$$IF75:
910 pop di ;Restore parse regs ;AN000;
911 pop cx ; ;AN000;
912 pop si ; ;AN000;
913 pop ds ; ;AN000;
914 ret ; ;AN000;
915
916Interpret_Parse endp ; ;AN000;
917
918
919
920;*****************************************************************************
921;Routine name: Validate_Target_Drive
922;*****************************************************************************
923;
924;Description: Control routine for validating the specified format target drive.
925; If any of the called routines find an error, they will print
926; message and terminate program, without returning to this routine
927;
928;Called Procedures: Check_Target_Drive
929; Check_For_Network
930; Check_Translate_Drive
931;
932;Change History: Created 5/1/87 MT
933;
934;Input: Fatal_Error = NO
935;
936;Output: Fatal_Error = YES/NO
937;
938;Psuedocode
939;----------
940;
941; CALL Check_Target_Drive
942; IF !Fatal_Error
943; CALL Check_For_Network
944; IF !Fatal_Error
945; CALL Check_Translate_Drive
946; ENDIF
947; ENDIF
948; ret
949;*****************************************************************************
950
951Procedure Validate_Target_Drive ; ;AN000;
952 ;
953 call Check_Target_Drive ;See if valid drive letter ;AN000;
954 cmp Fatal_Error,YES ;Can we continue? ;AN000;
955; $IF NE ;Yep ;AN000;
956 JE $$IF80
957 call Check_For_Network ;See if Network drive letter ;AN000;
958 cmp Fatal_Error,YES ;Can we continue? ;AN000;
959; $IF NE ;Yep ;AN000;
960 JE $$IF81
961 call Check_Translate_Drive ;See if Subst, Assigned ;AN000;
962; $ENDIF ;- Fatal_Error passed back ;AN000;
963$$IF81:
964; $ENDIF ; ;AN000;
965$$IF80:
966 ret ; ;AN000;
967
968Validate_Target_Drive endp ; ;AN000;
969
970;*****************************************************************************
971;Routine name: Check_Target_Drive
972;*****************************************************************************
973;
974;Description: Check to see if valid DOS drive by checking if drive is
975; removable. If error, the drive is invalid. Save default
976; drive info.
977;
978;Called Procedures: Message (macro)
979;
980;Change History: Created 5/1/87 MT
981;
982;Input: Fatal_Error = NO
983;
984;Output: BIOSFile = default drive letter
985; DOSFile = default drive letter
986; CommandFile = default drive letter
987; Fatal_Error = YES/NO
988;
989;Psuedocode
990;----------
991;
992; Get default drive (INT 21h, AH = 19h)
993; Convert it to drive letter
994; Save into BIOSFile,DOSFile,CommandFile
995; See if drive removable (INT 21h, AX=4409h IOCtl)
996; IF error - drive invalid
997; Display Invalid drive message
998; Fatal_Error= YES
999; ENDIF
1000; ret
1001;*****************************************************************************
1002
1003Procedure Check_Target_Drive ; ;AN000;
1004 ;
1005 DOS_Call Get_Default_Drive ;Find the current drive ;AC000;
1006 add al,'A' ;Convert to drive letter ; ;
1007 mov BIOSFile,al ;Put it into path strings ; ;
1008 mov DOSFile,al ; " " " " ; ;
1009 mov CommandFile,al ; " " " " ; ;
1010 mov bl,Drive ;Set up for next call ;AN000;
1011 inc bl ;A=1,B=2 for IOCtl call ;AN000;
1012 mov al,09h ;See if drive is local ;AC000;
1013 DOS_Call IOCtl ;-this will fail if bad drive ;AC000;
1014; $IF C ;CY means invalid drive ;AC000;
1015 JNC $$IF84
1016 Extended_Message ;Print message ;AC000;
1017 mov Fatal_Error,Yes ;Indicate error ;AN000;
1018; $ENDIF ; ;AN000;
1019$$IF84:
1020 ret ;And we're outa here ;AN000;
1021
1022Check_Target_Drive endp ; ;AN000;
1023
1024;*****************************************************************************
1025;Routine name: Check_For_Network
1026;*****************************************************************************
1027;
1028;Description: See if target drive isn't local, or if it is a shared drive. If
1029; so, exit with error message. The IOCtl call is not checked for
1030; an error because it is called previously in another routine, and
1031; invalid drive is the only error it can generate. That condition
1032; would not get this far
1033;
1034;Called Procedures: Message (macro)
1035;
1036;Change History: Created 5/1/87 MT
1037;
1038;Input: Drive
1039; Fatal_Error = NO
1040;
1041;Output: Fatal_Error = YES/NO
1042;
1043;Psuedocode
1044;----------
1045; See if drive is local (INT 21h, AX=4409 IOCtl)
1046; IF not local
1047; Display network message
1048; Fatal_ERROR = YES
1049; ELSE
1050; IF 8000h bit set on return
1051; Display assign message
1052; Fatal_Error = YES
1053; ENDIF
1054; ENDIF
1055; ret
1056;*****************************************************************************
1057
1058Procedure Check_For_Network ; ;AN000;
1059 ;
1060 mov bl,Drive ;Drive is 0=A, 1=B ; ;
1061 inc bl ;Get 1=A, 2=B for IOCtl call ; ;
1062 mov al,09h ;See if drive is local or remote;AC000;
1063 DOS_CALL IOCtl ;We will not check for error ;AC000;
1064 test dx,Net_Check ;if (x & 1200H)(redir or shared); ;
1065; $IF NZ ;Found a net drive ;AC000;
1066 JZ $$IF86
1067 Message MsgNetDrive ;Tell 'em ;AC000;
1068 mov Fatal_Error,Yes ;Indicate bad stuff ;AN000;
1069; $ELSE ;Local drive, now check assign ;AN000;
1070 JMP SHORT $$EN86
1071$$IF86:
1072 test dx,Assign_Check ;8000h bit is bad news ; ;
1073; $IF NZ ;Found it ;AC000;
1074 JZ $$IF88
1075 Message MsgAssignedDrive ;Tell error ;AC000;
1076 mov Fatal_Error,Yes ;Indicate bad stuff ;AN000;
1077; $ENDIF ; ;AN000;
1078$$IF88:
1079; $ENDIF ; ;AN000;
1080$$EN86:
1081 ret ; ;AN000;
1082
1083Check_For_Network endp ; ;AN000;
1084
1085;*****************************************************************************
1086;Routine name: Check_Translate_Drive
1087;*****************************************************************************
1088;
1089;Description: Do a name translate call on the drive letter to see if it is
1090; assigned by SUBST or ASSIGN
1091;
1092;Called Procedures: Message (macro)
1093;
1094;Change History: Created 5/1/87 MT
1095;
1096;Input: Drive
1097; Fatal_Error = NO
1098;
1099;Output: Fatal_Error = YES/NO
1100;
1101;Psuedocode
1102;----------
1103; Put drive letter in ASCIIZ string "d:\",0
1104; Do name translate call (INT 21)
1105; IF drive not same
1106; Display assigned message
1107; Fatal_Error = YES
1108; ENDIF
1109; ret
1110;*****************************************************************************
1111
1112Procedure Check_Translate_Drive ; ;AN000;
1113 ;
1114 mov bl,Drive ;Get drive ; ;
1115 add byte ptr [TranSrc],bl ;Make string "d:\" ; ;
1116 mov si,offset TranSrc ;Point to translate string ; ;
1117 push ds ;Set ES=DS (Data segment) ; ;
1118 pop es ; " " " " ; ;
1119 mov di,offset Command_Line_Buffer ;Point at output buffer ; ;
1120 DOS_Call xNameTrans ;Get real path ;AC000;
1121 mov bl,byte ptr [TranSrc] ;Get drive letter from path ; ;
1122 cmp bl,byte ptr Command_Line_Buffer ;Did drive letter change? ; ;
1123; $IF NE ;If not the same, it be bad ;AC000;
1124 JE $$IF91
1125 Message MsgAssignedDrive ;Tell user ;AC000;
1126 mov Fatal_Error,Yes ;Setup error flag ;AN000;
1127; $ENDIF ; ;AN000;
1128$$IF91:
1129 ret ; ;AN000;
1130
1131Check_Translate_Drive endp ; ;AN000;
1132
1133;*****************************************************************************
1134;Routine name: Hook_CNTRL_C
1135;*****************************************************************************
1136;
1137;Description: Change the interrupt handler for INT 13h to point to the
1138; ControlC_Handler routine
1139;
1140;Called Procedures: None
1141;
1142;Change History: Created 4/21/87 MT
1143;
1144;Input: None
1145;
1146;Output: None
1147;
1148;Psuedocode
1149;----------
1150;
1151; Point at ControlC_Handler routine
1152; Set interrupt handler (INT 21h, AX=2523h)
1153; ret
1154;*****************************************************************************
1155
1156Procedure Hook_CNTRL_C ; ;AN000;
1157 ;
1158 mov al,23H ;Specify CNTRL handler ; ;
1159 mov dx, offset ControlC_Handler ;Point at it ; ;
1160 push ds ;Save data seg ; ;
1161 push cs ;Point to code segment ; ;
1162 pop ds ; ; ;
1163 DOS_Call Set_Interrupt_Vector ;Set the INT 23h handler ;AC000;
1164 pop ds ;Get Data degment back ; ;
1165 ret ; ;AN000;
1166
1167Hook_CNTRL_C endp ; ;AN000;
1168
1169;=========================================================================
1170; Check_For_Invalid_Drive : This routine checks the AX received by
1171; FORMAT on its entry. This value will
1172; tell us if we are attempting to format
1173; a JOINED drive.
1174;
1175; Inputs : Org_AX - AX on entry to FORMAT
1176;
1177; Outputs : Fatal_Error - Yes if AL contained FFh
1178;=========================================================================
1179
1180Procedure Check_For_Invalid_Drive ;an000; dms;
1181
1182 push ax ;an000; dms;save ax
1183 cmp FAT_Flag,Yes ;an000; dms;FAT system?
1184; $if e ;an000; dms;yes
1185 JNE $$IF93
1186 mov ax,Org_AX ;an000; dms;get its org. value
1187 cmp al,0ffh ;an000; dms;Invalid drive?
1188; $if e ;an000; dms;yes
1189 JNE $$IF94
1190 mov Fatal_Error,YES ;an000; dms;flag an error
1191 mov ax,Invalid_Drive;an000; dms;error message
1192 Extended_Message ;an000; dms;tell error
1193; $endif ;an000; dms;
1194$$IF94:
1195; $endif ;an000; dms;
1196$$IF93:
1197 pop ax ;an000; dms;
1198 ret ;an000; dms;
1199
1200Check_For_Invalid_Drive endp ;an000; dms;
1201
1202
1203;=========================================================================
1204; Determine_FAT_Non_FAT - This routine determines whether or
1205; not a device is formatted to a FAT
1206; specification versus a Non-FAT
1207; specification.
1208;
1209; Inputs : DX - Pointer to device parameters buffer
1210;
1211; Outputs : DeviceParameters - buffer containing BPB.
1212;
1213; Date : 11/6/87
1214;=========================================================================
1215
1216Procedure Determine_FAT_Non_FAT ;an012; dms;
1217
1218 push ax ;an012; dms;save regs
1219 push dx ;an012; dms;
1220
1221 lea dx, deviceParameters ;an012; dms;point to buffer
1222 mov deviceParameters.DP_SpecialFunctions, 0 ;an012; dms;get default BPB
1223 call GetDeviceParameters ;an012; dms;make the call
1224; $if nc ;an012; dms;no error occurred
1225 JC $$IF97
1226 cmp byte ptr DeviceParameters.DP_BPB.BPB_NumberOfFATS,00h ;an012; dms;non-FAT system?
1227; $if e ;an012; dms;yes
1228 JNE $$IF98
1229 mov FAT_Flag,No ;an012; dms;signal system non-FAT
1230 mov ax,5f07h ;an012; dms;allow access to disk
1231 mov dl,Drive ;an012; dms;get 0 based driver number
1232 int 21h ;an012; dms;allow access to the drive
1233; $else ;an012; dms;FAT system
1234 JMP SHORT $$EN98
1235$$IF98:
1236 mov FAT_Flag,Yes ;an012; dms;flag FAT system
1237; $endif ;an012; dms;
1238$$EN98:
1239; $endif ;an012; dms;
1240$$IF97:
1241
1242 pop dx ;an012; dms;restore regs
1243 pop ax ;an012; dms;
1244
1245 ret ;an012; dms;
1246
1247Determine_FAT_Non_FAT endp ;an012; dms;
1248
1249
1250
1251
1252code ends
1253 end
1254
1255 \ 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 @@
1
2;
3;*****************************************************************************
4;*****************************************************************************
5;
6;UTILITY NAME: FORMAT.COM
7;
8;MODULE NAME: FORLABEL.SAL
9;
10; Interpret_Parse
11; |
12;* |
13;³ÚÄÄÄÄÄ¿ÚÄÄÄÄÄÄÄÄÄÄÄÄÄ¿|ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
14;À´VolIDôGet_New_LabelÃÄ´Get_11_CharactersôChange_Blanks³
15; ÀÄÄÄÄÄÙÀÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
16; ³ÚÄÄÄÄÄÄÄÄÄÄÄ¿
17; ôSkip_Blanks³
18; ³ÀÄÄÄÄÄÄÄÄÄÄÄÙ
19; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
20; ôCheck_DBCS_OverrunôCheck_DBCS_Character³
21; ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
22; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
23; À´Copy_FCB_String³
24; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
25;*****************************************************************************
26;*****************************************************************************
27
28data segment public para 'DATA'
29data ends
30
31code segment public para 'CODE'
32 assume cs:code,ds:data
33code ends
34
35.xlist
36INCLUDE FORCHNG.INC
37INCLUDE FORMACRO.INC
38INCLUDE SYSCALL.INC
39INCLUDE FOREQU.INC
40INCLUDE FORSWTCH.INC
41.list
42
43;
44;*****************************************************************************
45; Equates
46;*****************************************************************************
47;
48
49None equ 0
50StdIn equ 0
51StdOut equ 1
52StdErr equ 2
53Tab equ 09h
54Label_Buffer_length equ 80h
55Create_Worked equ 0 ;an024;
56
57
58;
59;*****************************************************************************
60; External Data Declarations
61;*****************************************************************************
62;
63
64 Extrn SwitchMap:Word
65 Extrn Switch_String_Buffer:Byte
66 Extrn VolFCB:Byte
67 Extrn MsgBadCharacters:Byte
68 Extrn MsgLabelPrompt:Byte
69 Extrn MsgBadVolumeID:Byte
70 Extrn MsgCRLF:Byte
71 Extrn VolNam:Byte
72 Extrn Vol_Label_Count:Byte
73 Extrn VolDrive:Byte
74 Extrn Drive:Byte
75 Extrn Command_Line:Byte
76 Extrn Vol_Label_Buffer:Byte
77 Extrn DelDrive:Byte
78 Extrn DelFCB:Byte
79
80code segment public para 'CODE'
81
82;************************************************************************************************
83;Routine name Volid
84;************************************************************************************************
85;
86;Description: Get volume id from command line /V:xxxxxxx if it is there, or
87; else prompt user for volume label, parse the input. At this
88; point setup the FCB and create the volume label. If failure,
89; prompt user that they entered bad input, and try again.
90;
91; Note: This routine in 3.30 and prior used to check for /V
92; switch. Volume labels are always required now, so /V
93; is ignored, except to get volume label on command line.
94;
95;Called Procedures: Message (macro)
96; Get_New_Label
97;
98;Change History: Created 5/1/87 MT
99;
100;Input: Switch_V
101; Command_Line = YES/NO
102;
103;Output: None
104;
105;Psuedocode
106;----------
107;
108; Save registers
109; IF /V switch entered
110; IF /v:xxxxx form not entered
111; CALL Get_New_Label ;Return string in Volume_Label
112; ENDIF
113; ELSE
114; CALL Get_New_Label ;Return string in Volume_Label
115; ENDIF
116; DO
117; Create volume label
118; LEAVE Create Ok
119; Display Bad Character message
120; CALL Get_New_Label ;Return string in Volume_Label
121; ENDDO
122; Restore registers
123; ret
124;*****************************************************************************
125
126Procedure Volid ; ;AN000;
127
128 push ds ;Save registers ;AN000;
129 push si ; " " " " ;AN000;
130 test SwitchMap,Switch_V ;Was /V entered ;AN000;
131; $IF NZ ;Yes, see if label entered also ;AN000;
132 JZ $$IF1
133 cmp Command_Line,YES ;Is there a string there? ;AN000;
134; $IF NE ;Nope ;AN000;
135 JE $$IF2
136 call Get_New_Label ;Go get volume label from user ;AN000;
137; $ENDIF ; ;AN000;
138$$IF2:
139; $ELSE ;Label not entered on cmd line ;AN000;
140 JMP SHORT $$EN1
141$$IF1:
142 call Get_New_Label ;Go get label from user ;AN000;
143; $ENDIF ; ;AN000;
144$$EN1:
145 mov dl,drive ;Get drive number A=0 ;AN000;
146 inc dl ;Make it 1 based ;AN000;
147 mov DelDrive,dl ;Put into FCBs ;AN000;
148 mov VolDrive,dl ; ;AN000;
149 mov dx,offset DelFCB ;Point at FCB to delete label ;AN000;
150 DOS_Call FCB_Delete ;Do the delete ;AN000;
151 mov dx,offset VolFCB ;Point at FCB for create ;AN000;
152 DOS_CALL FCB_Create ;Go create it ;AN000;
153 cmp dl,Create_Worked ;See if the create worked ;an024;
154; $IF E ;an024;
155 JNE $$IF6
156 mov dx,offset VolFCB ;Point to the FCB created ;an022; dms;
157 DOS_Call FCB_Close ;Close the newly created FCB ;an022; dms;
158; $ENDIF ;an024;
159$$IF6:
160
161 pop si ;Restore registers ;AN000;
162 pop ds ; " " " " ;AN000;
163 ret ; ;AN000;
164
165Volid endp ; ;AN000;
166
167;*****************************************************************************
168;Routine name: Get_New_Label
169;*****************************************************************************
170;
171;Description: Prompts, inputs and verifies a volume label string. Continues
172; to prompt until valid vol label is input
173;
174;Called Procedures: Message (macro)
175; Build_String
176; Get_11_Characters
177;
178;Change History: Created 3/18/87 MT
179;
180;Input: None
181;
182;Output: Volume_Label holds
183;
184;Psuedocode
185;----------
186;
187; DO
188; Display new volume label prompt
189; Input vol label
190; IF No error (NC)
191; Build Asciiz string with label, pointer DS:SI (CALL Build_String)
192; Call Get_11_Characters (Error returned CY)
193; ENDIF
194; LEAVE no error (NC)
195; Display label error
196; ENDDO
197; ret
198;*****************************************************************************
199
200Procedure Get_New_Label ; ;AN000;
201
202; $DO ;Loop until we get good one ;AN000;
203$$DO8:
204 Message msgLabelPrompt ;Prompt to input Vol label ;AN000;
205 mov ax,(Std_Con_Input_Flush shl 8) + 0 ;an000; dms;clean out input
206 int 21h ;an000; dms;
207 mov dx,offset Vol_Label_Count ;an000; dms;beginning of buffer
208 mov ah,Std_Con_String_Input ;an000; dms;get input
209 int 21h ;an000; dms;
210 mov ax,(Std_Con_Input_Flush shl 8) + 0 ;an000; dms; clean out input
211 int 21h ;an000; dms;
212; $IF NC ;Read ok if NC, Bad sets CY ;AN000;
213 JC $$IF9
214 mov si,offset Vol_Label_Buffer ;Get pointer to string ;AN000;
215 call Get_11_Characters ;Handle DBCS stuff on input ;AN000;
216; $ENDIF ;Ret CY if error ;AN000;
217$$IF9:
218; $LEAVE NC ;Done if NC ;AN000;
219 JNC $$EN8
220 Message MsgCRLF ;next line ;an020; dms;
221 Message msgBadVolumeID ;Tell user error ;AN000;
222; $ENDDO ;Try again ;AN000;
223 JMP SHORT $$DO8
224$$EN8:
225 Message MsgCRLF ;an000; dms;next line
226 ret ; ;AN000;
227
228Get_New_Label endp ; ;AN000;
229
230;*****************************************************************************
231;Routine name: Get_11_Characters
232;*****************************************************************************
233;
234;Description: Handle DBCS considerations, and build FCB to create vol label
235;
236;
237;Called Procedures: Change_Blanks
238; Skip_Blanks
239; Check_DBCS_Overrun
240; Copy_FCB_String
241;
242;Change History: Created 5/12/87 MT
243;
244;Input: DS:SI = Asciiz string containing volume label input
245; Command_Line = YES/NO
246;
247;Output: Volname will contain an 8.3 volume label in FCB
248; CY set on invalid label
249;
250;Psuedocode
251;----------
252; Save regs used
253; Scan line replacing all DBCS blanks with SBCS (CALL_Change_Blanks)
254; Skip over leading blanks (Call Skip_Blanks)
255; IF leading blanks ,AND
256; IF Command line
257; Indicate invalid label (STC)
258; ELSE
259; See if DBCS character at 11th byte (CALL Check_DBCS_Overrun)
260; IF DBCS character at 11th byte
261; Indicate invalid label (STC)
262; ELSE
263; Put string into FCB (CALL Copy_FCB_STRING)
264; CLC
265; ENDIF
266; ENDIF
267; Restore regs
268; ret
269;*****************************************************************************
270
271Procedure Get_11_Characters ; ;AN000;
272
273 call Change_Blanks ;Change DBCS blanks to SBCS ;AN000;
274 call Skip_Blanks ;Skip over leading blanks ;AN000;
275; $IF C,AND ;Find leading blanks? ;AN000;
276 JNC $$IF13
277 cmp Command_Line,YES ;Is this command line input? ;AN000;
278; $IF E ;Yes ;AN000;
279 JNE $$IF13
280 stc ;Indicate error (CY set) ;AN000;
281; $ELSE ;Leading blanks ok ;AN000;
282 JMP SHORT $$EN13
283$$IF13:
284 call Check_DBCS_Overrun ;Is DBCS char at 11th byte? ;AN000;
285; $IF C ;Yes ;AN000;
286 JNC $$IF15
287 stc ;Indicate invalid label ;AN000;
288; $ELSE ;No, good characters ;AN000;
289 JMP SHORT $$EN15
290$$IF15:
291 call Copy_FCB_String ;Put string into FCB ;AN000;
292 clc ;Indicate everything A-OK! ;AN000;
293; $ENDIF ; ;AN000;
294$$EN15:
295; $ENDIF ; ;AN000;
296$$EN13:
297 ret ; ;AN000;
298
299Get_11_Characters endp ; ;AN000;
300
301;*****************************************************************************
302;Routine name: Change_Blanks
303;*****************************************************************************
304;
305;Description: Replace all DBCS blanks with SBCS blanks, end string with
306; Asciiz character if one doesn't already exist
307;
308;Called Procedures: Check_DBCS_Character
309;
310;Change History: Created 6/12/87 MT
311;
312;Input: DS:SI = String containing volume label input
313;
314;Output: DS:SI = ASCIIZ string with all DBCS blanks replaced with 2 SBCS blanks
315;
316;
317;Psuedocode
318;----------
319;
320; Save pointer to string
321; DO
322; LEAVE End of string (0)
323; See if DBCS character (Check_DBCS_Character)
324; IF CY (DBCS char found)
325; IF first byte DBCS blank, AND
326; IF second byte DBCS blank
327; Convert to SBCS blanks
328; ENDIF
329; Point to next byte to compensate for DBCS character
330; ENDIF
331; ENDDO
332; Tack on ASCIIZ character to string
333; Restore pointer to string
334;
335;*****************************************************************************
336
337Procedure Change_Blanks ; ;AN000;
338
339 push si ;Save pointer to string ;AN000;
340 push cx ; ;AN000;
341 push ax ; ;AN000;
342 xor cx,cx ; ;AN000;
343; $DO ;Do while not CR ;AN000;
344$$DO19:
345 cmp byte ptr [si],Asciiz_End ;Is it end of string? ;AN000;
346; $LEAVE E,OR ;All done if so ;AN000;
347 JE $$EN19
348 cmp byte ptr [si],CR ;Is it CR? ;AN000;
349; $LEAVE E,OR ;Exit if yes,end of label ;AN000;
350 JE $$EN19
351 inc cx ;Count the character ;AN000;
352 cmp cx,Label_Buffer_Length ;Reached max chars? (80h) ;AN000;
353; $LEAVE E ;Exit if so ;AN000;
354 JE $$EN19
355 mov al,byte ptr [si] ;Get char to test for DBCS ;AN000;
356 call Check_DBCS_Character ;Test for dbcs lead byte ;AN000;
357; $IF C ;We have a lead byte ;AN000;
358 JNC $$IF21
359 cmp byte ptr [si],DBCS ;Is it a lead blank? ;AN000;
360; $IF E,AND ;If a dbcs char ;AN000;
361 JNE $$IF22
362 cmp byte ptr [si+1],DBCS_Blank ;Is it an Asian blank? ;AN000;
363; $IF E ;If an Asian blank ;AN000;
364 JNE $$IF22
365 mov byte ptr [si+1],Blank ;set up moves ;AN000;
366 mov byte ptr [si],Blank ; to replace ;AN000;
367; $ENDIF ; ;AN000;
368$$IF22:
369 inc si ;Point to dbcs char ;AN000;
370; $ENDIF ;End lead byte test ;AN000;
371$$IF21:
372 inc si ;Point to si+1 ;AN000;
373; $ENDDO ;End do while ;AN000;
374 JMP SHORT $$DO19
375$$EN19:
376 mov byte ptr [si],Asciiz_End ;Mark end of string ;AN000;
377 pop ax ;Restore regs ;AN000;
378 pop cx ; ;AN000;
379 pop si ; ;AN000;
380 ret ;return to caller ;AN000;
381
382Change_Blanks endp ; ;AN000;
383
384;*****************************************************************************
385;Routine name: Skip_Blanks
386;*****************************************************************************
387;
388;Description: Scan ASCIIZ string for leading blanks, return pointer to first
389; non-blank character. Set CY if blanks found
390;
391;Called Procedures: None
392;
393;Change History: Created 6/12/87 MT
394;
395;Input: DS:SI = ASCIIZ string containing volume label input
396;
397;Output: DS:SI = Input string starting at first non-blank character
398; CY set if blanks found
399;
400;
401;
402;Psuedocode
403;----------
404;
405; Save original pointer, DI register
406; DO
407; Look at character from string
408; LEAVE End of string (0)
409; IF character is blank,OR
410; IF character is tab
411; INC pointer (SI)
412; Indicate blank
413; ELSE
414; Indicate non-blank
415; ENDIF
416; ENDDO non-blank
417; Get back pointer
418; Cmp string pointer to original pointer
419; IF NE
420; STC
421; ELSE
422; CLC
423; ENDIF
424; ret
425;*****************************************************************************
426
427Procedure Skip_Blanks ; ;AN000;
428
429 push di ;Preserve DI, just in case ;AN000;
430 push si ;Save pointer to string ;AN000;
431; $DO ;Look at entire ASCIIZ string ;AN000;
432$$DO26:
433 cmp byte ptr [si],ASCIIZ_End ;End of string? ;AN000;
434; $LEAVE E ;Yep, exit loop ;AN000;
435 JE $$EN26
436 cmp byte ptr [si],Blank ;Find a blank? ;AN000;
437; $IF E,OR ;Yes ;AN000;
438 JE $$LL28
439 cmp byte ptr [si],TAB ;Is it tab? ;AN000;
440; $IF E ;Yes ;AN000;
441 JNE $$IF28
442$$LL28:
443 inc si ;Bump pointer to next character ;AN000;
444 clc ;Indicate found blank ;AN000;
445; $ELSE ;Not blank or tab ;AN000;
446 JMP SHORT $$EN28
447$$IF28:
448 stc ;Force exit ;AN000;
449; $ENDIF ; ;AN000;
450$$EN28:
451; $ENDDO C ;Go look at next character ;AN000;
452 JNC $$DO26
453$$EN26:
454 pop di ;Get back original pointer ;AN000;
455 cmp di,si ;Are they the same? ;AN000;
456; $IF NE ;If not equal blanks were found ;AN000;
457 JE $$IF32
458 stc ;Set CY ;AN000;
459; $ELSE ;No leading blanks found ;AN000;
460 JMP SHORT $$EN32
461$$IF32:
462 clc ;Clear CY ;AN000;
463; $ENDIF ; ;AN000;
464$$EN32:
465 pop di ;Restore DI ;AN000;
466 ret ; ;AN000;
467
468Skip_Blanks endp ; ;AN000;
469
470
471;*****************************************************************************
472;Routine name: Copy_FCB_String
473;*****************************************************************************
474;
475;Description: Build an 11 character string in the FCB from ASCIIZ string
476; If nothing entered, than terminated with 0. Also add drive
477; number in FCB
478;
479;Called Procedures: None
480;
481;Change History: Created 6/12/87 MT
482;
483;Input: DS:SI = String containing volume label input
484;
485;Output: VOLNAM is filled in with Volume label string
486;
487;
488;
489;Psuedocode
490;----------
491;
492; Save regs
493; Init VolNam to blanks
494; DO
495; LEAVE if character is end of ASCIIZ string
496; Mov character to FCB
497; Inc counter
498; ENDDO all 11 chars done
499; Restore regs
500;*****************************************************************************
501
502Procedure Copy_FCB_String ; ;AN000;
503
504 push di ; ;AN000;
505 push cx ; ;AN000;
506 push si ;Save pointer to string ;AN000;
507 cld ;Set string direction to up ;AN000;
508 mov di,offset Volnam ;Init FCB field to blanks ;AN000;
509 mov al,Blank ; " " " " ;AN000;
510 mov cx,Label_Length ; " " " " ;AN000;
511 rep stosb ; " " " " ;AN000;
512 pop si ;Get back pointer to string ;AN000;
513 mov di,offset VolNam ;Point at FCB field ;AN000;
514 xor cx,cx ;Init counter ;AN000;
515; $DO ;Copy characters over ;AN000;
516$$DO35:
517 cmp byte ptr [si],ASCIIZ_End ;End of String? ;AN000;
518; $LEAVE E ;Yes, don't copy - leave blanks ;AN000;
519 JE $$EN35
520 movsb ;Nope, copy character ;AN000;
521 inc cx ;Bump up count ;AN000;
522 cmp cx,Label_Length ;Have we moved 11? ;AN000;
523; $ENDDO E ;Quit if so ;AN000;
524 JNE $$DO35
525$$EN35:
526 pop cx ; ;AN000;
527 pop di ; ;AN000;
528 ret ; ;AN000;
529
530Copy_FCB_String endp ; ;AN000;
531
532
533;*****************************************************************************
534;Routine name: Check_DBCS_Overrun
535;*****************************************************************************
536;
537;Description: Check 11th byte, if the string is that long, to see
538; if it is a DBCS character that is split down the middle. Must
539; scan entire string to properly find DBCS characters, due to
540; the fact a second byte of a DBCS character can fall into
541; the range of the first byte environment vector, and thus look
542; like a DBCS char when it really isn't
543;
544;Called Procedures: Check_DBCS_Character
545;
546;Change History: Created 6/12/87 MT
547;
548;Input: DS:SI = String containing volume label input
549;
550;Output: CY set if DBCS character at bytes 11-12 in string
551;
552;*****************************************************************************
553
554Procedure Check_DBCS_Overrun ; ;AN000;
555
556 push si ;Save pointer ;AN000;
557 push ax ;Save registers ;AN000;
558 push cx ; " " " " ;AN000;
559 mov cx,si ;Get start of string ;AN000;
560 add cx,Label_Length ;Find where to check for overrun;AN000;
561
562Check_DBCS_OverRun_Cont: ;Scan string for DBCS chars ;AN000;
563
564 cmp byte ptr [si],ASCIIZ_End ;End of string? ;AN000;
565 je DBCS_Good_Exit ;Yep ;AN000;
566
567 mov al,[si] ;Get character for routine ;AN000;
568 call Check_DBCS_Character ;See if DBCS leading character ;AN000;
569; $if c ;DBCS if CY set ;AN000;
570 JNC $$IF38
571 inc si ;Next byte to handle DBCS ;AN000;
572 cmp si,cx ;Is DBCS char spanning 11-12? ;AN000;
573; $if e ;truncate string
574 JNE $$IF39
575 mov byte ptr [si-1],20h;blank it out
576 mov byte ptr [si],20h ;blank it out
577 jmp DBCS_Good_Exit ;exit
578; $endif ;
579$$IF39:
580; $else ;Not DBCS character ;an000; dms;
581 JMP SHORT $$EN38
582$$IF38:
583 mov al,[si] ;Get character for routine ;an000; dms;
584 call Scan_For_Invalid_Char ;See if invalid vol ID char ;an000; dms;
585 jc DBCS_Bad_Exit ;Bad char entered - exit ;an000; dms;
586; $endif ; ;an000; dms;
587$$EN38:
588
589 inc si ;Point to next character ;an000; dms;
590 jmp Check_DBCS_OverRun_Cont ;Continue looping ;an000; dms;
591
592DBCS_Good_Exit:
593 ;an000; dms;
594 clc ;Signal no error ;an000; dms;
595 jmp DBCS_Exit ;Exit routine ;an000; dms;
596
597DBCS_Bad_Exit: ;an000; dms;
598
599 stc ;Signal error ;an000; dms;
600
601DBCS_Exit: ;an000; dms;
602
603 pop cx ;Restore registers ;AN000;
604 pop ax ; " " " " ;AN000;
605 pop si ;Restore string pointer ;AN000;
606 ret ; ;AN000;
607
608Check_DBCS_Overrun endp ; ;AN000;
609
610;*****************************************************************************
611;Routine name: Check_DBCS_Character
612;*****************************************************************************
613;
614;Description: Check if specified byte is in ranges of DBCS vectors
615;
616;Called Procedures: None
617;
618;Change History: Created 6/12/87 MT
619;
620;Input: AL = Character to check for DBCS lead character
621; DBCS_Vector = YES/NO
622;
623;Output: CY set if DBCS character
624; DBCS_VECTOR = YES
625;
626;
627;Psuedocode
628;----------
629; Save registers
630; IF DBCS vector not found
631; Get DBCS environmental vector (INT 21h
632; Point at first set of vectors
633; ENDIF
634; SEARCH
635; LEAVE End of DBCS vectors
636; EXITIF Character > X1,AND (X1,Y1) are environment vectors
637; EXITIF Character < Y1
638; STC (DBCS character)
639; ORELSE
640; Inc pointer to next set of vectors
641; ENDLOOP
642; CLC (Not DBCS character)
643; ENDSRCH
644; Restore registers
645; ret
646;*****************************************************************************
647
648Procedure Check_DBCS_Character ; ;AN000;
649
650 push ds ;Save registers ;AN000;
651 push si ; " " " " ;AN000;
652 push ax ; " " " " ;AN000;
653 push ds ; " " " " ;AN000;
654 pop es ;Establish addressability ;AN000;
655 cmp byte ptr es:DBCS_VECTOR,Yes ;Have we set this yet? ;AN000;
656 push ax ;Save input character ;AN000;
657; $IF NE ;Nope ;AN000;
658 JE $$IF43
659 mov al,0 ;Get DBCS environment vectors ;AN000;
660 DOS_Call Hongeul ; " " " " ;AN000;
661 mov byte ptr es:DBCS_VECTOR,YES ;Indicate we've got vector ;AN000;
662 mov es:DBCS_Vector_Off,si ;Save the vector ;AN000;
663 mov ax,ds ; ;AN000;
664 mov es:DBCS_Vector_Seg,ax ; ;AN000;
665; $ENDIF ; for next time in ;AN000;
666$$IF43:
667 pop ax ;Restore input character ;AN000;
668 mov si,es:DBCS_Vector_Seg ;Get saved vector pointer ;AN000;
669 mov ds,si ; ;AN000;
670 mov si,es:DBCS_Vector_Off ; ;AN000;
671; $SEARCH ;Check all the vectors ;AN000;
672$$DO45:
673 cmp word ptr ds:[si],End_Of_Vector ;End of vector table? ;AN000;
674; $LEAVE E ;Yes, done ;AN000;
675 JE $$EN45
676 cmp al,ds:[si] ;See if char is in vector ;AN000;
677; $EXITIF AE,AND ;If >= to lower, and ;AN000;
678 JNAE $$IF45
679 cmp al,ds:[si+1] ; =< than higher range ;AN000;
680; $EXITIF BE ; then DBCS character ;AN000;
681 JNBE $$IF45
682 stc ;Set CY to indicate DBCS ;AN000;
683; $ORELSE ;Not in range, check next ;AN000;
684 JMP SHORT $$SR45
685$$IF45:
686 add si,DBCS_Vector_Size ;Get next DBCS vector ;AN000;
687; $ENDLOOP ;We didn't find DBCS char ;AN000;
688 JMP SHORT $$DO45
689$$EN45:
690 clc ;Clear CY for exit ;AN000;
691; $ENDSRCH ; ;AN000;
692$$SR45:
693 pop ax ;Restore registers ;AN000;
694 pop si ; " " " " ;AN000;
695 pop ds ;Restore data segment ;AN000;
696 ret ; ;AN000;
697
698Check_DBCS_Character endp ; ;AN000;
699
700;=========================================================================
701; Scan_For_Invalid_Char : This routine scans the bad character table
702; to determine if the referenced character is
703; invalid.
704;
705; Inputs : Bad_Char_Table - Table of bad characters
706; Bad_Char_Table_Len - Length of table
707; AL - Character to be searched for
708;
709; Outputs : CY - Bad character
710; NC - Character good
711;=========================================================================
712
713Procedure Scan_For_Invalid_Char ;an000; dms;
714
715 push ax ;an000; dms;save ax
716 push cx ;an000; dms;save cx
717 push di ;an000; dms;save di
718
719 lea di,Bad_Char_Table ;an000; dms;point to bad character table
720 mov cx,Bad_Char_Table_Len ;an000; dms;get its length
721 repnz scasb ;an000; dms;scan the table
722 cmp cx,0000h ;an000; dms;did we find the character
723; $if e ;an000; dms;no - a good character
724 JNE $$IF51
725 clc ;an000; dms;flag a good character
726; $else ;an000; dms;yes - a bad character
727 JMP SHORT $$EN51
728$$IF51:
729 stc ;an000; dms;flag a bad character
730; $endif ;an000; dms;
731$$EN51:
732
733 pop di ;an000; dms;restore di
734 pop cx ;an000; dms;restore cx
735 pop ax ;an000; dms;restore ax
736
737 ret ;an000; dms;
738
739Scan_For_Invalid_Char endp ;an000; dms;
740
741
742code ends
743
744data segment public para 'DATA'
745
746Bad_Char_Table label byte ;an000; dms;table of invalid vol ID chars
747 db "*"
748 db "?"
749 db "["
750 db "]"
751 db ":"
752 db "<"
753 db "|"
754 db ">"
755 db "+"
756 db "="
757 db ";"
758 db ","
759 db "/"
760 db "\"
761 db '.'
762 db '"'
763 db " "
764Bad_Char_Table_Len equ $-Bad_Char_Table;an000; dms;length of table
765
766DBCS_Vector_Off dw 0 ;
767DBCS_Vector_Seg dw 0 ;
768
769data ends
770 end
771 \ 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 @@
1
2
3
4
5
6
7
8;
9;******************************************************************************
10; Message Macro Definitions
11;******************************************************************************
12;
13
14 EXTRN Display_Interface:near
15
16
17;-----------------------------------------------------------------------------
18
19Message macro Message_Name ; ;AN000;
20 ;
21 mov dx,offset data:Message_Name ; ;AN000;
22 call Display_Interface ; ;AN000;
23 endm ; ;AN000;
24
25;-----------------------------------------------------------------------------
26
27Parse_Message macro ; ;AN000;
28
29 ;
30 push ds
31 mov dx,data
32 mov ds,dx
33 mov word ptr Parse_Error_Msg,ax ; ;AN000;
34 mov dx,offset Parse_Error_Msg ; ;AN000;
35 call Display_Interface ; ;AN000;
36 pop ds ;
37 endm ; ;AN000;
38
39;-----------------------------------------------------------------------------
40
41Extended_Message macro ; ;AN000;
42 ;
43
44 push ds
45 mov dx,data
46 mov ds,dx
47 mov word ptr Extended_Error_Msg,ax ; ;AN000;
48 mov dx,offset data:Extended_Error_Msg ; ;AN000;
49 call Display_Interface ; ;AN000;
50 pop ds
51 endm ; ;AN000;
52
53;
54;*****************************************************************************
55; General Macro's
56;*****************************************************************************
57;
58
59Procedure macro Proc_Name
60
61Public Proc_Name
62Proc_Name proc
63
64 endm
65;-----------------------------------------------------------------------------
66
67DOS_Call macro Function
68
69 mov ah,Function
70 int 21h
71
72 endm
73;-----------------------------------------------------------------------------
74
75Popff macro
76
77 jmp $+3
78 iret
79 push cs
80 call $-2
81
82 endm
83
84
85;-----------------------------------------------------------------------------
86
87Set_Data_Segment macro
88
89 push ax
90 mov ax,data ;Point to data segment
91 mov ds,ax ;
92 push ds
93 pop es
94 pop ax
95
96assume ds:data,es:data
97
98 endm
99
100
101
102 \ 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 @@
1page 84,132
2;
3; SCCSID = @(#)format.asm 1.26 85/10/20
4; SCCSID = @(#)format.asm 1.26 85/10/20
5;***************************************************************
6;
7; 86-DOS FORMAT DISK UTILITY
8;
9; This routine formats a new disk,clears the FAT and DIRECTORY then
10; optionally copies the SYSTEM and COMMAND.COM to this new disk
11;
12; SYNTAX: FORMAT [drive][/switch1][/switch2]...[/switch16]
13;
14; Regardless of the drive designator , the user will be prompted to
15; insert the diskette to be formatted.
16;
17;***************************************************************
18
19; 5/12/82 ARR Mod to ask for volume ID
20; 5/19/82 ARR Fixed rounding bug in CLUSCAL:
21; REV 1.5
22; Added rev number message
23; Added dir attribute to DELALL FCB
24; REV 2.00
25; Redone for 2.0
26; REV 2.10
27; 5/1/83 ARR Re-do to transfer system on small memory systems
28; REV 2.20
29; 6/17/83 system size re-initialization bug -- mjb001
30; Rev 2.25
31; 8/31/83 16-bit fat insertion
32; Rev 2.26
33; 11/2/83 MZ fix signed compare problems for bad sectors
34; Rev 2.27
35; 11/8/83 EE current directories are always saved and restored
36; Rev 2.28
37; 11/9/83 NP Printf and changed to an .EXE file
38; Rev 2.29
39; 11/11/83 ARR Fixed ASSIGN detection to use NameTrans call to see
40; if drive letter remapped. No longer IBM only
41; Rev 2.30
42; 11/13/83 ARR SS does NOT = CS, so all use of BP needs CS override
43; Rev 2.31
44; 12/27/83 ARR REP STOSB instruction at Clean: changed to be
45; sure ES = CS.
46
47
48
49
50code segment public para 'CODE'
51code ends
52
53
54
55data segment public para 'DATA'
56data ends
57
58End_Of_Memory segment public para 'BUFFERS'
59End_Of_Memory ends
60
61
62code segment public para 'CODE'
63
64 assume cs:code,ds:nothing,es:nothing
65
66;-------------------------------------------------------------------------------
67; Define as public for debugging
68
69; procedures
70 public GetSize
71 public AddToSystemSize
72 public Phase1Initialisation
73 public SetStartSector
74 public SetfBigFat
75 public Phase2Initialisation
76 public DiskFormat
77 public BadSector
78 public DisplayCurrentTrack
79 public WriteFileSystem
80 public Done
81 public CurrentLogicalSector
82 public PrintErrorAbort
83 public GetDeviceParameters
84 public SetDeviceParameters
85 public Multiply_32_Bits
86
87 public START
88 public FatAllocated
89 public MEMERRJ
90 public MEM_OK
91 public RDFRST
92 public NEEDSYS
93 public INITCALL
94 public SWITCHCHK
95 public SYSLOOP
96 public FRMTPROB
97 public GETTRK
98 public TRKFND
99 public CLRTEST
100 public CMPTRKS
101 public BadClus
102; public DoBig
103; public DoSet
104 public DRTFAT
105 public CLEARED
106 public LOUSE
107 public LOUSEP
108 public FATWRT
109 public SYSOK
110 public STATUS
111 public REPORTC
112 public ONCLUS
113 public MORE
114 public FEXIT
115 public SYSPRM
116 public fexitJ
117 public DoPrompt
118 public TARGPRM
119 public IsRemovable
120 public CheckRemove
121 public IsRemove
122 public NotRemove
123 public DSKPRM
124 public GOPRNIT
125 public crlf
126 public PrintString
127 public std_printf
128 public READDOS
129 public RDFILS
130 public FILESDONE
131 public CLSALL
132 public GOTBIOS
133 public GOTDOS
134 public CLSALLJ
135 public GOTCOM
136 public WRITEDOS
137 public GOTALLBIO
138 public BIOSDONE
139 public GOTNDOS
140 public PARTDOS
141 public GOTALLDOS
142 public DOSDONE
143 public PARTCOM
144 public GOTALLCOM
145 public COMDONE
146 public MAKEFIL
147 public CheckMany
148 public CLOSETARG
149 public IOLOOP
150 public GOTTARG
151 public GSYS
152 public TESTSYS
153 public GETOFFS
154; public TESTSYSDISK ; dcl 8/23/86
155 public SETBIOS
156 public BIOSCLS
157 public SETBIOSSIZ
158 public DOSOPNOK
159 public DOSCLS
160 public SETDOSSIZ
161 public GotComHand
162 public COMCLS
163 public SETCOMSIZ
164 public GETFSIZ
165 public READFILE
166 public WRITEFILE
167 public FILIO
168 public NORMIO
169 public IORETP
170 public IORET
171 public NORMALIZE
172 public GotDeviceParameters
173 public LoadSectorTable
174 public NotBigTotalSectors
175 public NotBig
176 public FormatLoop
177 public FormatDone
178 public ContinueFormat
179 public ReportBadTrack
180 public NoMoreTracks
181 public WriteDIRloop
182 public Main_Routine
183 public ControlC_Handler
184
185; bytes
186 public fBigFat
187 public formatError
188 public ROOTSTR
189 public DBLFLG
190 public DRIVE
191 public FILSTAT
192 public USERDIRS
193 public VOLFCB
194 public VOLNAM
195 public TRANSRC
196 public TRANDST
197 public INBUFF
198 public driveLetter
199 public systemDriveLetter
200 public CommandFile
201 public ExitStatus
202 public VolDrive
203 public DelFCB
204 public DelDrive
205
206; words
207 public startSector
208 public fatSpace
209 public firstHead
210 public firstCylinder
211 public tracksLeft
212 public tracksPerDisk
213 public sectorsInRootDirectory
214 public directorySector
215 public printStringPointer
216 public MSTART
217 public MSIZE
218 public TempHandle
219 public BEGSEG
220 public SWITCHMAP
221 public SWITCHCOPY
222 public FAT
223 public CLUSSIZ
224 public SECSIZ
225 public SYSTRKS
226 public SECTORS
227 public currentHead
228 public currentCylinder
229 public PercentComplete
230 public Formatted_Tracks_High
231 public Formatted_Tracks_Low
232
233; other
234 public deviceParameters
235 public Disk_Access
236 public formatPacket
237;-------------------------------------------------------------------------------
238
239data segment public para 'DATA'
240 extrn msgAssignedDrive:byte
241 extrn msgBadDosVersion:byte
242 extrn msgDirectoryWriteError:byte
243 extrn msgFormatComplete:byte
244 extrn msgFormatNotSupported:byte
245 extrn msgFATwriteError:byte
246 extrn msgInvalidDeviceParameters:byte
247 extrn msgLabelPrompt:byte
248 extrn msgNeedDrive:byte
249 extrn msgNoSystemFiles:byte
250 extrn msgNetDrive:byte
251 extrn msgInsertDisk:byte
252 extrn msgHardDiskWarning:byte
253 extrn msgSystemTransfered:byte
254 extrn msgFormatAnother?:byte
255 extrn msgBadCharacters:byte
256 extrn msgBadDrive:byte
257 extrn msgInvalidParameter:byte
258 extrn msgParametersNotSupported:byte
259 extrn msgReInsertDisk:byte
260 extrn msgInsertDosDisk:byte
261 extrn msgFormatFailure:byte
262 extrn ContinueMsg:Byte
263 extrn msgNotSystemDisk:byte
264 extrn msgDiskUnusable:byte
265 extrn msgOutOfMemory:byte
266 extrn msgCurrentTrack:byte
267 extrn msgWriteProtected:byte
268 extrn msgInterrupt:byte
269 extrn msgCRLF:byte
270 extrn Fatal_Error:Byte
271 extrn Read_Write_Relative:Byte
272 extrn PSP_Segment:Word
273 extrn Parse_Error_Msg:Byte
274 extrn Extended_Error_Msg:Byte
275 extrn MsgVerify:Byte
276
277data ends
278
279
280debug equ 0
281 .xlist
282 INCLUDE VERSIONA.INC
283 INCLUDE DOSMAC.INC
284 INCLUDE SYSCALL.INC
285 INCLUDE ERROR.INC
286 INCLUDE DPB.INC
287 INCLUDE CPMFCB.INC
288 INCLUDE DIRENT.INC
289 INCLUDE CURDIR.INC
290 INCLUDE PDB.INC
291 INCLUDE BPB.INC
292 INCLUDE FOREQU.INC
293 INCLUDE FORMACRO.INC
294 INCLUDE IOCTL.INC
295 INCLUDE FORSWTCH.INC
296 INCLUDE SYSVAR.INC
297 .list
298
299
300;-------------------------------------------------------------------------------
301; And this is the actual data
302
303data segment public para 'DATA'
304 public deviceParameters
305 public bios
306 public dos
307 public command
308 public FAT_Flag
309
310validSavedDeviceParameters db 0
311savedDeviceParameters a_DeviceParameters <>
312deviceParameters a_DeviceParameters <>
313
314Disk_Access A_DiskAccess_Control <> ;an000; dms;
315
316formatPacket a_FormatPacket <>
317RWPacket a_TrackReadWritePacket <>
318RW_TRF_Area db 512 dup(0)
319
320startSector dw ?
321fatSpace dd ?
322fBigFat db FALSE
323
324firstHead dw ?
325firstCylinder dw ?
326tracksLeft dw ?
327tracksPerDisk dw ?
328
329Formatted_Tracks_Low dw 0
330Formatted_Tracks_High dw 0
331
332
333public NumSectors ,TrackCnt
334NumSectors dw 0FFFFh
335TrackCnt dw 0FFFFh
336PercentComplete dw 0FFFFh ;Init non-zero so msg will display first time
337
338public Old_Dir
339Old_Dir db FALSE
340
341public fLastChance
342fLastChance db FALSE ; Flags reinvocation from
343 ; LastChanceToSaveIt. Used by DSKPRM
344
345sectorsInRootDirectory dw ?
346
347directorySector dd 0
348
349formatError db 0
350
351printStringPointer dw 0
352
353; Exit status defines
354ExitStatus db 0
355ExitOK equ 0
356ExitCtrlC equ 3
357ExitFatal equ 4
358ExitNo equ 5
359ExitDriveNotReady equ 6 ;an017; dms;drive not ready error
360ExitWriteProtect equ 7 ;an017; dms;write protect error
361
362ROOTSTR DB ?
363 DB ":\",0
364DBLFLG DB 0 ;Initialize flags to zero
365IOCNT DD ?
366MSTART DW ? ; Start of sys file buffer (para#)
367MSIZE DW ? ; Size of above in paragraphs
368TempHandle DW ?
369FILSTAT DB ? ; In memory status of files
370 ; XXXXXX00B BIOS not in
371 ; XXXXXX01B BIOS partly in
372 ; XXXXXX10B BIOS all in
373 ; XXXX00XXB DOS not in
374 ; XXXX01XXB DOS partly in
375 ; XXXX10XXB DOS all in
376 ; XX00XXXXB COMMAND not in
377 ; XX01XXXXB COMMAND partly in
378 ; XX10XXXXB COMMAND all in
379
380USERDIRS DB DIRSTRLEN+3 DUP(?) ; Storage for users current directory
381
382Paras_Per_Fat dw 0000h ;an000;holds fat para count
383Fat_Init_Value dw 0000h ;an000;initializes the FAT
384
385bios a_FileStructure <>
386BiosAttributes EQU attr_hidden + attr_system + attr_read_only
387
388dos a_FileStructure <>
389DosAttributes EQU attr_hidden + attr_system + attr_read_only
390
391command a_FileStructure <>
392CommandAttributes EQU 0
393CommandFile DB "X:\COMMAND.COM",0
394CommandFile_Buffer DB 127 dup(0) ;an000;allow room for copy
395
396Command_Com DB "COMMAND.COM",0
397
398VOLFCB DB -1,0,0,0,0,0,8
399VOLDRIVE DB 0
400VOLNAM DB " "
401 DB 8
402 DB 26 DUP(?)
403
404DelFCB DB -1,0,0,0,0,0,8
405DelDRIVE DB 0
406DelNAM DB "???????????"
407 DB 8
408 DB 26 DUP(?)
409
410TRANSRC DB "A:CON",0,0 ; Device so we don't hit the drive
411TRANDST DB "A:\",0,0,0,0,0,0,0,0,0,0
412
413BEGSEG DW ?
414SWITCHMAP DW ?
415SWITCHCOPY DW ?
416FAT DW ?
417 DW ?
418CLUSSIZ DW ?
419SECSIZ DW ?
420SYSTRKS DW ?
421SECTORS DW ?
422INBUFF DB 80,0
423 DB 80 DUP(?)
424
425
426drive db 0
427driveLetter db "x"
428systemDriveLetter db "x"
429
430CTRL_BREAK_VECTOR dd ? ;ac010; dms;Holds CTRL-Break
431 ; vector
432
433Command_Path dd ? ;an011; dms;hold pointer to
434 ; COMMAND's path
435
436Comspec_ID db "COMSPEC=",00 ;an011; dms;Comspec target
437
438
439Environ_Segment dw ? ;an011; dms;hold segment of
440 ; environ. vector
441;======== Disk Table ========== ;an012; dms;
442;Used if NumberOfFATs in BPB
443;is 0.
444
445DiskTable dw 0, 32680, 0803h, 512, 0
446 dw 4h, 0000h, 0402h, 512, Fbig
447 dw 8h, 0000h, 0803h, 512, Fbig
448 dw 10h, 0000h, 1004h, 512, Fbig
449 dw 20h, 0000h, 2005h, 512, Fbig
450
451public Org_AX ;an000; dms;make it known
452Org_AX dw ? ;an000; dms;AX on entry
453
454Cluster_Boundary_Adj_Factor dw ? ;an000; dms;
455Cluster_Boundary_SPT_Count dw ? ;an000; dms;
456Cluster_Boundary_Flag db False ;an000; dms;
457Cluster_Boundary_Buffer_Seg dw ? ;an000; dms;
458
459Relative_Sector_Low dw ? ;an000; dms;
460Relative_Sector_High dw ? ;an000; dms;
461
462FAT_Flag db ? ;an000; dms;
463Tracks_To_Format dw ? ;an015; dms;
464Track_Count dw ? ;an015; dms;
465Format_End db FALSE ;an015; dms;
466
467public Msg_Allocation_Unit_Val
468
469Msg_Allocation_Unit_Val dd ? ;an019; dms;
470
471
472data ends
473
474;For FORPROC and FORMES modules
475
476 public secsiz,clussiz,inbuff
477
478 PUBLIC crlf,std_printf
479
480 public switchmap,drive,driveLetter,fatSpace
481 public fBigFat, PrintString,currentHead,currentCylinder
482 extrn CheckSwitches:near,LastChanceToSaveIt:near
483 extrn Volid:near
484 extrn WriteBootSector:near,OemDone:near
485 extrn AccessDisk:near
486 extrn Main_Init:near
487 extrn Read_Disk:near
488 extrn Write_Disk:near
489
490data segment public para 'DATA'
491 extrn BiosFile:byte,DosFile:byte
492data ends
493
494;For FORPROC module
495
496 EXTRN FormatAnother?:near,Yes?:near,REPORT:NEAR,USER_STRING:NEAR
497data segment public para 'DATA'
498 extrn syssiz:dword,biosiz:dword
499data ends
500
501DOSVER_LOW EQU 0300H+20
502DOSVER_HIGH EQU 0300H+20
503
504RECLEN EQU fcb_RECSIZ+7
505RR EQU fcb_RR+7
506
507PSP_Environ equ 2ch ;an011; dms;location of
508 ; environ. segment
509 ; in PSP
510
511Fbig equ 0ffh ;an000; dms;flag for big FAT
512
513START:
514 xor bx,bx ; ;AN000;
515 push bx ; ;AN000;
516 Set_Data_Segment ; ;AC000;
517 mov Org_AX,ax ;an000; dms;save ax on entry
518 jmp Main_Init ; ;AC000;
519
520
521Main_Routine: ; ;AN000;
522; Set memory requirements
523 mov bx,PSP_Segment ;Shrink to free space for FAT ;AC000;
524 mov es,bx ; ;AC000;
525 mov bx,End_Of_Memory ; ;AC000;
526 sub bx,PSP_Segment ; ;AC000;
527 DOS_Call Setblock ; ;AC000;
528
529 call Get_Disk_Access ;an014; dms;
530 cmp Disk_Access.DAC_Access_Flag,0ffh ;an014; dms;is access already allowed?
531; $if ne ;an014; dms;no, don't change status
532 JE $$IF1
533 lea dx,Disk_Access ;an014; dms;point to parm block
534 mov Disk_Access.DAC_Access_Flag,01h ;an014; dms;signal disk access
535 call Set_Disk_Access_On_Off ;an014;dms;allow disk access
536; $endif ;an014; dms;
537$$IF1:
538
539 CALL Phase1Initialisation
540 jnc FatAllocated
541
542 Message msgFormatFailure ; ;AC000;
543 jmp Fexit
544
545MEMERR:
546 mov ax, seg data
547 mov ds, ax
548 Message msgOutOfMemory ; ;AC000;
549 ;call PrintString
550 JMP FEXIT
551
552FatAllocated:
553
554 TEST SWITCHMAP,SWITCH_S
555 JZ INITCALL
556 MOV BX,0FFFFH
557 MOV AH,ALLOC
558 INT 21H
559 OR BX,BX
560 JZ MEMERRJ ;No memory
561 MOV [MSIZE],BX
562 MOV AH,ALLOC
563 INT 21H
564 JNC MEM_OK
565MEMERRJ:
566 JMP MEMERR ;No memory
567
568MEM_OK:
569 MOV [MSTART],AX
570
571RDFRST:
572 mov bios.fileSizeInParagraphs,0 ;mjb001 initialize file size
573 mov dos.fileSizeInParagraphs,0 ;mjb001 ...
574 mov command.fileSizeInParagraphs,0 ;mjb001 ...
575 CALL READDOS ;Read BIOS and DOS
576 JNC INITCALL ;OK -- read next file
577NEEDSYS:
578 CALL SYSPRM ;Prompt for system disk
579 JMP RDFRST ;Try again
580
581INITCALL:
582 CALL Phase2Initialisation
583
584SWITCHCHK:
585 MOV DX,SWITCHMAP
586 MOV SWITCHCOPY,DX
587
588SYSLOOP:
589 ;Must intialize for each iteration
590
591 MOV WORD PTR SYSSIZ,0
592 MOV WORD PTR SYSSIZ+2,0
593 MOV BYTE PTR DBLFLG,0
594 mov ExitStatus, ExitOK
595 MOV DX,SWITCHCOPY
596 MOV SWITCHMAP,DX ;Restore original Switches
597; DiskFormat will handle call for new disk
598 CALL DISKFORMAT ;Format the disk
599 JNC GETTRK
600FRMTPROB:
601
602 test SwitchMap,Switch_Select ;an017; dms;SELECT option?
603; $if z ;an017; dms;no - display message
604 JNZ $$IF3
605 Message msgFormatFailure ; ;AC000;
606 mov ExitStatus, ExitFatal ;an017; dms;
607; $endif ;an017; dms;
608$$IF3:
609 CALL MORE ;See if more disks to format
610 JMP SHORT SYSLOOP
611
612;Mark any bad sectors in the FATs
613;And keep track of how many bytes there are in bad sectors
614
615GETTRK:
616 CALL BADSECTOR ;Do bad track fix-up
617 JC FRMTPROB ;Had an error in Formatting - can't recover
618 CMP AX,0 ;Are we finished?
619 JNZ TRKFND ;No - check error conditions
620 JMP DRTFAT ;Yes
621TRKFND:
622 mov bx,word ptr Relative_Sector_Low ;get the low word of the sector ;an000; dms;
623 CMP BX,STARTSECTOR ;Are any sectors in the system area bad?
624 JAE CLRTEST ; MZ 2.26 unsigned compare
625 Message msgDiskUnusable ; ;AC000;
626 JMP FRMTPROB ;Bad disk -- try again
627CLRTEST:
628 MOV SECTORS,AX ;Save the number of sectors on the track
629 TEST SWITCHMAP,SWITCH_S ;If system requested calculate size
630 JZ BAD100
631 CMP BYTE PTR DBLFLG,0 ;Have we already calculated System space?
632 JNZ CMPTRKS ;Yes -- all ready for the compare
633 INC BYTE PTR DBLFLG ;No -- set the flag
634 CALL GETBIOSIZE ; Get the size of the BIOS
635 MOV DX,WORD PTR SYSSIZ+2
636 MOV AX,WORD PTR SYSSIZ
637 MOV WORD PTR BIOSIZ+2,DX
638 MOV WORD PTR BIOSIZ,AX
639 CALL GETDOSSIZE
640 CALL GETCMDSIZE
641 MOV DX,WORD PTR BIOSIZ+2
642 MOV AX,WORD PTR BIOSIZ
643 DIV deviceParameters.DP_BPB.BPB_BytesPerSector
644 ADD AX,STARTSECTOR
645 MOV SYSTRKS,AX ;Space FAT,Dir,and system files require
646CMPTRKS:
647 mov bx,word ptr Relative_Sector_Low ;get the low word of the sector ;an000; dms;
648 CMP BX,SYSTRKS
649 JA BAD100 ; MZ 2.26 unsigned compare
650 mov ExitStatus, ExitFatal
651 Message msgNotSystemDisk ; ;AC000;
652 AND SWITCHMAP,NOT SWITCH_S ;Turn off system transfer switch
653 MOV WORD PTR SYSSIZ+2,0 ;No system to transfer
654 MOV WORD PTR SYSSIZ,0 ;No system to transfer
655BAD100:
656
657 CMP deviceParameters.DP_DeviceType, DEV_HARDDISK ;an000; dms;hard disk?
658; $if e ;an000; dms; yes
659 JNE $$IF5
660 call Get_Bad_Sector_Hard ;an000; dms;see if a sector is bad
661; $else ;an000; dms;floppy disk
662 JMP SHORT $$EN5
663$$IF5:
664 call Get_Bad_Sector_Floppy ;an000; dms;mark entire track bad
665; $endif ;an000; dms;
666$$EN5:
667
668 JMP GETTRK
669
670; Inputs: BX = Cluster number
671; Outputs: The given cluster is marked as invalid
672; Zero flag is set if the cluster was already marked bad
673; Registers modified: DX,SI
674; No other registers affected
675
676;=========================================================================
677; BADCLUS : Marks off a bad cluster in the FAT
678; If a cluster has already been marked bad it
679; will return with ZR.
680;
681; Inputs : DX:AX - Cluster Number
682;
683; Outputs : Cluster is marked invalid
684; ZR set if cluster already marked bad
685;=========================================================================
686
687BadClus proc near ;an000; mark bad clusters
688
689 push di ;an000; save affected regs
690 push ax
691 push bx
692 push cx
693 push dx
694 push es
695
696 mov es, word ptr fatSpace + 2 ;an005; obtain seg of FAT
697 CMP fBigFat,TRUE ;an005; 16 bit fat?
698; $if ne ;an005; no - 12-bit fat
699 JE $$IF8
700 push ax ;an000; save ax - contains low cluster number
701 mov si,dx ;an000; pick up high word of cluster
702 mov di,ax ;an000; pick up low word of cluster
703 mov cx,2 ;an000; divide by 2
704 call Divide_32_Bits ;an000; 32 bit divide
705
706 add ax,di ;an000; add in low word of result
707 adc dx,si ;an000; pick up low word carry
708 ;cluster = cluster * 1.5
709 add ax,word ptr fatspace ;an005; add 0
710 adc dx,0 ;an000; pick up carry
711
712 mov bx,dx ;an000; get high word for adjust
713 mov cx,es ;an005; place seg in ax
714 call BadClus_Address_Adjust ;an000; adjust segment offset
715 mov es,cx ;an000; new segment
716 mov si,ax ;an000; new offset
717
718 MOV DX,0FF7h ;an005; bad cluster flag
719 MOV AX,0FFFh ;an005; mask value
720
721 pop cx ;an000; restore ax in cx - low cluster number
722 test cx,1 ;an000; is old clus num odd?
723; $if nz ;an005; yes
724 JZ $$IF9
725 mov cl,4 ;an005; set shift count
726 SHL AX,cl ;an005; get only 12 bits - fff0
727 mov cl,4 ;an005; set shift count
728 SHL DX,cl ;an005; get 12 bits - ff70
729; $endif ;an005;
730$$IF9:
731; $else ;an005; 16-bit fats here
732 JMP SHORT $$EN8
733$$IF8:
734 xor si,si ;an005; clear si
735 mov bx,dx ;an000; get high word for multiply
736 mov cx,2 ;an000; multiply by 2
737 call Multiply_32_Bits ;an000; 32 bit multiply
738 ; due to 2 bytes per
739 ; FAT cell. This gives
740 ; us an offset into the
741 ; FAT.
742
743 mov cx,es ;an005; place seg in cx
744 call BadClus_Address_Adjust ;an000; adjust segment:offset
745 mov es,cx ;an000; new segment
746 mov si,ax ;an000; new offset
747
748 MOV DX,0FFF7h ;an005; bad cluster value
749 MOV AX,0FFFFh ;an005; mask value
750; $endif
751$$EN8:
752
753 MOV CX,es:[SI] ;an005; get contents of fat cell
754 AND CX,AX ;an005; make it 12 or 16 bit
755 ; depending on value in AX
756 NOT AX ;an005; set AX to 0
757 AND es:[SI],AX ;an005; clear FAT entry
758 OR es:[SI],DX ;an005; flag it a bad cluster
759 CMP DX,CX ; return op == badval;
760
761 pop es
762 pop dx
763 pop cx
764 pop bx
765 pop ax
766 pop di
767 return
768
769badclus endp
770
771DRTFAT:
772 TEST SWITCHMAP,SWITCH_S ;If system requested, calculate size
773 JZ CLEARED
774 CMP BYTE PTR DBLFLG,0 ;Have we already calculated System space?
775 JNZ CLEARED ;Yes
776 INC BYTE PTR DBLFLG ;No -- set the flag
777 CALL GETSIZE ;Calculate the system size
778CLEARED:
779 call Ctrl_Break_Save ;ac010; dms;save CTRL-Break
780 call Set_Ctrl_Break
781 CALL WriteFileSystem
782
783 JNC FATWRT
784
785
786LOUSE:
787
788 call Reset_Ctrl_Break ;ac010; dms;restore CTRL-Break
789 Message msgDiskUnusable ; ;AC000;
790 JMP FRMTPROB
791
792LOUSEP:
793 POP DS
794 JMP LOUSE
795
796FATWRT:
797
798 PUSH DS
799 MOV DL,DRIVE
800 INC DL
801 MOV AH,GET_DPB
802 INT 21H
803 CMP AL,-1
804 JZ LOUSEP ;Something BAD has happened
805 MOV [BX.dpb_next_free],0 ; Reset allocation to start of disk
806 MOV [BX.dpb_free_cnt],-1 ; Force free space to be computed
807 POP DS
808 TEST SWITCHMAP,SWITCH_S ;System desired
809 JZ STATUS
810 mov al, drive
811 call AccessDisk ; note what is current logical drive
812 CALL WRITEDOS ;Write the BIOS & DOS
813 JNC SYSOK
814 Message msgNotSystemDisk ; ;AC000;
815 MOV WORD PTR SYSSIZ+2,0 ;No system transfered
816 MOV WORD PTR SYSSIZ,0 ;No system transfered
817 JMP SHORT STATUS
818
819SYSOK:
820
821
822 test SwitchMap,(Switch_Select or SWITCH_AUTOTEST) ;Don't display if EXEC'd by ;AN000;
823; $IF Z ; Select ;AN000;
824 JNZ $$IF13
825 Message msgSystemTransfered ; ;AC000;
826; $ENDIF ;AN000;
827$$IF13:
828STATUS:
829
830 call Reset_Ctrl_Break ;ac010; dms;restore CTRL-Break
831
832 CALL CRLF
833
834
835
836
837 MOV AH,DISK_RESET
838 INT 21H
839 CALL DONE ;Final call to OEM module
840 JNC REPORTC
841 JMP FRMTPROB ;Report an error
842
843REPORTC:
844
845;
846;TEMP FIX for /AUTOTEST
847;
848 test SwitchMap,(Switch_Autotest or Switch_8) ;TEMP
849; $IF Z
850 JNZ $$IF15
851 CALL VOLID
852; $ENDIF
853$$IF15:
854 test SwitchMap,(Switch_Select or SWITCH_AUTOTEST) ;Need to shut down the report? ;AN000;
855; $IF Z ;If exec'd by Select, we do ;AN000;
856 JNZ $$IF17
857 CALL REPORT ;Print report
858; $ENDIF ; ;AN000;
859$$IF17:
860 CALL MORE ;See if more disks to format
861 JMP SYSLOOP ;If we returned from MORE then continue
862
863;******************************************
864; Calculate the size in bytes of the system rounded up to sector and
865; cluster boundries, Answer in SYSSIZ
866
867GetSize proc near
868 call GetBioSize
869 call GetDosSize
870 call GetCmdSize
871 return
872GetSize endp
873
874GetBioSize proc near
875 MOV AX,WORD PTR bios.fileSizeInBytes
876 MOV DX,WORD PTR bios.fileSizeInBytes+2
877 CALL AddToSystemSize
878 return
879GetBioSize endp
880
881GetDosSize proc near
882 MOV AX,WORD PTR dos.fileSizeInBytes
883 MOV DX,WORD PTR dos.fileSizeInBytes+2
884 CALL AddToSystemSize
885 return
886GetDosSize endp
887
888GetCmdSize proc near
889 MOV AX,WORD PTR command.fileSizeInBytes
890 MOV DX,WORD PTR command.fileSizeInBytes+2
891 call AddToSystemSize
892 return
893GetCmdSize endp
894
895;Calculate the number of sectors used for the system
896PUBLIC AddToSystemSize
897AddToSystemSize proc near
898 push bx
899 DIV deviceParameters.DP_BPB.BPB_BytesPerSector
900 OR DX,DX
901 JZ FNDSIZ0
902 INC AX ; Round up to next sector
903FNDSIZ0:
904 PUSH AX
905 XOR DX,DX
906 xor bx,bx
907 mov bl, deviceParameters.DP_BPB.BPB_SectorsPerCluster
908 div bx
909 POP AX
910 OR DX,DX
911 JZ ONCLUS
912 SUB DX, bx
913 NEG DX
914 ADD AX,DX ; Round up sector count to cluster
915 ; boundry
916ONCLUS:
917 MUL deviceParameters.DP_BPB.BPB_BytesPerSector
918 ADD WORD PTR SYSSIZ,AX
919 ADC WORD PTR SYSSIZ+2,DX
920 pop bx
921 return
922AddToSystemSize endp
923
924MORE:
925
926 mov Formatted_Tracks_Low,0 ;Reinit the track counter ;AN000;
927 mov Formatted_Tracks_High,0 ; in case of another format ;AN000;
928 test SwitchMap,(Switch_Select or SWITCH_AUTOTEST) ;Don't display if EXEC'd by ;AN000;
929 jnz ExitProgram ; Select ;AN000;
930
931 CMP deviceParameters.DP_DeviceType, DEV_HARDDISK
932 je ExitProgram
933 test SwitchMap,(SWITCH_Select or SWITCH_AUTOTEST) ;If exec'd from select, then;AN000;
934 jnz ExitProgram ; don't give user choice ;AN000;
935 CALL FormatAnother? ;Get yes or no response
936 JC ExitProgram
937 CALL CRLF
938 JMP CRLF
939
940
941FEXIT:
942 Set_Data_Segment ;Make sure have addressability ;AN000;
943 mov ExitStatus,ExitFatal
944
945ExitProgram:
946 test validSavedDeviceParameters, 0ffH
947 jz DoNotRestoreDeviceParameters
948 mov savedDeviceParameters.DP_SpecialFunctions, TRACKLAYOUT_IS_GOOD
949 lea dx, savedDeviceParameters
950 call SetDeviceParameters
951DoNotRestoreDeviceParameters:
952
953 call Format_Access_Wrap_Up ;determine access status ;an000; dms;determine access status
954 mov al,ExitStatus ;Get Errorlevel ;AN000;
955 DOS_Call Exit ;Exit program ;AN000;
956 int 20h ;If other exit fails ;AN000;
957
958; Prompt the user for a system diskette in the default drive
959SYSPRM:
960 MOV AH,GET_DEFAULT_DRIVE ;Will find out the default drive
961 INT 21H ;Default now in AL
962 MOV BL,AL
963 INC BL ; A = 1
964 ADD AL,41H ;Now in Ascii
965 MOV systemDriveLetter,AL ;Text now ok
966 CALL IsRemovable
967 JNC DoPrompt
968;
969; Media is non-removable. Switch sys disk to drive A. Check, though, to see
970; if drive A is removable too.
971;
972 MOV AL,"A"
973 MOV BYTE PTR [systemDriveLetter],AL
974 MOV [BiosFile],AL
975 MOV [DosFile],AL
976 MOV [CommandFile],AL
977 MOV BX,1
978 CALL IsRemovable
979 JNC DoPrompt
980 Message msgNoSystemFiles ; ;AC000;
981fexitJ:
982 JMP FEXIT
983
984DoPrompt:
985 mov al, systemDriveLetter
986 sub al, 'A'
987 call AccessDisk
988 Message msgInsertDOSDisk ; ;AC000;
989 Message ContinueMsg
990 ;lea dx, ptr_msgInsertDosDisk
991 ;CALL std_printf ;Print first line
992 CALL USER_STRING ;Wait for a key
993 CALL CRLF
994 call crlf
995 return
996
997TARGPRM:
998 mov al, drive
999 call AccessDisk
1000 Message MsgInsertDisk ; ;AC000;
1001 Message ContinueMsg ;
1002 ;lea DX, ptr_msgInsertDisk
1003 ;CALL std_printf ;Print first line
1004 CALL USER_STRING ;Wait for a key
1005 CALL CRLF
1006 return
1007
1008;
1009; Determine if the drive indicated in BX is removable or not.
1010;
1011; Inputs: BX has drive (0=def, 1=A)
1012; Outputs: Carry clear
1013; Removable
1014; Carry set
1015; not removable
1016; Registers modified: none
1017
1018IsRemovable:
1019 SaveReg <AX>
1020 MOV AX,(IOCTL SHL 8) OR 8 ; Rem media check
1021 INT 21H
1022 JNC CheckRemove
1023 MOV AX,(IOCTL SHL 8) + 9 ; Is it a NET drive?
1024 INT 21h
1025 JC NotRemove ; Yipe, say non-removable
1026 TEST DX,1000h
1027 JNZ NotRemove ; Is NET drive, say non-removeable
1028 JMP IsRemove ; Is local, say removable
1029CheckRemove:
1030 TEST AX,1
1031 JNZ NotRemove
1032IsRemove:
1033 CLC
1034 RestoreReg <AX>
1035 return
1036NotRemove:
1037 STC
1038 RestoreReg <AX>
1039 return
1040
1041
1042; DiSKPRoMpt:
1043;
1044; This routine prompts for the insertion of the correct diskette
1045; into the Target drive, UNLESS we are being re-entrantly invoked
1046; from LastChanceToSaveIt. If the target is a Hardisk we issue a
1047; warning message.
1048;
1049; INPUTS:
1050; deviceParameters.DP_DeviceType
1051; fLastChance
1052;
1053; OUTPUTS:
1054; Prompt string
1055; fLastChance := FALSE
1056;
1057; Registers affected:
1058; Flags
1059;
1060DSKPRM:
1061 CMP fLastChance,TRUE
1062 JE PrmptRet
1063
1064 CMP deviceParameters.DP_DeviceType, DEV_HARDDISK
1065 jne goprnit
1066 Message msgHardDiskWarning ; ;AC000;
1067 ;lea dx, ptr_msgHardDiskWarning
1068 ;call std_printf
1069 CALL Yes?
1070 jnc OkToFormatHardDisk
1071 mov ExitStatus, ExitNo
1072 jmp ExitProgram
1073
1074OkToFormatHardDisk:
1075 CALL CRLF
1076 CALL CRLF
1077 return
1078
1079GOPRNIT:
1080 mov al, drive
1081 call AccessDisk
1082 Message msgInsertDisk ; ;AC000;
1083 Message ContinueMsg ;
1084 ;lea dx,ptr_msgInsertDisk
1085 ;CALL std_printf
1086 CALL USER_STRING ;Wait for any key
1087 CALL CRLF
1088 CALL CRLF
1089
1090PrmptRet:
1091 mov fLastChance, FALSE
1092 return
1093
1094
1095;-------------------------------------------------------------------------------
1096
1097ControlC_Handler:
1098 mov ax, seg data
1099 mov ds, ax
1100 Message msgInterrupt ; ;AC000;
1101 mov ExitStatus, ExitCtrlC
1102 jmp ExitProgram
1103
1104
1105crlf:
1106 ;lea dx, msgCRLF
1107 mov dx,offset msgCRLF ;CR,LF added to message ;AC000;
1108PrintString:
1109 ;mov printStringPointer, dx
1110 ;lea dx, PrintStringPointer
1111
1112std_printf:
1113 ;push dx
1114 ;call printf
1115 call Display_Interface ; ;AC000;
1116 return
1117
1118;-------------------------------------------------------------------------------
1119
1120
1121;****************************************
1122;Copy IO.SYS, MSDOS.SYS and COMMAND.COM into data area.
1123; Carry set if problems
1124
1125READDOS:
1126 push ax ;save regs ;an025; dms;
1127 push bx ; ;an025; dms;
1128 push es ; ;an025; dms;
1129
1130 mov ah,Get_In_Vars ;Find out boot drive ;an025; dms;
1131 int 21h ; ;an025; dms;
1132 mov al,byte ptr es:[bx].SysI_Boot_Drive ;get 1 based drive ID ;an025; dms;
1133 add al,40h ;Make it ASCII ;an025; dms;
1134 mov [BiosFile],al ;Stuff it in file specs. ;an025; dms;
1135 mov [DosFile],al ; ;an025; dms;
1136 mov [CommandFile],al ; ;an025; dms;
1137
1138 pop es ;restore regs ;an025; dms;
1139 pop bx ; ;an025; dms;
1140 pop ax ; ;an025; dms;
1141
1142 call Get_BIOS ; dcl 8/23/86
1143 JNC RDFILS
1144 return
1145
1146RDFILS:
1147 MOV BYTE PTR [FILSTAT],0
1148 MOV BX,[bios.fileHandle]
1149 MOV AX,[MSTART]
1150 MOV DX,AX
1151 ADD DX,[MSIZE] ; CX first bad para
1152 MOV [bios.fileStartSegment],AX
1153 MOV CX,[bios.fileSizeInParagraphs]
1154 ADD AX,CX
1155 CMP AX,DX
1156 JBE GOTBIOS
1157 MOV BYTE PTR [FILSTAT],00000001B ; Got part of BIOS
1158 MOV SI,[MSIZE]
1159 XOR DI,DI
1160 CALL DISIX4
1161 push ds
1162 MOV DS,[bios.fileStartSegment]
1163 assume ds:nothing
1164 CALL READFILE
1165 pop ds
1166 assume ds:data
1167 JC CLSALL
1168 XOR DX,DX
1169 MOV CX,DX
1170 MOV AX,(LSEEK SHL 8) OR 1
1171 INT 21H
1172 MOV WORD PTR [bios.fileOffset],AX
1173 MOV WORD PTR [bios.fileOffset+2],DX
1174FILESDONE:
1175 CLC
1176CLSALL:
1177 PUSHF
1178; CALL COMCLS ; dcl 8/23/86
1179 call FILE_CLS ; dcl 8/23/86
1180 POPF
1181 return
1182
1183GOTBIOS:
1184 MOV BYTE PTR [FILSTAT],00000010B ; Got all of BIOS
1185 push es
1186 LES SI,[bios.fileSizeInBytes]
1187 MOV DI,ES
1188 pop es
1189 push ds
1190 MOV DS,[bios.fileStartSegment]
1191 assume ds:nothing
1192 CALL READFILE
1193 pop ds
1194 assume ds:data
1195 JC CLSALL
1196
1197 push ax ; dcl 8/23/86
1198 push dx ; dcl 8/23/86
1199 call File_Cls ; dcl 8/23/86
1200 call Get_DOS ; dcl 8/23/86
1201 pop dx ; dcl 8/23/86
1202 pop ax ; dcl 8/23/86
1203
1204 JNC Found_IBMDOS ;mt 12/8/86 P894
1205 return ;mt 12/8/86
1206
1207Found_IBMDOS: ;mt 12/8/86
1208
1209 MOV BX,[dos.fileHandle]
1210 MOV [dos.fileStartSegment],AX
1211 CMP AX,DX ; No room left?
1212 JZ CLSALL ; Yes
1213 MOV CX,[dos.fileSizeInParagraphs]
1214 ADD AX,CX
1215 CMP AX,DX
1216 JBE GOTDOS
1217 OR BYTE PTR [FILSTAT],00000100B ; Got part of DOS
1218 SUB DX,[dos.fileStartSegment]
1219 MOV SI,DX
1220 XOR DI,DI
1221 CALL DISIX4
1222 push ds
1223 MOV DS,[dos.fileStartSegment]
1224 assume ds:nothing
1225 CALL READFILE
1226 pop ds
1227 assume ds:data
1228 JC CLSALL
1229 XOR DX,DX
1230 MOV CX,DX
1231 MOV AX,(LSEEK SHL 8) OR 1
1232 INT 21H
1233 MOV WORD PTR [dos.fileOffset],AX
1234 MOV WORD PTR [dos.fileOffset+2],DX
1235 JMP FILESDONE
1236
1237GOTDOS:
1238 OR BYTE PTR [FILSTAT],00001000B ; Got all of DOS
1239 push es
1240 LES SI,[dos.fileSizeInBytes]
1241 MOV DI,ES
1242 pop es
1243 push ds
1244 MOV DS,[dos.fileStartSegment]
1245 assume ds:nothing
1246 CALL READFILE
1247 pop ds
1248 assume ds:data
1249
1250CLSALLJ: JNC NOTCLSALL ;PTM P894 mt 12/8/86
1251 jmp clsall ;
1252
1253NotCLSALL:
1254 push ax ; dcl 8/23/86
1255
1256 push dx ; dcl 8/23/86
1257 call File_cls ; dcl 8/23/86
1258 call Get_Command_Path ;ac011; dms; get path of
1259 ; COMMAND.COM
1260 call Get_COMMAND ;ac011; dms; Point to COMMAND
1261 ; and read it
1262 pop dx ; dcl 8/23/86
1263 pop ax ; dcl 8/23/86
1264
1265 JNC Found_COMMAND ;mt 12/8/86 P894
1266 return ;mt 12/8/86
1267
1268Found_COMMAND: ;mt 12/8/86
1269 MOV BX,[command.fileHandle]
1270 MOV [command.fileStartSegment],AX
1271 CMP AX,DX ; No room left?
1272 JZ CLSALLJ ; Yes
1273 MOV CX,[command.fileSizeInParagraphs]
1274 ADD AX,CX
1275 CMP AX,DX
1276 JBE GOTCOM
1277 OR BYTE PTR [FILSTAT],00010000B ; Got part of COMMAND
1278 SUB DX,[command.fileStartSegment]
1279 MOV SI,DX
1280 XOR DI,DI
1281 CALL DISIX4
1282 push ds
1283 MOV DS,[command.fileStartSegment]
1284 assume ds:nothing
1285 CALL READFILE
1286 pop ds
1287 assume ds:data
1288 JC CLSALLJ
1289 XOR DX,DX
1290 MOV CX,DX
1291 MOV AX,(LSEEK SHL 8) OR 1
1292 INT 21H
1293 MOV WORD PTR [command.fileOffset],AX
1294 MOV WORD PTR [command.fileOffset+2],DX
1295 JMP FILESDONE
1296
1297GOTCOM:
1298 OR BYTE PTR [FILSTAT],00100000B ; Got all of COMMAND
1299 push es
1300 LES SI,[command.fileSizeInBytes]
1301 MOV DI,ES
1302 pop es
1303 push ds
1304 MOV DS,[command.fileStartSegment]
1305 assume ds:nothing
1306 CALL READFILE
1307 pop ds
1308 assume ds:data
1309 JMP CLSALL
1310
1311;**************************************************
1312;Write BIOS DOS COMMAND to the newly formatted disk.
1313
1314ASSUME DS:DATA
1315WRITEDOS:
1316 MOV CX,BiosAttributes
1317 MOV DX,OFFSET BiosFile
1318 push es
1319 LES SI,[bios.fileSizeInBytes]
1320 MOV DI,ES
1321 pop es
1322 CALL MAKEFIL
1323 retc
1324
1325 MOV [TempHandle],BX
1326 TEST BYTE PTR FILSTAT,00000010B
1327 JNZ GOTALLBIO
1328 call Get_BIOS ; dcl 8/23/86
1329 jnc Got_WBIOS ;mt 12/8/86 P894
1330 ret
1331
1332Got_WBIOS:
1333
1334 push es
1335 LES SI,[bios.fileOffset]
1336 MOV DI,ES
1337 pop es
1338 MOV WORD PTR [IOCNT],SI
1339 MOV WORD PTR [IOCNT+2],DI
1340 MOV BP,OFFSET bios
1341 CALL GOTTARG
1342 retc
1343 JMP SHORT BIOSDONE
1344
1345GOTALLBIO:
1346 push es
1347 LES SI,[bios.fileSizeInBytes]
1348 MOV DI,ES
1349 pop es
1350 push ds
1351 MOV DS,[bios.fileStartSegment]
1352 assume ds:nothing
1353 CALL WRITEFILE
1354 pop ds
1355 assume ds:data
1356BIOSDONE:
1357 MOV BX,[TempHandle]
1358 MOV CX,bios.fileTime
1359 MOV DX,bios.fileDate
1360 CALL CLOSETARG
1361 MOV CX,DosAttributes
1362 MOV DX,OFFSET DosFile
1363 push es
1364 LES SI,[dos.fileSizeInBytes]
1365 MOV DI,ES
1366 pop es
1367 CALL MAKEFIL
1368 retc
1369
1370GOTNDOS:
1371 MOV [TempHandle],BX
1372 TEST BYTE PTR FILSTAT,00001000B
1373 JNZ GOTALLDOS
1374 call Get_DOS ; dcl 8/23/86
1375 jnc Got_WDOS ;mt 12/8/86 P894
1376 ret
1377
1378Got_WDOS:
1379 MOV BP,OFFSET dos
1380 TEST BYTE PTR FILSTAT,00000100B
1381 JNZ PARTDOS
1382 MOV WORD PTR [dos.fileOffset],0
1383 MOV WORD PTR [dos.fileOffset+2],0
1384 CALL GETSYS3
1385 retc
1386 JMP SHORT DOSDONE
1387
1388PARTDOS:
1389 push es
1390 LES SI,[dos.fileOffset]
1391 MOV DI,ES
1392 pop es
1393 MOV WORD PTR [IOCNT],SI
1394 MOV WORD PTR [IOCNT+2],DI
1395 CALL GOTTARG
1396 retc
1397 JMP SHORT DOSDONE
1398
1399GOTALLDOS:
1400 push es
1401 LES SI,[dos.fileSizeInBytes]
1402 MOV DI,ES
1403 pop es
1404 push ds
1405 MOV DS,[dos.fileStartSegment]
1406 assume ds:nothing
1407 CALL WRITEFILE
1408 pop ds
1409 assume ds:data
1410DOSDONE:
1411 MOV BX,[TempHandle]
1412 MOV CX,dos.fileTime
1413 MOV DX,dos.fileDate
1414 CALL CLOSETARG
1415 MOV CX,CommandAttributes
1416 call Command_Root ;an011; dms;adjust path for
1417 ;COMMAND.COM creation
1418 MOV DX,OFFSET CommandFile
1419 push es
1420 LES SI,[command.fileSizeInBytes]
1421 MOV DI,ES
1422 pop es
1423 CALL MAKEFIL
1424 retc
1425
1426 MOV [TempHandle],BX
1427 TEST BYTE PTR FILSTAT,00100000B
1428 JNZ GOTALLCOM
1429 call Get_COMMAND ; dcl 8/23/86
1430 jnc Got_WCOM ;mt 12/8/86 P894
1431 ret
1432
1433Got_WCOM:
1434 MOV BP,OFFSET command
1435 TEST BYTE PTR FILSTAT,00010000B
1436 JNZ PARTCOM
1437 MOV WORD PTR [command.fileOffset],0
1438 MOV WORD PTR [command.fileOffset+2],0
1439 CALL GETSYS3
1440 retc
1441 JMP SHORT COMDONE
1442
1443PARTCOM:
1444 push es
1445 LES SI,[command.fileOffset]
1446 MOV DI,ES
1447 pop es
1448 MOV WORD PTR [IOCNT],SI
1449 MOV WORD PTR [IOCNT+2],DI
1450 CALL GOTTARG
1451 retc
1452 JMP SHORT COMDONE
1453
1454GOTALLCOM:
1455 push es
1456 LES SI,[command.fileSizeInBytes]
1457 MOV DI,ES
1458 pop es
1459 push ds
1460 MOV DS,[command.fileStartSegment]
1461 assume ds:nothing
1462 CALL WRITEFILE
1463 pop ds
1464 assume ds:data
1465COMDONE:
1466 MOV BX,[TempHandle]
1467 MOV CX,command.fileTime
1468 MOV DX,command.fileDate
1469 CALL CLOSETARG
1470;****************************************************************
1471; I don't see the need for the following code!! - RS 3.20
1472; CMP BYTE PTR [FILSTAT],00101010B
1473; JZ NOREDOS
1474;RDFRST2:
1475; CALL READDOS ; Start back with BIOS
1476; JNC NOREDOS
1477; CALL SYSPRM ;Prompt for system disk
1478; JMP RDFRST2 ;Try again
1479;NOREDOS:
1480;****************************************************************
1481 CLC
1482 return
1483
1484;*********************************************
1485; Create a file on target disk
1486; CX = attributes, DX points to name
1487; DI:SI is size file is to have
1488;
1489; There is a bug in DOS 2.00 and 2.01 having to do with writes
1490; from the end of memory. In order to circumvent it this routine
1491; must create files with the length in DI:SI
1492;
1493; On return BX is handle, carry set if problem
1494
1495MAKEFIL:
1496 MOV BX,DX
1497 PUSH WORD PTR [BX]
1498 MOV AL,DriveLetter
1499 MOV [BX],AL
1500 MOV AH,CREAT
1501 INT 21H
1502 POP WORD PTR [BX]
1503 MOV BX,AX
1504 JC CheckMany
1505 MOV CX,DI
1506 MOV DX,SI
1507 MOV AX,LSEEK SHL 8
1508 INT 21H ; Seek to eventual EOF
1509 XOR CX,CX
1510 MOV AH,WRITE
1511 INT 21H ; Set size of file to position
1512 XOR CX,CX
1513 MOV DX,CX
1514 MOV AX,LSEEK SHL 8
1515 INT 21H ; Seek back to start
1516 return
1517
1518;
1519; Examine error code in AX to see if it is too-many-open-files.
1520; If it is, we abort right here. Otherwise we return.
1521;
1522CheckMany:
1523 CMP AX,error_too_many_open_files
1524 retnz
1525 Extended_Message ; ;AC006;
1526 JMP FEXIT
1527
1528;*********************************************
1529; Close a file on the target disk
1530; CX/DX is time/date, BX is handle
1531
1532CLOSETARG:
1533 MOV AX,(FILE_TIMES SHL 8) OR 1
1534 INT 21H
1535 MOV AH,CLOSE
1536 INT 21H
1537 return
1538
1539;****************************************
1540; Transfer system files
1541; BP points to data structure for file involved
1542; offset is set to current amount read in
1543; Start set to start of file in buffer
1544; TempHandle is handle to write to on target
1545
1546IOLOOP:
1547 MOV AL,[systemDriveLetter]
1548 CMP AL,[DriveLetter]
1549 JNZ GOTTARG
1550 MOV AH,DISK_RESET
1551 INT 21H
1552 CALL TARGPRM ;Get target disk
1553
1554GOTTARG:
1555ASSUME DS:DATA
1556;Enter here if some of file is already in buffer, IOCNT must be set
1557; to size already in buffer.
1558 MOV BX,[TempHandle]
1559 MOV SI,WORD PTR [IOCNT]
1560 MOV DI,WORD PTR [IOCNT+2]
1561 push ds
1562 MOV DS,ds:[BP.fileStartSegment]
1563 assume ds:nothing
1564 CALL WRITEFILE ; Write next part
1565 pop ds
1566 assume ds:data
1567 retc
1568
1569 push es
1570 LES AX,ds:[BP.fileOffset]
1571 CMP AX,WORD PTR ds:[BP.fileSizeInBytes]
1572 JNZ GETSYS3
1573 MOV AX,ES
1574 CMP AX,WORD PTR ds:[BP.fileSizeInBytes+2]
1575 JNZ GETSYS3
1576 pop es
1577 return ; Carry clear from CMP
1578
1579GETSYS3:
1580;Enter here if none of file is in buffer
1581 pop es
1582 MOV AH,DISK_RESET
1583 INT 21H
1584 MOV AX,[MSTART] ;Furthur IO done starting here
1585 MOV ds:[BP.fileStartSegment],AX ;point to start of buffer
1586 MOV AL,[systemDriveLetter] ;see if we have system disk
1587 CMP AL,[DriveLetter]
1588 JNZ TESTSYS
1589GSYS:
1590 MOV AH,DISK_RESET
1591 INT 21H
1592 CALL SYSPRM ;Prompt for system disk
1593TESTSYS:
1594; CALL TESTSYSDISK ; dcl 8/23/86
1595 JC GSYS
1596 MOV BX,word ptr DS:[BP.fileHandle] ; CS over ARR 2.30
1597 push es
1598 LES DX,dword ptr DS:[BP.fileOffset] ; CS over ARR 2.30
1599 MOV CX,ES
1600 pop es
1601 PUSH DX
1602 MOV AX,LSEEK SHL 8
1603 INT 21H
1604 POP DX
1605 push es
1606 LES SI,dword ptr DS:[BP.fileSizeInBytes] ; CS over ARR 2.30
1607 MOV DI,ES ;put high word in di
1608 pop es
1609 SUB SI,DX ;get low word value
1610 SBB DI,CX ; DI:SI is #bytes to go
1611 PUSH DI
1612 PUSH SI
1613 ADD SI,15 ;round up 1 para
1614 ADC DI,0 ;pick up carry
1615 CALL DISID4 ;div 16 to get para count
1616 MOV AX,SI ;put para count in ax
1617 POP SI ;restore bytes remaining
1618 POP DI ;restore bytes remaining
1619 CMP AX,[MSIZE] ;enough memory to read remainder?
1620 JBE GOTSIZ2 ;yes
1621 MOV SI,[MSIZE]
1622 XOR DI,DI
1623 CALL DISIX4
1624GOTSIZ2:
1625 MOV WORD PTR [IOCNT],SI ;save byte count for read
1626 MOV WORD PTR [IOCNT+2],DI
1627 push ds
1628 MOV DS,[MSTART]
1629 assume ds:nothing
1630 CALL READFILE
1631 pop ds
1632 assume ds:data
1633 JNC GETOFFS
1634 CALL CLSALL
1635 JMP GSYS
1636GETOFFS:
1637 XOR DX,DX ;clear dx
1638 MOV CX,DX ;clear cx
1639 MOV AX,(LSEEK SHL 8) OR 1
1640 INT 21H
1641 MOV WORD PTR DS:[BP.fileOffset],AX ; CS over ARR 2.30
1642 MOV WORD PTR DS:[BP.fileOffset+2],DX ; CS over ARR 2.30
1643;;;;;; CALL CLSALL
1644 JMP IOLOOP
1645
1646;*************************************************
1647; Test to see if correct system disk. Open handles
1648
1649CRET12:
1650 STC
1651 return
1652
1653;TESTSYSDISK: ; dcl 8/23/86
1654Get_BIOS: ; dcl 8/23/86
1655 MOV AX,OPEN SHL 8
1656 MOV DX,OFFSET BiosFile
1657 INT 21H
1658 JNC SETBIOS
1659; call CheckMany ; dcl 8/23/86
1660 jmp CheckMany ; dcl 8/23/86
1661
1662SETBIOS:
1663 MOV [Bios.fileHandle],AX
1664 MOV BX,AX
1665 CALL GETFSIZ
1666 CMP [bios.fileSizeInParagraphs],0
1667 JZ SETBIOSSIZ
1668 CMP [bios.fileSizeInParagraphs],AX
1669 JZ SETBIOSSIZ
1670BIOSCLS:
1671 MOV AH,CLOSE
1672 MOV BX,[Bios.fileHandle]
1673 INT 21H
1674; JMP CRET12 ; dcl 8/23/86
1675 ret
1676
1677SETBIOSSIZ:
1678 MOV [bios.fileSizeInParagraphs],AX
1679 MOV WORD PTR [bios.fileSizeInBytes],SI
1680 MOV WORD PTR [bios.fileSizeInBytes+2],DI
1681 MOV [bios.fileDate],DX
1682 MOV [bios.fileTime],CX
1683 clc
1684 ret ; dcl 8/23/86
1685
1686Get_DOS: ; dcl 8/23/86
1687 MOV AX,OPEN SHL 8
1688 MOV DX,OFFSET DosFile
1689 INT 21H
1690 JNC DOSOPNOK
1691; call CheckMany ; dcl 8/23/86
1692; JMP BIOSCLS ; dcl 8/23/86 Checkmany no ret.
1693 jmp CheckMany ; dcl 8/23/86
1694
1695DOSOPNOK:
1696 MOV [dos.fileHandle],AX
1697 MOV BX,AX
1698 CALL GETFSIZ
1699 CMP [dos.fileSizeInParagraphs],0
1700 JZ SETDOSSIZ
1701 CMP [dos.fileSizeInParagraphs],AX
1702 JZ SETDOSSIZ
1703
1704DOSCLS:
1705 MOV AH,CLOSE
1706 MOV BX,[dos.fileHandle]
1707 INT 21H
1708; JMP BIOSCLS ; dcl 8/23/86
1709 ret ; dcl 8/23/86
1710
1711SETDOSSIZ:
1712 MOV [dos.fileSizeInParagraphs],AX
1713 MOV WORD PTR [dos.fileSizeInBytes],SI
1714 MOV WORD PTR [dos.fileSizeInBytes+2],DI
1715 MOV [dos.fileDate],DX
1716 MOV [dos.fileTime],CX
1717 clc
1718 ret ; dcl 8/23/86
1719
1720
1721
1722Get_COMMAND:
1723 MOV AX,OPEN SHL 8
1724 MOV DX,OFFSET CommandFile
1725 INT 21H
1726 JNC GotComHand
1727; call CheckMany ; dcl 8/23/86
1728; JMP DosCls ; dcl 8/23/86
1729 jmp Checkmany ; dcl 8/23/86
1730
1731GotComHand:
1732 MOV [command.fileHandle],AX
1733 MOV BX,AX
1734 CALL GETFSIZ
1735 CMP [command.fileSizeInParagraphs],0
1736 JZ SETCOMSIZ
1737 CMP [command.fileSizeInParagraphs],AX
1738 JZ SETCOMSIZ
1739COMCLS:
1740 MOV AH,CLOSE
1741 MOV BX,[command.fileHandle]
1742 INT 21H
1743; JMP DOSCLS ; dcl 8/23/86
1744 ret ; dcl 8/23/86
1745
1746SETCOMSIZ:
1747 MOV [command.fileSizeInParagraphs],AX
1748 MOV WORD PTR [command.fileSizeInBytes],SI
1749 MOV WORD PTR [command.fileSizeInBytes+2],DI
1750 MOV [command.fileDate],DX
1751 MOV [command.fileTime],CX
1752 CLC
1753 return
1754
1755FILE_CLS: ; dcl 8/23/86
1756 MOV AH,CLOSE ; dcl 8/23/86
1757 INT 21H ; dcl 8/23/86
1758 ret ; dcl 8/23/86
1759
1760;*******************************************
1761; Handle in BX, return file size in para in AX
1762; File size in bytes DI:SI, file date in DX, file
1763; time in CX.
1764
1765GETFSIZ:
1766 MOV AX,(LSEEK SHL 8) OR 2
1767 XOR CX,CX
1768 MOV DX,CX
1769 INT 21H
1770 MOV SI,AX
1771 MOV DI,DX
1772 ADD AX,15 ; Para round up
1773 ADC DX,0
1774 AND DX,0FH ; If the file is larger than this it
1775 ; is bigger than the 8086 address
1776 ; space!
1777 MOV CL,12
1778 SHL DX,CL
1779 MOV CL,4
1780 SHR AX,CL
1781 OR AX,DX
1782 PUSH AX
1783 MOV AX,LSEEK SHL 8
1784 XOR CX,CX
1785 MOV DX,CX
1786 INT 21H
1787 MOV AX,FILE_TIMES SHL 8
1788 INT 21H
1789 POP AX
1790 return
1791
1792;********************************************
1793; Read/Write file
1794; DS:0 is Xaddr
1795; DI:SI is byte count to I/O
1796; BX is handle
1797; Carry set if screw up
1798;
1799; I/O SI bytes
1800; I/O 64K - 1 bytes DI times
1801; I/O DI bytes
1802
1803
1804READFILE:
1805; Must preserve AX,DX
1806 PUSH AX
1807 PUSH DX
1808 PUSH BP
1809 MOV BP,READ SHL 8
1810 CALL FILIO
1811 POP BP
1812 POP DX
1813 POP AX
1814 return
1815
1816WRITEFILE:
1817 PUSH BP
1818 MOV BP,WRITE SHL 8
1819 CALL FILIO
1820 POP BP
1821 return
1822
1823FILIO:
1824 XOR DX,DX
1825 MOV CX,SI
1826 JCXZ K64IO
1827 MOV AX,BP
1828 INT 21H
1829 retc
1830 ADD DX,AX
1831 CMP AX,CX ; If not =, AX<CX, carry set.
1832 retnz
1833 CALL NORMALIZE
1834K64IO:
1835 CLC
1836 MOV CX,DI
1837 JCXZ IORET
1838 MOV AX,BP
1839 INT 21H
1840 retc
1841 ADD DX,AX
1842 CMP AX,CX ; If not =, AX<CX, carry set.
1843 retnz
1844 CALL NORMALIZE
1845 MOV CX,DI
1846K64M1:
1847 PUSH CX
1848 XOR AX,AX
1849 OR DX,DX
1850 JZ NORMIO
1851 MOV CX,10H
1852 SUB CX,DX
1853 MOV AX,BP
1854 INT 21H
1855 JC IORETP
1856 ADD DX,AX
1857 CMP AX,CX ; If not =, AX<CX, carry set.
1858 JNZ IORETP
1859 CALL NORMALIZE
1860NORMIO:
1861 MOV CX,0FFFFH
1862 SUB CX,AX
1863 MOV AX,BP
1864 INT 21H
1865 JC IORETP
1866 ADD DX,AX
1867 CMP AX,CX ; If not =, AX<CX, carry set.
1868 JNZ IORETP
1869 CALL NORMALIZE ; Clears carry
1870 POP CX
1871 LOOP K64M1
1872 PUSH CX
1873IORETP:
1874 POP CX
1875IORET:
1876 return
1877
1878
1879;*********************************
1880; Shift DI:SI left 4 bits
1881DISIX4:
1882 MOV CX,4
1883SH32:
1884 SHL SI,1
1885 RCL DI,1
1886 LOOP SH32
1887 return
1888
1889;*********************************
1890; Shift DI:SI right 4 bits
1891DISID4:
1892 MOV CX,4
1893SH32B:
1894 SHR DI,1
1895 RCR SI,1
1896 LOOP SH32B
1897 return
1898
1899;********************************
1900; Normalize DS:DX
1901
1902NORMALIZE:
1903 PUSH DX
1904 PUSH AX
1905 SHR DX,1
1906 SHR DX,1
1907 SHR DX,1
1908 SHR DX,1
1909 MOV AX,DS
1910 ADD AX,DX
1911 MOV DS,AX
1912 POP AX
1913 POP DX
1914 AND DX,0FH ; Clears carry
1915 return
1916
1917;-------------------------------------------------------------------------------
1918; Phase1Initialisation:
1919; This routine MUST set up fatSpace, and fBigFat
1920; It also does most of the other initialisation
1921;
1922; Algorithm:
1923; Open a handle for accessing the drive
1924; Get device parameters
1925; save device parameters for exit
1926; Check switches against parameters
1927; Use switches to modify device parameters
1928; directorySector = malloc( Bytes Per Sector )
1929; fatSpace = malloc( Bytes Per Sector * Sectors Per Fat )
1930; Calculate start sector (first sector not used by DOS)
1931; fBigFat = (((Total Sectors - StartSector)/Sectors Per Cluster) >= 4086)
1932;
1933Phase1Initialisation proc near
1934
1935; Get device parameters
1936 lea dx, deviceParameters
1937 mov deviceParameters.DP_SpecialFunctions, 0
1938 call GetDeviceParameters
1939 jnc GotDeviceParameters
1940 Message msgFormatNotSupported ; ;AC000;
1941 ;lea dx, ptr_msgFormatNotSupported
1942 ;call std_printf
1943 jmp fexit
1944GotDeviceParameters:
1945
1946; Save the device parameters for when we exit
1947 lea si, deviceParameters
1948 lea di, savedDeviceParameters
1949 mov cx, size a_DeviceParameters
1950 push ds
1951 pop es
1952 rep movsb
1953
1954; Ensure that there is a valid number of sectors in the track table
1955 mov savedDeviceParameters.DP_TrackTableEntries, 0
1956 mov validSavedDeviceParameters, 1
1957
1958; Initialise this to zero to know if CheckSwitches defined the track layout
1959 mov deviceParameters.DP_TrackTableEntries, 0
1960
1961 call Set_BPB_Info ;an000; dms; Check to see if we are on
1962 ; FAT system. If not set BPB to proper
1963 ; values for format.
1964SetMTsupp:
1965
1966; Check switches against parameters and use switches to modify device parameters
1967 call CheckSwitches
1968 retc
1969
1970IF ShipDisk
1971
1972 test SwitchMap,Switch_Z ;an000; dms;1 sector/cluster disk?
1973; $if nz ;an000; dms;yes
1974 JZ $$IF19
1975 mov DeviceParameters.DP_BPB.BPB_SectorsPerCluster,01h ;an000; dms;set BPB accordingly
1976 call Calc_Small_Fat ;an000; dms;calc FAT size
1977; $endif ;an000; dms;
1978$$IF19:
1979
1980ENDIF
1981
1982
1983 cmp deviceParameters.DP_TrackTableEntries, 0
1984 jne TrackLayoutSet ; There is a good track layout
1985
1986; Store sector table info
1987 mov cx, deviceParameters.DP_BPB.BPB_SectorsPerTrack
1988 mov deviceParameters.DP_TrackTableEntries, cx
1989 mov ax, 1
1990 mov bx, deviceParameters.DP_BPB.BPB_bytesPerSector
1991 lea di, deviceParameters.DP_SectorTable
1992LoadSectorTable:
1993 stosw
1994 xchg ax, bx
1995 stosw
1996 xchg ax, bx
1997 inc ax
1998 loop LoadSectorTable
1999TrackLayoutSet:
2000
2001;
2002; directorySector = malloc( Bytes Per Sector )
2003;
2004 mov bx, deviceParameters.DP_BPB.BPB_BytesPerSector
2005 add bx, 0fH
2006 shr bx, 1
2007 shr bx, 1
2008 shr bx, 1
2009 shr bx, 1
2010 mov ah, Alloc
2011 int 21H
2012 retc
2013 mov word ptr directorySector+2, ax
2014 xor ax,ax
2015 mov word ptr directorySector, ax
2016
2017;
2018; fatSpace = malloc( Bytes Per Sector * Sectors Per FAT )
2019;
2020 mov ax, deviceParameters.DP_BPB.BPB_BytesPerSector
2021 add ax, 0fH
2022 shr ax, 1
2023 shr ax, 1
2024 shr ax, 1
2025 shr ax, 1
2026 mul deviceParameters.DP_BPB.BPB_SectorsPerFAT
2027 mov Paras_Per_Fat,ax ;AN005;128k FAT
2028 mov bx,ax
2029 mov ah,Alloc
2030 int 21H
2031 retc
2032 mov word ptr fatSpace+2,ax
2033 xor ax,ax
2034 mov word ptr fatSpace,ax
2035
2036 call SetStartSector
2037 call SetfBigFat
2038
2039 clc
2040 return
2041
2042Phase1Initialisation endp
2043
2044;-------------------------------------------------------------------------------
2045
2046SetStartSector proc near
2047
2048; startSector = number of reserved sectors
2049; + number of FAT Sectors ( Number of FATS * Sectors Per FAT )
2050; + number of directory sectors ( 32* Root Entries / bytes Per Sector )
2051; ( above is rounded up )
2052
2053; Calculate the number of directory sectors
2054 mov ax, deviceParameters.DP_BPB.BPB_RootEntries
2055 mov bx, size dir_entry
2056 mul bx
2057 add ax, deviceParameters.DP_BPB.BPB_bytesPerSector
2058 dec ax
2059 xor dx,dx
2060 div deviceParameters.DP_BPB.BPB_bytesPerSector
2061 mov sectorsInRootDirectory,ax
2062 mov startSector, ax
2063
2064; Calculate the number of FAT sectors
2065 mov ax, deviceParameters.DP_BPB.BPB_SectorsPerFAT
2066 mul deviceParameters.DP_BPB.BPB_numberOfFATs
2067; Add in the number of boot sectors
2068 add ax, deviceParameters.DP_BPB.BPB_ReservedSectors
2069 add startSector, ax
2070
2071 return
2072
2073SetStartSector endp
2074
2075;-------------------------------------------------------------------------------
2076
2077SetfBigFat proc near
2078;
2079; fBigFat = ( ( (Total Sectors - Start Sector) / Sectors Per Cluster) >= 4086 )
2080;
2081 cmp deviceParameters.DP_BPB.BPB_BigTotalSectors+2,0 ; > 32mb part? ;AN000;
2082; $IF NE ;Yes, big FAT ;AC000;
2083 JE $$IF21
2084 mov fBigFat, TRUE ;Set flag ;AN000;
2085; $ELSE ;Nope, < 32,b ;AC000;
2086 JMP SHORT $$EN21
2087$$IF21:
2088 mov ax,deviceParameters.DP_BPB.BPB_BigTotalSectors ;Assume this used ;AN000;
2089 cmp ax,0 ;Was this field used? ;AN000;
2090; $IF E ;Nope, use the other sector field;AN000;
2091 JNE $$IF23
2092 mov ax, deviceParameters.DP_BPB.BPB_TotalSectors ; ;AC000;
2093 ;** Fix for PTM PCDOS P51
2094; $ENDIF ; ;AN000;
2095$$IF23:
2096 sub ax,startSector ;Get sectors in data area
2097 xor dx,dx
2098 xor bx,bx
2099 mov bl,deviceParameters.DP_BPB.BPB_sectorsPerCluster
2100 div bx ;Get total clusters
2101 cmp ax,BIG_FAT_THRESHOLD ;Is clusters >= 4086?
2102; $IF AE
2103 JNAE $$IF25
2104 mov fBigFAT,TRUE ;16 bit FAT if >=4096
2105 ;** END fix for PTM PCDOS P51
2106; $ENDIF
2107$$IF25:
2108; $ENDIF
2109$$EN21:
2110 return
2111
2112SetfBigFat endp
2113
2114;-------------------------------------------------------------------------------
2115;
2116; Phase2Initialisation:
2117; Use device parameters to build information that will be
2118; required for each format
2119;
2120; Algorithm:
2121; Calculate first head/cylinder to format
2122; Calculate number of tracks to format
2123; Calculate the total bytes on the disk and save for later printout
2124; First initialise the directory buffer
2125;
2126Phase2Initialisation proc near
2127
2128; Calculate first track/head to format (round up - kludge)
2129 mov ax, deviceParameters.DP_BPB.BPB_HiddenSectors
2130 mov dx, deviceParameters.DP_BPB.BPB_HiddenSectors + 2
2131 add ax, deviceParameters.DP_BPB.BPB_SectorsPerTrack
2132 adc dx, 0
2133 dec ax
2134 sbb dx, 0
2135 div deviceParameters.DP_BPB.BPB_SectorsPerTrack
2136 xor dx,dx
2137 div deviceParameters.DP_BPB.BPB_Heads
2138 mov firstCylinder, ax
2139 mov firstHead, dx
2140
2141; Calculate the total number of tracks to be formatted (round down - kludge)
2142 mov ax, deviceParameters.DP_BPB.BPB_TotalSectors
2143 xor dx,dx
2144; if (TotalSectors == 0) then use BigTotalSectors
2145 or ax,ax
2146 jnz NotBigTotalSectors
2147 mov ax, deviceParameters.DP_BPB.BPB_BigTotalSectors
2148 mov dx, deviceParameters.DP_BPB.BPB_BigTotalSectors + 2
2149
2150NotBigTotalSectors:
2151 div deviceParameters.DP_BPB.BPB_SectorsPerTrack
2152 mov tracksPerDisk, ax
2153
2154; Initialise the directory buffer
2155; Clear out the Directory Sector before any information is inserted.
2156 mov cx, deviceParameters.DP_BPB.BPB_BytesPerSector
2157 les di, directorySector
2158 xor ax,ax
2159 rep stosb
2160
2161 mov ax, deviceParameters.DP_BPB.BPB_BytesPerSector
2162 xor dx, dx
2163 mov bx, size dir_entry
2164 div bx
2165 mov cx, ax
2166
2167 les bx, directorySector
2168; If Old_Dir = TRUE then put the first letter of each directory entry must be 0E5H
2169 xor al, al
2170 cmp old_Dir, TRUE
2171 jne StickE5
2172 mov al, 0e5H
2173StickE5:
2174 mov es:[bx], al
2175 add bx, size dir_entry
2176 loop stickE5
2177
2178 ret
2179
2180Phase2Initialisation endp
2181
2182;-------------------------------------------------------------------------------
2183;
2184; SetDeviceParameters:
2185; Set the device parameters
2186;
2187; Input:
2188; drive
2189; dx - pointer to device parameters
2190;
2191SetDeviceParameters proc near
2192
2193 mov ax, (IOCTL shl 8) or GENERIC_IOCTL
2194 mov bl, drive
2195 inc bl
2196 mov cx, (RAWIO shl 8) or SET_DEVICE_PARAMETERS
2197 int 21H
2198 return
2199
2200SetDeviceParameters endp
2201
2202;-------------------------------------------------------------------------------
2203;
2204; GetDeviceParameters:
2205; Get the device parameters
2206;
2207; Input:
2208; drive
2209; dx - pointer to device parameters
2210;
2211GetDeviceParameters proc near
2212
2213 mov ax, (IOCTL shl 8) or GENERIC_IOCTL
2214 mov bl, drive
2215 inc bl
2216 mov cx, (RAWIO shl 8) or GET_DEVICE_PARAMETERS
2217 int 21H
2218 return
2219
2220GetDeviceParameters endp
2221
2222;-------------------------------------------------------------------------------
2223;
2224; DiskFormat:
2225; Format the tracks on the disk
2226; Since we do our SetDeviceParameters here, we also need to
2227; detect the legality of /N /T if present and abort with errors
2228; if not.
2229; This routine stops as soon as it encounters a bad track
2230; Then BadSector is called to report the bad track, and it continues
2231; the format
2232;
2233; Algorithm:
2234; Initialise in memory FAT
2235; current track = first
2236; while not done
2237; if format track fails
2238; DiskFormatErrors = true
2239; return
2240; next track
2241
2242DiskFormat proc near
2243
2244
2245;
2246; Initialise fatSpace
2247;
2248
2249
2250 push es
2251
2252 call Fat_Init ;an000; initialize the FAT
2253
2254 mov di, word ptr fatspace+2 ;an000; get segment of FAT
2255 mov es, di ;an000; place it in es
2256 mov di, word ptr fatSpace ;Should be 0
2257 mov al, deviceParameters.DP_BPB.BPB_MediaDescriptor
2258 mov ah, 0ffH
2259 stosw
2260 mov ax, 00ffH
2261 test fBigFat, TRUE
2262 jz NotBig
2263 mov ax, 0ffffH
2264NotBig: stosw
2265 pop es
2266
2267; don't bother to do the formatting if /c was given
2268 test switchmap, SWITCH_C
2269 jz Keep_Going
2270 jmp FormatDone ;FormatDone is to far away
2271
2272Keep_Going:
2273foofoo = INSTALL_FAKE_BPB or TRACKLAYOUT_IS_GOOD
2274 mov deviceParameters.DP_SpecialFunctions, foofoo
2275 lea dx, deviceParameters
2276
2277 call SetDeviceParameters
2278
2279 call Cluster_Buffer_Allocate ;an000; dms;get room for retry buffer
2280
2281 call Prompt_User_For_Disk ;an016; dms;
2282
2283 test switchmap,switch_8 ; DCL 5/12/86 avoid Naples AH=18h
2284 jnz stdBpB ; lackof support for 8 sectors/track
2285
2286 ; DCL 5/12/86
2287 ; Always do the STATUS_FOR_FORMAT test, as we don't know if the machine
2288 ; has this support. For 3.2 /N: & /T: were not documented & therefore
2289 ; not fully supported thru the ROM of Aquarius & Naples & Royal Palm
2290
2291 ;test SwitchMap, SWITCH_N or SWITCH_T ; IF ( /N or /T ) ;; DCL 5/12/86
2292 ;jz StdBPB
2293 ; THEN check if
2294 ; supported
2295 mov formatPacket.FP_SpecialFunctions, STATUS_FOR_FORMAT
2296 mov ax, (IOCTL shl 8) or GENERIC_IOCTL
2297 mov bl, drive
2298 inc bl
2299 mov cx, (RAWIO shl 8) or FORMAT_TRACK
2300 lea dx, formatPacket
2301 int 21H
2302 ; switch ( FormatStatusCall)
2303
2304 ;cmp FormatPacket.FP_SpecialFunctions, Format_No_ROM_Support
2305 ;jb NTSupported ; 0 returned from IBMBIO
2306 ;ja IllegalComb ; 2 returned - ROM Support
2307 ; Illegal Combination!
2308 cmp FormatPacket.FP_SpecialFunctions,0
2309 je NTSupported
2310 cmp FormatPacket.FP_SpecialFunctions,2
2311; $IF E ; ;AC000;
2312 JNE $$IF28
2313 Message msgInvalidParameter ; ;AC000;
2314 mov Fatal_Error,Yes ;Indicate quittin'type err! ;AN000;
2315; $ELSE ; ; ;
2316 JMP SHORT $$EN28
2317$$IF28:
2318 cmp FormatPacket.FP_SpecialFunctions,3 ; ; ;
2319; $IF E ; ;AC000;
2320 JNE $$IF30
2321 mov ax,Error_Not_Ready ;flag not ready ;an000;dms;
2322 call CheckError ; set error level ;an017; dms;
2323 jmp FrmtProb ; exit program ;an017; dms;
2324; $ELSE ; DCL No ROM support is okay ; ;
2325 JMP SHORT $$EN30
2326$$IF30:
2327 ; except for /N: & /T: ; ;
2328 test SwitchMap, SWITCH_N or SWITCH_T ; DCL 5/12/86 ; ;
2329; $IF NZ ; ;AC000;
2330 JZ $$IF32
2331 Message msgParametersNotSupported ; ;AC000;
2332 mov Fatal_Error,Yes ;Indicate quittin'type err! ;AN000;
2333; $ENDIF ; ;AN000;
2334$$IF32:
2335; $ENDIF ; ;AN000;
2336$$EN30:
2337; $ENDIF ; ;AN000;
2338$$EN28:
2339 cmp Fatal_Error,Yes ; ;AN000;
2340 jne StdBPB ; ;AN000;
2341 jmp Fexit
2342;
2343; We have the support to carry out the FORMAT
2344;
2345NTSupported:
2346StdBPB:
2347 ;call DSKPRM ; prompt user for disk ;; DCL 5/12/86
2348 mov FormatPacket.FP_SpecialFunctions, 0
2349 mov ax, firstHead
2350 mov formatPacket.FP_Head, ax
2351 mov ax, firstCylinder
2352 mov formatPacket.FP_Cylinder, ax
2353 mov cx, tracksPerDisk
2354 mov tracksLeft, cx
2355 mov Format_End,False ;an015; dms;flag not at end of format
2356 call Calc_Max_Tracks_To_Format ;an015; dms;max track count for FormatTrack call
2357FormatLoop:
2358 call Format_Loop ;an015; dms;Format until CY occurs
2359
2360 cmp Format_End,True ;an015; dms;End of Format?
2361; $if e ;an015; dms;yes
2362 JNE $$IF36
2363 mov FormatError,0 ;an015; dms;signal good format
2364 clc ;an015; dms;clear CY
2365; $else ;an015; dms;bad format
2366 JMP SHORT $$EN36
2367$$IF36:
2368 call CheckError ;an015; dms;determine type of error
2369; $if nc ;an015; dms;
2370 JC $$IF38
2371 call LastChanceToSaveIt ;an015; dms;acceptable error?
2372; $if c ;an015; dms;yes
2373 JNC $$IF39
2374 mov FormatError,1 ;an015; dms;signal error type
2375 clc ;an015; dms;clear CY
2376; $else ;an015; dms;not acceptable error
2377 JMP SHORT $$EN39
2378$$IF39:
2379 call SetStartSector ;an015; dms;start from scratch
2380 call SetFBigFat ;an015; dms;
2381 push ax ;an015; dms;
2382 call Phase2Initialisation ;an015; dms;
2383 clc ;an015; dms;
2384 pop ax ;an015; dms;
2385 jmp DiskFormat ;an015; dms;try again
2386; $endif ;an015; dms;
2387$$EN39:
2388; $endif ;an015; dms;
2389$$IF38:
2390; $endif ;an015; dms;
2391$$EN36:
2392 return
2393
2394FormatDone:
2395 mov FormatError,0
2396 clc
2397 return
2398
2399DiskFormat endp
2400
2401
2402;-------------------------------------------------------------------------------
2403;
2404; BadSector:
2405; Reports the bad sectors.
2406; Reports the track where DiskFormat stopped.
2407; From then on it formats until it reaches a bad track, or end,
2408; and reports that.
2409;
2410; Output:
2411; Carry: set --> fatal error
2412; if Carry not set
2413; ax - The number of consecutive bad sectors encountered
2414; ax == 0 --> no more bad sectors
2415; bx - The logical sector number of the first bad sector
2416;
2417; Algorithm:
2418; if DiskFormatErrors
2419; DiskFormatErrors = false
2420; return current track
2421; else
2422; next track
2423; while not done
2424; if format track fails
2425; return current track
2426; next track
2427; return 0
2428
2429BadSector proc near
2430
2431
2432; don't bother to do the formatting if /c was given
2433 test switchmap, SWITCH_C
2434 jnz NoMoreTracks
2435
2436 test formatError, 0ffH
2437 jz ContinueFormat
2438 mov formatError, 0
2439 jmp ReportBadTrack
2440
2441ContinueFormat:
2442 call Adj_Track_Count ;an015; dms;decrease track counter
2443 call NextTrack ;an015; dms;adjust head and cylinder
2444 cmp Format_End,True ;an015; dms;end of format?
2445; $if ne ;an015; dms;no
2446 JE $$IF44
2447 call Format_Loop ;an015; dms;format until CY
2448 cmp Format_End,True ;an015; dms;end of format?
2449; $if ne ;an015; dms;no
2450 JE $$IF45
2451 call CheckError ;an015; dms;must be error - which error?
2452; $if nc ;an015; dms;non-fatal error?
2453 JC $$IF46
2454 call CurrentLogicalSector ;an015; dms;yes - get position
2455 mov ax,DeviceParameters.DP_BPB.BPB_SectorsPerTrack ;an015; dms; set track size
2456 clc ;an015; dms;signal O.K. to continue
2457; $endif ;an015; dms;
2458$$IF46:
2459; $else ;an015; dms;
2460 JMP SHORT $$EN45
2461$$IF45:
2462 jmp NoMoreTracks ;an015; dms;end of format
2463; $endif ;an015; dms;
2464$$EN45:
2465; $else ;an015; dms;
2466 JMP SHORT $$EN44
2467$$IF44:
2468 jmp NoMoreTracks ;an015; dms;end of format
2469; $endif ;an015; dms;
2470$$EN44:
2471 return ;an015; dms;
2472
2473ReportBadTrack:
2474 call CurrentLogicalSector
2475 mov ax, deviceParameters.DP_BPB.BPB_SectorsPerTrack
2476 clc
2477 return
2478
2479NoMoreTracks:
2480 test SwitchMap,(Switch_Select or SWITCH_AUTOTEST) ;Don't display done msg;AN000;
2481; $IF Z ; if EXEC'd by SELECT ;AN000;
2482 JNZ $$IF52
2483 Message msgFormatComplete ; ;AC000;
2484; $ENDIF ; ;AN000;
2485$$IF52:
2486 mov ax, 0
2487 clc
2488 return
2489
2490BadSector endp
2491
2492
2493
2494;-------------------------------------------------------------------------------
2495
2496data segment public para 'DATA'
2497
2498;ptr_msgCurrentTrack dw offset msgCurrentTrack
2499currentHead dw 0
2500currentCylinder dw 0
2501
2502data ends
2503
2504;=========================================================================
2505; Calc_Current_Head_Cyl : Obtain the current head and cylinder of the
2506; track being formatted.
2507;
2508; Inputs: FP_Cylinder - Cylinder of track being formatted
2509; FP_Head - Head of track being formatted
2510;=========================================================================
2511
2512Procedure Calc_Current_Head_Cyl ;an000; dms;
2513
2514 push cx ;an000; dms;save cx
2515 mov cx,FormatPacket.FP_Cylinder ;an000; dms;get current cylinder
2516 mov CurrentCylinder,cx ;an000; dms;put into variable
2517 mov cx,FormatPacket.FP_Head ;an000; dms;get current head
2518 mov CurrentHead,cx ;an000; dms;put into variable
2519 pop cx ;an000; dms;restore cx
2520 ret ;an000; dms;
2521
2522Calc_Current_Head_Cyl endp ;an000; dms;
2523
2524
2525DisplayCurrentTrack proc near
2526
2527 push dx ; ;AN000;
2528 push cx ; ;AN000;
2529 push ax ;an015; dms;
2530
2531 mov ax,Tracks_To_Format ;an015; dms;get track count
2532
2533 add Formatted_Tracks_Low,ax ;Indicate formatted a track ;AN000;
2534 adc Formatted_Tracks_High,0 ; ;AN000;
2535 mov ax,Formatted_Tracks_Low ; ;AN000;
2536 mov bx,Formatted_Tracks_High ; ;AN000;
2537 mov cx,100 ;Make integer calc for div ;AN000;
2538 call Multiply_32_Bits ; BX:AX = (Cyl * Head *100) ;AN000;
2539 mov dx,bx ;Set up divide ;AN000;
2540 div TracksPerDisk ;% = (Cyl * Head *100)/ # tracks;AN000;
2541 cmp ax,PercentComplete ;Only print message when change ;AN000;
2542; $IF NE ;To avoid excess cursor splat ;AN000;
2543 JE $$IF54
2544 mov PercentComplete,ax ;Save it if changed ;AN000;
2545 Message msgCurrentTrack ; ;AC000;
2546; $ENDIF ;
2547$$IF54:
2548 pop ax ;an015; dms;
2549 pop cx ;Restore register ;AN000;
2550 pop dx ; ;AN000;
2551 return
2552
2553DisplayCurrentTrack endp
2554
2555
2556;-------------------------------------------------------------------------------
2557; CheckError:
2558; Input:
2559; ax - extended error code
2560; Ouput:
2561; carry set if error is fatal
2562; Message printed if Not Ready or Write Protect
2563;
2564CheckError proc near
2565 cmp ax, error_write_protect
2566 je WriteProtectError
2567 cmp ax, error_not_ready
2568 je NotReadyError
2569 cmp currentCylinder, 0
2570 jne CheckRealErrors
2571 cmp currentHead, 0
2572 je BadTrackZero
2573
2574CheckRealErrors:
2575 cmp ax, error_CRC
2576 je JustABadTrack
2577 cmp ax, error_sector_not_found
2578 je JustABadTrack
2579 cmp ax, error_write_fault
2580 je JustABadTrack
2581 cmp ax, error_read_fault
2582 je JustABadTrack
2583 cmp ax, error_gen_failure
2584 je JustABadTrack
2585
2586 stc
2587 ret
2588
2589JustABadTrack:
2590 clc
2591 ret
2592
2593WriteProtectError:
2594
2595 test SwitchMap,Switch_SELECT ;an017; dms;SELECT option?
2596; $if z ;an017; dms;no - display messages
2597 JNZ $$IF56
2598 Message msgCRLF ; ;AC006;
2599 Message msgCRLF ; ;AC006;
2600 Extended_Message ; ;AC006;
2601; $else ;an017; dms;yes - set error level
2602 JMP SHORT $$EN56
2603$$IF56:
2604 mov ExitStatus,ExitWriteProtect ;an017; dms;signal write protect error
2605; $endif ;an017; dms;
2606$$EN56:
2607
2608 stc ;an017; dms;signal fatal error
2609 ret ;an017; dms;return to caller
2610
2611NotReadyError:
2612 test SwitchMap,Switch_SELECT ;an017; dms; SELECT option?
2613; $if z ;an017; dms; no - display messages
2614 JNZ $$IF59
2615 Message msgCRLF ; ;AC006;
2616 Message msgCRLF ; ;AC006;
2617 Extended_Message ; ;AC006;
2618; $else ;an017; dms;yes - set error level
2619 JMP SHORT $$EN59
2620$$IF59:
2621 mov ExitStatus,ExitDriveNotReady ;an017; dms;signal drive not ready
2622; $endif ;an017; dms;
2623$$EN59:
2624 stc
2625 ret
2626
2627
2628BadTrackZero:
2629 Message msgDiskUnusable ; ;AC000;
2630 stc
2631 ret
2632
2633CheckError endp
2634
2635;-------------------------------------------------------------------------------
2636; WriteFileSystem:
2637; Write the boot sector and FATs out to disk
2638; Clear the directory sectors to zero
2639;
2640
2641WriteFileSystem proc near
2642
2643
2644 call WriteBootSector
2645 retc
2646
2647 Set_Data_Segment ;Set DS,ES = DATA ;AN000;
2648; Write out each of the FATs
2649 push ds ;ac005; dms;save ds
2650 xor cx, cx
2651 mov cl, es:deviceParameters.DP_BPB.BPB_numberOfFATs ; ;AC000;
2652 mov dx, es:deviceParameters.DP_BPB.BPB_ReservedSectors ; ;AC000;
2653 mov al, es:drive ; ;AC000;
2654 mov bx,word ptr es:FatSpace+2 ;Get segment of memory Fat ;AC000;
2655 mov ds,bx ; ;AN000;
2656 mov bx,word ptr es:FatSpace ; ;AN000;
2657
2658 mov si,bx ;ac005; dms;set up for add. calc
2659 call SEG_ADJ ;ac005; dms;get adjusted seg:off
2660 mov bx,si ;ac005; dms;get new off
2661 assume ds:nothing,es:data ; ;AN000;
2662
2663; $do ;ac005; dms;while FATS > 0
2664$$DO62:
2665 cmp cx,00 ;ac005; dms;FATS remaining?
2666; $leave e ;ac005; dms;no
2667 JE $$EN62
2668 push bx ;ac005; dms;save FAT offset
2669 push ds ;ac005; dms;save FAT segment
2670 push cx ;ac005; dms;save FAT count
2671 push dx ;ac005; dms;reserved FAT sector
2672 call WRITE_FAT ;ac005; dms;write the FAT
2673 pop dx ;ac005; dms;get 1st. FAT sector
2674 pop cx ;ac005; dms;get FAT count
2675 pop ds ;ac005; dms;restore FAT segment
2676 pop bx ;ac005; dms;restore FAT offset
2677; $if c ;ac005; dms;an error occurred
2678 JNC $$IF64
2679 Message msgFATwriteError;ac005; dms;say why failed
2680 jmp FEXIT ;ac005; dms;exit format
2681; $endif ;ac005; dms;
2682$$IF64:
2683 add dx, es:deviceParameters.DP_BPB.BPB_SectorsPerFAT ; ;AC000;
2684 dec cx ;ac005; dms;decrease FAT count
2685; $enddo ;ac005; dms;
2686 JMP SHORT $$DO62
2687$$EN62:
2688
2689 pop ds ;ac005; dms;restore ds
2690 assume ds:data ;ac005; dms;
2691
2692
2693; Clear the directory
2694
2695; Now write the initialised directory sectors out to disk
2696 mov ax, es:deviceParameters.DP_BPB.BPB_SectorsPerFAT ; ;AC000;
2697 xor dx,dx
2698 push bx ;an000; dms;save bx
2699 xor bx,bx ;an000; dms;clear bx
2700 mov bl,es:DeviceParameters.DP_BPB.BPB_NumberOfFATs ;an000; dms;get FAT count
2701 mul bx ;an000; dms;get total FAT sectors
2702 pop bx ;an000; dms;restore bx
2703
2704 mov dx, es:deviceParameters.DP_BPB.BPB_ReservedSectors ; ;AC000;
2705 add dx, ax
2706 mov cx, es:sectorsInRootDirectory ; ;AC000;
2707WriteDIRloop:
2708 push cx
2709 push dx
2710 mov al, es:drive ; ;AC000;
2711 mov cx, 1
2712 lds bx, es:directorySector ; ;AC000;
2713
2714 assume ds:nothing,es:data ; ;AN000;
2715
2716;Assume dir is alway contined in first 32mb of partition
2717
2718 mov es:Read_Write_Relative.Start_Sector_High,0 ; ;AC000;
2719 Call Write_Disk ; ;AN000;
2720 jnc Dir_OK ; ;AC000;
2721 Message msgDirectoryWriteError ; ;AC000;
2722 jmp FExit ; ;AN000;
2723Dir_OK: ; ;AN000;
2724 pop dx
2725 add dx, 1
2726 pop cx
2727 loop WriteDIRLoop
2728
2729 Set_Data_Segment ;Set DS to DATA segment ;AN000;
2730; Ok, we can tell the device driver that we are finished formatting
2731 mov savedDeviceParameters.DP_TrackTableEntries, 0
2732 mov savedDeviceParameters.DP_SpecialFunctions, TRACKLAYOUT_IS_GOOD
2733 lea dx, savedDeviceParameters
2734 call SetDeviceParameters
2735
2736 MOV AH,DISK_RESET ; Flush any directories in
2737 INT 21H ; buffers
2738
2739 return
2740
2741
2742WriteFileSystem endp
2743
2744;=========================================================================
2745; WRITE_FAT : This routine writes the logical sector count requested.
2746; It will write a maximum of 40h sectors. If more
2747; than 40h exists it will continue looping until
2748; all sectors have been written.
2749;
2750; Inputs : AL - Drive letter
2751; DS:BX - Segment:offset of transfer address
2752; CX - Sector count
2753; DX - 1st. sector
2754;
2755; Outputs : Logical sectors written
2756;=========================================================================
2757
2758procedure write_fat
2759
2760 mov cx, es:deviceParameters.DP_BPB.BPB_SectorsPerFAT ; ;AC000;
2761
2762; $do ;an000;while sectors left
2763$$DO67:
2764 cmp cx,00h ;an000;any sectors?
2765; $leave e ;an000;no
2766 JE $$EN67
2767
2768 cmp cx,40h
2769; $if a ;an000;yes
2770 JNA $$IF69
2771 push cx ;an000;save cx
2772 mov cx,40h
2773 push ax ;an000;save ax
2774 call write_disk ;an000;write it
2775 pop ax ;an000;restore ax
2776 pop cx ;an000;restore cx
2777 jc Write_Exit ;an000;exit if fail
2778 mov si,8000h
2779 call seg_adj ;an000;adjust segment
2780 mov bx,si ;an000;new offset
2781 add dx,40h
2782 sub cx,40h
2783; $else ;an000;< 64k
2784 JMP SHORT $$EN69
2785$$IF69:
2786 push ax ;an000;save ax
2787 call write_disk ;an000;write it
2788 pop ax ;an000;restore ax
2789 xor cx,cx ;an000;set cx to 0 - last read
2790; $endif
2791$$EN69:
2792; $enddo
2793 JMP SHORT $$DO67
2794$$EN67:
2795
2796 Write_Exit:
2797
2798 ret
2799
2800write_fat endp
2801
2802;=========================================================================
2803; SEG_ADJ : This routine adjusts the segment:offset to prevent
2804; address wrap.
2805;
2806; Inputs : SI - Offset to adjust segment with
2807; DS - Segment to be adjusted
2808;
2809; Outputs : SI - New offset
2810; DS - Adjusted segment
2811;=========================================================================
2812
2813procedure seg_adj
2814
2815 push ax
2816 push cx
2817 push dx
2818 mov ax,si ;an000;get offset
2819 mov bx,0010h ;an000;16
2820 xor dx,dx ;an000;clear dx
2821 div bx ;an000;get para count
2822; $if c ;an000;overflow?
2823 JNC $$IF73
2824 adc bx,0 ;an000;pick it up
2825; $endif ;an000;
2826$$IF73:
2827 mov bx,ds ;an000;get seg
2828 add bx,ax ;an000;adjust for paras
2829 mov ds,bx ;an000;save new seg
2830 mov si,dx ;an000;new offset
2831 pop dx
2832 pop cx
2833 pop ax
2834 ret
2835
2836seg_adj endp
2837
2838;-------------------------------------------------------------------------------
2839; format is done... so clean up the disk!
2840;
2841Done proc near
2842
2843
2844 call OemDone
2845 return
2846
2847Done endp
2848
2849;-------------------------------------------------------------------------------
2850; CurrentLogicalSector:
2851; Get the current logical sector number
2852;
2853; Input:
2854; current track = tracksPerDisk - tracksLeft
2855; SectorsPerTrack
2856;
2857; Output:
2858; BX = logical sector number of the first sector in the track we
2859; just tried to format
2860;
2861CurrentLogicalSector proc near
2862
2863 push ax ;an000; dms;save regs
2864 push bx ;an000; dms;
2865 push dx ;an000; dms;
2866
2867 mov ax, tracksPerDisk
2868 sub ax, tracksLeft
2869 xor dx,dx ;an000; dms;clear dx
2870 mul deviceParameters.DP_BPB.BPB_SectorsPerTrack
2871 mov word ptr Relative_Sector_High,dx ;an000; dms;save high word of sector #
2872 mov word ptr Relative_Sector_Low,ax ;an000; dms;save low word of sector #
2873
2874 pop dx ;an000; dms;restore regs
2875 pop bx ;an000; dms;
2876 pop ax ;an000; dms;
2877
2878 return
2879
2880CurrentLogicalSector endp
2881
2882;-------------------------------------------------------------------------------
2883; PrintErrorAbort:
2884; Print an error message and abort
2885;
2886; Input:
2887; dx - Pointer to error message string
2888;
2889PrintErrorAbort proc near
2890
2891 push dx
2892 call crlf
2893 pop dx
2894 call PrintString
2895
2896 jmp fexit
2897
2898PrintErrorAbort endp
2899
2900
2901
2902
2903;*****************************************************************************
2904;Routine name: Multiply_32_Bits
2905;*****************************************************************************
2906;
2907;Description: A real sleazy 32 bit x 16 bit multiply routine. Works by adding
2908; the 32 bit number to itself for each power of 2 contained in the
2909; 16 bit number. Whenever a bit that is set in the multiplier (CX)
2910; gets shifted to the bit 0 spot, it means that that amount has
2911; been multiplied so far, and it should be added into the total
2912; value. Take the example CX = 12 (1100). Using the associative
2913; rule, this is the same as CX = 8+4 (1000 + 0100). The
2914; multiply is done on this principle - whenever a bit that is set
2915; is shifted down to the bit 0 location, the value in BX:AX is
2916; added to the running total in DI:SI. The multiply is continued
2917; until CX = 0. The routine will exit with CY set if overflow
2918; occurs.
2919;
2920;
2921;Called Procedures: None
2922;
2923;Change History: Created 7/23/87 MT
2924;
2925;Input: BX:AX = 32 bit number to be multiplied
2926; CX = 16 bit number to be multiplied. (Must be even number)
2927;
2928;Output: BX:AX = output.
2929; CY set if overflow
2930;
2931;Psuedocode
2932;----------
2933;
2934; Point at ControlC_Handler routine
2935; Set interrupt handler (INT 21h, AX=2523h)
2936; ret
2937;*****************************************************************************
2938
2939Public Multiply_32_Bits
2940Multiply_32_Bits proc ; ;AN000;
2941
2942 push di ; ;AN000;
2943 push si ; ;AN000;
2944 xor di,di ;Init result to zero
2945 xor si,si ;
2946 cmp cx,0 ;Multiply by 0? ;AN000;
2947; $IF NE ;Keep going if not ;AN000;
2948 JE $$IF75
2949; $DO ;This works by adding the result;AN000;
2950$$DO76:
2951 test cx,1 ;Need to add in sum of this bit?;AN000;
2952; $IF NZ ;Yes ;AN000;
2953 JZ $$IF77
2954 add si,ax ;Add in the total so far for ;AN000;
2955 adc di,bx ; this bit multiplier (CY oflow);AN000;
2956; $ELSE ;Don't split multiplier ;AN000;
2957 JMP SHORT $$EN77
2958$$IF77:
2959 clc ;Force non exit ;AN000;
2960; $ENDIF ; ;AN000;
2961$$EN77:
2962; $LEAVE C ;Leave on overflow ;AN000;
2963 JC $$EN76
2964 shr cx,1 ;See if need to multiply value ;AN000;
2965 cmp cx,0 ;by 2 ;AN000;
2966; $LEAVE E ;Done if cx shifted down to zero;AN000;
2967 JE $$EN76
2968 add ax,ax ;Each time cx is shifted, add ;AN000;
2969 adc bx,bx ;value to itself (Multiply * 2) ;AN000;
2970; $ENDDO C ;CY set on overflow ;AN000;
2971 JNC $$DO76
2972$$EN76:
2973; $IF NC ;If no overflow, add in DI:SI ;AN000;
2974 JC $$IF83
2975 mov ax,si ; which contains the original ;AN000;
2976 mov bx,di ; value if odd, 0 if even. This ;AN000;
2977 clc ;Set no overflow flag ;AN000;
2978; $ENDIF ; ;AN000;
2979$$IF83:
2980; $ELSE ;
2981 JMP SHORT $$EN75
2982$$IF75:
2983 xor ax,ax ;
2984 xor bx,bx ;
2985; $ENDIF ;Multiply by 0 ;AN000;
2986$$EN75:
2987 pop si ; ;AN000;
2988 pop di ; ;AN000;
2989 ret ; ;AN000;
2990
2991Multiply_32_Bits endp
2992
2993
2994;=========================================================================
2995; Divide_32_Bits - This routine will perform 32bit division
2996;
2997; Inputs : SI:DI - value to be divided
2998; CX - divisor
2999;
3000; Outputs : SI:DI - result
3001; CX - remainder
3002;=========================================================================
3003
3004Procedure Divide_32_Bits ;an000; dms;
3005
3006 push ax ;an000; dms;save regs
3007 push bx ;an000; dms;
3008 push dx ;an000; dms;
3009
3010 xor dx,dx ;an000; dms;clear dx
3011 mov ax,si ;an000; dms;get high word
3012 div cx ;an000; dms;get high word result
3013 mov si,ax ;an000; dms;save high word result
3014
3015 mov ax,di ;an000; dms;get low word
3016 div cx ;an000; dms;get low word result
3017 mov di,ax ;an000; dms;save low word result
3018 mov cx,dx ;an000; dms;pick up remainder
3019
3020 pop dx ;an000; dms;restore regs
3021 pop bx ;an000; dms;
3022 pop ax ;an000; dms;
3023
3024 ret ;an000; dms;
3025
3026Divide_32_Bits endp ;an000; dms;
3027
3028
3029
3030
3031;=========================================================================
3032; FAT_INIT: This routine initializes the FAT based on the
3033; number of paragraphs.
3034;
3035;
3036; input - fatspace
3037; fatspace+2
3038; paras_per_fat
3039; fat_init_value
3040; output - fat space is initialized
3041;
3042;=========================================================================
3043Public Fat_Init
3044Fat_Init proc near
3045
3046 push es
3047 push di
3048 push ax
3049 push bx
3050 push cx
3051 mov di, word ptr FatSpace+2 ;Get segment of Fat space ;AC000;
3052 mov es,di ; ;AN000;
3053 mov di, word ptr FatSpace ; ;AN000;
3054 mov bx,Paras_Per_Fat ;an000;get number of paras
3055 mov ax,fat_init_value ;an000;
3056 push dx ;an000;save bx
3057 mov dx,es ;an000;grab es into dx
3058; $do
3059$$DO87:
3060 cmp bx,0 ;an000;do while bx not = 0
3061; $leave e ;an000;exit if 0
3062 JE $$EN87
3063 mov cx,10h ;an000;word move of paragraph
3064 rep stosb ;an000;move the data to FAT
3065 xor di,di ;an000;offset always init to 0
3066 inc dx ;an000;next paragraph
3067 mov es,dx ;an000;put next para in es
3068 dec bx ;an000;loop iteration counter
3069; $enddo ;an000;
3070 JMP SHORT $$DO87
3071$$EN87:
3072 pop dx ;an000;
3073 pop cx ;an000;
3074 pop bx ;an000;
3075 pop ax ;an000;
3076 pop di ;an000;
3077 pop es ;an000;
3078
3079 ret ;an000;
3080
3081Fat_Init endp ;an000;
3082
3083
3084;=========================================================================
3085; Ctrl_Break_Write : This routine takes the control break request
3086; an returns. In essence, it disables the CTRL-BREAK.
3087; This routine is used during the writing of the
3088; FAT, DIR, and SYSTEM.
3089;=========================================================================
3090
3091Ctrl_Break_Write: ;ac010; dms;
3092
3093 iret ;ac010; dms;return to caller
3094
3095
3096;=========================================================================
3097; Ctrl_Break_Save : This routine gets the current vector of
3098; INT 23h and saves it in CTRL_BREAK_VECTOR.
3099;
3100; Inputs : none
3101;
3102; Outputs : CTRL_BREAK_VECTOR - holds address of INT 23h routine
3103;=========================================================================
3104
3105Ctrl_Break_Save proc near ;ac010; dms;
3106
3107 push es ;ac010; dms;save es
3108 push bx ;ac010; dms;save bx
3109 push ax ;ac010; dms;save ax
3110
3111 mov ax,3523h ;ac010; dms;get CTRL-BREAK
3112 ; interrupt vector
3113 int 21h ;ac010; dms;
3114
3115 mov word ptr Ctrl_Break_Vector,bx ;ac010; dms;get vector offset
3116 mov word ptr Ctrl_Break_Vector+2,es ;ac010; dms;get vector segment
3117
3118 pop ax ;ac010; dms;restore ax
3119 pop bx ;ac010; dms;restore bx
3120 pop es ;ac010; dms;restore es
3121
3122 ret ;ac010; dms;
3123
3124
3125Ctrl_Break_Save endp ;ac010; dms;
3126
3127
3128;=========================================================================
3129; Set_Ctrl_Break : This routine sets the CTRL-Break vector to one
3130; defined by the user.
3131;
3132; Inputs : none
3133;
3134; Outputs : CTRL_BREAK_VECTOR - holds address of INT 23h routine
3135;=========================================================================
3136
3137Set_Ctrl_Break proc near ;ac010; dms;
3138
3139 push ds ;ac010; dms;save ds
3140 push ax ;ac010; dms;save ax
3141 push bx ;ac010; dms;save bx
3142 push dx ;ac010; dms;save dx
3143
3144 push cs ;ac010; dms;swap cs with ds
3145 pop ds ;an000; dms;point to code seg
3146
3147 mov dx,offset Ctrl_Break_Write ;ac010; dms;get interrupt vec.
3148 mov ax,2523h ;ac010; dms;set CTRL-BREAK
3149 ; interrupt vector
3150 int 21h ;ac010; dms;
3151
3152 pop dx ;ac010; dms;restore dx
3153 pop bx ;ac010; dms;restore bx
3154 pop ax ;ac010; dms;restore ax
3155 pop ds ;ac010; dms;restore ds
3156
3157 ret ;ac010; dms;
3158
3159
3160Set_Ctrl_Break endp ;ac010; dms;
3161
3162
3163;=========================================================================
3164; Reset_Ctrl_Break : This routine resets the CTRL-Break vector to that
3165; originally defined.
3166;
3167; Inputs : CTRL_BREAK_VECTOR - holds address of INT 23h routine
3168;
3169; Outputs : none
3170;=========================================================================
3171
3172Reset_Ctrl_Break proc near ;ac010; dms;
3173
3174 push ds ;ac010; dms;save ds
3175 push ax ;ac010; dms;save ax
3176 push bx ;ac010; dms;save bx
3177 push dx ;ac010; dms;save ds
3178
3179 mov ax,word ptr Ctrl_Break_Vector+2 ;ac010; dms;get seg. of vector
3180 mov bx,word ptr Ctrl_Break_Vector ;ac010; dms;get off. of vector
3181 mov ds,ax ;ac010; dms;get seg.
3182 mov dx,bx ;ac010; dms;get off.
3183 mov ax,2523h ;ac010; dms;set CTRL-BREAK
3184 ; interrupt vector
3185 int 21h ;ac010; dms;
3186
3187 pop dx ;ac010; dms;restore dx
3188 pop bx ;ac010; dms;restore bx
3189 pop ax ;ac010; dms;restore ax
3190 pop ds ;ac010; dms;restore ds
3191
3192 ret ;ac010; dms;
3193
3194
3195Reset_Ctrl_Break endp ;ac010; dms;
3196
3197;=========================================================================
3198; Get_Command_Path : This routine finds the path where
3199; COMMAND.COM resides based on the
3200; environmental vector. Once the
3201; path is found it is copied to
3202; CommandFile.
3203;
3204; Inputs : Exec_Block.Segment_Env - Segment of environmental vector
3205; Comspec_ID - "COMSPEC="
3206;
3207; Outputs : CommandFile - Holds path to COMMAND.COM
3208;=========================================================================
3209
3210Procedure Get_Command_Path ;an011; dms;
3211
3212 push ds ;an011; dms;save ds
3213 push es ;an011; dms;save es
3214
3215 Set_Data_Segment ;an011; dms; DS,ES = Data
3216 call Get_PSP_Parms ;an011; dms; gets PSP info.
3217 cld ;an011; dms; clear direction
3218 mov ax,es:Environ_Segment ;an011; dms; get seg. of
3219 ; environ. vector
3220 mov ds,ax ;an011; dms; put it in DS
3221 assume ds:nothing ;an011; dms;
3222 xor si,si ;an011; dms; clear si
3223 mov bx,si ;an011; dms; save si
3224 mov di,offset Comspec_ID ;an011; dms; point to target
3225 mov cx,127 ;an011; dms; loop 127 times
3226; $do ;an011; dms; while cx not 0
3227$$DO90:
3228 ; and target not found
3229 cmp cx,00h ;an011; dms; end of env.?
3230; $leave e ;an011; dms; yes
3231 JE $$EN90
3232
3233 push cx ;an011; dms; save cx
3234 mov cx,0008h ;an011; dms; loop 8 times
3235 repe cmpsb ;an011; dms; "COMSPEC=" ?
3236 pop cx ;an011; dms; restore cx
3237; $if z ;an011; dms; yes
3238 JNZ $$IF92
3239 push di ;an011; dms; save di
3240 mov di,offset es:CommandFile ;an011; dms
3241 lodsb ;an011; dms; priming read
3242 mov dl,al ;an011; dms; prepare for capitalization
3243 call Cap_Char ;an011; dms; capitalize character in DL
3244 cmp dl,es:CommandFile ;an011; dms;COMSPEC same as default drive?
3245; $if e ;an000; dms; yes
3246 JNE $$IF93
3247; $do ;an011; dms; while AL not = 0
3248$$DO94:
3249 cmp al,00h ;an011; dms; at end?
3250; $leave e ;an011; dms; yes
3251 JE $$EN94
3252 stosb ;an011; dms; save it
3253 lodsb ;an011; dms; get character
3254; $enddo
3255 JMP SHORT $$DO94
3256$$EN94:
3257; $endif ;an011; dms;
3258$$IF93:
3259 pop di ;an011; dms; restore di
3260 mov cx,0ffffh ;an011; dms; flag target found
3261; $endif ;an011; dms;
3262$$IF92:
3263
3264 cmp cx,0ffffh ;an011; dms; target found?
3265; $leave e ;an011; dms; yes
3266 JE $$EN90
3267
3268 mov di,offset Comspec_ID ;an011; dms; point to target
3269 mov si,bx ;an011; dms; restore si
3270 inc si ;an011; dms; point to next byte
3271 mov bx,si ;an011; dms; save si
3272
3273 dec cx ;an011; dms; decrease counter
3274; $enddo ;an011; dms;
3275 JMP SHORT $$DO90
3276$$EN90:
3277
3278 pop es ;an011; dms; restore es
3279 pop ds ;an011; dms; restore ds
3280
3281 ret ;an011; dms;
3282
3283Get_Command_Path endp ;an011; dms;
3284
3285
3286;
3287;****************************************************************************
3288; Get_PSP_Parms
3289;****************************************************************************
3290;
3291;
3292;
3293;
3294
3295Procedure Get_PSP_Parms ; ;AC000;
3296
3297 Set_Data_Segment
3298 mov ax,PSP_Segment ;Get segment of PSP ;AN000;
3299 mov ds,ax ; " " " " ;AN000;
3300 ; ;
3301 assume ds:nothing
3302 ;Setup segment of Environment string, get from PSP ; ;
3303
3304 mov ax,ds:PSP_Environ ; ; ;
3305 mov es:Environ_Segment,ax ; ; ;
3306 Set_Data_Segment
3307 ret ; ; ;
3308
3309
3310Get_PSP_Parms endp ; ;AN000;
3311
3312
3313;=========================================================================
3314; Command_Root : This routine sets up CommandFile so that the
3315; COMMAND.COM will be written to the root.
3316; It does this by copying at offset 3 of CommandFile
3317; the literal COMMAND.COM. This effectively
3318; overrides the original path, but maintains the
3319; drive letter that is to be written to.
3320;
3321; Inputs : CommandFile - Holds full path to default COMMAND.COM
3322; Outputs : CommandFile - Holds modified path to new COMMAND.COM
3323; on target drive.
3324;=========================================================================
3325
3326Procedure Command_Root ;an011; dms;
3327
3328 push ds ;an011; dms; save ds
3329 push es ;an011; dms; save es
3330 push di ;an011; dms; save di
3331 push si ;an011; dms; save si
3332 push cx ;an011; dms; save cx
3333 Set_Data_Segment ;an011;
3334
3335 mov di,offset CommandFile+3 ;an011; dms; point to path
3336 ; past drive spec
3337 mov si,offset Command_Com ;an011; dms; holds the literal
3338 ; COMMAND.COM
3339 mov cx,000ch ;an011; dms; len. of literal
3340 rep movsb ;an011; dms; move it
3341
3342 pop cx ;an011; dms; restore cx
3343 pop si ;an011; dms; restore si
3344 pop di ;an011; dms; restore di
3345 pop es ;an011; dms; restore es
3346 pop ds ;an011; dms; restore ds
3347
3348 ret ;an011; dms;
3349
3350Command_Root endp ;an011; dms;
3351
3352
3353;=========================================================================
3354; Set_BPB_Info : When we have a FAT count of 0, we must calculate
3355; certain parts of the BPB. The following code
3356; will do just that.
3357;
3358; Inputs : DeviceParameters
3359;
3360; Outputs : BPB information
3361;=========================================================================
3362
3363Procedure Set_BPB_Info ;an012; dms;calc new BPB
3364
3365 Set_Data_Segment ;an012; dms;set up addressibility
3366 cmp DeviceParameters.DP_BPB.BPB_NumberOfFats,00h ;an012; dms;see if we have 0 FATS specified
3367; $if e ;an012; dms;yes, 0 FATS specified
3368 JNE $$IF101
3369 call Scan_Disk_Table ;an012; dms;access disk table
3370 mov bl,byte ptr ds:[si+8] ;an012; dms;get FAT type
3371 mov cx,word ptr ds:[si+4] ;an012; dms;get sectors/cluster
3372 mov dx,word ptr ds:[si+6] ;an012; dms;number of entries for the root DIR
3373
3374 mov DeviceParameters.DP_BPB.BPB_RootEntries,dx ;an012; dms;save root entries
3375 mov DeviceParameters.DP_BPB.BPB_SectorsPerCluster,ch ;an012; dms;save sectors/cluster
3376 mov DeviceParameters.DP_BPB.BPB_BytesPerSector,0200h ;an012; dms;save bytes/sector
3377 mov DeviceParameters.DP_BPB.BPB_ReservedSectors,0001h ;an012; dms;save reserved sectors
3378 mov DeviceParameters.DP_BPB.BPB_NumberOfFats,02h ;an012; dms;FAT count
3379
3380 cmp bl,FBIG ;an012; dms;Big FAT?
3381; $if e ;an012; dms;yes
3382 JNE $$IF102
3383 call Calc_Big_FAT ;an012; dms;calc big FAT info
3384; $else ;an012; dms;
3385 JMP SHORT $$EN102
3386$$IF102:
3387 call Calc_Small_FAT ;an012; dms;calc small FAT info
3388; $endif ;an012; dms;
3389$$EN102:
3390; $endif ;an012; dms;
3391$$IF101:
3392
3393 ret ;an012; dms;
3394
3395Set_BPB_Info endp ;an012; dms;
3396
3397
3398
3399;=========================================================================
3400; Scan_Disk_Table : Scans the table containing information on
3401; the disk's attributes. When it finds the
3402; applicable data, it returns a pointer in
3403; DS:SI for reference by the calling proc.
3404;
3405; Inputs : DiskTable - Contains data about disk types
3406;
3407; Outputs : DS:SI - Points to applicable disk data
3408;=========================================================================
3409
3410Procedure Scan_Disk_Table ;an012; dms;
3411
3412 cmp DeviceParameters.DP_BPB.BPB_TotalSectors,00h ;an012; dms;small disk?
3413; $if ne ;an012; dms;yes
3414 JE $$IF106
3415 mov dx,00h ;an012; dms;set high to 0
3416 mov ax,word ptr DeviceParameters.DP_BPB.BPB_TotalSectors ;an012; dms;get sector count
3417; $else ;an012; dms;
3418 JMP SHORT $$EN106
3419$$IF106:
3420 mov dx,word ptr DeviceParameters.DP_BPB.BPB_BigTotalSectors[+2] ;an012; dms;get high count
3421 mov ax,word ptr DeviceParameters.DP_BPB.BPB_BigTotalSectors[+0] ;an012; dms;get low count
3422; $endif ;an012; dms;
3423$$EN106:
3424
3425 mov si,offset DiskTable ;an012; dms;point to disk data
3426Scan:
3427
3428 cmp dx,word ptr ds:[si] ;an012; dms;below?
3429 jb Scan_Disk_Table_Exit ;an012; dms;yes, exit
3430 ja Scan_Next ;an012; dms;no, continue
3431 cmp ax,word ptr ds:[si+2] ;an012; dms;below or equal?
3432 jbe Scan_Disk_Table_Exit ;an012; dms;yes, exit
3433
3434Scan_Next:
3435
3436 add si,5*2 ;an012; dms;adjust pointer
3437 jmp Scan ;an012; dms;continue scan
3438
3439Scan_Disk_Table_Exit:
3440
3441 ret ;an012; dms;
3442
3443Scan_Disk_Table endp ;an012; dms;
3444
3445
3446
3447;=========================================================================
3448; Calc_Big_FAT : Calculates the sectors per FAT for a 16 bit FAT.
3449;
3450; Inputs : DeviceParameters.DP_BPB.BPB_BigTotalSectors or
3451; DeviceParameters.DP_BPB.BPB_TotalSectors
3452;
3453; Outputs : DeviceParameters.DP_BPB.BPB_SectorsPerFat
3454;=========================================================================
3455
3456Procedure Calc_Big_FAT ;an012; dms;
3457
3458 cmp DeviceParameters.DP_BPB.BPB_TotalSectors,00h ;an012; dms;small disk?
3459; $if ne ;an012; dms;yes
3460 JE $$IF109
3461 mov dx,00h ;an012; dms;set high to 0
3462 mov ax,word ptr DeviceParameters.DP_BPB.BPB_TotalSectors ;an012; dms;get sector count
3463; $else ;an012; dms;
3464 JMP SHORT $$EN109
3465$$IF109:
3466 mov dx,word ptr DeviceParameters.DP_BPB.BPB_BigTotalSectors[+2] ;an012; dms;get high count
3467 mov ax,word ptr DeviceParameters.DP_BPB.BPB_BigTotalSectors[+0] ;an012; dms;get low count
3468; $endif ;an012; dms;
3469$$EN109:
3470
3471 mov cl,04h ;an012; dms;16 DIR entries per sector
3472 push dx ;an012; dms;save total sectors (high)
3473 mov dx,DeviceParameters.DP_BPB.BPB_RootEntries ;an012; dms;get root entry count
3474 shr dx,cl ;an012; dms;divide by 16
3475 sub ax,dx ;an012; dms;
3476 pop dx ;an012; dms;restore dx
3477 sbb dx,0 ;an012; dms;
3478 sub ax,1 ;an012; dms;AX = T - R - D
3479 sbb dx,0 ;an012; dms;
3480 mov bl,02h ;an012; dms;
3481 mov bh,DeviceParameters.DP_BPB.BPB_SectorsPerCluster ;an012; dms;get sectors per cluster
3482 add ax,bx ;an012; dms;AX = T-R-D+256*SPC+2
3483 adc dx,0 ;an012; dms;
3484 sub ax,1 ;an012; dms;AX = T-R-D+256*SPC+1
3485 sbb dx,0 ;an012; dms;
3486 div bx ;an012; dms; sec/FAT = CEIL((TOTAL-DIR-RES)/
3487 ; (256*SECPERCLUS+2)
3488 mov word ptr DeviceParameters.DP_BPB.BPB_SectorsPerFAT,ax ;an012; dms;Sectors/cluster
3489 ret ;an012; dms;
3490
3491Calc_Big_FAT endp ;an012; dms;
3492
3493
3494;=========================================================================
3495; Calc_Small_FAT: Calculates the sectors per FAT for a 12 bit FAT.
3496;
3497; Inputs : DeviceParameters.DP_BPB.BPB_BigTotalSectors or
3498; DeviceParameters.DP_BPB.BPB_TotalSectors
3499;
3500; Outputs : DeviceParameters.DP_BPB.BPB_SectorsPerFat
3501;=========================================================================
3502
3503Procedure Calc_Small_FAT ;an012; dms;
3504
3505 cmp DeviceParameters.DP_BPB.BPB_TotalSectors,00h ;an012; dms;small disk?
3506; $if ne ;an012; dms;yes
3507 JE $$IF112
3508 mov dx,00h ;an012; dms;set high to 0
3509 mov ax,word ptr DeviceParameters.DP_BPB.BPB_TotalSectors ;an012; dms;get sector count
3510; $else ;an012; dms;
3511 JMP SHORT $$EN112
3512$$IF112:
3513 mov dx,word ptr DeviceParameters.DP_BPB.BPB_BigTotalSectors[+2] ;an012; dms;get high count
3514 mov ax,word ptr DeviceParameters.DP_BPB.BPB_BigTotalSectors[+0] ;an012; dms;get low count
3515; $endif ;an012; dms;
3516$$EN112:
3517
3518 xor bx,bx ;an012; dms;clear bx
3519 mov bl,DeviceParameters.DP_BPB.BPB_SectorsPerCluster ;an012; dms;get sectors/cluster
3520 div bx ;an012; dms;
3521; now multiply by 3/2
3522 mov bx,3 ;an012; dms;
3523 mul bx ;an012; dms;div by log 2 of sectors/cluster
3524 mov bx,2 ;an012; dms;
3525 div bx ;an012; dms;
3526 xor dx,dx ;an012; dms;
3527; now divide by 512
3528 mov bx,512 ;an012; dms;
3529 div bx ;an012; dms;
3530 inc ax ;an012; dms;
3531; dx:ax contains number of FAT sectors necessary
3532 mov DeviceParameters.DP_BPB.BPB_SectorsPerFAT,ax ;an012; dms;save sectors/FAT
3533 ret ;an012; dms;
3534
3535Calc_Small_FAT endp ;an012; dms;
3536
3537;=========================================================================
3538; Get_Bad_Sector_Hard : Determine the bad sector.
3539;
3540; Inputs : Head of failing track
3541; Cylinder of failing track
3542; Relative_Sector_Low - 1st. sector in track
3543; Relative_Sector_High
3544;
3545; Cluster_Boundary_Adj_Factor - The number of sectors
3546; that are to be read
3547; at one time.
3548; Cluster_Boundary_SPT_Count - Used by Calc_Cluster_Boundary
3549; to track how many sectors
3550; have been read.
3551; Cluster_Boundary_Flag - True (Use cluster buffer)
3552; - False (Use internal buffer)
3553; Cluster_Boundary_Buffer_Seg - Segment of buffer
3554;
3555; Outputs : Marked cluster as bad
3556;=========================================================================
3557
3558Procedure Get_Bad_Sector_Hard ;an000; dms;
3559
3560 push cx ;an000; dms;save cx
3561 mov cx,0001h ;an000; dms;set counter to start at 1
3562 mov Cluster_Boundary_SPT_Count,00h ;an000; dms;clear sector counter
3563 mov Cluster_Boundary_Adj_Factor,01h ;an000; dms;default value
3564; $do ;an000; dms;while sectors left
3565$$DO115:
3566 cmp cx,DeviceParameters.DP_BPB.BPB_SectorsPerTrack ;an000; dms;at end?
3567; $leave a ;an000; dms;yes,exit
3568 JA $$EN115
3569 push cx ;an000; dms;save cx
3570
3571 cmp Cluster_Boundary_Flag,True ;an000; dms;full buffer there?
3572; $if e ;an000; dms;yes
3573 JNE $$IF117
3574 call Calc_Cluster_Boundary ;an000; dms;see if on boundary
3575 mov ax,Cluster_Boundary_Buffer_Seg
3576 mov word ptr RWPacket.TRWP_TransferAddress[0],0 ;an000; dms;point to transfer area
3577 mov word ptr RWPacket.TRWP_TransferAddress[2],ax ;an000; dms;
3578; $else ;an000; dms;default to internal buffer
3579 JMP SHORT $$EN117
3580$$IF117:
3581 mov word ptr RWPacket.TRWP_TransferAddress[0],offset RW_TRF_Area ;an000; dms;point to transfer area
3582 mov word ptr RWPacket.TRWP_TransferAddress[2],DS ;an000; dms;
3583; $endif ;an000; dms;
3584$$EN117:
3585
3586 call Verify_Structure_Set_Up ;an019; dms; set up verify vars
3587
3588 mov ax,(IOCTL shl 8) or GENERIC_IOCTL ;an000; dms;
3589 xor bx,bx ;an000; dms;clear bx
3590 mov bl,drive ;an000; dms;get drive
3591 inc bl ;an000; dms;adjust it
3592 mov cx,(IOC_DC shl 8) or READ_TRACK ;an000; dms;read track
3593 lea dx,RWPacket ;an000; dms;point to parms
3594 int 21h ;an000; dms;
3595
3596 pop cx ;an000; dms;restore cx
3597
3598 push cx ;an000; dms;save cx
3599
3600; $if c ;an000; dms;an error occurred
3601 JNC $$IF120
3602 call Calc_Cluster_Position ;an000; dms;determine which cluster
3603 call BadClus ;an000; dms;mark the cluster as bad
3604; $endif ;an000; dms;
3605$$IF120:
3606
3607 pop cx ;an000; dms;restore cx
3608
3609 add cx,Cluster_Boundary_Adj_Factor ;an000; dms;adjust loop counter
3610 mov ax,Cluster_Boundary_Adj_Factor ;an000; dms;get adjustment factor
3611 xor dx,dx ;an000; dms;clear dx
3612 add ax,Relative_Sector_Low ;an000; dms;add in low word
3613 adc dx,Relative_Sector_High ;an000; dms;pick up carry in high word
3614 mov Relative_Sector_Low,ax ;an000; dms;save low word
3615 mov Relative_Sector_High,dx ;an000; dms;save high word
3616
3617
3618; $enddo ;an000; dms;
3619 JMP SHORT $$DO115
3620$$EN115:
3621
3622 pop cx ;an000; dms;restore cx
3623
3624 ret ;an000; dms;
3625
3626Get_Bad_Sector_Hard endp ;an000; dms;
3627
3628
3629;=========================================================================
3630; Verify_Structure_Set_Up : Set up the fields for the Read IOCTL
3631; to verify the sectors in a failing
3632; track. Also, it displays the
3633; message notifying the user of the
3634; sectors it is verifying.
3635;=========================================================================
3636
3637Procedure Verify_Structure_Set_Up ;an019; dms;set up verify structure
3638
3639 mov RWPacket.TRWP_SpecialFunctions,00h ;an000; dms;reset special functions
3640
3641 mov ax,FormatPacket.FP_Head ;an000; dms;get current head
3642 mov RWPacket.TRWP_Head,ax ;an000; dms;get current head
3643
3644 mov ax,FormatPacket.FP_Cylinder ;an000; dms;get current cylinder
3645 mov RWPacket.TRWP_Cylinder,ax ;an000; dms;get current cylinder
3646
3647 dec cx ;an000; dms;make sector 0 based
3648 mov RWPacket.TRWP_FirstSector,cx ;an000; dms;get sector to read
3649
3650 mov ax,Cluster_Boundary_Adj_Factor ;an000; dms;get # of sectors to read
3651 mov RWPacket.TRWP_SectorsToReadWrite,ax ;an000; dms;read only # sector(s)
3652
3653 call Calc_Cluster_Position ;an019; dms;determine cluster number
3654 mov word ptr Msg_Allocation_Unit_Val[+2],dx ;an019; dms;save high word of cluster
3655 mov word ptr Msg_Allocation_Unit_Val[+0],ax ;an019; dms;save low word of cluster
3656 message MsgVerify
3657
3658 ret
3659
3660Verify_Structure_Set_Up endp ;an019; dms;
3661
3662
3663;=========================================================================
3664; Get_Bad_Sector_Floppy : This routine marks an entire track as bad
3665; since it is a floppy disk.
3666;
3667; Inputs : Relative_Sector_Low - first sector
3668;
3669; Outputs : FAT marked with bad sectors
3670;=========================================================================
3671
3672Procedure Get_Bad_Sector_Floppy ;an000; dms;
3673
3674 push bx ;an000; dms;save regs
3675 push cx ;an000; dms;
3676
3677 mov cx,DeviceParameters.DP_BPB.BPB_SectorsPerTrack ;an000; dms;get sectors/track
3678; $do ;an000; dms;while sectors left
3679$$DO123:
3680 cmp cx,00 ;an000; dms;at end
3681; $leave e ;an000; dms;yes
3682 JE $$EN123
3683 push bx ;an000; dms;save bx we destroy it
3684 push cx ;an000; dms;save cx we destroy it
3685 call Calc_Cluster_Position ;an000; dms;get cluster position
3686 call BadClus ;an000; dms;mark it as bad
3687 pop cx ;an000; dms;restore regs
3688 pop bx ;an000; dms;
3689 dec cx ;an000; dms;decrease loop counter
3690 inc Relative_Sector_Low ;an000; dms;next sector
3691; $enddo ;an000; dms;
3692 JMP SHORT $$DO123
3693$$EN123:
3694
3695 pop cx ;an000; dms;restore regs
3696 pop bx ;an000; dms;
3697
3698 ret ;an000; dms;
3699
3700Get_Bad_Sector_Floppy endp ;an000; dms;
3701
3702
3703;=========================================================================
3704; Calc_Cluster_Position : This routine calculates which cluster the
3705; failing sector falls in.
3706;
3707; Inputs : Relative_Sector_High - high word of sector position
3708; Relative_Sector_Low - low word of sector position
3709;
3710; Outputs : DX:AX - Cluster position
3711;=========================================================================
3712Procedure Calc_Cluster_Position ;an000; dms;
3713
3714 push cx ;an000; dms;save regs
3715 push di ;an000; dms;
3716 push si ;an000; dms;
3717
3718 xor dx,dx ;an000; dms;clear high word
3719 mov dx,word ptr Relative_Sector_High ;an000; dms;get the high sector word
3720 mov ax,word ptr Relative_Sector_Low ;an000; dms;get the low sector word
3721 sub ax,StartSector ;an000; dms;get relative sector #
3722 sbb dx,0 ;an000; dms;pick up borrow
3723
3724 mov si,dx ;an000; dms;get high word
3725 mov di,ax ;an000; dms;get low word
3726 xor cx,cx ;an000; dms;clear cx
3727 mov cl,DeviceParameters.DP_BPB.BPB_SectorsPerCluster ;an000; dms;get sectors/cluster
3728 call Divide_32_Bits ;an000; dms;32 bit division
3729
3730 mov dx,si ;an000; dms;get high word of result
3731 mov ax,di ;an000; dms;get low word of result
3732 add ax,2 ;an000; dms;adjust for cluster bias
3733 adc dx,0 ;an000; dms;pick up carry
3734
3735 pop si ;an000; dms;restore regs
3736 pop di ;an000; dms;
3737 pop cx ;an000; dms;
3738
3739 ret ;an000 ;dms;
3740
3741Calc_Cluster_Position endp ;an000; dms;
3742
3743
3744;=========================================================================
3745; Cap_Char : This routine will capitalize the character passed in
3746; DL.
3747;
3748; Inputs : DL - Character to be capitalized
3749;
3750; Outputs : DL - Capitalized character
3751;=========================================================================
3752
3753Procedure Cap_Char ;an011; dms;
3754
3755 push ax ;an011; dms;save ax
3756 mov ax,6520h ;an011; dms;capitalize character
3757 int 21h ;an011; dms;
3758 pop ax ;an011; dms;restore ax
3759 ret ;an011; dms;
3760
3761Cap_Char endp ;an011; dms;
3762
3763;=========================================================================
3764; Set_Disk_Access_On_Off: This routine will either turn access on or off
3765; to a disk depending on the contents of the
3766; buffer passed in DX.
3767;
3768; Inputs : DX - pointer to buffer
3769;
3770;=========================================================================
3771
3772Procedure Set_Disk_Access_On_Off ;an014; dms;
3773
3774 push ax ;an014; dms;save regs
3775 push bx ;an014; dms;
3776 push cx ;an014; dms;
3777 push dx ;an014; dms;
3778
3779 xor bx,bx ;an014; dms;clear bx
3780 mov bl,Drive ;an014; dms;get driver number
3781 inc bl ;an014; dms;make it 1 based
3782 call IsRemovable ;an014; dms;see if removable media
3783; $if c ;an014; dms;not removable
3784 JNC $$IF126
3785 mov ax,(IOCTL shl 8) or Generic_IOCTL ;an014; dms;generic ioctl
3786 xor bx,bx ;an014; dms;clear bx
3787 mov bl,Drive ;an014; dms;get drive letter
3788 inc bl ;an014; dms;make it 1 based
3789 mov cx,(RAWIO shl 8) or Set_Access_Flag ;an014; dms;allow access to disk
3790 int 21h ;an014; dms;
3791; $endif ;an014; dms;
3792$$IF126:
3793
3794 pop dx ;an014; dms;restore regs
3795 pop cx ;an014; dms;
3796 pop bx ;an014; dms;
3797 pop ax ;an014; dms;
3798
3799 ret ;an014; dms;
3800
3801Set_Disk_Access_On_Off endp ;an014; dms;
3802
3803
3804;=========================================================================
3805; Get_Disk_Access : This routine will determine the access state of
3806; the disk.
3807;
3808; Inputs : DX - pointer to buffer
3809; Outputs : Disk_Access.DAC_Access_Flag - 0ffh signals access allowed
3810; to the disk previously.
3811;
3812;=========================================================================
3813
3814Procedure Get_Disk_Access ;an014; dms;
3815
3816 push ax ;an014; dms;save regs
3817 push bx ;an014; dms;
3818 push cx ;an014; dms;
3819 push dx ;an014; dms;
3820
3821 xor bx,bx ;an014; dms;clear bx
3822 mov bl,Drive ;an014; dms;get driver number
3823 inc bl ;an014; dms;make it 1 based
3824 call IsRemovable ;an014; dms;see if removable media
3825; $if c ;an014; dms;not removable
3826 JNC $$IF128
3827 mov ax,(IOCTL shl 8) or Generic_IOCTL ;an014; dms;generic ioctl
3828 xor bx,bx ;an014; dms;clear bx
3829 mov bl,Drive ;an014; dms;get drive letter
3830 inc bl ;an014; dms;make it 1 based
3831 mov cx,(RAWIO shl 8) or Get_Access_Flag ;an014; dms;determine disk access
3832 lea dx,Disk_Access ;an014; dms;point to parm list
3833 int 21h ;an014; dms;
3834 cmp Disk_Access.DAC_Access_Flag,01h ;an014; dms;access is currently allowed?
3835; $if e ;an014; dms;yes
3836 JNE $$IF129
3837 mov Disk_Access.DAC_Access_Flag,0ffh ;an014; dms;signal access is currently allowed
3838; $endif ;an014; dms;
3839$$IF129:
3840; $endif ;an014; dms;
3841$$IF128:
3842
3843 pop dx ;an014; dms;restore regs
3844 pop cx ;an014; dms;
3845 pop bx ;an014; dms;
3846 pop ax ;an014; dms;
3847
3848 ret ;an014; dms;
3849
3850Get_Disk_Access endp ;an014; dms;
3851
3852;=========================================================================
3853; Calc_Cluster_Boundary : This routine will determine where, within a
3854; cluster, a sector resides.
3855;
3856; Inputs : Relative_Sector_Low - Sector
3857; Relative_Sector_High
3858;
3859; Outputs : Cluster_Boundary_Adj_Factor - The number of sectors
3860; remaining in the cluster.
3861; Cluster_Boundary_SPT_Count - The count of sectors
3862; having been accessed for
3863; a track.
3864;=========================================================================
3865
3866Procedure Calc_Cluster_Boundary ;an000; dms;
3867
3868 push ax ;an000; dms;save regs
3869 push bx ;an000; dms;
3870 push cx ;an000; dms;
3871 push dx ;an000; dms;
3872 push si ;an000; dms;
3873 push di ;an000; dms;
3874
3875 xor dx,dx ;an000; dms;clear high word
3876 mov dx,word ptr Relative_Sector_High ;an000; dms;get the high sector word
3877 mov ax,word ptr Relative_Sector_Low ;an000; dms;get the low sector word
3878 sub ax,StartSector ;an000; dms;get relative sector #
3879 sbb dx,0 ;an000; dms;pick up borrow
3880
3881 mov si,dx ;an000; dms;get high word
3882 mov di,ax ;an000; dms;get low word
3883 xor cx,cx ;an000; dms;clear cx
3884 mov cl,DeviceParameters.DP_BPB.BPB_SectorsPerCluster ;an000; dms;get sectors/cluster
3885 call Divide_32_Bits ;an000; dms;32 bit division
3886
3887 or cx,cx ;an000; dms;see if remainder exists
3888; $if nz ;an000; dms;remainder exists
3889 JZ $$IF132
3890 xor bx,bx ;an021; dms;
3891 mov bl,DeviceParameters.DP_BPB.BPB_SectorsPerCluster ;an021; dms;get sectors/cluster
3892 sub bx,cx ;an021; dms;get number of sectors to read
3893 mov Cluster_Boundary_Adj_Factor,bx ;ac021; dms;remainder = sector count
3894; $else ;an000; dms;no remainder
3895 JMP SHORT $$EN132
3896$$IF132:
3897 xor bx,bx ;an000; dms;clear bx
3898 mov bl,DeviceParameters.DP_BPB.BPB_SectorsPerCluster ;an000; dms;get sectors/cluster
3899 mov Cluster_Boundary_Adj_Factor,bx ;an000; dms;get sectors/cluster
3900; $endif ;an000; dms;
3901$$EN132:
3902
3903 mov ax,Cluster_Boundary_SPT_Count ;an000; dms;get current sector count
3904 xor dx,dx ;an000; dms;clear high word
3905 add ax,Cluster_Boundary_Adj_Factor ;an000; dms;get next sector count
3906 cmp ax,DeviceParameters.DP_BPB.BPB_SectorsPerTrack ;an000; dms;exceeded sectors/track?
3907; $if a ;an000; dms;yes
3908 JNA $$IF135
3909 mov ax,DeviceParameters.DP_BPB.BPB_SectorsPerTrack ;an000; dms;only use difference
3910 sub ax,Cluster_Boundary_SPT_Count ;an000; dms;get next sector count
3911 mov Cluster_Boundary_Adj_Factor,ax ;an000; dms;
3912; $endif ;an000; dms;
3913$$IF135:
3914
3915 mov ax,Cluster_Boundary_SPT_Count ;an000; dms;get sector count
3916 xor dx,dx ;an000; dms;clear high word
3917 add ax,Cluster_Boundary_Adj_Factor ;an000; dms;get new sector count
3918 mov Cluster_Boundary_SPT_Count,ax ;an000; dms;save it
3919
3920 pop di ;an000; dms;restore regs
3921 pop si ;an000; dms;
3922 pop dx ;an000; dms;restore regs
3923 pop cx ;an000; dms;
3924 pop bx ;an000; dms;
3925 pop ax ;an000; dms;
3926
3927 ret ;an000; dms;
3928
3929Calc_Cluster_Boundary endp ;an000; dms;
3930
3931;=========================================================================
3932; Cluster_Buffer_Allocate : This routine will allocate a buffer
3933; based on a cluster's size. If enough
3934; space does not exist, a cluster will
3935; be redefined to a smaller size for
3936; purposes of sector retries.
3937;
3938; Inputs : DeviceParameters.DP_BPB.BPB_BytesPerSector
3939; DeviceParameters.DP_BPB.BPB_SectorsPerCluster
3940;
3941; Outputs : Cluster_Boundary_Flag - True (space available)
3942; False(not enough space)
3943; Cluster_Boundary_Buffer_Seg - Pointer to buffer
3944;=========================================================================
3945
3946Procedure Cluster_Buffer_Allocate ;an000; dms;
3947
3948 push ax ;an000; dms;save regs
3949 push bx ;an000; dms;
3950 push cx ;an000; dms;
3951 push dx ;an000; dms;
3952
3953 mov ax,(Alloc shl 8) ;an000; dms;allocate memory
3954 mov bx,0ffffh ;an000; dms;get available memory
3955 int 21h ;an000; dms;
3956
3957 mov ax,DeviceParameters.DP_BPB.BPB_BytesPerSector ;an000; dms;get bytes/sector
3958 xor dx,dx ;an000; dms;clear high word
3959 xor cx,cx ;an000; dms;clear cx
3960 mov cl,DeviceParameters.DP_BPB.BPB_SectorsPerCluster ;an000; dms;get sector count
3961 mul cx ;an000; dms;get total byte count
3962 mov cl,4 ;an000; dms;set up shift count
3963 shr ax,cl ;an000; dms;divide by 16
3964 inc ax ;an000; dms;round up
3965
3966 cmp bx,ax ;an000; dms;enough room
3967; $if a ;an000; dms;yes
3968 JNA $$IF137
3969 mov bx,ax ;an000; dms;allocate needed memory
3970 mov ax,(Alloc shl 8) ;an000; dms;
3971 int 21h ;an000; dms;
3972 mov Cluster_Boundary_Buffer_Seg,ax ;an000; dms;save pointer to buffer
3973 mov Cluster_Boundary_Flag,True ;an000; dms;signal space available
3974; $else ;an000; dms;not enough room
3975 JMP SHORT $$EN137
3976$$IF137:
3977 mov Cluster_Boundary_Flag,False ;an000; dms;signal not enough space
3978; $endif ;an000; dms;
3979$$EN137:
3980
3981 pop dx ;an000; dms;restore regs
3982 pop cx ;an000; dms;
3983 pop bx ;an000; dms;
3984 pop ax ;an000; dms;
3985
3986 ret ;an000; dms;
3987
3988Cluster_Buffer_Allocate endp ;an000; dms;
3989
3990
3991;=========================================================================
3992; Set_CDS_Off - This routine disallows access to a
3993; disk if a format fails on a non-FAT
3994; formatted disk.
3995;
3996;=========================================================================
3997
3998Procedure Set_CDS_Off ;an000; dms;
3999
4000 push ax ;an000; dms;save regs
4001 push dx ;an000; dms;
4002
4003 mov ax,5f08h ;an000; dms;reset CDS
4004 mov dl,Drive ;an000; dms;drive to reset
4005 int 21h ;an000; dms;
4006
4007 pop dx ;an000; dms;restore regs
4008 pop ax ;an000; dms;
4009
4010 ret ;an000; dms;
4011
4012Set_CDS_Off endp ;an000; dms;
4013
4014
4015;=========================================================================
4016; Format_Access_Wrap_Up - This routine determines whether or
4017; not access should be allowed to the
4018; disk based on the exit status of
4019; format.
4020;
4021;=========================================================================
4022
4023Procedure Format_Access_Wrap_Up ;an000; dms;
4024
4025 cmp Disk_Access.DAC_Access_Flag,0ffh ;an015; dms;access prev. allowed?
4026; $if ne ;an015; dms;no
4027 JE $$IF140
4028 cmp ExitStatus,ExitOK ;an015; dms;good exit?
4029; $if ne ;an015; dms;no
4030 JE $$IF141
4031 lea dx,Disk_Access ;an015; dms;point to parm block
4032 mov Disk_Access.DAC_Access_Flag,00h ;an015; dms;signal no disk access
4033 call Set_Disk_Access_On_Off ;an015; dms;don't allow disk access
4034; $else ;an015; dms;bad exit
4035 JMP SHORT $$EN141
4036$$IF141:
4037 lea dx,Disk_Access ;an015; dms;point to parm block
4038 mov Disk_Access.DAC_Access_Flag,01h ;an015; dms;signal disk access
4039 call Set_Disk_Access_On_Off ;an015; dms;allow disk access
4040; $endif ;an015; dms;
4041$$EN141:
4042; $endif ;an015; dms;
4043$$IF140:
4044
4045 cmp FAT_Flag,No ;an012; dms;non-FAT format?
4046; $if e ;an012; dms;yes
4047 JNE $$IF145
4048 cmp ExitStatus,ExitOK ;an012; dms;good exit?
4049; $if ne ;an012; dms;no
4050 JE $$IF146
4051 call Set_CDS_Off ;an012; dms;disallow FAT access
4052; $endif ;an012; dms;
4053$$IF146:
4054; $endif ;an012; dms;
4055$$IF145:
4056
4057 ret ;an000; dms;
4058
4059Format_Access_Wrap_Up endp ;an000; dms;
4060
4061;=========================================================================
4062; BadClus_Address_Adjust - This routine adjusts the segment and
4063; offset to provide addressibility into
4064; the FAT table.
4065;
4066; Inputs : bx - high word to adjust segment for
4067; ax - low word to adjust segment for
4068; cx - segment to be adjusted
4069;
4070; Outputs : cx - new segment value
4071; ax - new offset value
4072;=========================================================================
4073
4074Procedure BadClus_Address_Adjust ;an000; dms;
4075
4076 push bx ;an000; save regs
4077 push dx ;an000;
4078 push di ;an000;
4079 push si ;an000;
4080
4081 mov dx,cx ;an000; save segment value
4082 mov si,bx ;an000; get high word for divide
4083 mov di,ax ;an000; get low word for divide
4084 xor cx,cx ;an000; clear cx
4085 mov cl,Paragraph_Size ;an000; divide by 16
4086 call Divide_32_Bits ;an000; perform division
4087
4088 add dx,di ;an000; adjust segment for result
4089 mov ax,cx ;an000; pick up the remainder
4090 mov cx,dx ;an000; pass back new segment
4091
4092 pop si ;an000; restore regs
4093 pop di ;an000;
4094 pop dx ;an000;
4095 pop bx ;an000;
4096
4097 ret ;an000; dms;
4098
4099BadClus_Address_Adjust endp ;an000; dms;
4100
4101
4102
4103;=========================================================================
4104; NextTrack : This routine determines the next track to be
4105; formatted.
4106;
4107; Inputs : TracksLeft - # of tracks remaining
4108; Tracks_To_Format - # of tracks to format in 1 call
4109; FP_Head - disk head
4110; FP_Cylinder - disk cylinder
4111;
4112; Outputs : TracksLeft - # of tracks remaining
4113; FP_Head - disk head
4114; FP_Cylinder - disk cylinder
4115; CY - no tracks left to format
4116; NC - tracks left to format
4117;=========================================================================
4118
4119Procedure NextTrack ;an015; dms;
4120
4121
4122 cmp TracksLeft,00 ;an015; dms;end of format?
4123; $if e ;an015; dms;yes
4124 JNE $$IF149
4125 stc ;an015; dms;signal end of format
4126 mov Format_End,True
4127; $else
4128 JMP SHORT $$EN149
4129$$IF149:
4130 mov cx,Tracks_To_Format ;an015; dms;get max track count for call
4131; $do ;an015; dms;while tracks remain
4132$$DO151:
4133 cmp TracksLeft,00 ;an015; dms;end of format?
4134; $leave e ;an015; dms;yes
4135 JE $$EN151
4136 cmp cx,00 ;an015; dms;end of head/cyl. adjustment?
4137; $leave e ;an015; dms;yes
4138 JE $$EN151
4139 inc FormatPacket.FP_Head ;an015; dms;next head
4140 mov ax,FormatPacket.FP_Head ;an015; dms;get head for comp
4141 cmp ax,DeviceParameters.DP_BPB.BPB_Heads ;an015; dms;exceeded head count?
4142; $if e ;an015; dms;yes
4143 JNE $$IF154
4144 mov FormatPacket.FP_Head,00 ;an015; dms;reinit. head
4145 inc FormatPacket.FP_Cylinder ;an015; dms;next cylinder
4146; $endif ;an015; dms;
4147$$IF154:
4148
4149 dec cx ;an015; dms;decrease counter
4150; $enddo ;an015; dms;
4151 JMP SHORT $$DO151
4152$$EN151:
4153
4154 clc ;an015; dms;clear CY
4155; $endif ;an015; dms;
4156$$EN149:
4157
4158 ret ;an015; dms;
4159
4160NextTrack endp ;an015; dms;
4161
4162;=========================================================================
4163; Determine_Format_Type : This routine determines the type of format
4164; that is to occur based on the media type.
4165;
4166; Inputs : Dev_HardDisk - Media type (harddisk)
4167; Multi_Track_Format - EQU 02h
4168; Single_Track_Format - EQU 00h
4169;
4170; Outputs : FP_SpecialFunctions - Set appropriately for single
4171; or multi track format
4172;=========================================================================
4173
4174Procedure Determine_Format_Type ;an015; dms;
4175
4176 cmp DeviceParameters.DP_DeviceType,Dev_HardDisk ;an015; dms;harddisk?
4177; $if e ;an015; dms;yes
4178 JNE $$IF158
4179 mov FormatPacket.FP_SpecialFunctions,Multi_Track_Format ;an015; dms;set for multi track format
4180; $else ;an015; dms;
4181 JMP SHORT $$EN158
4182$$IF158:
4183 mov FormatPacket.FP_SpecialFunctions,Single_Track_Format ;an015; dms;set for single track format
4184; $endif ;an015; dms;
4185$$EN158:
4186 ret ;an015; dms;
4187
4188Determine_Format_Type endp ;an015; dms;
4189
4190
4191;=========================================================================
4192; FormatTrack : This routine performs multi track or single
4193; track formatting based on the state of the
4194; SpecialFunctions byte.
4195;
4196; Inputs : Tracks_To_Format - # of tracks to format in 1 call
4197; FormatPacket - Parms for IOCTL call
4198;
4199; Outputs : NC - formatted track(s)
4200; CY - error in format
4201; AX - extended error on CY
4202;=========================================================================
4203
4204Procedure FormatTrack ;an015; dms;
4205
4206 mov ax,(IOCTL shl 8) or Generic_IOCTL ;an015; dms;Generic IOCTL
4207 mov bl,drive ;an015; dms;get drive number
4208 inc bl ;an015; dms;make it 1 based
4209 mov cx,(RawIO shl 8) or Format_Track ;an015; dms;Format track(s)
4210 mov dx,Tracks_To_Format ;an015; dms;get track count
4211 mov FormatPacket.FP_TrackCount,dx ;an015; dms;put count in parms list
4212 lea dx,FormatPacket ;an015; dms;ptr to parms
4213 int 21h ;an015; dms;
4214
4215; $if c ;an015; dms;error?
4216 JNC $$IF161
4217 mov ah,59h ;an015; dms;get extended error
4218 xor bx,bx ;an015; dms;clear bx
4219 int 21h ;an015; dms;
4220 stc ;an015; dms;flag an error
4221; $endif ;an015; dms;
4222$$IF161:
4223
4224 ret ;an015; dms;
4225
4226FormatTrack endp ;an015; dms;
4227
4228
4229;=========================================================================
4230; Determine_Track_Count : This routine determines the number of
4231; tracks to be formatted, based on whether
4232; or not we have a hard disk. If we have
4233; a hard disk we can use multi-track
4234; format/verify, otherwise we use the
4235; single track format/verify.
4236;
4237; Inputs : Device_Type - Media type
4238;
4239; Outputs : Tracks_To_Format - Max. number of tracks
4240; to be formatted in one
4241; call
4242;=========================================================================
4243
4244Procedure Determine_Track_Count ;an015; dms;
4245
4246 cmp DeviceParameters.DP_DeviceType,Dev_HardDisk ;an015; dms;harddisk?
4247; $if e ;an015; dms;yes
4248 JNE $$IF163
4249 call Calc_Track_Count ;an015; dms;calc Tracks_To_Format
4250; $else ;an015; dms;removable media
4251 JMP SHORT $$EN163
4252$$IF163:
4253 mov Tracks_To_Format,0001h ;an015; dms;default to 1 track
4254; $endif ;an015; dms;
4255$$EN163:
4256
4257 ret ;an015; dms;
4258
4259Determine_Track_Count endp ;an015;dms;
4260
4261
4262;=========================================================================
4263; Calc_Track_Count : This routine determines if we have enough tracks
4264; remaining to use the max. number of tracks
4265; in the FormatTrack call. If the tracks remaining
4266; to be formatted is less that the max. number of
4267; allowable tracks for the call, the max. number
4268; of allowable tracks is set to the remaining track
4269; count.
4270;
4271; Inputs : Track_Count - Max. number of allowable tracks to be
4272; formatted in 1 FormatTrack call.
4273; TracksLeft - Track count of remaining tracks to be
4274; formatted.
4275;
4276; Outputs : Tracks_To_Format - Count of the tracks to be formatted
4277; in the next FormatTrack call.
4278;
4279;
4280;=========================================================================
4281
4282Procedure Calc_Track_Count ;an015; dms;
4283
4284 push ax ;an015; dms;save regs
4285 mov ax,Track_Count ;an015; dms;max bytes to format
4286 cmp ax,TracksLeft ;an015; dms;too many tracks?
4287; $if a ;an015; dms;yes
4288 JNA $$IF166
4289 mov ax,TracksLeft ;an015; dms;format remaining tracks
4290; $endif ;an015; dms;
4291$$IF166:
4292 mov Tracks_To_Format,ax ;an015; dms;save track count
4293
4294 pop ax ;an015; dms;
4295
4296 ret ;an015; dms;
4297
4298Calc_Track_Count endp ;an015; dms;
4299
4300;=========================================================================
4301; Calc_Max_Tracks_To_Format : This routine determines the maximum
4302; number of tracks to format at 1 time.
4303;
4304; Inputs : DeviceParameters - SectorsPerTrack
4305; BytesPerSector
4306;
4307; Outputs : Track_Count - Max. # of tracks to format in 1 call
4308; to FormatTrack
4309;=========================================================================
4310
4311Procedure Calc_Max_Tracks_To_Format
4312
4313 push ax ;an015; dms;save regs
4314 push bx ;an015; dms;
4315 push dx ;an015; dms;
4316
4317 mov ax,DeviceParameters.DP_BPB.BPB_SectorsPerTrack ;an015; dms;get sectors per track
4318 mov bx,DeviceParameters.DP_BPB.BPB_BytesPerSector ;an015; dms;get byte count
4319 xor dx,dx ;an015; dms;clear dx
4320 mul bx ;an015; dms;get total byte count
4321 mov bx,ax ;an015; dms;put count in bx
4322 mov ax,Max_Format_Size ;an015; dms;max bytes to format
4323 div bx ;an015; dms;get track count
4324 mov Track_Count,ax
4325
4326 pop dx ;an015; dms;
4327 pop bx ;an015; dms;
4328 pop ax ;an015; dms;
4329
4330 ret
4331
4332Calc_Max_Tracks_To_Format endp
4333
4334
4335
4336
4337
4338;=========================================================================
4339; Format_Track_Retry : This routine performs the retry logic for
4340; the format multi-track. It will retry each track
4341; until the failing track is encountered through
4342; a CY condition.
4343;
4344; Inputs : none
4345;
4346; Outputs : CY - indicates either a failing track or end of format
4347;
4348;
4349;=========================================================================
4350
4351Procedure Format_Track_Retry
4352
4353 clc ;an022; dms; clear existing CY
4354 mov Tracks_To_Format,1 ;an015; dms; only format 1 track
4355; $do ;an015; dms; while we have good tracks
4356$$DO168:
4357; $leave c ;an015; dms; exit on bad track
4358 JC $$EN168
4359 call FormatTrack ;an015; dms; format the track
4360; $if nc ;an015; dms;error?
4361 JC $$IF170
4362 call DisplayCurrentTrack ;an022; dms;adjust percent counter
4363 call Adj_Track_Count
4364 call NextTrack ;an015; dms;calc next track
4365; $endif ;an015; dms;
4366$$IF170:
4367; $enddo ;an015; dms;
4368 JMP SHORT $$DO168
4369$$EN168:
4370
4371 ret ;an015; dms;
4372
4373Format_Track_Retry endp ;an015; dms;
4374
4375;=========================================================================
4376; Format_Loop : This routine provides the main template
4377; for the formatting of a disk. A disk
4378; will be formatted as long as there are
4379; tracks remaining to be formatted.
4380; This routine can be exited on a carry
4381; condition; i.e., bad track, last track, etc.
4382;
4383; Inputs : none
4384;
4385; Outputs : CY - Set on exit from this routine
4386; AX - Possible error condition code
4387;=========================================================================
4388
4389Procedure Format_Loop ;an015; dms;
4390
4391 clc ;an015; dms;initialize to NC
4392; $do ;an015; dms;while NC
4393$$DO173:
4394; $leave c ;an015; dms;exit on CY
4395 JC $$EN173
4396 call Calc_Current_Head_Cyl ;an015; dms;head and cylinder calc.
4397 call Determine_Format_Type ;an015; dms;floppy/hard media?
4398 call Determine_Track_Count ;an015; dms;how many tracks?
4399 call FormatTrack ;an015; dms;format track(s)
4400; $if c ;an015; dms;formattrack failed
4401 JNC $$IF175
4402 pushf ;an015; dms;save flags
4403 cmp DeviceParameters.DP_DeviceType,Dev_HardDisk ;an015; dms;harddisk?
4404; $if e ;an015; dms;yes
4405 JNE $$IF176
4406 popf ;an015; dms;restore flags
4407 call Format_Track_Retry ;an015; dms;find failing track
4408; $else ;an015; dms;
4409 JMP SHORT $$EN176
4410$$IF176:
4411 popf ;an015; dms;restore flags
4412; $endif ;an015; dms;
4413$$EN176:
4414; $endif ;an015; dms;
4415$$IF175:
4416
4417; $if c ;an015; dms;format error?
4418 JNC $$IF180
4419 pushf ;an015; dms;yes - save flags
4420 push ax ;an015; dms;save return code
4421 call CheckRealErrors ;an015; dms;check error type
4422; $if nc ;an015; dms;if non-fatal
4423 JC $$IF181
4424 call DisplayCurrentTrack ;an015; dms;display % formatted
4425; $endif ;an015; dms;
4426$$IF181:
4427 pop ax ;an015; dms;restore regs
4428 popf ;an015; dms;
4429; $endif ;an015; dms;
4430$$IF180:
4431
4432; $leave c ;an015; dms;exit on CY
4433 JC $$EN173
4434
4435 call DisplayCurrentTrack ;an015; dms;tell how much formatted
4436 call Adj_Track_Count ;an015; dms;decrease track counter
4437 call NextTrack ;an015; dms;adjust head and cylinder
4438; $enddo ;an015; dms;
4439 JMP SHORT $$DO173
4440$$EN173:
4441 ret ;an015; dms;
4442
4443Format_Loop endp ;an015; dms;
4444
4445;=========================================================================
4446; Adj_Track_Count : This routine adjusts the track count by the
4447; number of tracks that have been formatted
4448; in one FormatTrack call.
4449;
4450; Inputs : TracksLeft - # of tracks remaining to be formatted
4451; Tracks_To_Format - Tracks formatted in 1 call
4452;
4453; Outputs : TracksLeft - # of tracks remaining to be formatted
4454;=========================================================================
4455
4456Procedure Adj_Track_Count ;an015; dms;
4457
4458 push ax ;an015; dms; save regs
4459 mov ax,TracksLeft ;an015; dms; get tracks remaining
4460 sub ax,Tracks_To_Format ;an015; dms; subtract amount formatted
4461 mov TracksLeft,ax ;an015; dms; save new tracks remaining value
4462 pop ax ;an015; dms; restore regs
4463 ret ;an015; dms;
4464
4465Adj_Track_Count endp ;an015; dms;
4466
4467;=========================================================================
4468; Prompt_User_For_Disk : This routine prompts the user for the
4469; disk to be formatted. An appropriate
4470; message is chosen based on the type
4471; of switch entered. If the /SELECT
4472; switch is entered, the disk prompt is
4473; issued through the INT 2fh services
4474; provided by SELECT.
4475;
4476; Inputs : Switchmap - Switches chosen for format
4477;
4478; Outputs : Message printed as appropriate.
4479;=========================================================================
4480
4481Procedure Prompt_User_For_Disk ;an016;dms;
4482
4483 push ax ;an016;dms;save ax
4484 test switchmap, (SWITCH_Backup or SWITCH_Select or SWITCH_AUTOTEST) ;Suppress prompt? ;AC000;
4485; $IF Z ; ;AC000;
4486 JNZ $$IF186
4487 call DSKPRM ; prompt user for disk
4488; $ENDIF ; ;AC000;
4489$$IF186:
4490
4491 test switchmap, (Switch_Select) ;an016;dms;/SELECT requested?
4492; $if nz ;an016;dms;yes
4493 JZ $$IF188
4494 mov al, drive ;an016;dms;get drive to access for format
4495 call AccessDisk ;an016;dms;access the disk
4496 mov ax,Select_Disk_Message ;an016;dms;display disk prompt
4497 int 2fh ;an016;dms; through INT 2fh services
4498; $endif ;an016;dms;
4499$$IF188:
4500 pop ax ;an016;dms;restore ax
4501
4502 ret ;an016;dms;
4503
4504Prompt_User_For_Disk endp ;an016;dms;
4505
4506
4507code ends
4508 END START
4509 \ 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 @@
1DISPLAY.OBJ+
2FORINIT.OBJ+
3FORLABEL.OBJ+
4FORMAT.OBJ+
5FORPROC.OBJ+
6MSFOR.OBJ+
7FOREXEC.OBJ
8FORMAT.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 @@
1
2:util FORMAT
3
4:class 1
5:use EXTEND2 ;File not found
6:use EXTEND4 ;Too many open files
7:use EXTEND5 ;Access denied
8:use EXTEND8 ;Insufficient memory
9:use EXTEND15 ;Invalid drive was specified
10:use EXTEND26 ;Unknown media type
11
12:class A
13;msgBadDosVersion
14;"Incorrect DOS version",CR,LF,"$"
15:use COMMON1
16
17;msgCurrentTrack
18;"Head: %3d Cylinder: %4d", CR, 0
19;:def 2 "Head: %1 Cylinder: %2",CR
20:def 2 CR,"%1 percent of disk formatted ",CR
21
22;msgDataSpace
23;"%l10d bytes available on disk",CR,LF,0
24:use COMMON3
25
26;msgFormatComplete
27;"Format complete ",CR,LF,0
28:def 4 CR,"Format complete ",CR,LF
29
30;msgBadSpace
31;"%l10d bytes in bad sectors", CR, LF, 0
32:use COMMON5
33
34;msgTotalDiskSpace
35;"%l10d bytes total disk space", CR, LF, 0
36:use COMMON6
37
38;msgInsertDisk
39;"Insert new diskette for drive %c:",CR,LF
40:def 7 "Insert new diskette for drive %1:",CR,LF
41
42;msgSystemSpace
43;"%l10d bytes used by system", CR, LF, 0
44:use COMMON8
45
46;msgReInsertDisk
47;"Re-insert diskette for drive %c:",0
48:def 9 "Re-insert diskette for drive %1:",CR,LF
49
50;msgLabelPrompt
51;"Volume label (11 characters, ENTER for none)? ",0
52:use 10 COMMON35
53
54;msgFormatNotSupported
55;"Format not supported on drive %c:", CR,LF,0
56:def 11 CR,"Format not supported on drive %1:", CR,LF
57
58;msgInvalidDeviceParameters
59;"Invalid device parameters from device driver",CR,LF,0
60:def 12 CR,"Invalid device parameters from device driver",CR,LF
61
62;msgErrorInIOCTL
63;"Error in IOCTL call", CR, LF, 0
64:def 13 CR,"Error in IOCTL call ",CR,LF
65
66;msgNotBlockDevice
67;"Not a block device", CR, LF
68:def 14 CR,"Not a block device ",CR,LF
69
70;msgFATwriteError
71;"Error writing FAT", CR, LF, 0
72:def 15 CR,"Error writing FAT ",CR,LF
73
74;msgDirectoryWriteError
75;"Error writing directory ", CR, LF, 0
76:def 16 CR,"Error writing directory",CR,LF
77
78;msgAssignedDrive
79;"Cannot format an ASSIGNed, SUBSTed, or JOINed drive. ", CR, LF, 0
80:def 17 CR,"Cannot format an ASSIGNed, SUBSTed, or JOINed drive. ",CR,LF
81
82
83;msgNoSystemFiles
84;"Cannot find System Files",CR,LF,0
85:def 18 CR,"Cannot find System Files",CR,LF
86
87
88;msgNetDrive
89;"Cannot FORMAT a Network drive", CR, LF, 0
90:def 19 CR,"Cannot FORMAT a Network drive",CR,LF
91
92;msgBadCharacters
93;"Invalid characters in volume label ", CR, LF, 0
94:use 20 COMMON21
95
96
97:CLASS B
98
99;msgParametersNotSupported
100;"Parameters not supported",CR,LF,0
101:def 21 CR,"Parameters not supported",CR,LF
102
103;msgFormatFailure
104; Note: This message must be long enough to wipe out message msgCurrentTrack
105;"Format terminated ",CR,LF,0
106:def 22 CR,"Format terminated ",CR,LF
107
108;msgNotSystemDisk
109;"Disk unsuitable for system disk", CR, LF, 0
110:def 23 CR,"Disk unsuitable for system disk",CR,LF
111
112;msgDiskUnusable
113;"Invalid media or Track 0 bad - disk unusable", CR, LF, 0
114:def 24 CR,"Invalid media or Track 0 bad - disk unusable",CR,LF
115
116;msgBootWriteError
117;"Unable to write BOOT", CR, LF, 0
118:def 25 CR,"Unable to write BOOT ",CR,LF
119
120;msgDirectoryReadError
121;"Error reading directory", CR, LF, 0
122:def 26 CR,"Error reading directory",CR,LF
123
124;msgNeedDrive
125;"No target drive specified",CR,LF,0
126:use COMMON27
127
128;ContinueMsg
129;Press any key to continue
130:def 28 CR,"and press ENTER when ready..."
131
132;msgBadVolumeId
133;"Invalid Volume ID", CR, LF, 0
134:def 29 CR,"Invalid Volume ID ",CR,LF
135
136;msgSystemTransfered
137;"System transferred",CR,LF,0
138:use COMMON30
139
140;msgWhatIsVolumeId?
141;"Enter current Volume Label for drive %c: ", 0
142:def 31 CR,"Enter current Volume Label for drive %1: "
143
144
145;msgIncompatibleParametersForHardDisk
146;" with fixed disk", CR,LF,0
147:def 32 CR,"Parameters not compatible",CR,LF,"with fixed disk",CR,LF
148
149;msgPartitionTableReadError
150;"Error reading partition table", CR, LF, 0
151:def 35 CR,"Error reading partition table",CR,LF
152
153;msgSerialNumber
154:use COMMON36
155
156;msgFormatBroken
157;"Format Broken", CR, LF, 0
158:def 37 CR,"Format Broken",CR,LF
159
160;msgEXECFailure
161:def 38 CR,"Format not available on drive %1",CR,LF
162
163;NO_SYS_MESS:
164; THIS IS A SPECIAL MESSAGE WHICH IS INCLUDED IN THE "FAKE" IBMBIO.COM
165; FILE PLACED ON DISKS FORMATTED /B or /R. NOTE THAT IT IS NUL TERMINATED.
166;"Non-System disk or disk error",13,10,0
167:def 39 CR,"Non-System disk or disk error",CR,LF
168
169;msgbadpartitiontable
170;"Bad Partition Table", CR, LF, 0
171:def 40 CR,"Bad Partition Table ",CR,LF
172
173:CLASS C
174
175;msgParametersNotSupportedByDrive
176;"Parameters not Supported by Drive",CR, LF, 0
177:def 41 CR,"Parameters not Supported by Drive",CR,LF
178
179;msgCRLF
180:def 42 CR,LF
181
182;msgInterrupt
183:def 43 CR,LF,LF
184
185;msgInsertDosDisk db "Insert DOS disk in drive %c:", CR, LF
186:def 44 CR,"Insert DOS disk in drive %1:",CR,LF
187
188
189;msgHardDiskWarning db CR,LF
190; db "WARNING, ALL DATA ON NON-REMOVABLE DISK",CR,LF
191; db "DRIVE %c: WILL BE LOST!",CR,LF
192; db "Proceed with Format (Y/N)?",0
193:def 45 CR,LF,"WARNING, ALL DATA ON NON-REMOVABLE DISK",CR,LF
194"DRIVE %1: WILL BE LOST!",CR,LF
195"Proceed with Format (Y/N)?"
196
197;msgFormatAnother? db "Format another (Y/N)?",0
198:def 46 CR,"Format another (Y/N)?"
199
200;msgPartitionTableReadError db "Error reading partition table", CR, LF, 0
201:def 47 CR,"Error reading partition table",CR,LF
202
203;msgPartitionTableWriteError db "Error writing partition table", CR, LF, 0
204:def 48 CR,"Error writing partition table",CR,LF
205
206;msgIncompatibleParametere forproc.sal not compatible", CR,LF
207;"Parameters not compatible", CR,LF,0
208:def 49 CR,"Parameters not compatible", CR,LF
209
210;msgNumAlloc
211:def 50 "%1 allocation units available on disk",CR,LF
212
213;msgAllocSize
214:def 51 "%1 bytes in each allocation unit",CR,LF
215
216;msgPartitionTableWriteError
217; "Error writing partition table", CR, LF, 0
218:def 52 CR, "Error writing partition table",CR,LF
219
220;msgSameSwitch
221:def 53 CR,"Same parameter entered twice",CR,LF
222
223;msgBad_T_N
224:def 54 CR,"Must enter both /T and /N parameters",CR,LF ;AN009;
225
226;MsgVerify
227:def 55 CR,"Attempting to recover allocation unit %1 ",CR
228:end
229
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 @@
1;
2
3;
4;*****************************************************************************
5; Macro's
6;*****************************************************************************
7;
8
9
10Define_Msg macro Message_Name ; ;AN000;
11 ;
12Create_Msg Message_Name,Message_Number,Handle,Sublist,Count,Class,Function,Input;AN000;
13 ;
14 endm ; ;AN000;
15
16;-----------------------------------------------------------------------------
17
18Create_Msg macro Parm1,Parm2,Parm3,Parm4,Parm5,Parm6,Parm7,Parm8; ;AN000;
19
20Public Parm1
21Parm1 label word ; ;AN000;
22 dw Parm2 ; ;AN000;
23 dw Parm3 ; ;AN000;
24 dw Parm4 ; ;AN000;
25 dw Parm5 ; ;AN000;
26 db Parm6 ; ;AN000;
27 db Parm7 ; ;AN000;
28 dw Parm8 ; ;AN000;
29 endm ; ;AN000;
30
31
32;
33;*****************************************************************************
34; External data declarations
35;*****************************************************************************
36;
37
38 Extrn DriveLetter:Byte
39 Extrn SystemDriveLetter:Byte
40 Extrn CurrentHead:Byte
41 Extrn CurrentCylinder:Word
42 Extrn FdskSiz:Word
43 Extrn SysSiz:Word
44 Extrn BadSiz:Word
45 Extrn DataSiz:Word
46 Extrn Drive_Letter_Msg:Byte
47 Extrn PercentComplete:Byte
48 Extrn AllocSize:Dword
49 Extrn AllocNum:Word
50 Extrn Serial_Num_Low:Word
51 Extrn Serial_Num_High:Word
52 Extrn Command_Old_Ptr:Word
53 Extrn Msg_Allocation_Unit_Val:Dword
54
55;
56;*****************************************************************************
57; Publics
58;*****************************************************************************
59;
60
61
62
63;
64;*****************************************************************************
65; Message Retriever equates
66;*****************************************************************************
67;
68
69Format_Msg equ 'C'
70
71N_A equ 0
72Sublist_Length equ 11
73None equ 0
74
75Blank equ " "
76No_Function equ 0
77No_Replace equ 0
78
79Msg_Ser_Class equ 0
80Ext_Err_Class equ 1
81Parse_Err_Class equ 2
82Utility_Msg_Class equ 0FFh
83
84Reserved equ 0
85
86
87
88
89data segment public para 'DATA'
90 assume ds:data
91
92
93;
94;*****************************************************************************
95; Message Sublist Tables
96;*****************************************************************************
97;
98;The following control blocks are used for messages with
99;replaceable paramaters. These control blocks are used by the
100;SysDispMsg routine.
101;
102
103;--------------------------- ;
104Sublist_msgCurrentTrack label dword ; ;AN000;
105 ;
106 db Sublist_Length ; ;AN000;
107 db Reserved ; ;AN000;
108 dw offset PercentComplete ; ;AN000;
109 dw data ; ;AN000;
110 db 1 ; ;AN000;
111 db Right_Align+Unsgn_Bin_Word ; ;AN000;
112 db 3 ;Max % is 100 ;AN000;
113 db 3 ;Min % is 0 ;AN000;
114 db Blank ; ;AN000;
115;--------------------------- ;
116Sublist_msgInsertDisk label dword ; ;AN000;
117Sublist_msgReInsertDisk label dword ; ;AN000;
118Sublist_MsgHardDiskWarning label dword ;
119Sublist_msgFormatNotSupported label dword ; ;AN000;
120
121 db Sublist_Length ; ;AN000;
122 db Reserved ; ;AN000;
123 dw offset DriveLetter ; ;AN000;
124 dw data ; ;AN000;
125 db 1 ; ;AN000;
126 db Left_Align+Char_Field_Char ; ;AN000;
127 db 1 ; ;AN000;
128 db 1 ; ;AN000;
129 db Blank ; ;AN000;
130;--------------------------- ;
131Sublist_msgInsertDOSDisk label dword ; ;AN000;
132 ;
133 db Sublist_Length ; ;AN000;
134 db Reserved ; ;AN000;
135 dw offset SystemDriveLetter; ;AN000;
136 dw data ; ;AN000;
137 db 1 ; ;AN000;
138 db Left_Align+Char_Field_Char ; ;AN000;
139 db 1 ; ;AN000;
140 db 1 ; ;AN000;
141 db Blank ; ;AN000;
142;--------------------------- ;
143Sublist_msgTotalDiskSpace label dword ; ;AN000;
144 ;
145 db Sublist_Length ; ;AN000;
146 db Reserved ; ;AN000;
147 dw offset FdskSiz ; ;AN000;
148 dw data ; ;AN000;
149 db 1 ; ;AN000;
150 db Right_Align+Unsgn_Bin_Dword ; ;AN000;
151 db 10 ; ;AN000;
152 db 10 ;4,000,000,000 limit ;AN000;
153 db Blank ; ;AN000;
154;--------------------------- ;
155Sublist_msgSystemSpace label dword ; ;AN000;
156 ;
157 db Sublist_Length ; ;AN000;
158 db Reserved ; ;AN000;
159 dw offset SysSiz ; ;AN000;
160 dw data ; ;AN000;
161 db 1 ; ;AN000;
162 db Right_Align+Unsgn_Bin_DWord ; ;AN000;
163 db 10 ; ;AN000;
164 db 10 ;64k*3 max ;AN000;
165 db Blank ; ;AN000;
166;--------------------------- ;
167Sublist_msgBadSpace label dword ; ;AN000;
168 ;
169 db Sublist_Length ; ;AN000;
170 db Reserved ; ;AN000;
171 dw offset BadSiz ; ;AN000;
172 dw data ; ;AN000;
173 db 1 ; ;AN000;
174 db Right_Align+Unsgn_Bin_DWord ; ;AN000;
175 db 10 ; ;AN000;
176 db 10 ;4,000,000,000 max ;AN000;
177 db Blank ; ;AN000;
178;--------------------------- ;
179Sublist_msgDataSpace label dword ; ;AN000;
180 ;
181 db Sublist_Length ; ;AN000;
182 db Reserved ; ;AN000;
183 dw Offset DataSiz ; ;AN000;
184 dw data ; ;AN000;
185 db 1 ; ;AN000;
186 db Right_Align+Unsgn_Bin_DWord ; ;AN000;
187 db 10 ; ;AN000;
188 db 10 ;4,000,000,000 max ;AN000;
189 db Blank ; ;AN000;
190;--------------------------- ;
191Sublist_msgWhatIsVolumeId? label dword ; ;AN000;
192 ;
193 db Sublist_Length ; ;AN000;
194 db Reserved ; ;AN000;
195 dw offset DriveLetter ; ;AN000;
196 dw data ; ;AN000;
197 db 1 ; ;AN000;
198 db Left_Align+Char_Field_Char ; ;AN000;
199 db 1 ; ;AN000;
200 db 1 ; ;AN000;
201 db Blank ; ;AN000;
202;--------------------------- ;
203Sublist_msgEXECFailure label dword ; ;AN000;
204 ;
205 db Sublist_Length ; ;AN000;
206 db Reserved ; ;AN000;
207 dw Drive_Letter_Msg ; ;AN000;
208 dw data ; ;AN000;
209 db 1 ; ;AN000;
210 db Left_Align+Char_Field_ASCIIZ ; ;AN000;
211 db 2 ; ;AN000;
212 db 2 ; ;AN000;
213 db Blank ; ;AN000;
214;--------------------------- ;
215Sublist_msgAllocNum label dword ; ;AN000;
216 ;
217 db Sublist_Length ; ;AN000;
218 db Reserved ; ;AN000;
219 dw offset AllocNum ; ;AN000;
220 dw data ; ;AN000;
221 db 1 ; ;AN000;
222 db Right_Align+Unsgn_Bin_Word ; ;AN000;
223 db 10 ; ;AN000;
224 db 10 ; ;AN000;
225 db Blank ; ;AN000;
226;--------------------------- ;
227Sublist_msgAllocSize label dword ; ;AN000;
228 ;
229 db Sublist_Length ; ;AN000;
230 db Reserved ; ;AN000;
231 dw offset AllocSize ; ;AN000;
232 dw data ; ;AN000;
233 db 1 ; ;AN000;
234 db Right_Align+Unsgn_Bin_DWord ; ;AN000;
235 db 10 ; ;AN000;
236 db 10 ; ;AN000;
237 db Blank ; ;AN000;
238;--------------------------- ;
239Sublist_msgSerialNumber label dword ; ;AN000;
240 ;
241 db Sublist_Length ; ;AN000;
242 db Reserved ; ;AN000;
243 dw offset Serial_Num_Low ; ;AN000;
244 dw data ; ;AN000;
245 db 1 ; ;AN000;
246 db Right_Align+Bin_Hex_Word ; ;AN000;
247 db 4 ; ;AN000;
248 db 4 ; ;AN000;
249 db '0' ;Display leading 0's ;AN000;
250 db Sublist_Length ; ;AN000;
251 db Reserved ; ;AN000;
252 dw offset Serial_Num_High ; ;AN000;
253 dw data ; ;AN000;
254 db 2 ; ;AN000;
255 db Right_Align+Bin_hex_Word ; ;AN000;
256 db 4 ; ;AN000;
257 db 4 ; ;AN000;
258 db '0' ; ;AN000;
259
260Public Sublist_MsgParse_Error
261Sublist_msgParse_Error label dword ; ;AN000;
262
263 db Sublist_Length ; ;AN000;
264 db Reserved ; ;AN000;
265 dw 0 ; ;AN000;
266 dw Data ; ;AN000;
267 db 0 ; ;AN000;
268 db Left_Align+Char_Field_ASCIIZ ; ;AN000;
269 db 20 ; ;AN000;
270 db 01 ; ;AN000;
271 db Blank ; ;AN000;
272;--------------------------- ;
273Sublist_MsgVerify label dword ; ;AN000;
274 ;
275 db Sublist_Length ; ;AN000;
276 db Reserved ; ;AN000;
277 dw offset Msg_Allocation_Unit_Val; ;AN000;
278 dw data ; ;AN000;
279 db 1 ; ;AN000;
280 db Right_Align+Unsgn_Bin_DWord; ;AN000;
281 db 8 ; ;AN000;
282 db 8 ; ;AN000;
283 db Blank
284;
285;*****************************************************************************
286; Message Description Tables
287;*****************************************************************************
288;
289
290;---------------------- ;
291Message_Number = 1 ; ;AN000;
292Handle = No_Handle ; ;AN000;
293Sublist = No_Replace ; ;AN000;
294Count = N_A ; ;AN000;
295Class = Utility_Msg_Class ; ;AN000;
296Function = No_Input ; ;AN000;
297Input = N_A ; ;AN000;
298 Define_Msg msgBadDOSVersion ; ;AN000;
299;---------------------- ;
300Message_Number = 2 ; ;AN000;
301Handle = STDOUT ; ;AN000;
302Sublist = Sublist_msgCurrentTrack ; ;AN000;
303Count = 1 ; ;AN000;
304Class = Utility_Msg_Class ; ;AN000;
305Function = No_Input ; ;AN000;
306Input = N_A ; ;AN000;
307 Define_Msg msgCurrentTrack ; ;AN000;
308;---------------------- ;
309Message_Number = 3 ; ;AN000;
310Handle = STDOUT ; ;AN000;
311Sublist = Sublist_msgDataSpace ; ;AN000;
312Count = 1 ; ;AN000;
313Class = Utility_Msg_Class ; ;AN000;
314Function = No_Function ; ;AN000;
315Input = N_A ; ;AN000;
316 Define_Msg msgDataSpace ; ;AN000;
317;---------------------- ;
318Message_Number = 4 ; ;AN000;
319Handle = STDOUT ; ;AN000;
320Sublist = No_Replace ; ;AN000;
321Count = N_A ; ;AN000;
322Class = Utility_Msg_Class ; ;AN000;
323Function = No_Input ; ;AN000;
324Input = N_A ; ;AN000;
325 Define_Msg msgFormatComplete ; ;AN000;
326;---------------------- ;
327Message_Number = 5 ; ;AN000;
328Handle = STDOUT ; ;AN000;
329Sublist = Sublist_msgBadSpace ; ;AN000;
330Count = 1 ; ;AN000;
331Class = Utility_Msg_Class ; ;AN000;
332Function = No_Function ; ;AN000;
333Input = N_A ; ;AN000;
334 Define_Msg msgBadSpace ; ;AN000;
335;---------------------- ;
336Message_Number = 6 ; ;AN000;
337Handle = STDOUT ; ;AN000;
338Sublist = Sublist_msgTotalDiskSpace ; ;AN000;
339Count = 1 ; ;AN000;
340Class = Utility_Msg_Class ; ;AN000;
341Function = No_Function ; ;AN000;
342Input = N_A ; ;AN000;
343 Define_Msg msgTotalDiskSpace ; ;AN000;
344;---------------------- ;
345Message_Number = 7 ; ;AN000;
346Handle = STDOUT ; ;AN000;
347Sublist = Sublist_msgInsertDisk ; ;AN000;
348Count = 1 ; ;AN000;
349Class = Utility_Msg_Class ; ;AN000;
350Function = No_Function ; ;AN000;
351Input = N_A ; ;AN000;
352 Define_Msg msgInsertDisk ; ;AN000;
353;---------------------- ;
354Message_Number = 8 ; ;AN000;
355Handle = STDOUT ; ;AN000;
356Sublist = Sublist_msgSystemSpace ; ;AN000;
357Count = 1 ; ;AN000;
358Class = Utility_Msg_Class ; ;AN000;
359Function = No_Function ; ;AN000;
360Input = N_A ; ;AN000;
361 Define_Msg msgSystemSpace ; ;AN000;
362;---------------------- ;
363Message_Number = 9 ; ;AN000;
364Handle = STDOUT ; ;AN000;
365Sublist = Sublist_msgReInsertDisk ; ;AN000;
366Count = 1 ; ;AN000;
367Class = Utility_Msg_Class ; ;AN000;
368Function = No_Function ; ;AN000;
369Input = N_A ; ;AN000;
370 Define_Msg msgReInsertDisk ; ;AN000;
371;---------------------- ;
372Message_Number = 10 ; ;AN000;
373Handle = STDOUT ; ;AN000;
374Sublist = No_Replace ; ;AN000;
375Count = N_A ; ;AN000;
376Class = Utility_Msg_Class ; ;AN000;
377Function = No_Function ; ;AN000;
378Input = N_A ; ;AN000;
379 Define_Msg msgLabelPrompt ; ;AN000;
380;---------------------- ;
381Message_Number = 11 ; ;AN000;
382Handle = STDOUT ; ;AN000;
383Sublist = Sublist_msgFormatNotSupported ; ;AN000;
384Count = 1 ; ;AN000;
385Class = Utility_Msg_Class ; ;AN000;
386Function = No_Function ; ;AN000;
387Input = N_A ; ;AN000;
388 Define_Msg msgFormatNotSupported ; ;AN000;
389;---------------------- ;
390Message_Number = 12 ; ;AN000;
391Handle = STDOUT ; ;AN000;
392Sublist = No_Replace ; ;AN000;
393Count = N_A ; ;AN000;
394Class = Utility_Msg_Class ; ;AN000;
395Function = No_Function ; ;AN000;
396Input = N_A ; ;AN000;
397 Define_Msg msgInvalidDeviceParameters; ;AN000;
398;---------------------- ;
399Message_Number = 13 ; ;AN000;
400Handle = STDOUT ; ;AN000;
401Sublist = No_Replace ; ;AN000;
402Count = N_A ; ;AN000;
403Class = Utility_Msg_Class ; ;AN000;
404Function = No_Function ; ;AN000;
405Input = N_A ; ;AN000;
406 Define_Msg msgErrorInIOCTL ; ;AN000;
407;---------------------- ;
408Message_Number = 14 ; ;AN000;
409Handle = STDOUT ; ;AN000;
410Sublist = No_Replace ; ;AN000;
411Count = N_A ; ;AN000;
412Class = Utility_Msg_Class ; ;AN000;
413Function = No_Function ; ;AN000;
414Input = N_A ; ;AN000;
415 Define_Msg msgNotBlockDevice ; ;AN000;
416;---------------------- ;
417Message_Number = 15 ; ;AN000;
418Handle = STDOUT ; ;AN000;
419Sublist = No_Replace ; ;AN000;
420Count = N_A ; ;AN000;
421Class = Utility_Msg_Class ; ;AN000;
422Function = No_Function ; ;AN000;
423Input = N_A ; ;AN000;
424 Define_Msg msgFATwriteError ; ;AN000;
425;---------------------- ;
426Message_Number = 16 ; ;AN000;
427Handle = STDOUT ; ;AN000;
428Sublist = No_Replace ; ;AN000;
429Count = N_A ; ;AN000;
430Class = Utility_Msg_Class ; ;AN000;
431Function = No_Function ; ;AN000;
432Input = N_A ; ;AN000;
433 Define_Msg msgDirectoryWriteError ; ;AN000;
434;---------------------- ;
435Message_Number = 17 ; ;AN000;
436Handle = STDOUT ; ;AN000;
437Sublist = No_Replace ; ;AN000;
438Count = N_A ; ;AN000;
439Class = Utility_Msg_Class ; ;AN000;
440Function = No_Function ; ;AN000;
441Input = N_A ; ;AN000;
442 Define_Msg msgAssignedDrive ; ;AN000;
443;---------------------- ;
444Message_Number = 18 ; ;AN000;
445Handle = STDOUT ; ;AN000;
446Sublist = No_Replace ; ;AN000;
447Count = N_A ; ;AN000;
448Class = Utility_Msg_Class ; ;AN000;
449Function = No_Function ; ;AN000;
450Input = N_A ; ;AN000;
451 Define_Msg msgNoSystemFiles ; ;AN000;
452;---------------------- ;
453Message_Number = 19 ; ;AN000;
454Handle = STDOUT ; ;AN000;
455Sublist = No_Replace ; ;AN000;
456Count = N_A ; ;AN000;
457Class = Utility_Msg_Class ; ;AN000;
458Function = No_Function ; ;AN000;
459Input = N_A ; ;AN000;
460 Define_Msg msgNetDrive ; ;AN000;
461;---------------------- ;
462Message_Number = 20 ; ;AN000;
463Handle = STDOUT ; ;AN000;
464Sublist = No_Replace ; ;AN000;
465Count = N_A ; ;AN000;
466Class = Utility_Msg_Class ; ;AN000;
467Function = No_Function ; ;AN000;
468Input = N_A ; ;AN000;
469 Define_Msg msgBadCharacters ; ;AN000;
470;---------------------- ;
471Message_Number = 21 ; ;AN000;
472Handle = STDOUT ; ;AN000;
473Sublist = No_Replace ; ;AN000;
474Count = N_A ; ;AN000;
475Class = Utility_Msg_Class ; ;AN000;
476Function = No_Function ; ;AN000;
477Input = N_A ; ;AN000;
478 Define_Msg msgParametersNotSupported ; ;AN000;
479;---------------------- ;
480Message_Number = 22 ; ;AN000;
481Handle = STDOUT ; ;AN000;
482Sublist = No_Replace ; ;AN000;
483Count = N_A ; ;AN000;
484Class = Utility_Msg_Class ; ;AN000;
485Function = No_Function ; ;AN000;
486Input = N_A ; ;AN000;
487 Define_Msg msgFormatFailure ; ;AN000;
488;---------------------- ;
489Message_Number = 23 ; ;AN000;
490Handle = STDOUT ; ;AN000;
491Sublist = No_Replace ; ;AN000;
492Count = N_A ; ;AN000;
493Class = Utility_Msg_Class ; ;AN000;
494Function = No_Function ; ;AN000;
495Input = N_A ; ;AN000;
496 Define_Msg msgNotSystemDisk ; ;AN000;
497;---------------------- ;
498Message_Number = 24 ; ;AN000;
499Handle = STDOUT ; ;AN000;
500Sublist = No_Replace ; ;AN000;
501Count = N_A ; ;AN000;
502Class = Utility_Msg_Class ; ;AN000;
503Function = No_Function ; ;AN000;
504Input = N_A ; ;AN000;
505 Define_Msg msgDiskUnusable ; ;AN000;
506;---------------------- ;
507Message_Number = 25 ; ;AN000;
508Handle = STDOUT ; ;AN000;
509Sublist = No_Replace ; ;AN000;
510Count = N_A ; ;AN000;
511Class = Utility_Msg_Class ; ;AN000;
512Function = No_Function ; ;AN000;
513Input = N_A ; ;AN000;
514 Define_Msg msgBootWriteError ; ;AN000;
515;---------------------- ;
516Message_Number = 26 ; ;AN000;
517Handle = STDOUT ; ;AN000;
518Sublist = No_Replace ; ;AN000;
519Count = N_A ; ;AN000;
520Class = Utility_Msg_Class ; ;AN000;
521Function = No_Function ; ;AN000;
522Input = N_A ; ;AN000;
523 Define_Msg msgDirectoryReadError ; ;AN000;
524;---------------------- ;
525Message_Number = 27 ; ;AN000;
526Handle = STDOUT ; ;AN000;
527Sublist = No_Replace ; ;AN000;
528Count = N_A ; ;AN000;
529Class = Utility_Msg_Class ; ;AN000;
530Function = No_Function ; ;AN000;
531Input = N_A ; ;AN000;
532 Define_Msg msgNeedDrive ; ;AN000;
533;---------------------- ;
534Message_Number = 28 ; ;AN000;
535Handle = STDOUT ; ;AN000;
536Sublist = No_Replace ; ;AN000;
537Count = N_A ; ;AN000;
538Class = Utility_Msg_Class ; ;AN000;
539Function = No_Function ; ;AN000;
540Input = N_A ; ;AN000;
541 Define_Msg ContinueMsg ; ;AN000;
542;---------------------- ;
543Message_Number = 29 ; ;AN000;
544Handle = STDOUT ; ;AN000;
545Sublist = No_Replace ; ;AN000;
546Count = N_A ; ;AN000;
547Class = Utility_Msg_Class ; ;AN000;
548Function = No_Function ; ;AN000;
549Input = N_A ; ;AN000;
550 Define_Msg msgBadVolumeId ; ;AN000;
551;---------------------- ;
552Message_Number = 30 ; ;AN000;
553Handle = STDOUT ; ;AN000;
554Sublist = No_Replace ; ;AN000;
555Count = N_A ; ;AN000;
556Class = Utility_Msg_Class ; ;AN000;
557Function = No_Input ; ;AN000;
558Input = N_A ; ;AN000;
559 Define_Msg msgSystemTransfered ; ;AN000;
560;---------------------- ;
561Message_Number = 31 ; ;AN000;
562Handle = STDOUT ; ;AN000;
563Sublist = Sublist_msgWhatIsVolumeId? ; ;AN000;
564Count = 1 ; ;AN000;
565Class = Utility_Msg_Class ; ;AN000;
566Function = No_Function ; ;AN000;
567Input = N_A ; ;AN000;
568 Define_Msg msgWhatIsVolumeId? ; ;AN000;
569;---------------------- ;
570Message_Number = 32 ; ;AN000;
571Handle = STDOUT ; ;AN000;
572Sublist = No_Replace ; ;AN000;
573Count = N_A ; ;AN000;
574Class = Utility_Msg_Class ; ;AN000;
575Function = No_Function ; ;AN000;
576Input = N_A ; ;AN000;
577 Define_Msg msgIncompatibleParametersForHardDisk ; ;AN000;
578;---------------------- ;
579
580Message_Number = 33 ; ;AN000;
581Handle = STDOUT ; ;AN000;
582Sublist = No_Replace ; ;AN000;
583Count = N_A ; ;AN000;
584Class = Utility_Msg_Class ; ;AN000;
585Function = No_Function ; ;AN000;
586Input = N_A ; ;AN000;
587 Define_Msg msgWriteProtected ; ;AN000;
588;---------------------- ;
589Message_Number = 34 ; ;AN000;
590Handle = STDOUT ; ;AN000;
591Sublist = No_Replace ; ;AN000;
592Count = N_A ; ;AN000;
593Class = Utility_Msg_Class ; ;AN000;
594Function = No_Function ; ;AN000;
595Input = N_A ; ;AN000;
596 Define_Msg msgNotReady ; ;AN000;
597;---------------------- ;
598
599Message_Number = 35 ; ;AN000;
600Handle = STDOUT ; ;AN000;
601Sublist = No_Replace ; ;AN000;
602Count = N_A ; ;AN000;
603Class = Utility_Msg_Class ; ;AN000;
604Function = No_Function ; ;AN000;
605Input = N_A ; ;AN000;
606 Define_Msg msgPartitionTableReadErr ; ;AN000;
607;---------------------- ;
608Message_Number = 36 ; ;AN000;
609Handle = STDOUT ; ;AN000;
610Sublist = Sublist_msgSerialNumber ; ;AN000;
611Count = 2 ; ;AN000;
612Class = Utility_Msg_Class ; ;AN000;
613Function = No_Function ; ;AN000;
614Input = N_A ; ;AN000;
615 Define_Msg msgSerialNumber ; ;AN000;
616;---------------------- ;
617Message_Number = 37 ; ;AN000;
618Handle = STDOUT ; ;AN000;
619Sublist = No_Replace ; ;AN000;
620Count = N_A ; ;AN000;
621Class = Utility_Msg_Class ; ;AN000;
622Function = No_Function ; ;AN000;
623Input = N_A ; ;AN000;
624 Define_Msg msgFormatBroken ; ;AN000;
625;---------------------- ;
626Message_Number = 38 ; ;AN000;
627Handle = STDOUT ; ;AN000;
628Sublist = Sublist_msgEXECFailure ; ;AN000;
629Count = 1 ; ;AN000;
630Class = Utility_Msg_Class ; ;AN000;
631Function = No_Function ; ;AN000;
632Input = N_A ; ;AN000;
633 Define_Msg msgEXECFailure ; ;AN000;
634;---------------------- ;
635Message_Number = 39 ; ;AN000;
636Handle = STDOUT ; ;AN000;
637Sublist = No_Replace ; ;AN000;
638Count = N_A ; ;AN000;
639Class = Utility_Msg_Class ; ;AN000;
640Function = No_Function ; ;AN000;
641Input = N_A ; ;AN000;
642 Define_Msg NO_SYS_MESS ; ;AN000;
643;---------------------- ;
644Message_Number = 40 ; ;AN000;
645Handle = STDOUT ; ;AN000;
646Sublist = No_Replace ; ;AN000;
647Count = N_A ; ;AN000;
648Class = Utility_Msg_Class ; ;AN000;
649Function = No_Function ; ;AN000;
650Input = N_A ; ;AN000;
651 Define_Msg msgbadpartitiontable ; ;AN000;
652;---------------------- ;
653Message_Number = 41 ; ;AN000;
654Handle = STDOUT ; ;AN000;
655Sublist = No_Replace ; ;AN000;
656Count = N_A ; ;AN000;
657Class = Utility_Msg_Class ; ;AN000;
658Function = No_Function ; ;AN000;
659Input = N_A ; ;AN000;
660 Define_Msg msgParametersNotSupportedByDrive ; ;AN000;
661;---------------------- ;
662Message_Number = 42 ; ;AN000;
663Handle = STDOUT ; ;AN000;
664Sublist = No_Replace ; ;AN000;
665Count = N_A ; ;AN000;
666Class = Utility_Msg_Class ; ;AN000;
667Function = No_Function ; ;AN000;
668Input = N_A ; ;AN000;
669 Define_Msg msgCRLF ; ;AN000;
670;---------------------- ;
671Message_Number = 43 ; ;AN000;
672Handle = STDOUT ; ;AN000;
673Sublist = No_Replace ; ;AN000;
674Count = N_A ; ;AN000;
675Class = Utility_Msg_Class ; ;AN000;
676Function = No_Function ; ;AN000;
677Input = N_A ; ;AN000;
678 Define_Msg msgInterrupt ; ;AN000;
679;---------------------- ;
680Message_Number = 44 ; ;AN000;
681Handle = STDOUT ; ;AN000;
682Sublist = Sublist_MsgInsertDOSDisk ; ;AN000;
683Count = 1 ; ;AN000;
684Class = Utility_Msg_Class ; ;AN000;
685Function = No_Function ; ;AN000;
686Input = N_A ; ;AN000;
687 Define_Msg msgInsertDOSDisk ; ;AN000;
688;---------------------- ;
689Message_Number = 45 ; ;AN000;
690Handle = STDOUT ; ;AN000;
691Sublist = Sublist_MsgHardDiskWarning ; ;AN000;
692Count = 1 ; ;AN000;
693Class = Utility_Msg_Class ; ;AN000;
694Function = No_Function ; ;AN000;
695Input = N_A ; ;AN000;
696 Define_Msg msgHardDiskWarning ; ;AN000;
697;---------------------- ;
698Message_Number = 46 ; ;AN000;
699Handle = STDOUT ; ;AN000;
700Sublist = No_Replace ; ;AN000;
701Count = N_A ; ;AN000;
702Class = Utility_Msg_Class ; ;AN000;
703Function = No_Function ; ;AN000;
704Input = N_A ; ;AN000;
705 Define_Msg msgFormatAnother? ; ;AN000;
706;---------------------- ;
707Message_Number = 47 ; ;AN000;
708Handle = STDOUT ; ;AN000;
709Sublist = No_Replace ; ;AN000;
710Count = N_A ; ;AN000;
711Class = Utility_Msg_Class ; ;AN000;
712Function = No_Function ; ;AN000;
713Input = N_A ; ;AN000;
714 Define_Msg msgPartitionTableReadError ; ;AN000;
715;---------------------- ;
716Message_Number = 48 ; ;AN000;
717Handle = STDOUT ; ;AN000;
718Sublist = No_Replace ; ;AN000;
719Count = N_A ; ;AN000;
720Class = Utility_Msg_Class ; ;AN000;
721Function = No_Function ; ;AN000;
722Input = N_A ; ;AN000;
723 Define_Msg msgPartitionTableWriteError ; ;AN000;
724;---------------------- ;
725Message_Number = 49 ; ;AN000;
726Handle = STDOUT ; ;AN000;
727Sublist = No_Replace ; ;AN000;
728Count = N_A ; ;AN000;
729Class = Utility_Msg_Class ; ;AN000;
730Function = No_Function ; ;AN000;
731Input = N_A ; ;AN000;
732 Define_Msg msgIncompatibleParameters ; ;AN000;
733;---------------------- ;
734Message_Number = 50 ; ;AN000;
735Handle = STDOUT ; ;AN000;
736Sublist = Sublist_MsgAllocNum ; ;AN000;
737Count = 1 ; ;AN000;
738Class = Utility_Msg_Class ; ;AN000;
739Function = No_Function ; ;AN000;
740Input = N_A ; ;AN000;
741 Define_Msg msgAllocNum ; ;AN000;
742;---------------------- ;
743Message_Number = 51 ; ;AN000;
744Handle = STDOUT ; ;AN000;
745Sublist = Sublist_MsgAllocSize ; ;AN000;
746Count = 1 ; ;AN000;
747Class = Utility_Msg_Class ; ;AN000;
748Function = No_Function ; ;AN000;
749Input = N_A ; ;AN000;
750 Define_Msg msgAllocSize ; ;AN000;
751;---------------------- ;
752Message_Number = 52 ; ;AN000;
753Handle = STDOUT ; ;AN000;
754Sublist = No_Replace ; ;AN000;
755Count = N_A ; ;AN000;
756Class = Utility_Msg_Class ; ;AN000;
757Function = No_Function ; ;AN000;
758Input = N_A ; ;AN000;
759 Define_Msg msgPartitionTableWriteErr ; ;AN000;
760;---------------------- ;
761Message_Number = 53 ; ;AN002;
762Handle = STDOUT ; ;AN002;
763Sublist = No_Replace ; ;AN002;
764Count = N_A ; ;AN002;
765Class = Utility_Msg_Class ; ;AN002;
766Function = No_Function ; ;AN002;
767Input = N_A ; ;AN002;
768 Define_Msg msgSameSwitch ; ;AN002;
769;---------------------- ;
770Message_Number = 54 ; ;AN009;
771Handle = STDOUT ; ;AN009;
772Sublist = No_Replace ; ;AN009;
773Count = N_A ; ;AN009;
774Class = Utility_Msg_Class ; ;AN009;
775Function = No_Function ; ;AN009;
776Input = N_A ; ;AN009;
777 Define_Msg msgBad_T_N ; ;AN009;
778;---------------------- ;
779Message_Number = 55 ; ;an019; dms;
780Handle = STDOUT ; ;an019; dms;
781Sublist = Sublist_MsgVerify ; ;an019; dms;
782Count = 1 ; ;an019; dms;
783Class = Utility_Msg_Class ; ;an019; dms;
784Function = No_Function ; ;an019; dms;
785Input = N_A ; ;an019; dms;
786 Define_Msg MsgVerify ; ;an019; dms;
787;---------------------- ;
788Message_Number = 0 ; ;AN000;
789Handle = STDERR ; ;AN000;
790Sublist = No_Replace ; ;AN000;
791Count = N_A ; ;AN000;
792Class = Ext_Err_Class ; ;AN000;
793Function = No_Function ; ;AN000;
794Input = N_A ; ;AN000;
795 Define_Msg Extended_Error_Msg ; ;AN000;
796;----------------------
797Message_Number = 0 ; ;AN000;
798Handle = STDERR ; ;AN000;
799Sublist = Sublist_MsgParse_Error ; ;AN000;
800Count = 1 ; ;AN000;
801Class = Parse_Err_Class ; ;AN000;
802Function = No_Function ; ;AN000;
803Input = N_A ; ;AN000;
804 Define_Msg Parse_Error_Msg ; ;AN000;
805;-----------------------
806
807
808
809;
810;These need to be coded as extended an parse errors, but left here to link.
811;
812
813
814
815Message_Number = 70 ; ;AN000;
816Handle = STDOUT ; ;AN000;
817Sublist = No_Replace ; ;AN000;
818Count = N_A ; ;AN000;
819Class = Utility_Msg_Class ; ;AN000;
820Function = No_Input ; ;AN000;
821Input = N_A ; ;AN000;
822 Define_Msg msgOutOfMemory ; ;AN000;
823;---------------------- ;
824Message_Number = 71 ; ;AN000;
825Handle = STDOUT ; ;AN000;
826Sublist = No_Replace ; ;AN000;
827Count = N_A ; ;AN000;
828Class = Utility_Msg_Class ; ;AN000;
829Function = No_Input ; ;AN000;
830Input = N_A ; ;AN000;
831 Define_Msg msgBadDrive ; ;AN000;
832;---------------------- ;
833Message_Number = 10 ; ;AN000;
834Handle = StdErr ; ;AN000;
835Sublist = No_Replace ; ;AN000;
836Count = N_A ; ;AN000;
837Class = Parse_Err_Class ; ;AN000;
838Function = No_Input ; ;AN000;
839Input = N_A ; ;AN000;
840 Define_Msg msgInvalidParameter ; ;AN000;
841;---------------------- ;
842Message_Number = 73 ; ;AN000;
843Handle = STDOUT ; ;AN000;
844Sublist = No_Replace ; ;AN000;
845Count = N_A ; ;AN000;
846Class = Utility_Msg_Class ; ;AN000;
847Function = No_Input ; ;AN000;
848Input = N_A ; ;AN000;
849 Define_Msg msgLoadFailure ; ;AN000;
850
851
852
853
854
855
856
857
858
859data ends
860
861
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 @@
1;
2
3
4
5data segment public para 'DATA'
6
7;
8;*****************************************************************************
9; Publics
10;*****************************************************************************
11;
12
13 Public Drive_Letter_Buffer
14 Public Switch_Buffer
15 Public Switch_Num_Buffer
16 Public Switch_String_Buffer
17
18
19;
20;***************************************************************************
21; Equates
22;***************************************************************************
23;
24
25;Match Flags
26
27Numeric_Value equ 8000h ; ;AN000;
28Signed_Numeric_Value equ 4000h ; ;AN000;
29Simple_String equ 2000h ; ;AN000;
30Date_String equ 1000h ; ;AN000;
31Time_String equ 0800h ; ;AN000;
32Complex_List equ 0400h ; ;AN000;
33Filespec equ 0200h ; ;AN000;
34Drive_Only equ 0100h ; ;AN000;
35Quoted_String equ 0080h ; ;AN000;
36Ignore_Colon equ 0010h ; ;AN000;
37Repeats_Allowed equ 0002h ; ;AN000;
38Optional equ 0001h ; ;AN000;
39
40;Function_Flags
41
42File_Table_Capitalize equ 1 ; ;AN000;
43Char_Table_Capitalize equ 2 ; ;AN000;
44Remove_Colon equ 10h ; ;AN000;
45
46;Extra delimeters and EOL
47
48Delimiters_Only equ 1 ; ;AN000;
49EOL_Or_Delimiters equ 2 ; ;AN000;
50
51Semi_Colon equ ";" ; ;AN000;
52Tab equ 09h ; ;AN000;
53Colon equ ":" ; ;AN000;
54
55
56;Parse Errors
57
58No_Error equ 0 ; ;AN000;
59Too_Many_Operands equ 1 ; ;AN000;
60Operand_Missing equ 2 ; ;AN000;
61Not_In_Switch_List equ 3 ; ;AN000;
62Not_In_Keyword_List equ 4 ; ;AN000;
63Out_Of_Range equ 6 ; ;AN000;
64Not_In_Value_List equ 7 ; ;AN000;
65Not_In_String_List equ 8 ; ;AN000;
66Syntax_Error equ 9 ; ;AN000;
67End_Of_Parse equ -1 ; ;AN000;
68
69;Return types
70
71Type_Reserved equ 0 ; ;AN000;
72Type_Number equ 1 ; ;AN000;
73Type_List_Index equ 2 ; ;AN000;
74Type_String equ 3 ; ;AN000;
75Type_Complex equ 4 ; ;AN000;
76Type_Filespec equ 5 ; ;AN000;
77Type_Drive equ 6 ; ;AN000;
78Type_Date equ 7 ; ;AN000;
79Type_Time equ 8 ; ;AN000;
80Type_Quoted_String equ 9 ; ;AN000;
81
82;Other
83
84None equ 0 ; ;AN000;
85No_Error equ 0 ; ;AN000;
86Switch_Found equ 0FFFFh ; ;AN000;
87Range_Ok equ 1 ; ;AN000;
88Command_Line_Parms equ 81h ; ;AN000;
89
90;
91;*****************************************************************************
92; Parse Structures
93;*****************************************************************************
94;
95
96Control struc
97
98Match_Flags dw ?
99Function_Flags dw ?
100Result dw ?
101Values dw ?
102Num_Keywords db ?
103Keyword db ?
104
105Control ends
106
107Drive_Letter_Return struc ; ;AN000;
108
109Drive_Type db 0 ; ;AN000;
110Drive_Item_Tag db 0 ; ;AN000;
111Drive_Pointer dw 0 ; ;AN000;
112Drive_Number db 0 ;A=1, B=2, C=3 ;AN000;
113Drive_debug db 8 dup(0)
114
115Drive_Letter_Return ends ; ;AN000;
116
117Switch_Return struc ; ;AN000;
118
119Switch_Type db 0 ; ;AN000;
120Switch_Item_Tag db 0 ; ;AN000;
121Switch_Pointer dw 0 ; ;AN000;
122Switch_Debug db 4 dup(0)
123
124Switch_Return ends ; ;AN000;
125
126Switch_Num_Return struc ; ;AN000;
127
128Switch_Num_Type db 0 ; ;AN000;
129Switch_Num_Item_Tag db 0 ; ;AN000;
130Switch_Num_Pointer dw 0 ; ;AN000;
131Switch_Number_Low dw 0 ; ;AN000;
132Switch_Number_High dw 0 ; ;AN000;
133
134Switch_Num_Return ends ; ;AN000;
135
136Switch_String_Return struc ; ;AN000;
137
138Switch_String_Type db 0 ; ;AN000;
139Switch_String_Item_Tag db 0 ; ;AN000;
140Switch_String_Pointer dw 0 ; ;AN000;
141Switch_String_Off dw 0 ; ;AN000;
142Switch_String_Seg dw 0 ; ;AN000;
143
144Switch_String_Return ends ; ;AN000;
145
146
147;
148;**************************************************************************
149; Parse tables
150;**************************************************************************
151;
152
153IF FSExec ;conditionally assemble /FS: ;an018; dms;
154
155Switch_FS_Table label byte ; ;AN000;
156
157 dw Drive_Control_Definition ;Point to next level ;AN000;
158 db 0 ; ;AN000;
159
160ENDIF ;end conditional assembly /FS: ;an018; dms;
161
162Command_Line_Table label byte ; ;AN000;
163
164 dw Command_Control ;Point to next level ;AN000;
165 db 0 ; ;AN000;
166
167;
168;**************************************************************************
169;Define Positionals, Switches and Keywords
170;**************************************************************************
171;
172
173
174IF FSExec ;conditionally assemble /FS: ;an018; dms;
175
176Drive_Control_Definition label byte ; ;AN000;
177
178 db 1,1 ;Only drive letter posistional ;AN000;
179 dw Positional_Control ;Pointer to control table ;AN000;
180 db 1 ;1 switch ;AN000;
181 dw Switch_FS_Control ; ;AN000;
182 db None ;No Keywords (maxk) ;AN000;
183
184ENDIF ;end conditional assembly /FS: ;an018; dms;
185
186Command_Control label byte ; ;AN000;
187
188 db 1,1 ;Only drive letter posistional ;AN000;
189 dw Positional_Control ;Pointer to control table ;AN000;
190IF ShipDisk
191 db 13 ;if /Z switch needed ;an000; dms;
192ELSE
193 db 12 ; ;AC001;
194ENDIF
195 dw Switch_V_Control ;Without quotes AN000;
196 dw Switch_S_Control ; ;AN000;
197 dw Switch_4_Control ; ;AN000;
198 dw Switch_1_Control ; ;AN000;
199 dw Switch_8_Control ; ;AN000;
200 dw Switch_B_Control ; ;AN000;
201 dw Switch_T_Control ; ;AN000;
202 dw Switch_N_Control ; ;AN000;
203 dw Switch_Select_Control ; ;AN000;
204 dw Switch_Backup_Control ; ;AN000;
205 dw Switch_Autotest_Control ; ;AN000;
206 dw Switch_F_Control ; ;AC001;
207IF ShipDisk
208 dw Switch_Z_Control ;1 sector/cluster switch ;an000; dms;
209ENDIF
210 db None ;No Keywords (maxk) ;AN000;
211
212;
213;**************************************************************************
214;Control Tables
215;**************************************************************************
216;
217
218Positional_Control label byte ; ;AN000;
219
220 dw Drive_Only ;Match_Flag ;AN000;
221 dw None ;No function flags ;AN000;
222 dw Drive_Letter_Buffer ;Where it will be returned ;AN000;
223 dw No_Value ;No value ranges defined ;AN000;
224 db None ;No defined switches/keywords ;AN000;
225
226IF FSExec ;conditionally assemble /FS: ;an018; dms;
227
228Switch_FS_Control label byte
229 dw Simple_String ;/FS:xxxxx ;AN000;
230 dw File_Table_Capitalize ;Make it uppercase ;AN000;
231 dw Switch_String_Buffer ; ;AN000;
232 dw No_Value ; ;AN000;
233 db 1 ; ;AN000;
234 db "/FS",0 ; ;AN000;
235
236ENDIF ;end conditional assembly /FS: ;an018; dms;
237
238Switch_V_Control label byte ; ;AN000;
239
240 dw Simple_String+Quoted_String+Optional ;/v:xxxxxxxx ;AN000;
241 dw File_Table_Capitalize ; ;AN000;
242 dw Switch_String_Buffer ; ;AN000;
243 dw No_Value ; ;AN000;
244 db 1 ; ;AN000;
245 db "/V",0 ; ;AN000;
246
247Switch_S_Control label byte ; ;AN000;
248
249 dw None ; ;AN000;
250 dw None ; ;AN000;
251 dw Switch_Buffer ; ;AN000;
252 dw No_Value ; ;AN000;
253 db 1 ; ;AN000;
254 db "/S",0 ; ;AN000;
255
256Switch_4_Control label byte ; ;AN000;
257
258 dw None ; ;AN000;
259 dw None ; ;AN000;
260 dw Switch_Buffer ; ;AN000;
261 dw No_Value ; ;AN000;
262 db 1 ; ;AN000;
263 db "/4",0 ; ;AN000;
264
265Switch_1_Control label byte ; ;AN000;
266
267 dw None ; ;AN000;
268 dw None ; ;AN000;
269 dw Switch_Buffer ; ;AN000;
270 dw No_Value ; ;AN000;
271 db 1 ; ;AN000;
272 db "/1",0 ; ;AN000;
273
274Switch_8_Control label byte ; ;AN000;
275
276 dw None ; ;AN000;
277 dw None ; ;AN000;
278 dw Switch_Buffer ; ;AN000;
279 dw No_Value ; ;AN000;
280 db 1 ; ;AN000;
281 db "/8",0 ; ;AN000;
282
283Switch_B_Control label byte ; ;AN000;
284
285 dw None ; ;AN000;
286 dw None ; ;AN000;
287 dw Switch_Buffer ; ;AN000;
288 dw No_Value ; ;AN000;
289 db 1 ; ;AN000;
290 db "/B",0 ; ;AN000;
291
292Switch_T_Control label byte ; ;AN000;
293
294 dw Numeric_Value ; ;AN000;
295 dw None ; ;AN000;
296 dw Switch_Num_Buffer ; ;AN000;
297 dw Switch_T_Value ; ;AN000;
298 db 1 ; ;AN000;
299 db "/T",0 ; ;AN000;
300
301Switch_N_Control label byte ; ;AN000;
302
303 dw Numeric_Value ; ;AN000;
304 dw None ; ;AN000;
305 dw Switch_Num_Buffer ; ;AN000;
306 dw Switch_N_Value ; ;AN000;
307 db 1 ; ;AN000;
308 db "/N",0 ; ;AN000;
309
310Switch_Select_Control label byte ; ;AN000;
311
312 dw None ; ;AN000;
313 dw None ; ;AN000;
314 dw Switch_Buffer ; ;AN000;
315 dw No_Value ; ;AN000;
316 db 1 ; ;AN000;
317 db "/SELECT",0 ; ;AN000;
318
319Switch_Backup_Control label byte ; ;AN000;
320
321 dw None ; ;AN000;
322 dw None ; ;AN000;
323 dw Switch_Buffer ; ;AN000;
324 dw No_Value ; ;AN000;
325 db 1 ; ;AN000;
326 db "/BACKUP",0 ; ;AN000;
327
328Switch_Autotest_Control label byte ; ;AN000;
329
330 dw None ; ;AN000;
331 dw None ; ;AN000;
332 dw Switch_Buffer ; ;AN000;
333 dw No_Value ; ;AN000;
334 db 1 ; ;AN000;
335 db "/AUTOTEST",0 ; ;AN000;
336
337Switch_F_Control label byte ; ;AN001;
338 dw Simple_String ;/F:xxxxx ;AN001;
339 dw File_Table_Capitalize ;Make it uppercase ;AN001;
340 dw Switch_String_Buffer ; ;AN001;
341 dw Switch_Size_Value ; ;AN001;
342 db 1 ; ;AN001;
343 db "/F",0 ; ;AN001;
344
345IF ShipDisk
346
347Switch_Z_Control label byte ;control structure for /Z ;an000; dms;
348 dw None ; ;an000; dms;
349 dw None ; ;an000; dms;
350 dw Switch_Buffer ; ;an000; dms;
351 dw No_Value ; ;an000; dms;
352 db 1 ; ;an000; dms;
353 db "/Z",0 ; ;an000; dms;
354
355ENDIF
356
357;
358;************************************************************************
359; PARSE Value Lists
360;************************************************************************
361;
362
363Switch_T_Value label byte ; ;AN000;
364
365 db 1 ;Range only ;ANOOO;
366 db 1 ;1 range ;ANOOO;
367 db Range_OK ;Item_Tag ;ANOOO;
368 dd 1 ;1 is low bound ;ANOOO;
369 dd 1024 ;2**10 is max ;AN000;
370
371Switch_N_Value label byte ; ;AN000;
372
373 db 1 ;Range only ;ANOOO;
374 db 1 ;1 range ;ANOOO;
375 db Range_OK ;Item_Tag ;ANOOO;
376 dd 1 ;1 is low bound ;ANOOO;
377 dd 64 ;2**6 is max ;AN000;
378
379Switch_Size_Value label byte ; ;AN001;
380
381 db 3 ;Look for strings ;AN001;
382 db 0 ;No ranges ;AN001;
383 db 0 ;No numerics ;AN001;
384 db 27 ;16 possible strings ;AN001;
385 db Size_160 ; ;AN001;
386 dw String_160k_1 ;/F:160 ;AN001;
387 db Size_160 ; ;AN001;
388 dw String_160k_2 ;/F:160K ;AN001;
389 db Size_160 ; ;AN001;
390 dw String_160k_3 ;/F:160KB ;AN001;
391 db Size_180 ; ;AN001;
392 dw String_180k_1 ;/F:180 ;AN001;
393 db Size_180 ; ;AN001;
394 dw String_180k_2 ;/F:180K ;AN001;
395 db Size_180 ; ;AN001;
396 dw String_180k_3 ;/F:180KB ;AN001;
397 db Size_320 ; ;AN001;
398 dw String_320k_1 ;/F:320 ;AN001;
399 db Size_320 ; ;AN001;
400 dw String_320k_2 ;/F:320K ;AN001;
401 db Size_320 ; ;AN001;
402 dw String_320k_3 ;/F:320KB ;AN001;
403 db Size_360 ; ;AN001;
404 dw String_360k_1 ;/F:360 ;AN001;
405 db Size_360 ; ;AN001;
406 dw String_360k_2 ;/F:360K ;AN001;
407 db Size_360 ; ;AN001;
408 dw String_360k_3 ;/F:360KB ;AN001;
409 db Size_720 ; ;AN001;
410 dw String_720k_1 ;/F:720 ;AN001;
411 db Size_720 ; ;AN001;
412 dw String_720k_2 ;/F:720K ;AN001;
413 db Size_720 ; ;AN001;
414 dw String_720k_3 ;/F:720KB ;AN001;
415 db Size_1200 ; ;AN001;
416 dw String_1200k_1 ;/F:1200 ;AN001;
417 db Size_1200 ; ;AN001;
418 dw String_1200k_2 ;/F:1200K ;AN001;
419 db Size_1200 ; ;AN001;
420 dw String_1200k_3 ;/F:1200KB ;AN001;
421 db Size_1200 ; ;AN001;
422 dw String_1200k_4 ;/F:1.2 ;AN001;
423 db Size_1200 ; ;AN001;
424 dw String_1200k_5 ;/F:1.2M ;AN001;
425 db Size_1200 ; ;AN001;
426 dw String_1200k_6 ;/F:1.2MB ;AN001;
427 db Size_1440 ; ;AN001;
428 dw String_1440k_1 ;/F:1440 ;AN001;
429 db Size_1440 ; ;AN001;
430 dw String_1440k_2 ;/F:1440K ;AN001;
431 db Size_1440 ; ;AN001;
432 dw String_1440k_3 ;/F:1440KB ;AN001;
433 db Size_1440 ; ;AN001;
434 dw String_1440k_4 ;/F:1.44 ;AN001;
435 db Size_1440 ; ;AN001;
436 dw String_1440k_5 ;/F:1.44M ;AN001;
437 db Size_1440 ; ;AN001;
438 dw String_1440k_6 ;/F:1.44MB ;AN001;
439
440
441No_Value label byte ; ;AN000;
442 db 0 ; ;AN000;
443
444;
445;*****************************************************************************
446; Data Area for value lists
447;*****************************************************************************
448;
449
450;
451;The following are a list of the allowed strings for the /F:xxxxx switch.
452;
453
454String_160k_1 db "160" ,Asciiz_End ; ;AN001;
455String_160k_2 db "160K" ,Asciiz_End ; ;AN001;
456String_160k_3 db "160KB" ,Asciiz_End ; ;AN001;
457String_180k_1 db "180" ,Asciiz_End ; ;AN001;
458String_180k_2 db "180K" ,Asciiz_End ; ;AN001;
459String_180k_3 db "180KB" ,Asciiz_End ; ;AN001;
460String_320k_1 db "320" ,Asciiz_End ; ;AN001;
461String_320k_2 db "320K" ,Asciiz_End ; ;AN001;
462String_320k_3 db "320KB" ,Asciiz_End ; ;AN001;
463String_360k_1 db "360" ,Asciiz_End ; ;AN001;
464String_360k_2 db "360K" ,Asciiz_End ; ;AN001;
465String_360k_3 db "360KB" ,Asciiz_End ; ;AN001;
466String_720k_1 db "720" ,Asciiz_End ; ;AN001;
467String_720k_2 db "720K" ,Asciiz_End ; ;AN001;
468String_720k_3 db "720KB" ,Asciiz_End ; ;AN001;
469String_1200k_1 db "1200" ,Asciiz_End ; ;AN001;
470String_1200k_2 db "1200K",Asciiz_End ; ;AN001;
471String_1200k_3 db "1200KB",Asciiz_End ; ;AN001;
472String_1200k_4 db "1.2" ,Asciiz_End ; ;AN001;
473String_1200k_5 db "1.2M" ,Asciiz_End ; ;AN001;
474String_1200k_6 db "1.2MB" ,Asciiz_End ; ;AN001;
475String_1440k_1 db "1440" ,Asciiz_End ; ;AN001;
476String_1440k_2 db "1440K",Asciiz_End ; ;AN001;
477String_1440k_3 db "1440KB",Asciiz_End ; ;AN001;
478String_1440k_4 db "1.44",Asciiz_End ; ;AN001;
479String_1440k_5 db "1.44M",Asciiz_End ; ;AN001;
480String_1440k_6 db "1.44MB",Asciiz_End ; ;AN001;
481
482;
483;************************************************************************
484; PARSE Return Buffers
485;************************************************************************
486;
487
488Drive_Letter_Buffer Drive_Letter_Return <> ;Example of structure ;AN000;
489Switch_Buffer Switch_Return <> ; ;AN000;
490Switch_Num_Buffer Switch_Num_Return <> ; ;AN000;
491Switch_String_Buffer Switch_String_Return <> ; ;AN000;
492
493data ends
494
495;
496;*****************************************************************************
497; SysParse Routines
498;*****************************************************************************
499;
500
501
502code segment public para 'CODE'
503 assume cs:code,ds:Data
504
505FarSW equ Not_Include ;AN000;
506DateSW equ Not_Include ; ;AN000;
507TimeSW equ Not_Include ; ;AN000;
508FileSW equ Do_Include ; ;AN000;
509CAPSW equ Do_Include ; ;AN000;
510CmpxSW equ Not_Include ; ;AN000;
511NumSW equ Do_Include ; ;AN000;
512KeySW equ Not_Include ; ;AN000;
513SwSW equ Do_Include ; ;AN000;
514Val1SW equ DO_Include ; ;AN000;
515Val2SW equ Not_Include ; ;AN000;
516Val3SW equ Do_Include ; ;AN001;
517DrvSW equ Do_Include ; ;AN000;
518QusSW equ Do_Include ; ;AN000;
519
520INCLUDE PARSE.ASM ; ;AN000;
521
522
523code 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 @@
1; SCCSID = @(#)forproc.asm 1.2 85/07/25
2;
3.xlist
4.xcref
5BREAK MACRO subtitle
6 SUBTTL subtitle
7 PAGE
8ENDM
9
10 INCLUDE FORCHNG.INC
11 INCLUDE SYSCALL.INC
12 INCLUDE FOREQU.INC
13 INCLUDE FORMACRO.INC
14 INCLUDE FORSWTCH.INC
15 INCLUDE IOCTL.INC
16.cref
17.list
18data segment public para 'DATA'
19data ends
20
21code segment public para 'CODE'
22 assume cs:code,ds:data
23
24 PUBLIC FormatAnother?,Yes?,REPORT,USER_STRING
25 public fdsksiz,badsiz,syssiz,datasiz,biosiz
26 public AllocSize,AllocNum
27
28 extrn std_printf:near,crlf:near,PrintString:near
29 extrn Multiply_32_Bits:near
30 extrn AddToSystemSize:near
31
32data segment public para 'DATA'
33 extrn driveLetter:byte
34 extrn msgInsertDisk:byte
35 extrn msgFormatAnother?:byte
36 extrn msgTotalDiskSpace:byte
37 extrn msgSystemSpace:byte
38 extrn msgBadSpace:byte
39 extrn msgDataSpace:byte
40 extrn Read_Write_Relative:byte
41 extrn msgAllocSize:byte
42 extrn MsgAllocNum:Byte
43 extrn deviceParameters:byte
44 extrn bios:byte
45 extrn dos:byte
46 extrn command:byte
47 extrn Serial_Num_Low:Word
48 extrn Serial_Num_High:Word
49 extrn msgSerialNumber:Byte
50 extrn SwitchMap:Word
51
52
53 extrn inbuff:byte
54
55fdsksiz dd 0
56
57syssiz dd 0
58biosiz dd 0
59
60badsiz dd 0
61
62datasiz dd 0
63
64AllocSize dd 0 ; ;AN000;
65AllocNum dw 0 ; ;AN000;
66 dw offset driveLetter
67data ends
68
69FormatAnother? proc near
70; Wait for key. If yes return carry clear, else no. Insures
71; explicit Y or N answer.
72 Message msgFormatAnother? ; ;AC000;
73 CALL Yes?
74 JNC WAIT20
75 JZ WAIT20
76 CALL CRLF
77 JMP SHORT FormatAnother?
78WAIT20: ; ;AC000;
79 RET ; ;AC000;
80FormatAnother? endp
81
82;*****************************************************************************
83;Routine name:Yes?
84;*****************************************************************************
85;
86;Description: Validate that input is valid Y/N for the country dependent info
87; Wait for key. If YES return carry clear,else carry set.
88; If carry is set, Z is set if explicit NO, else key was not Yes or No.
89;
90;Called Procedures: Message (macro)
91; User_String
92;
93;Change History: Created 4/32/87 MT
94;
95;Input: None
96;
97;Output: CY = 0 Yes is entered
98; CY = 1, Z = No
99; CY = 1, NZ = other
100;
101;Psuedocode
102;----------
103;
104; Get input (CALL USER STRING)
105; IF got character
106; Check for country dependent Y/N (INT 21h, AX=6523h Get Ext Country)
107; IF Yes
108; clc
109; ELSE (No)
110; IF No
111; stc
112; Set Zero flag
113; ELSE (Other)
114; stc
115; Set NZ
116; ENDIF
117; ENDIF
118; ELSE (nothing entered)
119; stc
120; Set NZ flag
121; ENDIF
122; ret
123;*****************************************************************************
124
125Procedure YES? ; ;AN000;
126
127 call User_String ;Get character ; ;
128; $IF NZ ;Got one if returned NZ ;AC000;
129 JZ $$IF1
130 mov al,23h ;See if it is Y/N ;AN000;
131 mov dl,[InBuff+2] ;Get character ;AN000;
132 DOS_Call GetExtCntry ;Get country info call ;AN000;
133 cmp ax,Found_Yes ;Which one? ;AC000;
134; $IF E ;Got a Yes ;AC000;
135 JNE $$IF2
136 clc ;Clear CY for return ;AN000;
137; $ELSE ;Not a Yes ;AN000;
138 JMP SHORT $$EN2
139$$IF2:
140 cmp ax,Found_No ;Is it No? ;AC000;
141; $IF E ;Yep ;AN000;
142 JNE $$IF4
143 stc ;Set CY for return ;AC000;
144; $ELSE ;Something else we don't want ;AN000;
145 JMP SHORT $$EN4
146$$IF4:
147 xor al,al ;Set NZ flag for ret ;AC000;
148 cmp al,1 ; " " " " ;AC000;
149 stc ;And CY flag for good measure ;AN000;
150; $ENDIF ; ;AN000;
151$$EN4:
152; $ENDIF ; ;AN000;
153$$EN2:
154; $ELSE ;No char found at all ;AN000;
155 JMP SHORT $$EN1
156$$IF1:
157 xor al,al ;Set NZ flag for ret ;AN000;
158 cmp al,1 ; " " " " ;AN000;
159 stc ;And CY flag for good measure ;AN000;
160; $ENDIF ; ;AN000;
161$$EN1:
162 ret ; ; ;
163
164Yes? endp ; ;AN000;
165
166
167USER_STRING:
168; Get a string from user. Z is set if user typed no chars (imm CR)
169; We need to flush a second time to get rid of incoming Kanji characters also.
170 MOV AX,(STD_CON_INPUT_FLUSH SHL 8) + 0 ; Clean out input
171 INT 21H
172 MOV DX,OFFSET INBUFF
173 MOV AH,STD_CON_STRING_INPUT
174 INT 21H
175 MOV AX,(STD_CON_INPUT_FLUSH SHL 8) + 0 ; Clean out input
176 INT 21H
177 CMP BYTE PTR [INBUFF+1],0
178 RET
179
180;*********************************************
181; Make a status report including the following information:
182; Total disk capacity
183; Total system area used
184; Total bad space allocated
185; Total data space available
186; Number of allocation units
187; Size of allocation units
188
189REPORT:
190 call crlf
191
192 call Calc_System_Space ;an013; dms;calc system space
193 call Calc_Total_Addressible_Space ;an013; dms;calc total space
194
195 Message msgTotalDiskSpace ; ;AC000;
196 ;call std_printf
197 cmp WORD PTR SYSSIZ,0
198 JNZ SHOWSYS
199 cmp WORD PTR SYSSIZ+2,0
200 JZ CHKBAD
201SHOWSYS:
202 Message msgSystemSpace ; ;AC000;
203 ;CALL std_printf ;Report space used by system
204CHKBAD:
205 cmp WORD PTR BADSIZ,0
206 JNZ SHOWBAD
207 cmp WORD PTR BADSIZ+2,0
208 JZ SHOWDATA
209SHOWBAD:
210 Message msgBadSpace ; ;AC000;
211 ;call std_printf
212SHOWDATA:
213
214
215 MOV CX,WORD PTR Fdsksiz
216 MOV BX,WORD PTR Fdsksiz+2
217 SUB CX,WORD PTR BADSIZ
218 SBB BX,WORD PTR BADSIZ+2
219 SUB CX,WORD PTR SYSSIZ
220 SBB BX,WORD PTR SYSSIZ+2
221 MOV word ptr datasiz,CX
222 MOV word ptr datasiz+2,BX
223 Message msgDataSpace ; ;AC000;
224 ;call std_printf
225
226 call crlf ; ;AN000;
227 mov ax,deviceParameters.DP_BPB.BPB_BytesPerSector ; ;AN000;
228 mov cl,deviceParameters.DP_BPB.BPB_SectorsPerCluster ; ;AN000;
229 xor ch,ch ; ;AN000;
230 mul cx ;Get bytes per alloc ;AN000;
231
232 mov word ptr AllocSize,ax ;Save allocation size ;AN000;
233 mov word ptr AllocSize+2,dx ; for message ;AN000;
234 Message msgAllocSize ;Print size of cluster ;AN000;
235 call Get_Free_Space ;an013; dms;get disk space
236
237 mov word ptr AllocNum,bx ;Put result in msg ;AN000;
238 Message msgAllocNum ; = cluster/disk ;AN000;
239 call crlf ; ;AN000;
240 test switchmap, SWITCH_8 ;If 8 tracks, don't display ;AN027;
241 jnz NOSERIALNUMBER ;serial number ;AN027;
242 Message msgSerialNumber ;Spit out serial number ;AN000;
243 call crlf ;
244NOSERIALNUMBER: ;AN027;
245 RET ;
246
247;*****************************************************************************
248;Routine name: Read_Disk
249;*****************************************************************************
250;
251;description: Read in data using Generic IOCtl
252;
253;Called Procedures: None
254;
255;
256;Change History: Created 5/13/87 MT
257;
258;Input: AL = Drive number (0=A)
259; DS:BX = Transfer address
260; CX = Number of sectors
261; Read_Write_Relative.Start_Sector_High = Number of sectors high
262; DX = logical sector number low
263;
264;Output: CY if error
265; AH = INT 25h error code
266;
267;Psuedocode
268;----------
269; Save registers
270; Setup structure for function call
271; Read the disk (AX=440Dh, CL = 6Fh)
272; Restore registers
273; ret
274;*****************************************************************************
275
276Procedure Read_Disk ; ;AN000;
277
278 ;This is setup for INT 25h right;AN000;
279 ;Change it to Read relative sect;AN000;
280 push bx ;Save registers ;AN000;
281 push cx ; ;AN000;
282 push dx ; ;AN000;
283 push si ; ;AN000;
284 push di ; ;AN000;
285 push bp ; ;AN000;
286 push es ; ;AN000;
287 push ds ;
288 mov si,data ; ;AN000;
289 mov es,si ; ;AN000;
290
291 assume es:data,ds:nothing ; ;AN000;
292
293 mov es:Read_Write_Relative.Buffer_Offset,bx ;Get transfer buffer add;AN000;
294 mov bx,ds ; ;AN000;
295 mov es:Read_Write_Relative.Buffer_Segment,bx ;Get segment ;AN000;
296 mov bx,data ;Point DS at parameter list ;AN000;
297 mov ds,bx ; ;AN000;
298
299 assume ds:data,es:data
300
301 mov Read_Write_Relative.Number_Sectors,cx ;Number of sec to read ;AN000;
302 mov Read_Write_Relative.Start_Sector_Low,dx ;Start sector ;AN000;
303 mov bx,offset Read_Write_Relative ; ;AN000;
304 mov cx,0FFFFh ;Read relative sector ;AN000;
305 INT 25h ;Do the read ;AN000;
306 pop dx ;Throw away flags on stack ;AN000;
307 pop ds ;
308 pop es ; ;AN000;
309 pop bp ; ;AN000;
310 pop di ; ;AN000;
311 pop si ; ;AN000;
312 pop dx ;Restore registers ;AN000;
313 pop cx ; ;AN000;
314 pop bx ; ;AN000;
315 ret ; ;AN000;
316
317
318Read_Disk endp ; ;AN000;
319
320;*****************************************************************************
321;Routine name: Write_Disk
322;*****************************************************************************
323;
324;description: Write Data using Generic IOCtl
325;
326;Called Procedures: None
327;
328;
329;Change History: Created 5/13/87 MT
330;
331;Input: AL = Drive number (0=A)
332; DS:BX = Transfer address
333; CX = Number of sectors
334; Read_Write_Relative.Start_Sector_High = Number of sectors high
335; DX = logical sector number low
336;
337;Output: CY if error
338; AH = INT 26h error code
339;
340;Psuedocode
341;----------
342; Save registers
343; Setup structure for function call
344; Write to disk (AX=440Dh, CL = 4Fh)
345; Restore registers
346; ret
347;*****************************************************************************
348
349Procedure Write_Disk ; ;AN000;
350
351
352 ;This is setup for INT 26h right
353 ;Change it to Read relative sect
354
355 push bx ;Save registers ;AN000;
356 push cx ; ;AN000;
357 push dx ; ;AN000;
358 push si ; ;AN000;
359 push di ; ;AN000;
360 push bp ; ;AN000;
361 push es ; ;AN000;
362 push ds ;
363 mov si,data ; ;AN000;
364 mov es,si ; ;AN000;
365
366 assume es:data,ds:nothing ; ;AN000;
367
368 mov es:Read_Write_Relative.Buffer_Offset,bx ;Get transfer buffer add;AN000;
369 mov bx,ds ; ;AN000;
370 mov es:Read_Write_Relative.Buffer_Segment,bx ;Get segment ;AN000;
371 mov bx,data ;Point DS at parameter list ;AN000;
372 mov ds,bx ; ;AN000;
373
374 assume ds:data,es:data
375
376 mov Read_Write_Relative.Number_Sectors,cx ;Number of sec to write ;AN000;
377 mov Read_Write_Relative.Start_Sector_Low,dx ;Start sector ;AN000;
378 mov bx,offset Read_Write_Relative ; ;AN000;
379 mov cx,0FFFFh ;Write relative sector ;AN000;
380 INT 26h ;Do the write ;AN000;
381 pop dx ;Throw away flags on stack ;AN000;
382 pop ds ; ;AN000;
383 pop es ; ;AN000;
384 pop bp ; ;AN000;
385 pop di ; ;AN000;
386 pop si ; ;AN000;
387 pop dx ;Restore registers ;AN000;
388 pop cx ; ;AN000;
389 pop bx ; ;AN000;
390 ret ; ;AN000;
391
392Write_Disk endp ; ;AN000;
393
394;=========================================================================
395; Calc_Total_Addressible_Space : Calculate the total space that is
396; addressible on the the disk by DOS.
397;
398; Inputs : none
399;
400; Outputs : Fdsksiz - Size in bytes of the disk
401;=========================================================================
402
403Procedure Calc_Total_Addressible_Space ;an013; dms;
404
405 push ax ;an013; dms;save affected regs
406 push dx ;an013; dms;
407 push bx ;an013; dms;
408
409 call Get_Free_Space ;an013; dms;get free disk space
410
411 push bx ;an013; dms;save avail. cluster
412 push dx ;an013; dms;save total. cluster
413
414 mov ax,dx ;an013; dms;get total clusters
415
416 xor bx,bx ;an013; dms;clear bx
417 xor cx,cx ;an013; dms;clear cx
418 mov cl,DeviceParameters.DP_BPB.BPB_SectorsPerCluster ;an013; dms;get total sectors
419 call Multiply_32_Bits ;an013; dms;multiply
420
421 xor cx,cx ;an013; dms;clear cx
422 mov cx,DeviceParameters.DP_BPB.BPB_BytesPerSector ;an013; dms;get total bytes
423 call Multiply_32_Bits ;an013; dms; multiply
424
425 mov word ptr Fdsksiz,ax ;an013; dms;save high word
426 mov word ptr Fdsksiz+2,bx ;an013; dms;save low word
427
428 pop dx ;an000; dms;get total clusters
429 pop bx ;an000; dms;get avail clusters
430
431 mov ax,dx ;an013; dms;get total clusters
432 sub ax,bx ;an013; dms;get bad clusters
433
434 xor bx,bx ;an013; dms;clear bx
435 xor cx,cx ;an013; dms;clear cx
436 mov cl,DeviceParameters.DP_BPB.BPB_SectorsPerCluster ;an013; dms;get total sectors
437 call Multiply_32_Bits ;an013; dms;multiply
438
439 xor cx,cx ;an013; dms;clear cx
440 mov cx,DeviceParameters.DP_BPB.BPB_BytesPerSector ;an013; dms;get total bytes
441 call Multiply_32_Bits ;an013; dms; multiply
442
443 sub ax,word ptr syssiz ;an013; dms;account for system
444 sbb bx,word ptr syssiz+2 ;an013; dms;size
445
446 mov word ptr Badsiz,ax ;an013; dms;save high word
447 mov word ptr Badsiz+2,bx ;an013; dms;save low word
448
449 pop bx ;an013; dms;
450 pop dx ;an013; dms;restore regs
451 pop ax ;an013; dms;
452
453 ret ;an013; dms;
454
455Calc_Total_Addressible_Space endp ;an013; dms;
456
457
458;=========================================================================
459; Get_Free_Space : Get the free space on the disk.
460;
461; Inputs : none
462;
463; Outputs : BX - Available space in clusters
464; DX - Total space in clusters
465;=========================================================================
466
467Procedure Get_Free_Space ;an013; dms;
468
469 xor ax,ax ;an013; dms;clear ax
470 mov ah,36h ;an013; dms;Get disk free space
471 mov dl,driveletter ;an013; dms;get drive letter
472 sub dl,"A" ;an013; dms;get 0 based number
473 inc dl ;an013; dms;make it 1 based
474 int 21h ;an013; dms;
475 ret ;an013; dms;
476
477Get_Free_Space endp ;an013; dms;
478
479;=========================================================================
480; Calc_System_Space : This routine calculates the space occupied by
481; the system on the disk.
482;
483; Inputs : DOS.FileSizeInBytes
484; BIOS.FileSizeInBytes
485; Command.FileSizeInBytes
486;
487; Outputs : SysSiz - Size of the system
488;=========================================================================
489
490Procedure Calc_System_Space ;an013; dms;
491
492 push ax ;an013; dms;save regs
493 push dx ;an013; dms;
494
495 mov word ptr SysSiz+0,00h ;an013; dms;clear variable
496 mov word ptr SysSiz+2,00h ;an013; dms;
497
498 mov ax,word ptr [DOS.FileSizeInBytes+0] ;an013; dms;get low word
499 mov dx,word ptr [DOS.FileSizeInBytes+2] ;an013; dms;get high word
500 call AddToSystemSize ;an013; dms;add in values
501
502 mov ax,word ptr [BIOS.FileSizeInBytes+0] ;an013; dms;get bios size
503 mov dx,word ptr [BIOS.FileSizeInBytes+2] ;an013; dms;
504 call AddToSystemSize ;an013; dms;add in values
505
506 mov ax,word ptr [COMMAND.FileSizeInBytes+0] ;an013; dms;get command size
507 mov dx,word ptr [COMMAND.FileSizeInBytes+2] ;an013; dms;
508 call AddToSystemSize ;an013; dms;add in values
509
510 pop dx ;an013; dms;restore regs
511 pop ax ;an013; dms;
512
513 ret ;an013; dms;
514
515Calc_System_Space endp ;an013; dms;
516
517
518
519code ends
520 end
521 \ 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 @@
1;
2;FORMAT Pre-defined switches
3 SWITCH_S EQU 0001h ; System transfer
4 SWITCH_V EQU 0002h ; Volume ID prompt
5 SWITCH_BACKUP EQU 0004h
6 SWITCH_C EQU 0008h
7 SWITCH_T EQU 0010h
8 SWITCH_N EQU 0020h
9 SWITCH_1 EQU 0040h
10 SWITCH_4 EQU 0080h
11 SWITCH_8 EQU 0100h
12 SWITCH_B EQU 0200h
13 SWITCH_SELECT EQU 0400h
14 SWITCH_AUTOTEST EQU 0800h
15 SWITCH_F EQU 1000h
16 SWITCH_FS EQU 2000h
17
18IF ShipDisk
19
20 SWITCH_Z EQU 4000h ;an000; dms;1 sector/cluster switch
21
22ENDIF
23
24;
25; The following is a list of equates to define each IBM defined diskette size
26; for use with the /F switch
27
28
29Size_160 equ 0001h ;Flag settings for size switch ;AN000;
30Size_180 equ 0002h ; ;AN000;
31Size_320 equ 0004h ; ;AN000;
32Size_360 equ 0008h ; ;AN000;
33Size_720 equ 0010h ; ;AN000;
34Size_1200 equ 0020h ; ;AN000;
35Size_1440 equ 0040h ; ;AN000;
36
37
38
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 @@
1#************************ makefile for cmd\format *************************
2
3msg =..\..\messages
4dos =..\..\dos
5inc =..\..\inc
6hinc =..\..\h
7boot =..\..\boot
8
9#
10####################### dependencies begin here. #########################
11#
12
13all: format.com
14
15boot.cl1:
16 copy $(boot)\boot.cl1
17
18format.ctl: format.skl $(msg)\$(COUNTRY).msg
19
20display.obj: display.asm forequ.inc formsg.inc formacro.inc makefile \
21 format.ctl format.cl1 format.cl2 format.cla $(inc)\sysmsg.inc \
22 $(inc)\msgserv.asm \
23 format.clb format.clc formacro.inc
24
25forexec.obj: forexec.asm forequ.inc makefile $(inc)\syscall.inc \
26 formacro.inc
27
28forlabel.obj: forlabel.asm forequ.inc formacro.inc makefile \
29 $(inc)\syscall.inc $(inc)\ioctl.inc $(inc)\dosmac.inc \
30 forswtch.inc
31
32format.obj: format.asm $(inc)\dosmac.inc $(inc)\bpb.inc \
33 $(inc)\dirent.inc $(inc)\dpb.inc $(inc)\curdir.inc \
34 $(inc)\cpmfcb.inc $(inc)\pdb.inc makefile \
35 $(inc)\error.inc $(inc)\syscall.inc $(inc)\ioctl.inc \
36 forequ.inc formacro.inc forswtch.inc
37
38forinit.obj: forinit.asm forequ.inc formacro.inc makefile \
39 $(inc)\syscall.inc $(inc)\ioctl.inc forparse.inc \
40 forswtch.inc $(inc)\parse.asm $(inc)\psdata.inc
41
42msfor.obj: msfor.asm $(inc)\dosmac.inc $(inc)\syscall.inc $(inc)\bpb.inc \
43 $(inc)\dirent.inc boot.cl1 $(inc)\ioctl.inc \
44 $(inc)\boot.inc $(inc)\boot11.inc makefile \
45 $(inc)\bootform.inc filesize.inc forequ.inc formacro.inc forswtch.inc
46
47forproc.obj: forproc.asm $(inc)\syscall.inc makefile forequ.inc \
48 formacro.inc forswtch.inc
49
50
51format.com: format.obj forproc.obj msfor.obj forexec.obj display.obj \
52 forinit.obj forlabel.obj
53 link @format.lnk
54 convert format.exe
55 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 @@
1; e forproc.sal= @(#)ibmfor.asm 1.28 85/10/15
2 name OemFormatRoutines
3;
4;******************************************************************************
5;AN001 - ???
6;AN002 - D304 Modify Boot record structure for OS2 11/09/87 J.K.
7;******************************************************************************
8
9INCLUDE FORCHNG.INC
10debug equ 0
11;-------------------------------------------------------------------------------
12; Public for debugging only
13
14 public CheckSwitches
15 public LastChanceToSaveIt
16 public WriteBootSector
17 public OemDone
18 public WriteBogusDos
19 public ConvertToOldDirectoryFormat
20 public SetPartitionTable
21 public ReadSector
22 public WriteSector
23 public SectorIO
24 public GetVolumeId
25
26 public customBPBs
27 public NotSlashB
28 public NotSingleSided
29 public EndSwitchCheck
30 public WeCanNotIgnoreThisError
31 public HardDisk?
32 public BogusDos
33 public sys_mess_loop
34 public end_sys_loop
35 public DirectoryRead
36 public wrtdir
37 public DirectoryWritten
38 public FCBforVolumeIdSearch
39 public CopyVolumeId
40 public CompareVolumeIds
41 public BadVolumeId
42
43 public boot2
44 public boot
45 public scratchBuffer
46 public biosFilename
47 public dosFilename
48 public oldDrive
49 public oldVolumeId
50 public Read_Write_Relative
51 public Serial_Num_Low
52 public Serial_Num_High
53 public SizeMap
54
55 public ptr_msgWhatIsVolumeId?
56
57 public trackReadWritePacket
58
59 public BPB81
60 public BPB82
61 public BPB91
62 public BPB92
63
64;-------------------------------------------------------------------------------
65
66data segment public para 'DATA'
67data ends
68
69code segment public para 'CODE'
70 assume cs:code,ds:data
71
72 Public AccessDisk
73 public CheckSwitches
74 public LastChanceToSaveIt
75 public OemDone
76 public BiosFile
77 public DosFile
78
79data segment public para 'DATA'
80 extrn AddToSystemSize:near
81 extrn currentCylinder:word
82 extrn currentHead:word
83 extrn deviceParameters:byte
84 extrn drive:byte
85 extrn driveLetter:byte
86 extrn fBigFAT:byte
87 extrn inbuff:byte
88 extrn switchmap:word
89 extrn Old_Dir:byte
90 extrn fLastChance:byte
91 extrn Fatal_Error:Byte
92 extrn Bios:Byte
93 extrn Dos:Byte
94 extrn Command:Byte
95
96 extrn msgBad_T_N:byte
97 extrn msgBadVolumeId:byte
98 extrn msgBadPartitionTable:byte
99 extrn msgBootWriteError:byte
100 extrn msgDirectoryReadError:byte
101 extrn msgDirectoryWriteError:byte
102 extrn msgInvalidParameter:byte
103 extrn msgIncompatibleParameters:byte
104 extrn msgIncompatibleParametersForHardDisk:byte
105 extrn msgParametersNotSupportedByDrive:byte
106 extrn msgPartitionTableReadError:byte
107 extrn msgPartitionTableWriteError:byte
108 extrn msgWhatIsVolumeId?:byte
109 extrn NumSectors:word, TrackCnt:word
110
111IF DEBUG
112 extrn msgFormatBroken:byte
113ENDIF
114
115data ends
116
117 extrn PrintString:near
118 extrn std_printf:near
119 extrn crlf:near
120 extrn user_string:near
121 extrn Read_Disk:near
122 extrn Write_Disk:near
123
124
125;-------------------------------------------------------------------------------
126; Constants
127
128.xlist
129INCLUDE DOSMAC.INC
130INCLUDE FORMACRO.INC
131INCLUDE FOREQU.INC
132INCLUDE FORSWTCH.INC
133
134; This defines all the int 21H system calls
135INCLUDE SYSCALL.INC
136
137; Limits
138
139INCLUDE filesize.inc
140
141;-------------------------------------------------------------------------------
142; These are the data structures which we will need
143
144INCLUDE DIRENT.INC
145INCLUDE ioctl.INC
146INCLUDE version.inc
147
148.list
149
150;-------------------------------------------------------------------------------
151; And this is the actual data
152data segment public para 'DATA'
153
154Read_Write_Relative Relative_Sector_Buffer <> ; ;AN000;
155
156
157 IF IBMCOPYRIGHT
158BiosFile db "x:\IBMBIO.COM", 0
159DosFile db "x:\IBMDOS.COM", 0
160 ELSE
161BiosFile db "x:\IO.SYS", 0
162DosFile db "x:\MSDOS.SYS", 0
163 ENDIF
164
165Dummy_Label db "NO NAME "
166Dummy_Label_Size dw 11 ;AN028
167
168Serial_Num_Low dw 0 ; ;AN000;
169Serial_Num_High dw 0 ; ;AN000;
170
171SizeMap db 0 ; ;AN000;
172
173trackReadWritePacket a_TrackReadWritePacket <>
174
175
176; BIOS parameter blocks for various media
177customBPBs label byte
178BPB92 a_BPB <512, 2, 1, 2, 112, 2*9*40, 0fdH, 2, 9, 2, 0, 0, 0, 0>
179BPB91 a_BPB <512, 1, 1, 2, 64, 1*9*40, 0fcH, 2, 9, 1, 0, 0, 0, 0>
180BPB82 a_BPB <512, 2, 1, 2, 112, 2*8*40, 0ffH, 1, 8, 2, 0, 0, 0, 0>
181BPB81 a_BPB <512, 1, 1, 2, 64, 1*8*40, 0feH, 1, 8, 1, 0, 0, 0, 0>
182BPB720 a_BPB <512, 2, 1, 2, 112, 2*9*80, 0F9h, 3, 9, 2, 0, 0, 0, 0>
183
184
185
186boot2 db 0,0,0, "Boot 1.x"
187 db 512 - 11 dup(?)
188
189REORG2 LABEL BYTE
190 ORG BOOT2
191 INCLUDE BOOT11.INC
192 ORG REORG2
193
194
195
196INCLUDE BOOTFORM.INC
197
198
199BOOT LABEL BYTE
200 INCLUDE BOOT.INC
201
202scratchBuffer db 512 dup(?)
203
204ptr_msgWhatIsVolumeId? dw offset msgWhatIsVolumeId?
205 dw offset driveLetter
206
207
208FAT12_String db "FAT12 "
209FAT16_String db "FAT16 "
210
211Media_ID_Buffer Media_ID <>
212
213
214data ends
215;-------------------------------------------------------------------------------
216; AccessDisk:
217; Called whenever a different disk is about to be accessed
218;
219; Input:
220; al - drive letter (0=A, 1=B, ...)
221;
222; Output:
223; none
224AccessDisk proc near
225
226 push ax ; save drive letter
227 mov bl,al ; Set up GENERIC IOCTL REQUEST preamble
228 inc bl
229 mov ax,(IOCTL SHL 8) + Set_Drv_Owner ; IOCTL function
230 int 21h
231 pop ax
232 return
233
234AccessDisk endp
235
236;-------------------------------------------------------------------------------
237; CheckSwitches:
238; Check switches against device parameters
239; Use switches to modify device parameters
240;
241; Input:
242; deviceParameters
243;
244; Output:
245; deviceParameters may be modified
246; Carry set if error
247;
248;
249; /B <> /S
250; /B/8 <> /V
251; /1 or /8 <> /T/N
252;
253
254
255Public CHeckSwitches
256CheckSwitches proc near
257
258
259; Disallow /C
260 ;lea dx, msgInvalidParameter ;AC000;
261 test switchmap, SWITCH_C
262 jz CheckExcl
263 Message msgInvalidParameter ;AC000;
264SwitchError:
265 ;call PrintString ;AC000;
266 stc
267 ret
268
269CheckExcl:
270
271 test SwitchMap,Switch_F ;Specify size? ;AN001;
272; $IF NZ ;Yes ;AN001;
273 JZ $$IF1
274 test SwitchMap,(Switch_1+Switch_8+Switch_4+Switch_N+Switch_T) ;AN001;
275; $IF NZ ;/F replaces above switches ;AN001;
276 JZ $$IF2
277 Message msgIncompatibleParameters ;Print error ;AN001;
278 mov Fatal_Error,Yes ;Force exit ;AN001;
279; $ELSE ; ;AN001;
280 JMP SHORT $$EN2
281$$IF2:
282 call Size_To_Switch ;Go set switches based ;AN001;
283; $ENDIF ; on the size ;AN001;
284$$EN2:
285; $ENDIF ; ;AN001;
286$$IF1:
287 cmp Fatal_Error,NO ; ;AN007;
288; $IF E ; ;AN007;
289 JNE $$IF6
290 call Check_Switch_8_B ; ;ac007
291 call Check_T_N
292; $ENDIF ; ;AN009;
293$$IF6:
294 cmp Fatal_Error,Yes ; ;AN007;
295 jne ExclChkDone ; ;AN007;
296 stc ; ;AN007;
297 ret ; ;AN007;
298
299ExclChkDone:
300; Patch the boot sector so that the boot strap loader knows what disk to
301; boot from
302; mov Boot.Boot_PhyDrv, 00H ;AC000;
303 mov Boot.EXT_PHYDRV, 00H ;AN00?;
304
305 cmp deviceParameters.DP_DeviceType, DEV_HARDDISK
306 jne CheckFor5InchDrives
307
308; Formatting a hard disk so we must repatch the boot sector
309; mov Boot.Boot_PhyDrv, 80H ;AC000;
310 mov Boot.EXT_PHYDRV, 80H ;AN00?;
311 test switchmap, not (SWITCH_S or SWITCH_V or SWITCH_Select or SWITCH_AUTOTEST or Switch_B) ;AN007;
312 jz SwitchesOkForHardDisk
313
314 Message msgIncompatibleParametersForHardDisk ; ;AC000;
315 stc
316 ret
317
318; Before checking the Volume Id we need to verify that a valid one exists
319; We assume that unless a valid boot sector exists on the target disk, no
320; valid Volume Id can exist.
321
322SwitchesOkForHardDisk:
323 SaveReg <ax,bx,cx,dx,ds>
324 mov al,drive
325 mov cx,LogBootSect
326 xor dx,dx
327 lea bx,scratchBuffer ; ScratchBuffer := Absolute_Read_Disk(
328 ;INT 25h ; Logical_sec_1 )
329
330 ;Assume Dir for vol ID exists in 1st 32mb of partition
331
332 mov Read_Write_Relative.Start_Sector_High,0
333 call Read_Disk ; ;AC000;
334 ; on the stack. We throw them away
335
336 jnc CheckSignature
337 stc
338 RestoreReg <ds,dx,cx,bx,ax>
339 ret
340
341CheckSignature: ; IF (Boot.Boot_Signature != aa55)
342
343 mov ax, word ptr ScratchBuffer.Boot_Signature ;AC000;
344 cmp ax, 0aa55h ;Find a valid boot record?
345 RestoreReg <ds,dx,cx,bx,ax>
346 clc ;No, so no need to check label
347; $IF Z ;No further checking needed ;AC000;
348 JNZ $$IF8
349 test SwitchMap,(SWITCH_Select or SWITCH_AUTOTEST) ;Should we prompt for vol label?;AN000;
350; $IF Z ;Yes, if /Select not entered ;AN000;
351 JNZ $$IF9
352 call CheckVolumeId ;Go ask user for vol label ; ;
353; $ELSE ;/Select entered ;AN000;
354 JMP SHORT $$EN9
355$$IF9:
356 clc ;CLC indicates passed label test;AN000;
357; $ENDIF ; for the return ;AN000;
358$$EN9:
359; $ENDIF
360$$IF8:
361 return
362
363Incomp_Message: ;an000; fix PTM 809
364
365 Message msgIncompatibleParameters ;an000; print incompatible parms
366 stc ;an000; signal error
367 return ;an000; return to caller
368
369Print_And_Return:
370 ;call PrintString ; ;AC000;
371 stc
372 return
373
374
375CheckFor5InchDrives:
376
377 ;If drive type is anything other than 48 or 96, then only /V/S/H/N/T allowed
378 cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH96TPI
379 je Got96
380
381 cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH
382 je Got48
383
384 xor ax,ax ;an000; dms;clear reg
385 or ax,(Switch_V or Switch_S or Switch_N or Switch_T or Switch_B) ;an000; dms;set up switch mask
386 or ax,(Switch_Backup or Switch_Select or Switch_Autotest) ;an000; dms;
387IF ShipDisk
388 or ax,Switch_Z ;an000; dms;
389ENDIF
390 not ax ;an000; dms;
391 test switchmap,ax ;an000; dms;invalid switch?
392 jz Goto_Got_BPB1 ;an000;dms;continue format
393 Message msgParametersNotSupportedByDrive ; ;AC000;
394 jmp short Print_And_Return
395
396Goto_Got_BPB1:
397 jmp Goto_Got_BPB
398 ; We have a 96tpi floppy drive
399 ; /4 allows just about all switches however, /1 requires /4
400Got96:
401;;;DMS;;test switchmap, SWITCH_8 ;an000; If /8 we have an error
402;;;DMS;;jnz Incomp_message ;an000; tell user error
403
404 test switchmap, SWITCH_4
405 jnz CheckForInterestingSwitches ;If /4 check /N/T/V/S
406
407 test switchmap, SWITCH_1 ;If /1 and /4 check others
408 jz Got48
409
410 ;If only /1 with no /4, see if /N/T
411 test SwitchMap,(Switch_N or Switch_T)
412 jnz CheckForInterestingSwitches
413
414 jmp Incomp_message ;an000; tell user error occurred
415
416Got48:
417 ;Ignore /4 for non-96tpi 5 1/4" drives
418 and switchmap, not SWITCH_4
419
420 ;Ignore /1 if drive has only one head and not /8
421 cmp word ptr deviceParameters.DP_BPB.BPB_Heads, 1
422 ja CheckForInterestingSwitches
423 test switchmap, SWITCH_8
424 jz CheckForInterestingSwitches
425 and switchmap, not SWITCH_1
426
427 ;Are any interesting switches set?
428CheckForInterestingSwitches:
429 test switchmap, not (SWITCH_V or SWITCH_S or Switch_Backup or SWITCH_SELECT or SWITCH_AUTOTEST or Switch_B)
430 jz Goto_EndSwitchCheck ;No, everything ok
431
432 ;At this point there are switches other than /v/s/h
433 test SwitchMap,(SWITCH_N or SWITCH_T)
434 jz Use_48tpi ;Not /n/t, so must be /b/1/8/4
435
436 ;We've got /N/T, see if there are others
437 test SwitchMap, not (SWITCH_N or SWITCH_T or SWITCH_V or SWITCH_S or Switch_Backup or SWITCH_SELECT or SWITCH_AUTOTEST)
438 jz NT_Compatible ;Nope, all is well
439
440 ;If 96tpi drive and /1 exists with /N/T, then okay, otherwise error
441 cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH96TPI
442 jne Bad_NT_Combo
443
444 test SwitchMap, not (SWITCH_1 or SWITCH_N or SWITCH_T or SWITCH_V)
445 jnz Bad_NT_Combo
446 test SwitchMap, not (SWITCH_S or Switch_Backup or SWITCH_SELECT or Switch_Autotest)
447 jz Goto_Got_BPB
448
449Bad_NT_Combo:
450 Message msgIncompatibleParameters ; ;AC000;
451 jmp Print_And_Return
452
453Goto_Got_BPB:
454 jmp Got_BPB_Ok ;Sleazy, but je won't reach it
455
456Goto_EndSwitchCheck:
457 jmp EndSwitchCheck
458 ;There is a problem with /N/T in that IBMBIO will default to a BPB with the
459 ;media byte set to F0 (other) if the /N/T combo is used for the format. This
460 ;will cause problems if we are creating a media that has an assigned media
461 ;byte, i.e. 160,180,320,360, or 720k media using /N/T. To avoid this problem,
462 ;if we detect a /N/T combo that would correspond to one of these medias, then
463 ; we will set things up using the /4/1/8 switches instead of the /N/T
464 ; MT - 7/17/86 PTR 33D0110
465
466 ; Combo's that we look for - 96tpi drive @ /T:40, /N:9
467 ; 96tpi drive @ /T:40, /N:8
468 ;
469 ; Look for this combo after we set everything up with the /T/N routine
470 ; 1.44 drive @ /T:80, /N:9
471
472NT_Compatible:
473 cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH96TPI
474 jne Goto_Got_BPB
475
476 cmp TrackCnt,40 ;Look for 40 tracks
477 jne Got_BPB_Ok
478
479 cmp NumSectors,9 ;9 sectors?
480 je Found_48tpi_Type
481
482 cmp NumSectors,8 ;8 sectors?
483 jne Goto_Got_BPB ;Nope, different type, let it go thru
484
485 or SwitchMap,SWITCH_8 ;Yes, turn on /8 switch
486
487Found_48tpi_Type:
488 and SwitchMap,not (SWITCH_N or SWITCH_T) ;Turn off /T/N
489
490;******End PTR fix
491
492; if we have a 96 tpi drive then we will be using it in 48 tpi mode
493Use_48tpi:
494 cmp byte ptr deviceParameters.DP_DeviceType, DEV_5INCH96TPI
495 jne Not96tpi
496
497 mov byte ptr deviceParameters.DP_MediaType, 1
498 mov word ptr deviceParameters.DP_Cylinders, 40
499Not96tpi:
500
501; Since we know we are formatting in 48 tpi mode turn on /4 switch
502; (We use this info in LastChanceToSaveIt)
503 or switchmap, SWITCH_4
504
505; At this point we know that we will require a special BPB
506; It will be one of:
507; 0) 9 track 2 sides - if no switches
508; 1) 9 track 1 side - if only /1 specified
509; 2) 8 track 2 sides - if only /8 specified
510; 3) 8 track 1 side - if /8 and /1 specified
511;
512Get_BPBs:
513; ax is used to keep track of which of the above BPB's we want
514 xor ax, ax
515
516NotSlashB:
517
518 test switchmap, SWITCH_1
519 jz NotSingleSided
520 add ax, 1
521NotSingleSided:
522
523 test switchmap, SWITCH_8
524 jz Not8SectorsPerTrack
525 add ax, 2
526; /8 implies Old_Dir = TRUE
527 mov Old_Dir,TRUE
528Not8SectorsPerTrack:
529
530; Ok now we know which BPB to use so lets move it to the device parameters
531
532 mov bx, size a_BPB
533 mul bx
534 lea si, CustomBPBs
535 add si, ax
536 lea di, deviceParameters.DP_BPB
537 mov cx, size a_BPB
538 push ds
539 pop es
540 repnz movsb
541
542;*****************************************************************
543;* /N/T DCR stuff. Possible flaw exists if we are dealing with a
544;* HardDisk. If they support the "custom format" features for
545;* Harddisks too, then CheckForInterestingSwitches should
546;* consider /n/t UNinteresting, and instead of returning
547;* after setting up the custom BPB we fall through and do our
548;* Harddisk Check.
549Got_BPB_OK:
550 test switchmap,SWITCH_N+SWITCH_T
551 jnz Setup_Stuff
552 jmp EndSwitchCheck
553Setup_Stuff:
554; Set up NumSectors and SectorsPerTrack entries correctly
555 test switchmap,SWITCH_N
556 jz No_Custom_Seclim
557 mov ax,word ptr NumSectors
558 mov DeviceParameters.DP_BPB.BPB_SectorsPerTrack,ax
559 jmp short Handle_Cyln
560No_Custom_Seclim:
561 mov ax,deviceParameters.DP_BPB.BPB_SectorsPerTrack
562 mov NumSectors,ax
563
564Handle_Cyln:
565 test switchmap,SWITCH_T
566 jz No_Custom_Cyln
567; Set up TrackCnt and Cylinders entries correctly
568 mov ax,TrackCnt
569 mov DeviceParameters.DP_Cylinders,ax
570 jmp short Check_720
571No_Custom_Cyln:
572 mov ax,DeviceParameters.DP_Cylinders
573 mov TrackCnt,ax
574
575;****PTM P868 - Always making 3 1/2 media byte 0F0h. If 720, then set to
576; 0F9h and use the DOS 3.20 BPB. Should check all drives
577; at this point (Make sure not 5 inch just for future
578; protection)
579; We will use the known BPB info for 720 3 1/2 diskettes for
580; this special case. All other new diskette media will use the
581; calculations that follow Calc_Total for BPB info.
582; Fix MT 11/12/86
583
584Check_720:
585
586 cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH96TPI
587 je Calc_Total
588
589 cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH
590 je Calc_Total
591
592 cmp TrackCnt,80
593 jne Calc_Total
594
595 cmp NumSectors,9
596 jne Calc_Total
597
598; At this point we know we have a 3 1/2 720kb diskette to format. Use the
599; built in BPB rather than the one handed to us by DOS, because the DOS one
600; will be based on the default for that drive, and it can be different from
601; what we used in DOS 3.20 for the 720's. Short sighted on our part to use
602; 0F9h as the media byte, should have use 0F0h (OTHER) and then we wouldn't
603; have this problem.
604
605 SaveReg <ds,es,si,di,cx>
606
607
608 mov cx,seg data ;Setup seg regs, just in case they ain't!
609 mov ds,cx
610 mov es,cx
611
612 mov si,offset BPB720 ;Copy the BPB!
613 mov di,offset deviceParameters.DP_BPB
614 mov cx,size a_BPB
615 rep movsb
616 RestoreReg <cx,di,si,es,ds>
617 jmp EndSwitchCheck
618
619;End PTM P868 fix ****************************************
620
621Calc_Total:
622 mov ax,NumSectors
623 mov bx,DeviceParameters.DP_BPB.BPB_Heads
624 mul bl ; AX = # of sectors * # of heads
625 mul TrackCnt ; DX:AX = Total Sectors
626 or dx,dx
627 jnz Got_BigTotalSectors
628 mov DeviceParameters.DP_BPB.BPB_TotalSectors,ax
629 jmp short Set_BPB
630Got_BigTotalSectors:
631 mov DeviceParameters.DP_BPB.BPB_BigTotalSectors,ax
632 mov DeviceParameters.DP_BPB.BPB_BigTotalSectors+2,dx
633 push dx ; preserve dx for further use
634 xor dx,dx
635 mov DeviceParameters.DP_BPB.BPB_TotalSectors,dx
636 pop dx
637
638Set_BPB:
639; We calculate the number of sectors required in a FAT. This is done as:
640; # of FAT Sectors = TotalSectors / SectorsPerCluster * # of bytes in FAT to
641; represent one cluster (i.e. 3/2) / BytesPerSector (i.e. 512)
642 xor bx,bx
643 mov bl,DeviceParameters.DP_BPB.BPB_SectorsPerCluster
644 div bx ; DX:AX contains # of clusters
645; now multiply by 3/2
646 mov bx,3
647 mul bx
648 mov bx,2
649 div bx
650 xor dx,dx ; throw away modulo
651; now divide by 512
652 mov bx,512
653 div bx
654; dx:ax contains number of FAT sectors necessary
655 inc ax ; Go one higher
656 mov DeviceParameters.DP_BPB.BPB_SectorsPerFAT,ax
657 mov DeviceParameters.DP_MediaType,0
658 mov DeviceParameters.DP_BPB.BPB_MediaDescriptor,Custom_Media
659
660
661EndSwitchCheck:
662 clc
663 return
664
665CheckSwitches endp
666
667;*****************************************************************************
668;Routine name: Size_To_Switch
669;*****************************************************************************
670;
671;Description: Given the SizeMap field as input indicating the SIZE= value
672; entered, validate that the specified size is valid for the
673; drive, and if so, turn on the appropriate data fields and
674; switches that would be turned on by the equivilent command line
675; using only switchs. All defined DOS 4.00 sizes are hardcoded,
676; in case a drive type of other is encountered that doesn't
677; qualify as a DOS 4.00 defined drive. Exit with error message if
678; unsupported drive. The switches will be setup for the CheckSwitches
679; routine to sort out, using existing switch matrix logic.
680;
681;Called Procedures: Low_Density_Drive
682; High_Capacity_Drive
683; 720k_Drives
684; Other_Drives
685;
686;Change History: Created 8/1/87 MT
687;
688;Input: SizeMap
689; Fatal_Error = NO
690;
691;Output: Fatal_Error = YES/NO
692; SwitchMap = appropriate Switch_?? values turned on
693; TrackCnt, NumSectors set if Switch_T,Switch_N turned on
694;*****************************************************************************
695
696
697Procedure Size_To_Switch
698
699 cmp SizeMap,0 ;Are there sizes entered? ;AN001;
700; $IF NE ;Yes ;AN001;
701 JE $$IF13
702 cmp deviceParameters.DP_DeviceType,DEV_HARDDISK ;AN000; ;AN001;
703; $IF E ;No size for fixed disk ;AN001;
704 JNE $$IF14
705 Message msgIncompatibleParametersForHardDisk ; ;AN001;
706; $ELSE ;Diskette, see what type ;AN001;
707 JMP SHORT $$EN14
708$$IF14:
709 cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH ; ;AN001;
710; $IF E ;Found 180/360k drive ;AN001;
711 JNE $$IF16
712 call Low_Density_Drive ;Go set switches ;AN001;
713; $ELSE ;Check for 96TPI ;AN001;
714 JMP SHORT $$EN16
715$$IF16:
716 cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH96TPI ;AN001; ;
717; $IF E ;Found it ;AN001;
718 JNE $$IF18
719 call High_Capacity_Drive ; ;AN001;
720; $ELSE ; ;AN001;
721 JMP SHORT $$EN18
722$$IF18:
723 cmp byte ptr deviceParameters.DP_DeviceType,DEV_3INCH720KB ;AN0001;
724; $IF E ;Found 720k drive ;AN001;
725 JNE $$IF20
726 call Small_Drives ; ;AN001;
727; $ELSE ; ;AN001;
728 JMP SHORT $$EN20
729$$IF20:
730 cmp byte ptr deviceParameters.DP_DeviceType,DEV_OTHER ;AN001;
731; $IF E ;Must be 1.44mb ;AN001;
732 JNE $$IF22
733 call Other_Drives ; ;AN001;
734; $ELSE ; ;AN001;
735 JMP SHORT $$EN22
736$$IF22:
737 Message msgParametersNotSupportedByDrive ; ;AN001;
738 mov Fatal_Error,Yes ; ;AN001;
739; $ENDIF ; ;AN001;
740$$EN22:
741; $ENDIF ; ;AN001;
742$$EN20:
743; $ENDIF ; ;AN001;
744$$EN18:
745; $ENDIF ; ;AN001;
746$$EN16:
747; $ENDIF ; ;AN001;
748$$EN14:
749; $ENDIF ; ;AN001;
750$$IF13:
751 cmp Fatal_Error,Yes ; ;AN001;
752; $IF E ; ;AN001;
753 JNE $$IF30
754 Message msgIncompatibleParameters ; ;AN001;
755; $ENDIF ; ;AN001;
756$$IF30:
757
758 cmp deviceParameters.DP_DeviceType,DEV_HARDDISK ;an001;
759; $if e ;an001;
760 JNE $$IF32
761 mov Fatal_Error,Yes ;an001;
762; $endif ;an001;
763$$IF32:
764
765 and SwitchMap,not Switch_F ;Turn off /F so doesn't effect ;AN001;
766 ret ; following logic ;AN001;
767
768Size_To_Switch endp
769
770;*****************************************************************************
771;Routine name: High_Capacity_Drive
772;*****************************************************************************
773;
774;Description: See if 1.2mb diskette, or one of the other 5 1/4 sizes. Turn
775; on /4 if 360k or lower
776;
777;Called Procedures: Low_Density_Drive
778;
779;Change History: Created 8/1/87 MT
780;
781;Input: SizeMap
782; Fatal_Error = NO
783;
784;Output: Fatal_Error = YES/NO
785; SwitchMap = Switch_4 if 360k or lowere
786;*****************************************************************************
787
788Procedure High_Capacity_Drive ;
789
790 test SizeMap,Size_1200 ;1.2mb diskette? ;AN001;
791; $IF Z ;Nope ;AN001;
792 JNZ $$IF34
793 call Low_Density_Drive ;Check for /4 valid types ;AN001;
794 cmp Fatal_Error, No ;Find 160/180/320/360k? ;AN001;
795; $IF E ;Yes ;AN001;
796 JNE $$IF35
797 or SwitchMap,Switch_4 ;Turn on /4 switch ;AN001;
798; $ELSE ;Did not find valid size ;AN001;
799 JMP SHORT $$EN35
800$$IF35:
801 mov Fatal_Error,Yes ;Indicate invalid device ;AN001;
802; $ENDIF ; ;AN001;
803$$EN35:
804; $ENDIF ; ;AN001;
805$$IF34:
806 ret ; ;AN001;
807
808High_Capacity_Drive endp
809
810;*****************************************************************************
811;Routine name: Low_Density_Drive
812;*****************************************************************************
813;
814;Description: See if 360k diskete or one of the other 5 1/4 sizes. Turn
815; on the /1/8 switch to match sizes
816;
817;Called Procedures: Low_Density_Drive
818;
819;Change History: Created 8/1/87 MT
820;
821;Input: SizeMap
822; Fatal_Error = NO
823;
824;Output: Fatal_Error = YES/NO
825; SwitchMap = Switch_1, Switch_8 to define size
826;
827; 360k = No switch
828; 320k = Switch_8
829; 180k = Switch_1
830; 160k = Switch_1 + Switch_8
831;*****************************************************************************
832
833
834Procedure Low_Density_Drive ; ;AN000;
835 ;
836 test SizeMap,Size_160 ; ;AN001;
837; $IF NZ ; ;AN001;
838 JZ $$IF39
839 or SwitchMap,Switch_1+Switch_8 ; ;AN001;
840; $ELSE ; ;AN001;
841 JMP SHORT $$EN39
842$$IF39:
843 test SizeMap,Size_180 ; ;AN001;
844; $IF NZ ; ;AN001;
845 JZ $$IF41
846 or SwitchMap,Switch_1 ; ;AN001;
847; $ELSE ; ;AN001;
848 JMP SHORT $$EN41
849$$IF41:
850 test SizeMap,Size_320 ; ;AN001;
851; $IF NZ ; ;AN001;
852 JZ $$IF43
853 or SwitchMap,Switch_8 ; ;AN001;
854; $ELSE ; ;AN001;
855 JMP SHORT $$EN43
856$$IF43:
857 test SizeMap,Size_360 ; ;AN001;
858; $IF Z ;None of the above, not valid ;AN001;
859 JNZ $$IF45
860 mov Fatal_Error,Yes ; ;AN001;
861; $ENDIF ; ;AN001;
862$$IF45:
863; $ENDIF ; ;AN001;
864$$EN43:
865; $ENDIF ; ;AN001;
866$$EN41:
867; $ENDIF ; ;AN001;
868$$EN39:
869 ret ; ;AN001;
870
871Low_Density_Drive endp
872
873;*****************************************************************************
874;Routine name: Small_Drives
875;*****************************************************************************
876;
877;Description: See if 720k media in 720 drive, set up /T/N if so, otherwise
878; error
879;
880;Called Procedures: None
881;
882;Change History: Created 8/1/87 MT
883;
884;Input: SizeMap
885; Fatal_Error = NO
886;
887;Output: Fatal_Error = YES/NO
888; SwitchMap
889; TrackCnt
890; NumSectors
891; 720k = /T:80 /N:9
892;*****************************************************************************
893
894Procedure Small_Drives ; ;AN000;
895
896 test SizeMap,Size_720 ;Ask for 720k? ;AN001;
897; $IF Z ;Nope, thats all drive can do ;AN001;
898 JNZ $$IF50
899 mov Fatal_Error,Yes ;Indicate error ;AN001;
900; $ENDIF ; ;AN001;
901$$IF50:
902 ret ; ;AN001;
903
904Small_Drives endp
905
906
907;*****************************************************************************
908;Routine name: Other_Drives
909;*****************************************************************************
910;
911;Description: See if 1.44 media or 720k media, setup /t/n, otherwise error
912;
913;Called Procedures: Small_Drives
914;
915;Change History: Created 8/1/87 MT
916;
917;Input: SizeMap
918; Fatal_Error = NO
919;
920;Output: Fatal_Error = YES/NO
921; SwitchMap
922; TrackCnt
923; NumSectors
924; 720k = /T:80 /N:9
925;*****************************************************************************
926
927Procedure Other_Drives ; ;AN001;
928
929 test SizeMap,Size_1440 ;Ask for 1.44mb diskette? ;AN001;
930; $IF Z ;Nope ;AN001;
931 JNZ $$IF52
932 call Small_Drives ;See if 720k ;AN001;
933 cmp Fatal_Error,No ;Fatal_error=Yes if not ;AN001;
934; $IF E ;Got 720k ;AN001;
935 JNE $$IF53
936 or SwitchMap,Switch_T+Switch_N ;Turn on /T:80 /N:9 ;AN001;
937 mov TrackCnt,80 ; ;AN001;
938 mov NumSectors,9 ; ;AN001;
939; $ENDIF ; ;AN001;
940$$IF53:
941; $ELSE ;Asked for 1.44mb ;AN001;
942 JMP SHORT $$EN52
943$$IF52:
944 or SwitchMap,Switch_T+Switch_N ;Turn on /T:80 /N:18; ;AN001;
945 mov TrackCnt,80 ;This will protect SIZE=1440 ;AN001;
946 mov NumSectors,18 ; from non-standard drives with ;AN001;
947; $ENDIF ; type of 'other' ;AN001;
948$$EN52:
949 ret ; ;AN001;
950
951Other_Drives endp
952
953
954;*****************************************************************************
955;Routine name:Check_T_N
956;*****************************************************************************
957;
958;Description: Make sure than if /T is entered, /N is also entered
959;
960;Called Procedures: None
961;
962;Change History: Created 8/23/87 MT
963;
964;Input: SizeMap
965; Fatal_Error = NO
966;
967;Output: Fatal_Error = YES/NO
968;*****************************************************************************
969
970Procedure Check_T_N
971
972 test SwitchMap,Switch_N ;Make sure /T entered if /N ;AN009;
973; $IF NZ,AND ; ;AN009;
974 JZ $$IF57
975 test SwitchMap,Switch_T ; ;AN009;
976; $IF Z ; ;AN009;
977 JNZ $$IF57
978 Message msgBad_T_N ;It wasn't, so barf ;AN009;
979 mov Fatal_Error,Yes ;Indicate error ;AN009;
980; $ELSE ; ;AN009;
981 JMP SHORT $$EN57
982$$IF57:
983 test SwitchMap,Switch_T ;Make sure /N entered if /T ;AN009;
984; $IF NZ,AND ; ;AN009;
985 JZ $$IF59
986 test SwitchMap,Switch_N ; ;AN009;
987; $IF Z ;It wasn't, so also barf ;AN009;
988 JNZ $$IF59
989 Message msgBad_T_N ; ;AN009;
990 mov Fatal_Error,Yes ;Indicate error ;AN009;
991; $ENDIF ; ;AN009;
992$$IF59:
993; $ENDIF ; ;AN009;
994$$EN57:
995 ret
996
997Check_T_N endp
998
999
1000
1001;-------------------------------------------------------------------------------
1002; LastChanceToSaveIt:
1003; This routine is called when an error is detected in DiskFormat.
1004; If it returns with carry not set then DiskFormat is restarted.
1005; It gives the oem one last chance to try formatting differently.
1006; fLastChance gets set Then to prevent multiple prompts from being
1007; issued for the same diskette.
1008;
1009; Algorithm:
1010; IF (error_loc == Track_0_Head_1) &
1011; ( Device_type < 96TPI )
1012; THEN
1013; fLastChance := TRUE
1014; try formatting 48TPI_Single_Sided
1015; ELSE return ERROR
1016;
1017LastChanceToSaveIt proc near
1018
1019 cmp currentCylinder, 0
1020 jne WeCanNotIgnoreThisError
1021 cmp currentHead, 1
1022 jne WeCanNotIgnoreThisError
1023
1024 cmp deviceParameters.DP_DeviceType, DEV_5INCH
1025 ja WeCanNotIgnoreThisError
1026
1027 mov fLastChance, TRUE
1028
1029 or switchmap, SWITCH_1
1030 call CheckSwitches
1031 clc
1032 ret
1033
1034WeCanNotIgnoreThisError:
1035 stc
1036 ret
1037
1038LastChanceToSaveIt endp
1039
1040;-------------------------------------------------------------------------------
1041
1042
1043;*****************************************************************************
1044;Routine name WriteBootSector
1045;*****************************************************************************
1046;
1047;DescriptioN: Copy EBPB information to boot record provided by Get recommended
1048; BPB, write out boot record, error
1049; if can write it, then fill in new fields (id, etc..). The volume
1050; label will not be added at this time, but will be set by the
1051; create volume label call later.
1052;
1053;Called Procedures: Message (macro)
1054;
1055;Change History: Created 4/20/87 MT
1056;
1057;Input: DeviceParameters.DP_BPB
1058;
1059;Output: CY clear if ok
1060; CY set if error writing boot or media_id info
1061;
1062;Psuedocode
1063;----------
1064;
1065; Copy recommended EBPB information to canned boot record
1066; Write boot record out (INT 26h)
1067; IF error
1068; Display boot error message
1069; stc
1070; ELSE
1071; Compute serial id and put into field (CALL Create_Serial_ID)
1072; Point at 'FAT_12' string for file system type
1073; IF fBIGFat ;16 bit FAT
1074; Point at 'FAT_16' for file system type
1075; ENDIF
1076; Copy file system string into media_id field
1077; Write info to boot (INT 21h AX=440Dh, CX=0843h SET MEDIA_ID)
1078; IF error (CY set)
1079; Display boot error message
1080; stc
1081; ELSE
1082; clc
1083; ENDIF
1084; ENDIF
1085; ret
1086;*****************************************************************************
1087
1088Procedure WriteBootSector ; ;AN000;
1089
1090 lea si, deviceParameters.DP_BPB ;Copy EBPB to the boot record ;
1091 lea di, Boot.EXT_BOOT_BPB ; " " " " ;AC000:
1092 mov cx, size EXT_BPB_INFO ; " " " " ;AC000:
1093 push ds ;Set ES=DS (data segment) ; ;
1094 pop es ; " " " " ; ;
1095 repnz movsb ;Do the copy ; ;
1096 ;Write out the boot record ; ;
1097 mov al, drive ;Get drive letter ; ;
1098 mov cx, 1 ;Specify 1 sector ; ;
1099 xor dx, dx ;Logical sector 0 ; ;
1100 lea bx, boot ;Point at boot record ; ;
1101;Boot record in 1st 32mb of partition
1102 mov Read_Write_Relative.Start_Sector_High,0 ; ;AN000;
1103 call Write_Disk ; ;AC000;
1104; $IF C ;Error on write ;AC000;
1105 JNC $$IF62
1106 Message msgBootWriteError ;Print error ; ;
1107 stc ;CY=1 means error ; ;
1108; $ELSE ;Good write of boot record! ;AN000;
1109 JMP SHORT $$EN62
1110$$IF62:
1111 mov cx,Dummy_Label_Size ;Put in dummy volume label size ;ac026;ac028;
1112 lea si,Dummy_Label ; " " " " ;AN000;
1113 lea di,Media_ID_Buffer.Media_ID_Volume_Label ; " " " " ;AN000;
1114 rep movsb ; " " " " ;AN000;
1115 call Create_Serial_ID ;Go create unique ID number ;AN000;
1116 lea si,FAT12_String ;Assume 12 bit FAT ;AN000;
1117 cmp fBigFAT,TRUE ;Is it? ;AN000;
1118; $IF E ;Not if fBigFat is set.... ;AN000;
1119 JNE $$IF64
1120 lea si,FAT16_String ;Got 16 bit FAT ;AN000;
1121; $ENDIF ; ;AN000;
1122$$IF64:
1123 ;Copy file system string ; ;
1124 mov cx,8 ; to buffer ;AN000;
1125 lea di,Media_ID_Buffer.Media_ID_File_System ; " " ;AN000;
1126 repnz movsb ; " " " " ;AN000;
1127 mov al,Generic_IOCtl ;Generic IOCtl call ;AN000;
1128 mov bl,Drive ;Get drive ;AN000;
1129 inc bl ;Make it 1 based ;AN000;
1130 xor bh,bh ;Set bh=0 ;AN000;
1131 mov ch,RawIO ;Set Media ID call ;AN000;
1132 mov cl,Set_Media_ID
1133 mov dx,offset Media_ID_Buffer ;Point at buffer ;AN000;
1134 DOS_Call IOCtl ;Do function call ;AN000;
1135; $IF C ;Error ? (Write or old boot rec);AN000;
1136 JNC $$IF66
1137 Message msgBootWriteError ;Indicate we couldn't write it ;AN000;
1138 stc ;CY=1 for error return ;AN000;
1139; $ELSE ;Set Media ID okay ;AN000;
1140 JMP SHORT $$EN66
1141$$IF66:
1142 clc ;CY=0 for good return ;AN000;
1143; $ENDIF ; ;AN000;
1144$$EN66:
1145; $ENDIF ; ;AN000;
1146$$EN62:
1147 ret ; ;AN000;
1148
1149WriteBootSector endp ; ;AN000;
1150
1151
1152;*****************************************************************************
1153;Routine name Create_Serial_ID
1154;*****************************************************************************
1155;
1156;DescriptioN&gml Create unique 32 bit serial number by getting current date and
1157; time and then scrambling it around.
1158;
1159;Called Procedures: Message (macro)
1160;
1161;Change History&gml Created 4/20/87 MT
1162;
1163;Input&gml None
1164;
1165;Output&gml Media_ID_Buffer.Serial_Number = set
1166; AX,CX,DX destroyed
1167; Serial_Num_Low/High = Serial number generated
1168;
1169;Psuedocode
1170;----------
1171;
1172; Get date (INT 21h, AH=2Bh)
1173; Get time (INT 21h, AH=2Ch)
1174; Serial_ID+0 = DX reg date + DX reg time
1175; Serial_ID+2 = CX reg date + CX reg time
1176; Serial_Num_Low = Serial_ID+2
1177; Serial_Num_High = Serial_ID+0
1178; ret
1179;*****************************************************************************
1180
1181Procedure Create_Serial_ID ; ;AN000;
1182
1183 DOS_Call Get_Date ;Get date from DOS ;AN000;
1184 push cx ;Save results ;AN000;
1185 push dx ; ;AN000;
1186 DOS_Call Get_Time ;Get_Time ;AN000;
1187 mov ax,dx ;Scramble it ;AN000;
1188 pop dx ; ;AN000;
1189 add ax,dx ; ;AN000;
1190 mov word ptr Media_ID_Buffer.Media_ID_Serial_Number+2,ax ; ;AC004;
1191 mov Serial_Num_Low,ax ; ;AN000;
1192 mov ax,cx ; ;AN000;
1193 pop cx ; ;AN000;
1194 add ax,cx ; ;AN000;
1195 mov word ptr Media_ID_Buffer.Media_ID_Serial_Number,ax ; ;AC004;
1196 mov Serial_Num_High,ax ; ;AN000;
1197 ret ; ;AN000;
1198
1199Create_Serial_ID endp ; ;AN000;
1200
1201;-------------------------------------------------------------------------------
1202
1203; OemDone:
1204;
1205OemDone proc near
1206
1207; if /b write out a fake dos & bios
1208 test switchmap, SWITCH_B
1209 jz Switch8?
1210 call WriteBogusDos
1211 retc
1212
1213Switch8?:
1214 test switchmap, SWITCH_8
1215 jz HardDisk?
1216 call ConvertToOldDirectoryFormat
1217 retc
1218
1219HardDisk?:
1220 cmp deviceParameters.DP_DeviceType, DEV_HARDDISK
1221 clc
1222 retnz
1223 call SetPartitionTable
1224
1225 return
1226
1227OemDone endp
1228
1229;------------------------------------------------------------------------------
1230
1231data segment public para 'DATA'
1232
1233 if IBMCOPYRIGHT
1234biosFilename db "x:\ibmbio.com",0
1235dosFilename db "x:\ibmdos.com",0
1236 else
1237biosFilename db "x:\io.sys",0
1238dosFilename db "x:\msdos.sys",0
1239 endif
1240
1241data ends
1242
1243; simple code to stuff bogus dos in old-style diskette.
1244
1245BogusDos:
1246 push cs
1247 pop ds
1248 mov al,20h
1249 out 20h,al ; turn on the timer so the disk motor
1250 mov si,mesofs ; shuts off
1251sys_mess_loop:
1252 lodsb
1253if ibmcopyright
1254end_sys_loop:
1255endif
1256 or al,al
1257 jz end_sys_loop
1258 mov ah,14
1259 mov bx,7
1260 int 16
1261 jmp sys_mess_loop
1262if not ibmcopyright
1263end_sys_loop:
1264 xor ah, ah ; get next char function
1265 int 16h ; call keyboard services
1266 int 19h ; reboot
1267endif
1268
1269 include BOOT.CL1
1270mesofs equ sysmsg - BogusDos
1271
1272WriteBogusDos proc near
1273
1274 mov al,driveLetter
1275 mov biosFilename,al
1276 mov dosFilename,al
1277 mov cx, ATTR_HIDDEN or ATTR_SYSTEM
1278 lea dx, biosFilename
1279 mov ah,CREAT
1280 int 21h
1281 mov bx,ax
1282 mov cx, BIOS_SIZE
1283 push ds
1284 push cs
1285 pop ds
1286 assume ds:code
1287 lea dx, BogusDos
1288 mov ah,WRITE
1289 int 21h
1290 pop ds
1291 assume ds:data
1292 mov ah,CLOSE
1293 int 21h
1294 mov cx, ATTR_HIDDEN or ATTR_SYSTEM
1295 lea dx, dosFilename
1296 mov ah,CREAT
1297 int 21h
1298 mov bx,ax
1299 mov cx, DOS_SIZE
1300 lea dx, BogusDos
1301 mov ah,WRITE
1302 int 21h
1303 mov ah,CLOSE
1304 int 21h
1305; Comunicate system size to the main format program
1306 mov word ptr DOS.FileSizeInBytes,DOS_SIZE ;an000; dms;get size of DOS
1307 mov word ptr DOS.FileSizeInBytes+2,00h ;an000; dms;
1308
1309 xor dx,dx
1310 mov ax,DOS_SIZE
1311 call AddToSystemSize
1312
1313 mov word ptr Bios.FileSizeInBytes,BIOS_SIZE ;an000; dms;get size of BIOS
1314 mov word ptr Bios.FileSizeInBytes+2,00h ;an000; dms;
1315
1316 xor dx,dx
1317 mov ax,BIOS_SIZE
1318 call AddToSystemSize
1319
1320 clc
1321 return
1322
1323WriteBogusDos endp
1324
1325;-------------------------------------------------------------------------------
1326
1327ConvertToOldDirectoryFormat proc near
1328
1329;
1330; convert to 1.1 directory
1331;
1332 mov al,drive ; Get 1st sector of directory
1333 mov cx,1 ; 1.1 directory always starts on
1334 mov dx,3 ; sector 3
1335 lea bx,scratchBuffer
1336;Root Directory always in 1st 32mb of partition
1337 mov Read_Write_Relative.Start_Sector_High,0 ; ;AN000;
1338 call Read_Disk ; ;AC000;
1339 jnc DirectoryRead
1340 Message msgDirectoryReadError ; ;AC000;
1341 stc
1342 ret
1343DirectoryRead:
1344
1345; fix attribute of ibmbio and ibmdos
1346 lea bx,scratchBuffer
1347 mov byte ptr [bx].dir_attr, ATTR_HIDDEN or ATTR_SYSTEM
1348 add bx, size dir_entry
1349 mov byte ptr [bx].dir_attr, ATTR_HIDDEN or ATTR_SYSTEM
1350
1351wrtdir:
1352 mov al,[drive] ; write out the directory
1353 cbw
1354 mov cx,1
1355 mov dx,3
1356 lea bx,scratchBuffer
1357;Root Directory always in 1st 32mb of partition
1358 mov Read_Write_Relative.Start_Sector_High,0 ; ;AN000;
1359 call Write_Disk ; ;AC000;
1360 jnc DirectoryWritten
1361 Message msgDirectoryWriteError ; ;AC000;
1362 stc
1363 ret
1364DirectoryWritten:
1365
1366 test switchmap, SWITCH_S ; Was system requested?
1367 retnz ; yes, don't write old boot sector
1368 mov al,drive
1369 cbw
1370 mov bx,offset boot2 ; no, write old boot sector
1371 cmp deviceParameters.DP_BPB.BPB_Heads, 1
1372 je bootset8
1373 mov word ptr [bx+3],0103h ; start address for double sided drives
1374bootset8:
1375 mov cx,1
1376 xor dx,dx
1377;Boot record in 1st 32mb of partition
1378 mov Read_Write_Relative.Start_Sector_High,0 ; ;AN000;
1379 call Write_Disk ; ;AC000;
1380 retnc
1381
1382 Message msgBootWriteError ; ;AC000;
1383 stc
1384 ret
1385
1386ConvertToOldDirectoryFormat endp
1387
1388;-------------------------------------------------------------------------------
1389
1390a_PartitionTableEntry struc
1391BootInd db ?
1392BegHead db ?
1393BegSector db ?
1394BegCylinder db ?
1395SysInd db ?
1396EndHead db ?
1397EndSector db ?
1398EndCylinder db ?
1399RelSec dd ?
1400CSec dd ?
1401a_PartitionTableEntry ends
1402
1403; structure of the IBM hard disk boot sector:
1404IBMBoot STRUC
1405 db 512 - (4*size a_PartitionTableEntry + 2) dup(?)
1406PartitionTable db 4*size a_PartitionTableEntry dup(?)
1407Signature dw ?
1408IBMBoot ENDS
1409
1410
1411;*****************************************************************************
1412;Routine name: SetPartitionTable
1413;*****************************************************************************
1414;
1415;Description: Find location for DOS partition in partition table, get the
1416; correct system indicator byte, and write it out. If can not
1417; read/write boot record or can't find DOS partition, display
1418; error
1419;
1420;Called Procedures: Message (macro)
1421; Determine_Partition_Type
1422; ReadSector
1423; WriteSector
1424;
1425;Change History: Created 4/20/87 MT
1426;
1427;Input: None
1428;
1429;Output: CY set if error
1430;
1431;Psuedocode
1432;----------
1433;
1434; Read the partition table (Call ReadSector)
1435; IF ok
1436; IF boot signature of 55AAh
1437; Point at system partition table
1438; SEARCH
1439; Assume DOS found
1440; IF System_Indicator <> 1,AND
1441; IF System_Indicator <> 4,AND
1442; IF System_Indicator <> 6
1443; STC (DOS not found)
1444; ELSE
1445; CLC
1446; ENDIF
1447; EXITIF DOS found (CLC)
1448; CALL Determine_Partition_Type
1449; Write the partition table (CALL WriteSector)
1450; IF error
1451; Display boot write error message
1452; stc
1453; ELSE
1454; clc
1455; ENDIF
1456; ORELSE
1457; Point at next partition entry (add 16 to partition table ptr)
1458; ENDLOOP if checked all 4 partition entries
1459; Display Bad partition table message
1460; stc
1461; ENDSRCH
1462; ELSE invalid boot record
1463; Display Bad partition table message
1464; stc
1465; ENDIF
1466; ELSE error
1467; Display Partition table error
1468; stc
1469; ENDIF
1470; ret
1471;*****************************************************************************
1472
1473Procedure SetPartitionTable ; ;AN000;
1474
1475 xor ax, ax ;Head ;AC000;
1476 xor bx, bx ;Cylinder ;AC000;
1477 xor cx, cx ;Sector ;AC000;
1478 lea dx, boot2 ;Never use 1.x boot on hardfile,; ;
1479 call ReadSector ;this will use space as buffer ; ;
1480; $IF NC ;If read okay ;AN000;
1481 JC $$IF70
1482 cmp Boot2.Boot_Signature,Boot_ID ; ;AC000;
1483; $IF E ;Does signature match? ;AN000;
1484 JNE $$IF71
1485 lea bx, boot2.PartitionTable ;Yes, point at partition table ;AN000;
1486; $SEARCH ;Look for DOS partition ;AN000;
1487$$DO72:
1488 cmp [bx].sysind,FAT12_File_System ; ;AC000;
1489; $IF NE,AND ; ;AN000;
1490 JE $$IF73
1491 cmp [bx].sysind,FAT16_File_System ; ;AC000;
1492; $IF NE,AND ; ;AN000;
1493 JE $$IF73
1494 cmp [bx].sysind,New_File_System ; ;AC000;
1495; $IF NE ; ;AN000;
1496 JE $$IF73
1497 stc ;We didn't find partition ;AN000;
1498; $ELSE ; ;AN000;
1499 JMP SHORT $$EN73
1500$$IF73:
1501 clc ;Indicate found partition ;AN000;
1502; $ENDIF ; ;AN000;
1503$$EN73:
1504; $EXITIF NC ;Get correct id for it ;AN000;
1505 JC $$IF72
1506 CALL Determine_Partition_Type ; ;AN000;
1507 mov ax, 0 ;Head ; ;
1508 mov bx, 0 ;Cylinder ; ;
1509 mov cx, 0 ;Sector ; ;
1510 lea dx, boot2 ; ; ;
1511 call WriteSector ;Write out partition table ; ;
1512; $IF C ;Error writing boot record ;AN000;
1513 JNC $$IF77
1514 MESSAGE msgPartitionTableWriteError ; ;AC000;
1515 stc ;Set CY to indicate error ; ;
1516; $ELSE ; ;AN000;
1517 JMP SHORT $$EN77
1518$$IF77:
1519 clc ;No error means no CY ; ;
1520; $ENDIF ; ;AN000;
1521$$EN77:
1522; $ORELSE ; ;AN000;
1523 JMP SHORT $$SR72
1524$$IF72:
1525 add bx,size a_PartitionTableEntry ; ; ;
1526 cmp bx,(offset Boot2.PartitionTable)+4*size a_PartitionTableEntry ; ;
1527; $ENDLOOP ;Checked all 4 partition entries;AN000;
1528 JMP SHORT $$DO72
1529 MESSAGE msgBadPartitionTable ;Tell user bad table ;AC000;
1530 stc ;Set CY for exit ; ;
1531; $ENDSRCH ; ;AN000;
1532$$SR72:
1533; $ELSE ;Invalid boot record ;AN000;
1534 JMP SHORT $$EN71
1535$$IF71:
1536 MESSAGE msgBadPartitionTable ; ;AC000;
1537 stc ;Set CY for error return ; ;
1538; $ENDIF ; ;AN000;
1539$$EN71:
1540; $ELSE ;Couldn't read boot record ;AN000;
1541 JMP SHORT $$EN70
1542$$IF70:
1543 MESSAGE msgPartitionTableReadError ; ;AC000;
1544 stc ;Set CY for error return ; ;
1545; $ENDIF ; ;AN000;
1546$$EN70:
1547 ret ; ; ;
1548
1549SetPartitionTable endp ; ;AN000;
1550
1551;*****************************************************************************
1552;Routine name: Determine_Partition_Type
1553;*****************************************************************************
1554;
1555;DescriptioN: Set the system indicator field to its correct value as
1556; determined by the following rules:
1557;
1558; - Set SysInd = 01h if partition or logical drive size is < 10mb
1559; and completely contained within the first 32mb of DASD.
1560; - Set SysInd = 04h if partition or logical drive size is >10mb,
1561; <32mb, and completely contained within the first 32mb of DASD
1562; - Set SysInd to 06h if partition or logical drive size is > 32mb,
1563;
1564;Called Procedures: Message (macro)
1565;
1566;Change History: Created 3/18/87 MT
1567;
1568;Input: BX has offset of partition table entry
1569; fBigFAT = TRUE if 16bit FAT
1570;
1571;Output: BX.SysInd = correct partition system indicator value (1,4,6)
1572;
1573;Psuedocode
1574;----------
1575; Add partition start location to length of partition
1576; IF end > 32mb
1577; BX.SysInd = 6
1578; ELSE
1579; IF fBigFat
1580; BX.SysInd = 4
1581; ELSE
1582; BX.SysInd = 1
1583; ENDIF
1584; ret
1585;*****************************************************************************
1586
1587Procedure Determine_Partition_Type ;AN000;
1588
1589 mov dx,word ptr [bx].Csec+2 ;an000; dms;Get high word of sector count
1590 cmp dx,0 ;AN000; ;> 32Mb?
1591; $IF NE ;AN000; ;yes
1592 JE $$IF87
1593 mov [BX].SysInd,New_File_System ;AN000; ;type 6
1594; $ELSE ;AN000;
1595 JMP SHORT $$EN87
1596$$IF87:
1597 call Calc_Total_Sectors_For_Partition ;an000; dms;returns DX:AX total sectors
1598 cmp DeviceParameters.DP_BPB.BPB_HiddenSectors[+2],0 ;an000; dms;> 32Mb?
1599; $if ne ;an000; dms;yes
1600 JE $$IF89
1601 mov [bx].SysInd,New_File_System ;an000; dms; type 6
1602; $else ;an000; dms;
1603 JMP SHORT $$EN89
1604$$IF89:
1605 cmp dx,0 ;an000; dms; partition > 32 Mb?
1606; $if ne ;an000; dms; yes
1607 JE $$IF91
1608 mov [bx].SysInd,New_File_System ;an000; dms; type 6
1609; $else ;an000; dms; < 32 Mb partition
1610 JMP SHORT $$EN91
1611$$IF91:
1612 cmp fBigFat,True ;an000; ;16 bit FAT
1613; $IF E ;AC000; ;yes
1614 JNE $$IF93
1615 mov [BX].SysInd,FAT16_File_System ;an000; ;type 4
1616; $ELSE ;an000; ;12 bit FAT
1617 JMP SHORT $$EN93
1618$$IF93:
1619 mov [bx].SysInd,FAT12_File_System ;an000; ;type 1
1620; $ENDIF ;AN000;
1621$$EN93:
1622; $ENDIF ;an000;
1623$$EN91:
1624; $ENDIF ;an000;
1625$$EN89:
1626; $endif ;an000;
1627$$EN87:
1628 ret ;an000;
1629
1630Determine_Partition_Type endp ; ;AN000;
1631
1632
1633;=========================================================================
1634; Calc_Total_Sectors_For_Partition : This routine determines the
1635; total number of sectors within
1636; this partition.
1637;
1638; Inputs : DeviceParameters
1639;
1640; Outputs : DX:AX - Double word partition size
1641;=========================================================================
1642
1643Procedure Calc_Total_Sectors_For_Partition ;an000; dms;
1644
1645 mov ax,word ptr DeviceParameters.DP_BPB.BPB_HiddenSectors[+0] ;an000; dms; low word
1646 mov dx,word ptr DeviceParameters.DP_BPB.BPB_HiddenSectors[+2] ;an000; dms; high word
1647 cmp DeviceParameters.DP_BPB.BPB_TotalSectors,0 ;an000; dms; extended BPB?
1648; $if e ;an000; dms; yes
1649 JNE $$IF99
1650 add ax,word ptr DeviceParameters.DP_BPB.BPB_BigTotalSectors[+0] ;an000; dms; add in low word
1651 adc dx,0 ;an000; dms; pick up carry if any
1652 add dx,word ptr DeviceParameters.DP_BPB.BPB_BigTotalSectors[+2] ;an000; dms; add in high word
1653; $else ;an000; dms; standard BPB
1654 JMP SHORT $$EN99
1655$$IF99:
1656 add ax,word ptr DeviceParameters.DP_BPB.BPB_TotalSectors ;an000; dms; add in total sector count
1657 adc dx,0 ;an000; dms; pick up carry if any
1658; $endif ;an000; dms;
1659$$EN99:
1660
1661 ret
1662
1663Calc_Total_Sectors_For_Partition endp
1664
1665
1666;-------------------------------------------------------------------------------
1667; ReadSector:
1668; Read one sector
1669;
1670; Input:
1671; ax - head
1672; bx - cylinder
1673; cx - sector
1674; dx - transfer address
1675
1676ReadSector proc near
1677
1678 mov TrackReadWritePacket.TRWP_FirstSector, cx
1679 mov cx,(RAWIO shl 8) or READ_TRACK
1680 call SectorIO
1681 return
1682
1683ReadSector endp
1684
1685;-------------------------------------------------------------------------------
1686; WriteSector:
1687; Write one sector
1688;
1689; Input:
1690; ax - head
1691; bx - cylinder
1692; cx - sector
1693; dx - transfer address
1694
1695WriteSector proc near
1696
1697 mov TrackReadWritePacket.TRWP_FirstSector, cx
1698 mov cx,(RAWIO shl 8) or WRITE_TRACK
1699 call SectorIO
1700 return
1701
1702WriteSector endp
1703
1704;-------------------------------------------------------------------------------
1705; SectorIO:
1706; Read/Write one sector
1707;
1708; Input:
1709; ax - head
1710; bx - cylinder
1711; cx - (RAWIO shl 8) or READ_TRACK
1712; - (RAWIO shl 8) or WRITE_TRACK
1713; dx - transfer address
1714
1715SectorIO proc near
1716
1717 mov TrackReadWritePacket.TRWP_Head, ax
1718 mov TrackReadWritePacket.TRWP_Cylinder, bx
1719 mov WORD PTR TrackReadWritePacket.TRWP_TransferAddress, dx
1720 mov WORD PTR TrackReadWritePacket.TRWP_TransferAddress + 2, ds
1721 mov TrackReadWritePacket.TRWP_SectorsToReadWrite, 1
1722
1723 mov bl, drive
1724 inc bl
1725 mov ax, (IOCTL shl 8) or GENERIC_IOCTL
1726 lea dx, trackReadWritePacket
1727 int 21H
1728 return
1729
1730SectorIO endp
1731
1732;-------------------------------------------------------------------------------
1733
1734data segment public para 'DATA'
1735
1736oldDrive db ?
1737
1738FCBforVolumeIdSearch db 0ffH
1739 db 5 dup(0)
1740 db 08H
1741 db 0
1742 db "???????????"
1743 db 40 DUP(0)
1744
1745data ends
1746
1747GetVolumeId proc near
1748; Input:
1749; dl = drive
1750; di = name buffer
1751
1752; Save current drive
1753 mov ah,19H
1754 int 21H
1755 mov oldDrive, al
1756
1757; Change current drive to the drive that has the volume id we want
1758 mov ah, 0eH
1759 int 21H
1760
1761; Search for the volume id
1762 mov ah, 11H
1763 lea dx, FCBforVolumeIdSearch
1764 int 21H
1765 push ax
1766
1767; Restore current drive
1768 mov ah, 0eH
1769 mov dl,oldDrive
1770 int 21H
1771
1772; Did the search succeed?
1773 pop ax
1774 or al,al
1775 jz CopyVolumeId
1776 stc
1777 ret
1778
1779CopyVolumeId:
1780; Find out where the FCB for the located volume id was put
1781 mov ah,2fH
1782 int 21H
1783
1784; Copy the Volume Id
1785 mov si, bx
1786 add si, 8
1787 push es
1788 push ds
1789 pop es
1790 pop ds
1791 mov cx, 11
1792 rep movsb
1793 push es
1794 pop ds
1795
1796 clc
1797 ret
1798
1799GetVolumeId endp
1800
1801data segment public para 'DATA'
1802oldVolumeId db 11 dup(0)
1803data ends
1804
1805CheckVolumeId proc near
1806
1807; Get the volume id that's on the disk
1808 lea di, oldVolumeId
1809 mov dl, drive
1810 call GetVolumeId
1811 jnc Ask_User ;Did we find one?
1812 clc ;No, return with no error
1813 ret
1814
1815; Ask the user to enter the volume id that he/she thinks is on the disk
1816; (first blank out the input buffer)
1817Ask_User:
1818
1819 Message msgWhatIsVolumeId? ; ;AC000;
1820 ;lea dx, ptr_msgWhatIsVolumeId?
1821 ;call std_printf
1822 call user_string
1823 call crlf
1824
1825; If the user just pressed ENTER, then there must be no label
1826 cmp inbuff+1, 0
1827 jne CompareVolumeIds
1828 cmp oldVolumeId, 0
1829 jne BadVolumeId
1830 ret
1831
1832CompareVolumeIds:
1833; pad the reponse with blanks
1834; The buffer is big enough so just add 11 blanks to what the user typed in
1835 push ds
1836 pop es
1837 mov cx, Label_Length ;AC000;
1838 xor bx,bx
1839 mov bl, inbuff + 1
1840 lea di, inbuff + 2
1841 add di, bx
1842 mov al, ' '
1843 rep stosb
1844; Make the reply all uppercase
1845 mov byte ptr Inbuff+2+Label_Length,ASCIIZ_End ;Make string ASCIIZ ;AN000;
1846 mov dx, offset inbuff + 2 ;Start of buffer ;AC000;
1847 mov al,22h ;Capitalize asciiz ;AC000;
1848 DOS_Call GetExtCntry ;Do it ;AC000;
1849
1850; Now compare what the user specified with what is really out there
1851 mov cx, Label_Length ; ;AC000;
1852 lea si, inbuff + 2
1853 lea di, oldVolumeId
1854 repe cmpsb
1855 jne BadVolumeId
1856 ret
1857
1858BadVolumeId:
1859 Message msgBadVolumeID ; ;AC000;
1860 stc
1861 ret
1862
1863CheckVolumeId endp
1864
1865
1866Check_Switch_8_B proc near
1867
1868 test SwitchMap, SWITCH_B ;/8/B <> /V because ;AC007;
1869; $IF NZ,AND ; old directory type ;AC007;
1870 JZ $$IF102
1871 test SwitchMap, Switch_8 ; used which didn't support ;AC007;
1872; $IF NZ,AND ; volume labels. ;AC007;
1873 JZ $$IF102
1874 test SwitchMap, SWITCH_V ; ;AC007;
1875; $IF NZ ; ;AC007;
1876 JZ $$IF102
1877 Message msgIncompatibleParameters ;Tell user ;AC007;
1878 mov Fatal_Error,Yes ;Bad stuff ;AC007;
1879; $ELSE ;No problem so far ;AC007;
1880 JMP SHORT $$EN102
1881$$IF102:
1882 test SwitchMap, Switch_B ;Can't reserve space and ;AC007;
1883; $IF NZ,AND ; install sys files at the ;AC007;
1884 JZ $$IF104
1885 test SwitchMap, Switch_S ; same time. ;AC007;
1886; $IF NZ ; No /S/B ;AC007;
1887 JZ $$IF104
1888 Message msgIncompatibleParameters ;Tell user ;AC007;
1889 mov Fatal_Error,Yes ;Bad stuff ;AC007;
1890; $ELSE ;Still okay ;AC007;
1891 JMP SHORT $$EN104
1892$$IF104:
1893 test SwitchMap,Switch_1 ;/1/8/4 not okay with /N/T ;AC007;
1894; $IF NZ,OR ; ;AC007;
1895 JNZ $$LL106
1896 test SwitchMap,Switch_8 ; ;AC007;
1897; $IF NZ,OR ; ;AC007;
1898 JNZ $$LL106
1899 test SwitchMap,Switch_4 ; ;AC007;
1900; $IF NZ ; ;AC007;
1901 JZ $$IF106
1902$$LL106:
1903 test SwitchMap,(Switch_T or Switch_N) ; ;AC007;
1904; $IF NZ ;Found /T/N <> /1/8 ;AC007;
1905 JZ $$IF107
1906 Message msgIncompatibleParameters ;Tell user ;AC007;
1907 mov Fatal_Error,Yes ;Bad stuff ;AC007;
1908; $ELSE ; ;ac007;
1909 JMP SHORT $$EN107
1910$$IF107:
1911 test SwitchMap,Switch_V ;ac007;
1912; $IF NZ,AND ;ac007;
1913 JZ $$IF109
1914 test SwitchMap,Switch_8 ;ac007;
1915; $IF NZ ;ac007;
1916 JZ $$IF109
1917 Message msgIncompatibleParameters ;ac007;
1918 mov Fatal_Error,Yes ;ac007;
1919; $ENDIF ;ac007;
1920$$IF109:
1921; $ENDIF ; ;AC007;
1922$$EN107:
1923; $ENDIF ; ;AC007;
1924$$IF106:
1925; $ENDIF ; ;AC007;
1926$$EN104:
1927; $ENDIF ; ;AC007;
1928$$EN102:
1929 ret
1930
1931Check_Switch_8_B endp
1932
1933
1934code ends
1935 end
1936 \ No newline at end of file