818 lines
22 KiB
NASM
818 lines
22 KiB
NASM
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
|
||
|