4 ;*****************************************************************************
5 ;*****************************************************************************
6 ;UTILITY NAME: FORMAT.COM
8 ;MODULE NAME: FOREXEC.SAL
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 ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ
32 ; Change List: AN000 - New code DOS 3.3 spec additions
33 ; AC000 - Changed code DOS 3.3 spec additions
34 ;*****************************************************************************
35 ;*****************************************************************************
37 title DOS
3.30 FORMAT EXEC Module
40 %
OUT ASSEMBLING
: DOS
3.3 FORMAT EXEC LOADER
44 code segment public para
'code'
49 ;*****************************************************************************
51 ;*****************************************************************************
62 ;*****************************************************************************
64 ;*****************************************************************************
67 Public Drive_Letter_Msg
70 ;*****************************************************************************
72 ;*****************************************************************************
76 IF FSExec
;an018; dms;if /FS: desired
80 ENDIF
;FSExec ;an018; dms;end /FS: conditional
86 ;*****************************************************************************
87 ; External Data Declarations
88 ;*****************************************************************************
92 extrn Fatal_Error
:Byte
93 extrn FS_String_Buffer
:Byte
94 extrn msgEXECFailure
:Byte
95 extrn PSP_Segment
:Word
99 ;****************************************************************************
101 ;****************************************************************************
105 Exec_Block_Parms
struc
114 Exec_Block_Parms ends
118 ;****************************************************************************
120 ;****************************************************************************
128 Stack_Space equ
02eh ;an000; dms; IBM addition ROM paras
131 ;****************************************************************************
133 ;****************************************************************************
136 PSP
segment public para
'DUMMY'
139 PSP_ENV_SEGMENT
label word
146 Command_Line
label byte
152 ;****************************************************************************
154 ;****************************************************************************
157 data segment public para
'DATA'
158 assume
ds:data,es:nothing
160 Exec_Block Exec_Block_Parms
<>
161 EXEC_Path db 66 dup(0)
163 Drive_Letter_Msg db "A:",0 ;Drive for exec fail message
165 SP_Save dw ?
;an000; dms;
166 SS_Save dw ?
;an000; dms;
169 ;These next two should stay togather
170 ; ---------------------------------------
172 Path_String db "PATH=" ; ;AN000;
173 Len_Path_String equ
$ - Path_String
; ;AN000;
175 ;----------------------------------------
180 ;These should stay togather
181 ; ---------------------------------------
183 Search_FORMAT db "FORMAT" ; ;AC000;
184 Len_Search_FORMAT equ
$ - Search_FORMAT
; ; ;
185 Search_Format_End equ
$
187 ;----------------------------------------
190 ;These next two should stay togather
191 ; ---------------------------------------
199 code segment public para
'code'
200 assume
cs:code,ds:data
203 ;****************************************************************************
205 ;****************************************************************************
212 IF FSExec
;an018; dms;if /FS: desired
215 Procedure Exec_FS_Format
; ;AC000;
218 call Set_FCB1_Drive
;an000;dms;
220 mov al,ExitStatus
;Setblock fail? ;AC000;
221 cmp al,Error
; " " " " ; ;
222 ; $IF NE ;Nah, keep crusin! ;AN000;
224 call Setup_Exec
; ; ;
225 call Exec_Argv
;try exec from dir BASIC loaded ; ;
226 mov al,ExitStatus
; ;AC000;
228 ; $IF E,AND ; ;AC000;
230 call Exec_Cur_Directory
; ; ;
231 mov al,ExitStatus
;Try exec from cur directory ;AC000;
233 ; $IF E,AND ; ;AC000;
235 call EXEC_Routine
; ; ;
236 mov al,ExitStatus
; ;AC000;
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;
248 mov si,FCB1
;an000;dms;ptr to 1st. FCB
249 mov bl,byte ptr ds:[si] ;an000;dms;get drive ID
251 pop si ;an000;dms;restore si
252 pop ds ;an000;dms;restore ds
253 Set_Data_Segment
;an000;dms;set segments
255 cmp bl,0 ;Is it default drive? ;AN000;
256 ; $IF E ;Yes, turn it into drive letter ;AN000;
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;
266 add bl,"A"-1 ;Convert to drive letter ;AN000;
267 mov Drive_Letter_Msg
,bl ; ;AN000;
270 Message msgEXECFailure
; ;AC000;
274 DOS_Call WaitProcess
; ;AC000;
275 mov ExitStatus
,al ; ; ;
280 mov Fatal_Error
,YES
;Not really, indicates FS used ;AN000;
287 ;****************************************************************************
289 ;****************************************************************************
296 Procedure Shrink
; ;AC000;
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 ; ;
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
312 DOS_Call SetBlock
; ;AC000;
313 ; $IF C ;If didn't work, quit ;AC000;
315 Message msgEXECFailure
; ; ;
316 mov ExitStatus
,Error
;Bad stuff, time to quit ;AN000;
321 Shrink endp
; ;AN000;
325 ;****************************************************************************
327 ;****************************************************************************
333 Procedure Setup_Exec
; ;AC000;
336 mov ax,PSP_Segment
;Get segment of PSP ;AN000;
337 mov ds,ax ; " " " " ;AN000;
340 ;Setup dword pointer to command line to be passed
342 mov es:Exec_Block
.Segment_Command
,ax ;Segment for command line ; ;
343 mov es:Exec_Block
.Offset_Command
,offset
ds:Command_Line
; ; ;
345 ;Setup dword pointer to first FCB to be passed
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 ; ;
350 ;Setup dword pointer to second FCB to be passed ; ;
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 ; ;
355 ;Setup segment of Environment string, get from PSP ; ;
357 mov ax,ds:PSP_Env_Segment
; ; ;
358 mov es:Exec_Block
.Segment_Env
,ax ; ; ;
363 Setup_EXEC endp
; ;AN000;
366 ;****************************************************************************
368 ;****************************************************************************
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
376 Procedure EXEC_Argv
; ;AC000;
378 Set_Data_Segment
;DS,ES = DATA
380 mov ax,Exec_Block
.Segment_Env
;Get the environment ; ;
381 mov ds,ax ;Get addressability ; ;
385 xor si,si ;Start at beginning ; ;
386 ; $DO ;Find argv(0) location ;AN000;
388 ; $DO ;Look for 0 ;AN000;
390 inc si ;Get character ; ;
391 cmp byte ptr [si-1],0 ;Find string seperator? ; ;
392 ; $ENDDO E ;Yep ;AC000;
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;
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;
403 cmp byte ptr [si-1],0 ;Is it the end? ; ;
404 ; $ENDDO E ;End found if 0 found ;AC000;
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;
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;
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
; ; ;
429 EXEC_ArgV endp
; ;AN000;
432 ;****************************************************************************
434 ;****************************************************************************
440 Procedure EXEC_Program
; ;AC000;
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
; ; ;
447 mov word ptr SP_Save
,sp ;an000; dms;save sp
448 mov word ptr SS_Save
,ss ;an000; dms;save ss
450 DOS_Call Exec
; ;AC000;
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
458 ; $IF C ;CY means failure ;AC000;
460 mov ExitStatus
,Error
;Set error code ; ;
465 EXEC_Program endp
; ;AN000;
469 ;****************************************************************************
471 ;****************************************************************************
477 Procedure EXEC_Routine
; ;AN000;
479 Set_Data_Segment
; ;AN000;
480 mov ExitStatus
,Error
;Assume the worst ; ;
483 mov ax,Exec_Block
.Segment_Env
;Get the environment ; ;
484 mov ds,ax ;Get addressability ; ;
487 xor si,si ;Start at beginning ; ;
490 cmp word ptr ds:[si],0 ;End of the Evironment? ; ;
491 ; $EXITIF E ;Reached end, no more look ;AC000;
494 ; $ORELSE ;Look for 'PATH=' in environment;AN000;
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;
502 ; $ENDLOOP ;Found PATH in environment ;AC000;
505 call Build_Path_And_Exec
; ;AN000;
514 ;****************************************************************************
515 ; Build_Path_For_EXEC
516 ;****************************************************************************
522 Procedure Build_Path_And_Exec
; ;AN000;
526 cmp byte ptr ds:[si],0 ;All path entries done? ; ;
529 mov di,offset EXEC_Path
;Point at where to put path ; ;
530 mov byte ptr es:[di],0 ;End path just in case ; ;
533 cmp byte ptr ds:[si],0 ;End of Path? ; ;
536 cmp byte ptr ds:[si],';' ;End of entry? ; ;
537 ; $if e ;yes ;an000; dms;
539 inc si ;point to next character ;an000; dms;
540 jmp EXIT_BPE_LOOP
;exit loop ;an000; dms;
541 ; $endif ; ;an000; dms;
543 movsb ;Put char in path string ; ;
548 EXIT_BPE_LOOP: ; ;an000; dms;
549 ;Path filled in,get backslash ; ;
550 cmp byte ptr ds:[si-1],0 ;Any path there? ; ;
554 cmp byte ptr ds:[si-1],"\" ;Need a backslash? ; ;
557 mov byte ptr es:[di],"\" ;Yes, put one in ; ;
558 inc di ;Line it up for next stuff ; ;
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
; ; ;
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;
575 ; $ENDIF ;E if all paths done ;AN000;
577 ; $ENDDO E ;Exit if E ;AN000;
581 Build_Path_And_EXEC Endp
; ;AN000;
586 ;****************************************************************************
588 ;****************************************************************************
594 Procedure Exec_Cur_Directory
; ;AC000;
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
; ; ;
601 call EXEC_Program
; ; ;
604 EXEC_Cur_Directory endp
; ;AN000;
606 ;=========================================================================
607 ; Set_FCB1_Drive : This routine sets the 1st. byte of the FCB1,
608 ; the drive identifier, to the default drive.
609 ;=========================================================================
611 Procedure Set_FCB1_Drive
;an000;dms;set drive ID
613 push ds ;an000;dms;save ds
614 push si ;an000;dms;save si
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
622 pop si ;an000;dms;restore si
623 pop ds ;an000;dms;restore ds
624 Set_Data_Segment
;an000;dms;set up segmentation
627 Set_FCB1_Drive endp
;an000;dms;
629 ENDIF
;FSExec ;an018; dms;end /FS: conditional
633 End_Program
label byte