home *** CD-ROM | disk | FTP | other *** search
- {$M $4000,0,0}
- {═══════════════════════════ DOSEXEC.PAS ════════════════════════════}
- { Usage: Dosexec (From Editor, just Run) }
- { (prompts for Program to run) }
- {═══════════════════════════ DOSEXEC.PAS ════════════════════════════}
-
- {- This demonstration illustrates the use of "local" CSeg assembly }
- {- variables allocated in the 1st Block of the current Code Segment. }
- {- This is a powerful but somewhat complicated technique that you }
- {- may NEVER need to use. (It is useful for creating customized }
- {- Exec Procedures, and Interrupt Routines that can 'Chain' rather }
- {- than Iret). For now, just run the demonstration, and keep in }
- {- the back of your mind that variables CAN be stored in the Code }
- {- segment if you should ever find it necessary. }
-
- {- NOTE: this demonstration program does not parse the parameters }
- {- into the 'default FCBs', so some programs (including diskcopy, }
- {- format, chkdsk, etc) cannot be run directly. However, using }
- {- example 2 below, you can shell to DOS and run these programs. }
-
- {═════════════════════════════ Examples ═════════════════════════════}
- { ( <CR> signifies Carriage Return ) }
- { 1. To list a directory on a system with a bootable hard disk: }
- { At the 'Path' prompt: --> C:\command.com<CR> }
- { At the 'Parameters' prompt: --> /c dir<CR> }
- { 2. To shell to DOS with a system disk in drive A: }
- { At the 'Path' prompt: --> A:\command.com<CR> }
- { At the 'Parameters' prompt: --> <CR> }
- { ( Type EXIT<CR> to return to Turbo ) }
- {═════════════════════════════ Examples ═════════════════════════════}
-
-
- {════════════════════════════ Exec ═════════════════════════════}
- { Execute specified Path and Command Line or return Error in }
- { global VAR DosError. Compatable with DOS Unit Exec Procedure }
- {════════════════════════════ Exec ═════════════════════════════}
- VAR DosError: Integer;
- PROCEDURE Exec(Path,CmdLine: String);
- VAR
- {- local var addr are assigned in reverse order -}
- FCB6C: Pointer; { Dword pointer to FCB2 (6CH in PSP) }
- FCB5C: Pointer; { Dword pointer to FCB1 (5CH in PSP) }
- CmdPtr: Pointer; { Dword pointer parameter string }
- EnvSeg: WORD; { Segment address of environment }
-
- PathPtr: Pointer; { Dword pointer Path to Exec }
-
- BEGIN
- Assemble
- Jmp Begin
- SaveSs Dw 0 ; Ss and Sp MUST be saved in our Code Segment
- SaveSp Dw 0 ; Int $21 Function $4B does not restore them
- Begin:
- Push Ds,Bp
- Mov SaveSs,Ss ; TP&Asm automatically supplies the needed
- Mov SaveSp,Sp ; Cs overrides for SaveSs and SaveSp
- ;- You can code the override explicitly (Cs Mov SaveSs,Ss) if you
- ;- prefer, and you can disable Presumptions for "WYSIWYG" assembly
-
- Mov W CmdPtr+2,Ss ; Save Command Line segment
- Lea AX,CmdLine
- Mov W CmdPtr,Ax ; And offset in Parameter Block.
-
- ;- Technical Note: For String Value Parameters, Turbo 4/5 pushes
- ;- a Pointer to a Copy of the String Value. The pointer will
- ;- reference either the Local Copy OR a "Packed" copy in the
- ;- callers Code Segment. Since we will be modifying the Path
- ;- string (to add a zero byte), it is essential that we use
- ;- the Local copy and not a Code Seg copy. For this reason
- ;- we do NOT want to use the Pointers at [Bp+4] and [Bp+8].
- ;- Instead, take advantage of the fact that TP&Asm allows
- ;- reference to parameters BY NAME - the resulting code is
- ;- easier to understand, and Value parameters referenced by
- ;- name will ALWAYS refer to a local copy in the Stack segment
-
- Push Ss ; Point ES:BX to Parameter Block
- Pop Es
- Lea Bx,EnvSeg ; Use LEA since EnvSeg is implicitly indexed (by BP)
- Mov EnvSeg,0 ; Pass a copy of the current enviroment
-
- Push Ss
- Pop Ds
- Lea Si,Path ; Point DS:SI to length byte of LOCAL COPY
-
- Xor Ax,Ax
- Mov Al,[Si] ; Get length
- Inc Si
- Mov Dx,Si ; Point DS:DX to program name
- Add Si,Ax ; Point past Last Char
- Mov b[Si],0 ; Make it AsciiZ in LOCAL COPY
-
- Mov Ax,4B00h ; DOS EXEC function: al=0, ah=4Bh
- Int 21h ; Execute
- IF NC Xor Al,Al ; If successful (No Carry), clear error code
- ; 'IF' is an A86 specialty, supported for compatibility
- Xor Ah,Ah
-
- Cli
- Mov Ss,SaveSs ; restore our Stack
- Mov Sp,SaveSp
- Sti
- Pop Bp,Ds ; Restore Turbo Bp and Ds
- Mov DosError,Ax ; Store DosError AFTER restoring DS
-
- end; {Assemble}
-
- END; {Exec}
-
-
- VAR Path,CmdLine: String;
-
- {════════════════════ Demonstrate Exec Call ════════════════════}
- BEGIN {Main Program}
- WRITELN('Path and Program to execute [e.g. C:\Command.com]');
- WRITE('--> '); READLN(Path);
- WRITELN('Parameters for executing program [e.g. /C Dir]');
- WRITE('--> '); READLN(CmdLine);
- WRITELN('Before Exec');
-
- Exec(Path,CmdLine);
-
- CASE DosError OF
- 0: WRITELN('Successful Exec');
- 2: WRITELN('File ',Path,' Not Found');
- 8: WRITELN('Not Enough Memory to Exec ',Path);
- ELSE WRITELN('Exec Failed: Dos Error ',DosError);
- END; {CASE DosError}
- END.
-