You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
817 lines
22 KiB
817 lines
22 KiB
page ,132
|
|
title COMMAND Resident DATA
|
|
;/*
|
|
; * Microsoft Confidential
|
|
; * Copyright (C) Microsoft Corporation 1991
|
|
; * All Rights Reserved.
|
|
; */
|
|
|
|
;
|
|
; Revision History
|
|
; ================
|
|
; M003 SR 07/16/90 Added LoadHiFlg for LoadHigh support
|
|
;
|
|
; M004 SR 07/17/90 Transient is now moved to its final
|
|
; location at EndInit time by allocating
|
|
; the largest available block, moving
|
|
; the transient to the top of the block
|
|
; and then freeing up the block.
|
|
;
|
|
; M027 SR 9/20/90 Fixed bug #2827. EndInit was using
|
|
; INIT seg variables after INIT seg
|
|
; had been freed.
|
|
;
|
|
; M036 SR 11/1/90 Free up environment segment passed
|
|
; by Exec always.
|
|
;
|
|
|
|
.xlist
|
|
.xcref
|
|
include dossym.inc
|
|
include pdb.inc
|
|
include syscall.inc
|
|
include comsw.asm
|
|
include comseg.asm
|
|
include resmsg.equ
|
|
include comequ.asm
|
|
include cmdsvc.inc
|
|
.list
|
|
.cref
|
|
|
|
; Equates for initialization (from COMEQU)
|
|
;
|
|
; Bugbug: Toss these after putting ctrl-c handler in init module.
|
|
|
|
INITINIT equ 01h ; initialization in progress
|
|
INITSPECIAL equ 02h ; in initialization time/date routine
|
|
INITCTRLC equ 04h ; already in ^C handler
|
|
|
|
|
|
CODERES segment public byte
|
|
extrn Ext_Exec:near
|
|
extrn MsgRetriever:far
|
|
extrn TRemCheck:near
|
|
|
|
;SR;
|
|
; The stack has no right to be in the code segment. Moved it to DATARES
|
|
;
|
|
; bugbug: Why this odd stack size? And what should stack size be?
|
|
;; db (80h - 3) dup (?)
|
|
;;RStack label word
|
|
;; public RStack
|
|
CODERES ends
|
|
|
|
INIT segment
|
|
|
|
extrn ConProc:near
|
|
extrn Chuckenv:byte
|
|
extrn UsedEnv:word
|
|
extrn OldEnv:word
|
|
extrn EnvSiz:word
|
|
extrn TrnSize:word ; M004
|
|
|
|
INIT ends
|
|
|
|
TAIL segment
|
|
|
|
extrn TranStart :word
|
|
|
|
TAIL ends
|
|
|
|
TRANCODE segment public byte
|
|
extrn Command:near
|
|
TRANCODE ends
|
|
|
|
TRANSPACE segment
|
|
|
|
extrn TranSpaceEnd :byte
|
|
|
|
TRANSPACE ends
|
|
|
|
;SR;
|
|
; All the routines below are entry points into the stub from the transient.
|
|
;The stub will then transfer control to the appropriate routines in the
|
|
;resident code segment, wherever it is present.
|
|
;
|
|
|
|
DATARES segment
|
|
|
|
extrn Exec_Trap :near
|
|
extrn RemCheck_Trap :near
|
|
extrn MsgRetrv_Trap :near
|
|
extrn HeadFix_Trap :near
|
|
extrn Issue_Exec_Call :near
|
|
|
|
DATARES ends
|
|
|
|
|
|
DATARES segment public byte
|
|
assume cs:DATARES
|
|
Org 0
|
|
ZERO = $
|
|
|
|
;; Org 100h
|
|
;;ProgStart:
|
|
;; jmp RESGROUP:ConProc
|
|
|
|
public Abort_Char
|
|
public Append_Flag
|
|
public Append_State
|
|
public BadFatSubst
|
|
public Batch
|
|
public Batch_Abort
|
|
public BlkDevErrRw
|
|
public BlkDevErrSubst
|
|
public Call_Batch_Flag
|
|
public Call_Flag
|
|
public CDevAt
|
|
public CharDevErrSubst
|
|
public CharDevErrRw
|
|
public Com_Fcb1
|
|
public Com_Fcb2
|
|
public Com_Ptr
|
|
public ComDrv
|
|
public ComSpec
|
|
public ComSpec_End
|
|
public Crit_Err_Info
|
|
public Crit_Msg_Off
|
|
public Crit_Msg_Seg
|
|
public CritMsgPtrs
|
|
public DataResEnd
|
|
public Dbcs_Vector_Addr
|
|
public DevName
|
|
public DrvLet
|
|
public EchoFlag
|
|
public EnvirSeg
|
|
public ErrCd_24
|
|
public ErrType
|
|
public Exec_block
|
|
public ExecErrSubst
|
|
public Extcom
|
|
public ExtMsgEnd
|
|
public Fail_Char
|
|
public fFail
|
|
public ForFlag
|
|
public ForPtr
|
|
public FUCase_Addr
|
|
public Handle01
|
|
public IfFlag
|
|
public Ignore_Char
|
|
public In_Batch
|
|
public InitFlag
|
|
public InPipePtr
|
|
public Int_2e_Ret
|
|
public Int2fHandler
|
|
public Io_Save
|
|
public Io_Stderr
|
|
public LenMsgOrPathBuf
|
|
public Loading
|
|
public LTpa
|
|
public MemSiz
|
|
public MsgBuffer
|
|
public MsgPtrLists
|
|
public MySeg
|
|
public MySeg1
|
|
public MySeg2
|
|
public MySeg3
|
|
public NeedVol
|
|
public NeedVolSubst
|
|
public Nest
|
|
public Next_Batch
|
|
public No_Char
|
|
public NullFlag
|
|
public NUMEXTMSGS
|
|
public NUMPARSMSGS
|
|
public OldErrNo
|
|
public OldTerm
|
|
public OutPipePtr
|
|
public Parent
|
|
public ParsMsgPtrs
|
|
public PermCom
|
|
public Pipe1
|
|
;;; public Pipe1T
|
|
public Pipe2
|
|
;;; public Pipe2T
|
|
public PipeFiles
|
|
public PipeFlag
|
|
public PipePtr
|
|
public PipeStr
|
|
public KSwitchFlag
|
|
public PutBackComSpec
|
|
public PutBackDrv
|
|
public PutBackSubst
|
|
public RDirChar
|
|
public Re_Out_App
|
|
public Re_OutStr
|
|
public ResMsgEnd
|
|
public Res_Tpa
|
|
public RestDir
|
|
public ResTest
|
|
public RetCode
|
|
public Retry_Char
|
|
public RSwitChar
|
|
public SafePathBuffer ; MSKK01 07/14/89
|
|
public Save_Pdb
|
|
public SingleCom
|
|
public Sum
|
|
public Suppress
|
|
public Trans
|
|
public TranVarEnd
|
|
public TranVars
|
|
public TrnSeg
|
|
public TrnMvFlg
|
|
public VerVal
|
|
public VolName
|
|
public VolSer
|
|
public Yes_Char
|
|
|
|
public ResSize
|
|
public RStack
|
|
public OldDS
|
|
|
|
|
|
public LoadHiFlg ;For LoadHigh support ; M003
|
|
public SCS_Is_First
|
|
public SCS_REENTERED
|
|
public SCS_FIRSTCOM
|
|
|
|
public SCS_PAUSE
|
|
public SCS_CMDPROMPT
|
|
public SCS_DOSONLY
|
|
public SCS_PROMPT16
|
|
public SCS_FIRSTTSR
|
|
public RES_RDRINFO
|
|
public RES_BATSTATUS
|
|
|
|
extrn LodCom_Trap:near
|
|
extrn Alloc_error:near
|
|
|
|
|
|
;*** Message substitution blocks
|
|
|
|
|
|
BlkDevErrSubst label byte
|
|
BlkDevErrRw subst <STRING,> ; "reading" or "writing"
|
|
subst <CHAR,DATARES:DrvLet> ; block device drive letter
|
|
|
|
DrvLet db 'A' ; drive letter
|
|
|
|
|
|
CharDevErrSubst label byte
|
|
CharDevErrRw subst <STRING,> ; "reading" or "writing"
|
|
CharDevErrDev subst <STRING,DATARES:DevName> ; character device name
|
|
|
|
DevName db 8 dup (?),0 ; device name, asciiz
|
|
|
|
|
|
NeedVolSubst label byte
|
|
subst <STRING,DATARES:VolName> ; volume name
|
|
subst <HEX,DATARES:VolSer+2> ; hi word of serial #
|
|
subst <HEX,DATARES:VolSer> ; lo word of serial #
|
|
|
|
; NOTE: VolName and VolSer must be adjacent
|
|
VolName db 11 dup (?),0 ; volume name
|
|
VolSer dd 0 ; volume serial #
|
|
|
|
|
|
CDevAt db ?
|
|
|
|
|
|
BadFatSubst label byte
|
|
subst <CHAR,DATARES:DrvLet> ; drive letter
|
|
|
|
|
|
PutBackSubst label byte
|
|
PutBackComSpec subst <STRING,> ; comspec string
|
|
subst <CHAR,DATARES:PutBackDrv> ; drive to put it in
|
|
|
|
PutBackDrv db ' ' ; drive letter
|
|
|
|
|
|
ExecErrSubst subst <STRING,DATARES:SafePathBuffer>
|
|
|
|
|
|
NeedVol dd ? ; ptr to volume name from get ext err
|
|
ErrType db ? ; critical error message style, 0=old, 1=new
|
|
|
|
Int_2e_Ret dd ? ; magic command executer return address
|
|
Save_Pdb dw ?
|
|
Parent dw ?
|
|
OldTerm dd ?
|
|
ErrCd_24 dw ?
|
|
Handle01 dw ?
|
|
Loading db 0
|
|
Batch dw 0 ; assume no batch mode initially
|
|
|
|
;;;;SR;
|
|
;;;; This flag has been added for a gross hack introduced in batch processing.
|
|
;;;;We use it to indicate that this batch file has no CR-LF before EOF and that
|
|
;;;;we need to fake the CR-LF for the line to be properly processed
|
|
;;;;
|
|
;;;BatchEOF db 0
|
|
|
|
; Bugbug: ComSpec should be 64+3+12+1?
|
|
; What's this comspec_end about?
|
|
ComSpec db 64 dup (0)
|
|
ComSpec_End dw ?
|
|
|
|
Trans label dword
|
|
dw TRANGROUP:Command
|
|
TrnSeg dw ?
|
|
|
|
TrnMvFlg db 0 ; set if transient portion has been moved
|
|
|
|
In_Batch db 0 ; set if we are in batch processing mode
|
|
Batch_Abort db 0 ; set if user wants to abort from batch mode
|
|
|
|
ComDrv db ? ; drive spec to load autoexec and command
|
|
MemSiz dw ?
|
|
Sum dw ?
|
|
ExtCom db 1 ; for init, pretend just did an external
|
|
RetCode dw ?
|
|
Crit_Err_Info db ? ; hold critical error flags for r,i,f
|
|
|
|
|
|
; The echo flag needs to be pushed and popped around pipes and batch files.
|
|
; We implement this as a bit queue that is shr/shl for push and pop.
|
|
|
|
EchoFlag db 00000001b ; low bit true => echo commands
|
|
Suppress db 1 ; used for echo, 1=echo line
|
|
Io_Save dw ?
|
|
Io_Stderr db ?
|
|
RestDir db 0
|
|
PermCom db 0 ; true => permanent command
|
|
SingleCom dw 0 ; true => single command version
|
|
KSwitchFlag db 0
|
|
VerVal dw -1
|
|
fFail db 0 ; true => fail all int 24s
|
|
IfFlag db 0 ; true => IF statement in progress
|
|
|
|
ForFlag db 0 ; true => FOR statement in progress
|
|
ForPtr dw 0
|
|
|
|
Nest dw 0 ; nested batch file counter
|
|
Call_Flag db 0 ; no CALL (batch command) in progress
|
|
Call_Batch_Flag db 0
|
|
Next_Batch dw 0 ; address of next batch segment
|
|
NullFlag db 0 ; flag if no command on command line
|
|
FUCase_Addr db 5 dup (0) ; buffer for file ucase address
|
|
; Bugbug: don't need crit_msg_ anymore?
|
|
Crit_Msg_Off dw 0 ; saved critical error message offset
|
|
Crit_Msg_Seg dw 0 ; saved critical error message segment
|
|
Dbcs_Vector_Addr dw 0 ; DBCS vector offset
|
|
dw 0 ; DBCS vector segment
|
|
|
|
Append_State dw 0 ; current state of append
|
|
; (if Append_Flag is set)
|
|
Append_Flag db 0 ; set if append state is valid
|
|
|
|
SCS_PAUSE db 0 ; yst 4-5-93
|
|
|
|
Re_Out_App db 0
|
|
Re_OutStr db 64+3+13 dup (?)
|
|
SCS_Is_First db 1
|
|
SCS_REENTERED db 0
|
|
SCS_FIRSTCOM db 0
|
|
SCS_CMDPROMPT db 0 ; means on TSR/Shell out use command.com
|
|
SCS_DOSONLY db 0 ; means by default run all binaries
|
|
; when at command.com prompt. if 1 means
|
|
; allow only dos binaries.
|
|
SCS_PROMPT16 db 0
|
|
SCS_FIRSTTSR db 1
|
|
RES_RDRINFO DD 0
|
|
RES_BATSTATUS db 0
|
|
|
|
; We flag the state of COMMAND in order to correctly handle the ^Cs at
|
|
; various times. Here is the breakdown:
|
|
;
|
|
; INITINIT We are in the init code.
|
|
; INITSPECIAL We are in the date/time prompt
|
|
; INITCTRLC We are handling a ^C already.
|
|
;
|
|
; If we get a ^C in the initialization but not in the date/time prompt, we
|
|
; ignore the ^C. This is so the system calls work on nested commands.
|
|
;
|
|
; If we are in the date/time prompt at initialization, we stuff the user's
|
|
; input buffer with a CR to pretend an empty response.
|
|
;
|
|
; If we are already handling a ^C, we set the carry bit and return to the user
|
|
; (ourselves). We can then detect the carry set and properly retry the
|
|
; operation.
|
|
|
|
InitFlag db INITINIT
|
|
|
|
; Note: these two bytes are referenced as a word
|
|
PipeFlag db 0
|
|
PipeFiles db 0
|
|
|
|
;--- 2.x data for piping
|
|
;
|
|
; All the "_" are substituted later, the one before the : is substituted
|
|
; by the current drive, and the others by the CreateTemp call with the
|
|
; unique file name. Note that the first 0 is the first char of the pipe
|
|
; name. -MU
|
|
;
|
|
;--- Order-dependent, do not change
|
|
|
|
;;;Pipe1 db "_:/"
|
|
;;;Pipe1T db 0
|
|
;;; db "_______.___",0
|
|
;;;Pipe2 db "_:/"
|
|
;;;Pipe2T db 0
|
|
;;; db "_______.___",0
|
|
|
|
;SR
|
|
; Pipe1 & Pipe2 now need to store full-fledged pathnames
|
|
;
|
|
|
|
; Bugbug: can we find any way around maintaining these
|
|
; large buffers?
|
|
|
|
Pipe1 db 67+12 dup (?)
|
|
Pipe2 db 67+12 dup (?)
|
|
|
|
PipePtr dw ?
|
|
|
|
PipeStr db 129 dup (?)
|
|
|
|
EndPipe label byte ; marks end of buffers; M004
|
|
|
|
;SR;
|
|
; We can move our EndInit code into above buffers. This way, the code will
|
|
;automatically be discarded after init.
|
|
;
|
|
; M004; We overlap our code with the Pipe buffers located above by changing
|
|
; M004; the origin.
|
|
;
|
|
ORG Pipe1 ; M004
|
|
|
|
; Bugbug: really need a procedure header for EndInit, describing
|
|
; what it expects, what it does.
|
|
|
|
Public EndInit
|
|
EndInit:
|
|
push ds
|
|
push es ;save segments
|
|
push cs
|
|
pop ds
|
|
assume ds:RESGROUP
|
|
|
|
;
|
|
; M004; Save size of transient here before INIT segment is deallocated
|
|
;
|
|
mov dx,TrnSize ; M004
|
|
;M027
|
|
; These variables are also defined in the INIT segment and need to be saved
|
|
;before we resize
|
|
;
|
|
mov ax,OldEnv ; Old Environment seg ;M027
|
|
mov bx,EnvSiz ; Size of new environment ;M027
|
|
mov cx,UsedEnv ; Size of old environment ;M027
|
|
push ax ; Save all these values ;M027
|
|
push bx ; M027
|
|
push cx ; M027
|
|
|
|
|
|
; Bugbug: push ds, pop es here.
|
|
mov bx,ds
|
|
mov es,bx ;es = RESGROUP
|
|
;
|
|
;ResSize is the actual size to be retained -- only data for HIMEM COMMAND,
|
|
; code + data for low COMMAND
|
|
;
|
|
mov bx,ResSize ;Total size of resident
|
|
mov ah,SETBLOCK
|
|
int 21h ;Set block to resident size
|
|
;
|
|
;We check if this is for autoexec.bat (PermCom = 1). If so, we then
|
|
;allocate a new batch segment, copy the old one into new batchseg and free
|
|
;the old batchseg. Remember that the old batchseg was allocated on top of the
|
|
;transient and we will leave a big hole if TSRs are loaded by autoexec.bat
|
|
;
|
|
; Bugbug: also describe why we alloc & copy batch seg BEFORE environment.
|
|
cmp PermCom,1 ;permanent command.com?
|
|
jne adjust_env ;no, do not free batchseg
|
|
|
|
cmp Batch,0 ;was there a valid batchseg?
|
|
je adjust_env ;no, dont juggle
|
|
|
|
; NTVDM temp name of the batch file may be up to 63 bytes, plus NULL
|
|
; mov bx,((SIZE BatchSegment) + 15 + 1 + 0fh)/16 ;batchseg size
|
|
mov bx,((SIZE BatchSegment) + 64 + 1 + 0fh)/16 ;batchseg size
|
|
mov ah,ALLOC
|
|
int 21h
|
|
; Bugbug: I just had a thought. If DOS or SHARE or somebody leaves
|
|
; a hole, the batch segment COULD already be in the ideal place. We
|
|
; could be making it worse! We're second-guessing where memory
|
|
; allocations go, which might not be such a great idea. Is there
|
|
; a strategy, short of doing something even worse like diddling
|
|
; arena headers, where we can minimize the possibility of fragmentation
|
|
; under all cases? Hmm..
|
|
jc adjust_env ;no memory, use old batchseg
|
|
mov es,ax ;es = New batch segment
|
|
xor di,di
|
|
xor si,si
|
|
|
|
push ds
|
|
mov ds,Batch ;ds = Old Batch Segment
|
|
assume ds:nothing
|
|
mov cx,SIZE BatchSegment
|
|
; NTVDM temp name of the batch file may be up to 63 bytes, plus NULL
|
|
; add cx,16 ;for the filename
|
|
add cx,64
|
|
; Bugbug: 16? Shouldn't this be a common equate or something?
|
|
; It's sure be bad if we copied more bytes than the batch segment
|
|
; holds!
|
|
cld
|
|
rep movsb
|
|
pop ds
|
|
assume ds:RESGROUP
|
|
|
|
mov cx,es ;save new batch segment
|
|
mov es,Batch
|
|
mov ah,DEALLOC
|
|
int 21h ;free the old batch segment
|
|
; Bugbug: should we check for error?
|
|
|
|
mov Batch,cx ;store new batch segment address
|
|
|
|
adjust_env:
|
|
pop cx ;cx = size of old env ;M027
|
|
pop bx ;bx = size of new env needed ;M027
|
|
pop bp ;bp = old env seg ;M027
|
|
|
|
;
|
|
;Allocate the correct size for the environment
|
|
;
|
|
mov ah,ALLOC
|
|
int 21h ;get memory
|
|
jc init_env_err ;out of memory,signal error
|
|
|
|
; Bugbug: why not continue, leaving environment where it is?
|
|
|
|
mov EnvirSeg,ax ;Store new environment segment
|
|
mov ds:PDB_Environ,ax ;Put new env seg in PSP
|
|
mov es,ax ;es = address of allocated memory
|
|
assume es:nothing
|
|
|
|
cmp PermCom, 1
|
|
jne copy_old_env
|
|
|
|
;
|
|
; First get the size of 32bit env
|
|
;
|
|
|
|
push bx
|
|
mov bx, 0
|
|
CMDSVC SVC_GETINITENVIRONMENT
|
|
mov ax, bx
|
|
pop bx
|
|
cmp ax, 0 ;bx returns 0, use old environment
|
|
je copy_old_env
|
|
|
|
;
|
|
; now compute the new size
|
|
; [ax] = size of 32 bit env
|
|
;
|
|
|
|
add bx, ax
|
|
mov ah, DEALLOC ;free the block
|
|
int 21h
|
|
mov ah, ALLOC ;and get a new block(don't use realloc please)
|
|
int 21h
|
|
jc nomem_err
|
|
|
|
mov EnvirSeg,ax ;Store new environment segment
|
|
mov ds:PDB_Environ,ax ;Put new env seg in PSP
|
|
mov es,ax ;es = address of allocated memory
|
|
mov EnvSiz, bx ;new size
|
|
push bx
|
|
CMDSVC SVC_GETINITENVIRONMENT ;get new environment
|
|
pop ax
|
|
cmp bx, ax
|
|
jbe adjust_env_done
|
|
init_env_err:
|
|
jmp short nomem_err
|
|
copy_old_env:
|
|
;
|
|
;Copy the environment to the newly allocated segment
|
|
;
|
|
push ds
|
|
mov ds, bp ;ds = Old environment segment
|
|
assume ds:nothing
|
|
|
|
xor si,si
|
|
mov di,si ;Start transfer from 0
|
|
|
|
cld
|
|
rep movsb ;Do the copy
|
|
|
|
pop ds ;ds = RESGROUP
|
|
assume ds:RESGROUP
|
|
adjust_env_done:
|
|
|
|
;
|
|
;We have to free the old environment block if it was allocated by INIT
|
|
;
|
|
; Bugbug: is this only for the case when we were NOT passed an environment,
|
|
; or does it also apply to passed environments?
|
|
;M036
|
|
; Free up old env segment always because this is a copy passed by Exec and
|
|
;takes up memory that is never used
|
|
;
|
|
;M044
|
|
;Go back to the old strategy of not freeing the environment. Freeing it leaves
|
|
;a hole behind that Ventura does not like. Basically, Ventura gives strange
|
|
;errors if it gets a memory alloc that it is below its load segment. The
|
|
;freed environment creates a large enough hole for some of its allocs to fit
|
|
;in
|
|
;
|
|
cmp Chuckenv,0 ;has env been allocated by INIT?
|
|
jne no_free ;no, do not free it
|
|
|
|
mov es,bp
|
|
mov ah,DEALLOC
|
|
int 21h ;Free it
|
|
no_free:
|
|
|
|
;
|
|
; M004; Start of changes
|
|
;
|
|
|
|
;
|
|
; Move the transient now. We will allocate the biggest block available
|
|
; now and move the transient to the top of the block. We will then
|
|
; deallocate this block. When the resident starts executing, it will
|
|
; hopefully allocate this block again and find the transient intact.
|
|
;
|
|
MOV TrnMvFlg, 1 ; Indicate that transient has been moved
|
|
push es
|
|
mov si,offset ResGroup:TranStart
|
|
mov di,0
|
|
mov cx,offset TranGroup:TranSpaceEnd ;size to move
|
|
;
|
|
; Find the largest block available
|
|
;
|
|
mov bx,0ffffh
|
|
mov ah,ALLOC
|
|
int 21h
|
|
|
|
;
|
|
; dx = size of transient saved previously
|
|
;
|
|
cmp bx,dx ;enough memory?
|
|
jb nomem_err ;not enough memory for transient
|
|
|
|
mov ah,ALLOC
|
|
int 21h ;get the largest block
|
|
jc nomem_err ;something is really messed up
|
|
|
|
push ax ;save memory address
|
|
add ax,bx ;ax = top of my memory block
|
|
sub ax,dx ;less size of transient
|
|
mov TrnSeg,ax ;save transient segment
|
|
mov es,ax ;
|
|
pop ax ;restore our seg addr
|
|
|
|
;
|
|
; Everything is set for a move. We need to move in the reverse direction to
|
|
; make sure we dont overwrite ourselves while copying
|
|
;
|
|
add si,cx
|
|
dec si
|
|
add di,cx
|
|
dec di
|
|
std
|
|
rep movsb
|
|
cld
|
|
;
|
|
; Now we have to free up this block so that resident can get hold of it
|
|
;
|
|
mov es,ax
|
|
mov ah,DEALLOC
|
|
int 21h ;release the memory block
|
|
|
|
;
|
|
; M004; End of changes
|
|
;
|
|
|
|
mov InitFlag,FALSE ;indicate INIT is done
|
|
|
|
pop es
|
|
pop ds
|
|
; Bugbug: did we need to save & restore seg reg's during EndInit?
|
|
assume ds:nothing
|
|
|
|
jmp LodCom_Trap ;allocate transient
|
|
|
|
nomem_err:
|
|
;
|
|
;We call the error routine which will never return. It will either exit
|
|
;with an error ( if not the first COMMAND ) or just hang after an error
|
|
;message ( if first COMMAND )
|
|
;
|
|
|
|
jmp Alloc_error
|
|
|
|
public EndCodeInit ; M004
|
|
EndCodeInit label byte ; M004
|
|
|
|
;
|
|
; M004; Check if the EndInit code will fit into the Pipe buffers above.
|
|
; M004; If not, we signal an assembly error
|
|
;
|
|
IF2
|
|
IF ($ GT EndPipe)
|
|
.err
|
|
%out "ENDINIT CODE TOO BIG"
|
|
ENDIF
|
|
ENDIF
|
|
;
|
|
; M004; Set the origin back to what it was at the end of the buffers
|
|
;
|
|
ORG EndPipe ; M004
|
|
|
|
|
|
|
|
InPipePtr dw offset DATARES:Pipe1
|
|
OutPipePtr dw offset DATARES:Pipe2
|
|
|
|
Exec_Block label byte ; the data block for exec calls
|
|
EnvirSeg dw ?
|
|
Com_Ptr label dword
|
|
dw 80h ; point at unformatted parameters
|
|
dw ?
|
|
Com_Fcb1 label dword
|
|
dw 5Ch
|
|
dw ?
|
|
Com_Fcb2 label dword
|
|
dw 6Ch
|
|
dw ?
|
|
|
|
; variables passed to transient
|
|
TranVars label byte
|
|
dw offset DATARES:HeadFix_Trap
|
|
MySeg dw 0 ; put our own segment here
|
|
LTpa dw 0 ; will store tpa segment here
|
|
RSwitChar db "/"
|
|
RDirChar db "\"
|
|
dw offset DATARES:Issue_Exec_Call
|
|
MySeg1 dw ?
|
|
dw offset DATARES:RemCheck_Trap
|
|
MySeg2 dw 0
|
|
ResTest dw 0
|
|
Res_Tpa dw 0 ; original tpa (not rounded to 64k)
|
|
TranVarEnd label byte
|
|
|
|
OldErrNo dw ?
|
|
|
|
|
|
;* NOTE: MsgBuffer and SafePathBuffer use the same
|
|
; memory. MsgBuffer is only used while a command
|
|
; is being executed. SafePathBuffer is no longer
|
|
; needed, since it is used for unsuccessful program
|
|
; launches.
|
|
|
|
MsgBuffer label byte ; buffer for messages from disk
|
|
SafePathBuffer label byte ; resident pathname for EXEC
|
|
; db 128 dup (0) ; path + 'd:\' 'file.ext' + null
|
|
db EXECPATHLEN dup (0) ; MAX_PATH+13 ntvdm extended
|
|
LenMsgOrPathBuf equ $ - MsgBuffer
|
|
|
|
|
|
Int2fHandler dd ? ; address of next int 2f handler
|
|
ResMsgEnd dw 0 ; holds offset of msg end (end of resident)
|
|
|
|
;SR;
|
|
; The three vars below have been added for a pure COMMAND.COM
|
|
;
|
|
|
|
ResSize dw ?
|
|
|
|
;SR;
|
|
; Moved the stack here from the code segment
|
|
;
|
|
; bugbug: Why this odd stack size? And what should stack size be?
|
|
db (80h - 3) dup (?)
|
|
RStack label word
|
|
|
|
OldDS dw ? ;keeps old ds value when jumping to
|
|
;resident code segments
|
|
|
|
LoadHiFlg db 0 ;Flag set to 1 if UMB loading enabled ; M003
|
|
|
|
ifdef BETA3WARN
|
|
%out Take this out before we ship
|
|
public Beta3Warned
|
|
Beta3Warned db 0
|
|
endif
|
|
|
|
;*** MESSAGES
|
|
; and other translatable text
|
|
|
|
include comrmsg.inc ;M00
|
|
|
|
DATARES ends
|
|
end
|
|
|