MZ is back!
This commit is contained in:
committed by
Microsoft Open Source
parent
8ee9712c74
commit
2d04cacc53
@@ -0,0 +1,619 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)command2.asm 4.3 85/10/16
|
||||
; SCCSID = @(#)command2.asm 4.3 85/10/16
|
||||
TITLE COMMAND2 - resident code for COMMAND.COM part II
|
||||
NAME COMMAND2
|
||||
.XCREF
|
||||
.XLIST
|
||||
INCLUDE DOSSYM.INC
|
||||
INCLUDE comsw.asm
|
||||
INCLUDE comequ.asm
|
||||
INCLUDE resmsg.equ ;AN000;
|
||||
.LIST
|
||||
.CREF
|
||||
|
||||
tokenized = FALSE
|
||||
|
||||
CODERES SEGMENT PUBLIC BYTE ;AC000;
|
||||
CODERES ENDS
|
||||
|
||||
DATARES SEGMENT PUBLIC BYTE
|
||||
EXTRN append_state:word ;AN020;
|
||||
EXTRN append_flag:byte ;AN020;
|
||||
EXTRN COMDRV:BYTE
|
||||
EXTRN comprmt1_block:byte ;AN000;
|
||||
EXTRN comprmt1_subst:byte ;AN000;
|
||||
EXTRN COMSPEC:BYTE
|
||||
EXTRN cpdrv:byte
|
||||
EXTRN envirseg:word
|
||||
EXTRN EXTCOM:BYTE
|
||||
EXTRN HANDLE01:WORD
|
||||
EXTRN InitFlag:BYTE
|
||||
EXTRN INT_2E_RET:DWORD ;AC000;
|
||||
EXTRN IO_SAVE:WORD
|
||||
EXTRN LOADING:BYTE
|
||||
EXTRN LTPA:WORD
|
||||
EXTRN MEMSIZ:WORD
|
||||
EXTRN number_subst:byte ;AN000;
|
||||
EXTRN OldTerm:DWORD ;AC000;
|
||||
EXTRN PARENT:WORD ;AC000;
|
||||
EXTRN PERMCOM:BYTE
|
||||
EXTRN RDIRCHAR:BYTE
|
||||
EXTRN RES_TPA:WORD
|
||||
EXTRN RETCODE:WORD
|
||||
EXTRN rsrc_xa_seg:word ;AN030;
|
||||
EXTRN RSWITCHAR:BYTE
|
||||
EXTRN SAVE_PDB:WORD
|
||||
EXTRN SINGLECOM:WORD
|
||||
EXTRN SUM:WORD
|
||||
EXTRN TRANS:WORD
|
||||
EXTRN TranVarEnd:BYTE
|
||||
EXTRN TRANVARS:BYTE
|
||||
EXTRN TRNSEG:WORD
|
||||
EXTRN VERVAL:WORD
|
||||
DATARES ENDS
|
||||
|
||||
BATARENA SEGMENT PUBLIC PARA ;AC000;
|
||||
BATARENA ENDS
|
||||
|
||||
BATSEG SEGMENT PUBLIC PARA ;AC000;
|
||||
BATSEG ENDS
|
||||
|
||||
ENVARENA SEGMENT PUBLIC PARA ;AC000;
|
||||
ENVARENA ENDS
|
||||
|
||||
ENVIRONMENT SEGMENT PUBLIC PARA ; Default COMMAND environment
|
||||
ENVIRONMENT ENDS
|
||||
|
||||
INIT SEGMENT PUBLIC PARA
|
||||
EXTRN envsiz:word
|
||||
EXTRN oldenv:word
|
||||
EXTRN resetenv:byte
|
||||
EXTRN usedenv:word
|
||||
INIT ENDS
|
||||
|
||||
TAIL SEGMENT PUBLIC PARA
|
||||
TAIL ENDS
|
||||
|
||||
TRANCODE SEGMENT PUBLIC PARA
|
||||
TRANCODE ENDS
|
||||
|
||||
TRANDATA SEGMENT PUBLIC BYTE
|
||||
EXTRN TRANDATAEND:BYTE
|
||||
TRANDATA ENDS
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE
|
||||
EXTRN TRANSPACEEND:BYTE
|
||||
EXTRN HEADCALL:DWORD
|
||||
TRANSPACE ENDS
|
||||
|
||||
TRANTAIL SEGMENT PUBLIC PARA
|
||||
TRANTAIL ENDS
|
||||
|
||||
RESGROUP GROUP CODERES,DATARES,BATARENA,BATSEG,ENVARENA,ENVIRONMENT,INIT,TAIL
|
||||
TRANGROUP GROUP TRANCODE,TRANDATA,TRANSPACE,TRANTAIL
|
||||
|
||||
; START OF RESIDENT PORTION
|
||||
|
||||
CODERES SEGMENT PUBLIC BYTE ;AC000;
|
||||
|
||||
PUBLIC CHKSUM
|
||||
PUBLIC endinit
|
||||
PUBLIC GETCOMDSK2
|
||||
PUBLIC INT_2E
|
||||
PUBLIC LOADCOM
|
||||
PUBLIC LODCOM
|
||||
PUBLIC LODCOM1
|
||||
PUBLIC RESTHAND
|
||||
PUBLIC SAVHAND
|
||||
PUBLIC SETVECT
|
||||
PUBLIC THEADFIX
|
||||
PUBLIC TREMCHECK
|
||||
PUBLIC tjmp
|
||||
|
||||
ASSUME CS:RESGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||||
|
||||
EXTRN contc:near
|
||||
EXTRN DSKERR:NEAR
|
||||
EXTRN rstack:word
|
||||
;
|
||||
; If we cannot allocate enough memory for the transient or there was some
|
||||
; other allocation error, we display a message and then die.
|
||||
;
|
||||
BADMEMERR: ; Allocation error loading transient
|
||||
MOV DX,BMEMMES ;AC000; get message number
|
||||
FATALC:
|
||||
PUSH CS
|
||||
POP DS
|
||||
ASSUME DS:ResGroup
|
||||
invoke RPRINT
|
||||
;
|
||||
; If this is NOT a permanent (top-level) COMMAND, then we exit; we can't do
|
||||
; anything else!
|
||||
;
|
||||
CMP PERMCOM,0
|
||||
JZ FATALRET
|
||||
;
|
||||
; We are a permanent command. If we are in the process of the magic interrupt
|
||||
; (Singlecom) then exit too.
|
||||
;
|
||||
CMP SINGLECOM,0 ; If PERMCOM and SINGLECOM
|
||||
JNZ FATALRET ; Must take INT_2E exit
|
||||
;
|
||||
; Permanent command. We can't do ANYthing except halt.
|
||||
;
|
||||
MOV DX,HALTMES ;AC000; get message number
|
||||
invoke RPRINT
|
||||
STI
|
||||
STALL:
|
||||
JMP STALL ; Crash the system nicely
|
||||
|
||||
FATALRET:
|
||||
MOV DX,FRETMES ;AC000; get message number
|
||||
invoke RPRINT
|
||||
FATALRET2:
|
||||
CMP [PERMCOM],0 ; If we get here and PERMCOM,
|
||||
JNZ RET_2E ; must be INT_2E
|
||||
invoke reset_msg_pointers ;AN000; reset critical & parse error messages
|
||||
MOV AX,[PARENT]
|
||||
MOV WORD PTR CS:[PDB_Parent_PID],AX
|
||||
MOV AX,WORD PTR OldTerm
|
||||
MOV WORD PTR CS:[PDB_Exit],AX
|
||||
MOV AX,WORD PTR OldTerm+2
|
||||
MOV WORD PTR CS:[PDB_Exit+2],AX
|
||||
MOV AX,(EXIT SHL 8) ; Return to lower level
|
||||
INT int_command
|
||||
|
||||
RET_2E:
|
||||
PUSH CS
|
||||
POP DS
|
||||
ASSUME DS:RESGROUP,ES:NOTHING,SS:NOTHING
|
||||
MOV [SINGLECOM],0 ; Turn off singlecom
|
||||
MOV ES,[RES_TPA]
|
||||
MOV AH,DEALLOC
|
||||
INT int_command ; Free up space used by transient
|
||||
MOV BX,[SAVE_PDB]
|
||||
MOV AH,SET_CURRENT_PDB
|
||||
INT int_command ; Current process is user
|
||||
MOV AX,[RETCODE]
|
||||
CMP [EXTCOM],0
|
||||
JNZ GOTECODE
|
||||
XOR AX,AX ; Internals always return 0
|
||||
GOTECODE:
|
||||
MOV [EXTCOM],1 ; Force external
|
||||
JMP [INT_2E_RET] ;"IRET"
|
||||
|
||||
INT_2E: ; Magic command executer
|
||||
ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||||
POP WORD PTR [INT_2E_RET]
|
||||
POP WORD PTR [INT_2E_RET+2] ;Get return address
|
||||
POP AX ;Chuck flags
|
||||
PUSH CS
|
||||
POP ES
|
||||
MOV DI,80H
|
||||
MOV CX,64
|
||||
REP MOVSW
|
||||
MOV AH,GET_CURRENT_PDB
|
||||
INT int_command ; Get user's header
|
||||
MOV [SAVE_PDB],BX
|
||||
MOV AH,SET_CURRENT_PDB
|
||||
MOV BX,CS
|
||||
INT int_command ; Current process is me
|
||||
MOV [SINGLECOM],81H
|
||||
MOV [EXTCOM],1 ; Make sure this case forced
|
||||
|
||||
LODCOM: ; Termination handler
|
||||
CMP [EXTCOM],0
|
||||
jz lodcom1 ; if internal, memory already allocated
|
||||
mov bx,0ffffh
|
||||
MOV AH,ALLOC
|
||||
INT int_command
|
||||
CALL SetSize
|
||||
ADD AX,20H
|
||||
CMP BX,AX ; Is less than 512 byte buffer worth it?
|
||||
JNC MEMOK
|
||||
BADMEMERRJ:
|
||||
JMP BADMEMERR ; Not enough memory
|
||||
|
||||
; SetSize - get transient size in paragraphs
|
||||
Procedure SetSize,NEAR
|
||||
MOV AX,OFFSET TRANGROUP:TRANSPACEEND + 15
|
||||
MOV CL,4
|
||||
SHR AX,CL
|
||||
return
|
||||
EndProc SetSize
|
||||
|
||||
MEMOK:
|
||||
MOV AH,ALLOC
|
||||
INT int_command
|
||||
JC BADMEMERRJ ; Memory arenas probably trashed
|
||||
MOV [EXTCOM],0 ; Flag not to ALLOC again
|
||||
MOV [RES_TPA], AX ; Save current TPA segment
|
||||
AND AX, 0F000H
|
||||
ADD AX, 01000H ; Round up to next 64K boundary
|
||||
JC BAD_TPA ; Memory wrap if carry set
|
||||
; Make sure that new boundary is within allocated range
|
||||
MOV DX, [RES_TPA]
|
||||
ADD DX, BX ; Compute maximum address
|
||||
CMP DX, AX ; Is 64K address out of range?
|
||||
JBE BAD_TPA
|
||||
; Must have 64K of usable space.
|
||||
SUB DX, AX ; Compute the usable space
|
||||
CMP DX, 01000H ; Is space >= 64K ?
|
||||
JAE LTPASET
|
||||
BAD_TPA:
|
||||
MOV AX, [RES_TPA]
|
||||
LTPASET:
|
||||
MOV [LTPA],AX ; Usable TPA is 64k buffer aligned
|
||||
MOV AX, [RES_TPA] ; Actual TPA is buffer allocated
|
||||
ADD BX,AX
|
||||
MOV [MEMSIZ],BX
|
||||
CALL SetSize
|
||||
SUB BX,AX
|
||||
MOV [TRNSEG],BX ; Transient starts here
|
||||
LODCOM1:
|
||||
MOV AX,CS
|
||||
MOV SS,AX
|
||||
ASSUME SS:RESGROUP
|
||||
MOV SP,OFFSET RESGROUP:RSTACK
|
||||
MOV DS,AX
|
||||
ASSUME DS:RESGROUP
|
||||
CALL HEADFIX ; Make sure files closed stdin and stdout restored
|
||||
XOR BP,BP ; Flag command ok
|
||||
MOV AX,-1
|
||||
XCHG AX,[VERVAL]
|
||||
CMP AX,-1
|
||||
JZ NOSETVER
|
||||
MOV AH,SET_VERIFY_ON_WRITE ; AL has correct value
|
||||
INT int_command
|
||||
NOSETVER:
|
||||
CMP [SINGLECOM],-1
|
||||
JNZ NOSNG
|
||||
JMP FATALRET2 ; We have finished the single command
|
||||
NOSNG:
|
||||
CALL CHKSUM ; Check the transient
|
||||
CMP DX,[SUM]
|
||||
JZ HAVCOM ; Transient OK
|
||||
BOGUS_COM:
|
||||
MOV [LOADING],1 ; Flag DSKERR routine
|
||||
CALL LOADCOM
|
||||
CHKSAME:
|
||||
|
||||
CALL CHKSUM
|
||||
CMP DX,[SUM]
|
||||
JZ HAVCOM ; Same COMMAND
|
||||
ALSO_BOGUS:
|
||||
CALL WRONGCOM
|
||||
JMP SHORT CHKSAME
|
||||
HAVCOM:
|
||||
MOV AX,CHAR_OPER SHL 8
|
||||
INT int_command
|
||||
MOV [RSWITCHAR],DL
|
||||
CMP DL,'/'
|
||||
JNZ USESLASH
|
||||
mov cl,'\'
|
||||
MOV [RDIRCHAR],cl ; Select alt path separator
|
||||
USESLASH:
|
||||
MOV [LOADING],0 ; Flag to DSKERR
|
||||
MOV SI,OFFSET RESGROUP:TRANVARS
|
||||
MOV DI,OFFSET TRANGROUP:HEADCALL
|
||||
MOV ES,[TRNSEG]
|
||||
CLD
|
||||
MOV CX,OFFSET ResGroup:TranVarEnd
|
||||
SUB CX,SI
|
||||
REP MOVSB ; Transfer INFO to transient
|
||||
MOV AX,[MEMSIZ]
|
||||
MOV WORD PTR DS:[PDB_block_len],AX ; Adjust my own header
|
||||
|
||||
; Just a public label so this spot can be found easily.
|
||||
tjmp:
|
||||
JMP DWORD PTR [TRANS]
|
||||
|
||||
; Far call to REMCHECK for TRANSIENT
|
||||
TREMCHECK PROC FAR
|
||||
CALL REMCHECK
|
||||
RET
|
||||
TREMCHECK ENDP
|
||||
|
||||
REMCHECK:
|
||||
;All registers preserved. Returns ZF set if media removable, NZ if fixed
|
||||
; AL is drive (0=DEF, 1=A,...).
|
||||
SaveReg <AX,BX>
|
||||
MOV BX,AX
|
||||
MOV AX,(IOCTL SHL 8) + 8
|
||||
INT 21h
|
||||
jnc RCcont ; If an error occurred, assume the media
|
||||
or ax,ax ; is NON-removable.
|
||||
; AX contains the non-zero error code
|
||||
; from the INT 21, so the OR AX,AX sets
|
||||
; Non-zero. This behavior makes Network
|
||||
; drives appear to be non-removable.
|
||||
jmp SHORT ResRegs
|
||||
RCcont:
|
||||
AND AX,1
|
||||
NOT AX
|
||||
ResRegs:
|
||||
RestoreReg <BX,AX>
|
||||
return
|
||||
|
||||
; Far call to HEADFIX for TRANSIENT
|
||||
THEADFIX PROC FAR
|
||||
CALL HEADFIX
|
||||
RET
|
||||
THEADFIX ENDP
|
||||
|
||||
HEADFIX:
|
||||
CALL SETVECT
|
||||
XOR BX,BX ; Clean up header
|
||||
MOV CX,[IO_SAVE]
|
||||
MOV DX,WORD PTR DS:[PDB_JFN_Table]
|
||||
CMP CL,DL
|
||||
JZ CHK1 ; Stdin matches
|
||||
MOV AH,CLOSE
|
||||
INT int_command
|
||||
MOV DS:[PDB_JFN_Table],CL ; Restore stdin
|
||||
CHK1:
|
||||
INC BX
|
||||
CMP CH,DH ; Stdout matches
|
||||
JZ CHKOTHERHAND
|
||||
MOV AH,CLOSE
|
||||
INT int_command
|
||||
MOV DS:[PDB_JFN_Table+1],CH ; Restore stdout
|
||||
CHKOTHERHAND:
|
||||
ADD BX,4 ; Skip 2,3,4
|
||||
MOV CX,FilPerProc - 5 ; Already done 0,1,2,3,4
|
||||
CLOSELOOP:
|
||||
MOV AH,CLOSE
|
||||
INT int_command
|
||||
INC BX
|
||||
LOOP CLOSELOOP
|
||||
push ds ;AN020; save data segment
|
||||
push cs ;AN020; Get local segment into DS
|
||||
pop ds ;AN020;
|
||||
cmp append_flag,-1 ;AN020; Do we need to reset APPEND?
|
||||
jnz append_fix_end ;AN030; no - just exit
|
||||
mov ax,AppendSetState ;AN020; Set the state of Append
|
||||
mov bx,Append_state ;AN020; back to the original state
|
||||
int 2fh ;AN020;
|
||||
mov append_flag,0 ;AN020; Set append flag to invalid
|
||||
append_fix_end: ;AN030;
|
||||
cmp [rsrc_xa_seg],no_xa_seg ;AN030; Is there any active XA segment?
|
||||
jz xa_fix_end ;AN030; no - exit
|
||||
push es ;AN030; Yes - deallocate it
|
||||
mov es,rsrc_xa_seg ;AN030;
|
||||
mov ax,(Dealloc SHL 8) ;AN030; Deallocate memory call
|
||||
int int_command ;AN030;
|
||||
pop es ;AN030;
|
||||
mov [rsrc_xa_seg],no_xa_seg ;AN030; reset to no segment
|
||||
xa_fix_end:
|
||||
pop ds ;AN020; get data segment back
|
||||
return
|
||||
|
||||
SAVHAND:
|
||||
ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||||
PUSH DS
|
||||
PUSH BX ; Set stdin to sterr, stdout to stderr
|
||||
PUSH AX
|
||||
MOV AH,GET_CURRENT_PDB
|
||||
INT int_command ; Get user's header
|
||||
MOV DS,BX
|
||||
LDS BX,DS:[PDB_JFN_POINTER] ; get pointer to JFN table...
|
||||
MOV AX,WORD PTR DS:[BX]
|
||||
MOV [HANDLE01],AX ; Save user's stdin, stdout
|
||||
MOV AL,CS:[PDB_JFN_Table+2] ; get COMMAND stderr
|
||||
MOV AH,AL
|
||||
MOV WORD PTR DS:[BX],AX ; Dup stderr
|
||||
POP AX
|
||||
POP BX
|
||||
POP DS
|
||||
return
|
||||
|
||||
ASSUME DS:RESGROUP
|
||||
GETCOMDSK2:
|
||||
CALL GETCOMDSK
|
||||
JMP LODCOM1 ; Memory already allocated
|
||||
|
||||
RESTHAND:
|
||||
PUSH DS
|
||||
PUSH BX ; Restore stdin, stdout to user
|
||||
PUSH AX
|
||||
MOV AH,GET_CURRENT_PDB
|
||||
INT int_command ; Point to user's header
|
||||
MOV AX,[HANDLE01]
|
||||
MOV DS,BX
|
||||
ASSUME DS:NOTHING
|
||||
LDS BX,DS:[PDB_JFN_POINTER] ; get pointer to JFN table...
|
||||
MOV WORD PTR DS:[BX],AX ; Stuff his old 0 and 1
|
||||
POP AX
|
||||
POP BX
|
||||
POP DS
|
||||
return
|
||||
ASSUME DS:RESGROUP,SS:RESGROUP
|
||||
|
||||
HOPELESS:
|
||||
MOV DX,COMBAD ;AC000;
|
||||
JMP FATALC
|
||||
|
||||
GETCOMDSK:
|
||||
mov al,[comdrv]
|
||||
CALL REMCHECK
|
||||
jNZ HOPELESS ;Non-removable media
|
||||
getcomdsk3:
|
||||
cmp dx,combad ;AC000;
|
||||
jnz getcomdsk4
|
||||
mov dx,combad ;AN000; get message number
|
||||
invoke RPRINT ; Say command is invalid
|
||||
getcomdsk4:
|
||||
cmp [cpdrv],0 ;g is there a drive in the comspec?
|
||||
jnz users_drive ;g yes - use it
|
||||
mov ah,Get_default_drive ;g use default drive
|
||||
int 21h ;g
|
||||
add al,"A" ;g convert to ascii
|
||||
mov [cpdrv],al ;g put in message to print out
|
||||
|
||||
users_drive: ;g
|
||||
mov dx,comprmt1 ;AC000; Prompt for diskette containing command
|
||||
IF tokenized
|
||||
or byte ptr [si],80h
|
||||
endif
|
||||
MOV AL,COMPRMT1_SUBST ;AN000; get number of substitutions
|
||||
MOV SI,OFFSET RESGROUP:COMPRMT1_BLOCK ;AN000; get address of subst block
|
||||
MOV NUMBER_SUBST,AL ;AN000;
|
||||
invoke rprint
|
||||
if tokenized
|
||||
and byte ptr [si],NOT 80h
|
||||
endif
|
||||
mov dx,prompt ;AN047; Tell the user to strike a key
|
||||
invoke rprint ;AN047;
|
||||
CALL GetRawFlushedByte
|
||||
return
|
||||
|
||||
; flush world and get raw input
|
||||
GetRawFlushedByte:
|
||||
MOV AX,(STD_CON_INPUT_FLUSH SHL 8) OR RAW_CON_INPUT
|
||||
INT int_command ; Get char without testing or echo
|
||||
MOV AX,(STD_CON_INPUT_FLUSH SHL 8) + 0
|
||||
INT int_command
|
||||
return
|
||||
|
||||
LOADCOM: ; Load in transient
|
||||
INC BP ; Flag command read
|
||||
MOV DX,OFFSET RESGROUP:COMSPEC
|
||||
MOV AX,OPEN SHL 8
|
||||
INT int_command ; Open COMMAND.COM
|
||||
JNC READCOM
|
||||
CMP AX,error_too_many_open_files
|
||||
JNZ TRYDOOPEN
|
||||
MOV DX,NOHANDMES ;AC000;
|
||||
JMP FATALC ; Fatal, will never find a handle
|
||||
|
||||
TRYDOOPEN:
|
||||
CALL GETCOMDSK
|
||||
JMP LOADCOM
|
||||
|
||||
READCOM:
|
||||
MOV BX,AX ; Handle
|
||||
MOV DX,OFFSET RESGROUP:TRANSTART
|
||||
XOR CX,CX ; Seek loc
|
||||
MOV AX,LSEEK SHL 8
|
||||
INT int_command
|
||||
JC WRONGCOM1
|
||||
MOV CX,OFFSET TRANGROUP:TRANSPACEEND - 100H
|
||||
|
||||
PUSH DS
|
||||
MOV DS,[TRNSEG]
|
||||
ASSUME DS:NOTHING
|
||||
MOV DX,100H
|
||||
MOV AH,READ
|
||||
INT int_command
|
||||
POP DS
|
||||
ASSUME DS:RESGROUP
|
||||
WRONGCOM1:
|
||||
PUSHF
|
||||
PUSH AX
|
||||
MOV AH,CLOSE
|
||||
INT int_command ; Close COMMAND.COM
|
||||
POP AX
|
||||
POPF
|
||||
JC WRONGCOM ; If error on READ
|
||||
CMP AX,CX
|
||||
retz ; Size matched
|
||||
WRONGCOM:
|
||||
MOV DX,COMBAD ;AC000;
|
||||
CALL GETCOMDSK
|
||||
JMP LOADCOM ; Try again
|
||||
|
||||
CHKSUM: ; Compute transient checksum
|
||||
PUSH DS
|
||||
MOV DS,[TRNSEG]
|
||||
MOV SI,100H
|
||||
MOV CX,OFFSET TRANGROUP:TranDataEnd - 100H
|
||||
|
||||
CHECK_SUM:
|
||||
CLD
|
||||
SHR CX,1
|
||||
XOR DX,DX
|
||||
CHK:
|
||||
LODSW
|
||||
ADD DX,AX
|
||||
ADC DX,0
|
||||
LOOP CHK
|
||||
POP DS
|
||||
return
|
||||
|
||||
SETVECT: ; Set useful vectors
|
||||
MOV DX,OFFSET RESGROUP:LODCOM
|
||||
MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 22H
|
||||
MOV WORD PTR DS:[PDB_EXIT],DX
|
||||
MOV WORD PTR DS:[PDB_EXIT+2],DS
|
||||
INT int_command
|
||||
MOV DX,OFFSET RESGROUP:CONTC
|
||||
INC AL
|
||||
INT int_command
|
||||
MOV DX,OFFSET RESGROUP:DSKERR
|
||||
INC AL
|
||||
INT int_command
|
||||
return
|
||||
|
||||
|
||||
;
|
||||
; This routine moves the environment to a newly allocated segment
|
||||
; at the end of initialization
|
||||
;
|
||||
|
||||
ENDINIT:
|
||||
push ds ;g save segments
|
||||
push es ;g
|
||||
push cs ;g get resident segment to DS
|
||||
pop ds ;g
|
||||
ASSUME DS:RESGROUP
|
||||
mov cx,usedenv ;g get number of bytes to move
|
||||
mov es,envirseg ;g get target environment segment
|
||||
|
||||
ASSUME ES:NOTHING
|
||||
mov DS:[PDB_environ],es ;g put new environment in my header ;AM067;
|
||||
mov ds,oldenv ;g source environment segment ;AM067;
|
||||
ASSUME DS:NOTHING ;AM067;
|
||||
xor si,si ;g set up offsets to start of segments ;AM067;
|
||||
xor di,di ;g ;AM067;
|
||||
cld ;g make sure we move the right way! ;AM067;
|
||||
rep movsb ;g move it ;AM067;
|
||||
xor ax,ax ;g ;AM067;
|
||||
stosb ;g make sure there are double 0 at end ;AM067;
|
||||
|
||||
cmp resetenv,1 ;eg Do we need to setblock to env end?
|
||||
jnz noreset ;eg no - we already did it
|
||||
mov bx,envsiz ;eg get size of environment in paragraphs
|
||||
push es ;eg save environment - just to make sure
|
||||
mov ah,SETBLOCK ;eg
|
||||
int int_command ;eg
|
||||
pop es ;eg
|
||||
|
||||
noreset:
|
||||
mov InitFlag,FALSE ;AC042; Turn off init flag
|
||||
pop es ;g
|
||||
pop ds ;g
|
||||
jmp lodcom ;g allocate transient
|
||||
|
||||
CODERES ENDS
|
||||
|
||||
; This TAIL segment is used to produce a PARA aligned label in the resident
|
||||
; group which is the location where the transient segments will be loaded
|
||||
; initial.
|
||||
|
||||
TAIL SEGMENT PUBLIC PARA
|
||||
ORG 0
|
||||
PUBLIC TranStart
|
||||
TRANSTART LABEL WORD
|
||||
TAIL ENDS
|
||||
|
||||
; This TAIL segment is used to produce a PARA aligned label in the transient
|
||||
; group which is the location where the exec segments will be loaded
|
||||
; initial.
|
||||
|
||||
TRANTAIL SEGMENT PUBLIC PARA
|
||||
ORG 0
|
||||
EXECSTART LABEL WORD
|
||||
TRANTAIL ENDS
|
||||
|
||||
END
|
||||
Reference in New Issue
Block a user