📄 process.a86
字号:
loop reloc_i30
xchg ax,di ; restore fixup to DI
pop bx ; recover handle
pop ax ; recover # left to do
test ax,ax
jnz reloc_image ; keep going until all done
ret
;READFILE
;
; This function reads in the load image of the file into memory
; (Paragraph DI) the size of the load image is calculated using
; the EXE_SIZE and EXE_FINAL fields enough memory exists at DI
; to load the image. The valid .EXE header has been moved to
; exe_buffer.
;
; Read in a Binary Image .COM or .EXE
; entry: bx -> handle
; di = load segment
;
; exit: bx, si, di Preserved
; cf = 1, ax = Error Code if load fails
;
MAX_READPARA equ 3200 ; Maximum Number of Paragraphs to
; read in one command 50Kb
readfile:
push si ! push di
mov si,offset exe_buffer ; Get the .EXE header
mov dx,EXE_HEADER[si] ; get the header size in paragraphs
mov cx,4 ; and seek to that offset in the
rol dx,cl ; file before reading any data
mov cl,dl
and cx,0Fh ! and dx,not 0Fh
mov ax,(MS_X_LSEEK*256)+0
call dos_entry ; Execute LSEEK Function
jc rf_error
call image_size ; Get the Load Image Sizes in Paras
mov si,dx ; Returned in DX save in SI
rf_10:
mov es,di ; Set the Buffer address
sub dx,dx ; es:dx -> load segment
cmp si,MAX_READPARA ; Can we read the rest of the file
jbe rf_20 ; in one command jif YES
sub si,MAX_READPARA ; Decrement the Image Size
mov cx,MAX_READPARA * 16 ; Number of bytes to read
add di,MAX_READPARA ; Number of Paragraphs Read
mov ah,MS_X_READ ; Read the Block into the
call dos_entry ; buffer Exit if Error
jc rf_error
jmps rf_10 ; Else go for the next bit
rf_20: ; Now reading the last part of
mov cl,4 ; the image so convert remainder
shl si,cl ; in SI to bytes and Read File
mov cx,si
mov ah,MS_X_READ ; Read data into the buffer
call dos_entry
jc rf_error ; Stop on Error
xor ax,ax ; Reset the carry Flag and Zero AX
rf_error: ; Error exit Carry Flag Set and AX
pop di ! pop si ; contains the error code.
ret
; Copy old PSP contents to new PSP.
; Parameter block supplied by user contains command line
; and default FCB's - copy these into the load_psp.
; save: bx -> Handle
pblk_to_psp:
push ds ; Save the PcMode Data Segment
push bx ; and file handle
mov dx,load_psp
call point_param_block ; ES:DI -> users parameter block
push es ! push di
lds si,es:dword ptr 2[di] ; Get the Source Pointer
mov cx,128 ; Copy the complete command line
mov di,offset PSP_COMLEN ; because BASCOM places a segment value
mov es,dx ; after the CR which was not previously
rep movsb ; copied.
pop di ! pop es
lds si,es:dword ptr 6[di] ; get 1st FCB address
mov ax,offset PSP_FCB1 ; First FCB Offset
call copy_fcb ; copy FCB
lds si,es:dword ptr 10[di] ; Get the Source Pointer
mov ax,offset PSP_FCB2 ; Second FCB Offset
call copy_fcb ; copy FCB
pop bx ; file handle back again
pop ds ; Restore PcMode Data Segment
ret
copy_fcb:
;--------
; On Entry:
; DS:SI -> source
; DX:AX -> destination
; On Exit:
; None
; ES:DI, DX preserved
;
push es
push di
mov es,dx
xchg ax,di ; ES:DI -> destination
mov cx,12 ; Copy Drive, Name and Extension
rep movsb ; and copy it
xchg ax,cx ; AX = 0
stosw ! stosw ; zero last 4 bytes
pop di
pop es
ret
; Set up a new psp for the child
;
set_up_psp:
mov ax,load_psp ; Change the ownership of the
mov bx,load_env ; Environment and Load Memory
call set_owner ; partitions.
mov ax,load_psp
mov bx,ax
call set_owner
cmp current_psp,1 ; Is This the ROOT DOS process
jnz setup_psp10 ; No! Continue as Normal
mov ax,load_psp ; Force the LOAD_PSP to
mov current_psp,ax ; to be the current PSP
mov es,ax ; Now Zero Fill the New PSP
mov cx,(offset PSP_FCB1)/2 ; up to user supplied parameters
xor ax,ax ! mov di,ax
rep stosw
jmps setup_psp20 ; and skip the INT22 Fudge
setup_psp10: ; Get the Function return address
xor di,di ! mov es,di ; and force into INT 22
mov di,INT22_OFFSET ; Set Interrupt Vectors 22
push ds
lds si,int21regs_ptr
lea si,reg_IP[si] ; DS:SI -> callers IP
movsw ; Save User IP
movsw ; Save User CS
pop ds
setup_psp20:
mov dx,load_psp ; Get the new PSP address
mov si,load_top ; Get the last paragraph allocated
mov cx,(offset PSP_FCB1)/2 ; Copy PSP up to user supplied bits
;
; CREATE_PSP is a local function called by the DOS EXEC function (4B)
; to create a new PSP and initialize it as a new process.
;
; The PSP_MEMORY field was original calculated as the highest memory
; location that could be allocated to a process. However this caused
; Carbon Copy Plus to Fail so the routine now uses the LOAD_TOP
; value calculated by the CALC_PSP function. This is the last
; paragraph allocated to the current PSP.
;
call create_psp ; Create the New Process
mov ax,load_env ; Now Update the Environment
mov PSP_ENVIRON,ax
mov si,offset load_file ; Copy the process name into the DMD
; jmp SetPspNameAndVersion
SetPspNameAndVersion:
;---------------------
; On Entry:
; ES = PSP
; DS:SI -> pathaname (nb. DS need not be dos data seg!)
; On Exit:
; None
;
mov bx,es
dec bx
mov es,bx ; ES points at DMD (We Hope)
call check_dmd_id ; Check for a valid DMD
jc SetPspNameAndVersion10 ; bail out now if none
if DOS5
inc bx ; BX -> PSP again
push bx ; keep it on the stack
endif
call FindName ; DS:SI -> start of name
push si
call SetName ; update the name field
pop si
if DOS5
call GetVersion ; AX = version to return
pop es ; ES = PSP
mov PSP_VERSION,ax ; set version number
endif
SetPspNameAndVersion10:
ret
FindName:
;--------
; On Entry:
; DS:SI -> pathname of file
; On Exit:
; DS:SI -> final leaf name of file
; CX = length of leaf name
;
mov cx,si ; remember start of leaf
FindName10:
lodsb
cmp al,' ' ; end of the name ?
jbe FindName30
call dbcs_lead ; is it a double byte pair ?
jne FindName20
lodsb ; include the second byte
jmps FindName10
FindName20:
cmp al,'\' ; is it a seperator ?
je FindName
cmp al,'/'
je FindName
jmps FindName10
FindName30:
xchg cx,si ; SI -> start of leaf name
sub cx,si
dec cx ; CX = length
ret
SetName:
;-------
; On Entry:
; DS:SI -> leaf name to update
; ES = DMD to update
; On Exit:
; CX preserved
;
mov di,offset DMD_NAME ; point at the owners name field
SetName10:
lodsb
cmp al,' ' ; end of the name ?
jbe SetName30
call dbcs_lead ; is it a double byte pair ?
jne SetName20
stosb ; copy 1st byte of pair
cmp di,(offset DMD_NAME)+DMD_NAME_LEN
jae SetName30 ; don't overflow if name too long
movsb ; and the second
jmps SetName10
SetName20:
stosb
cmp al,'.' ; discard all following '.'
je SetName30
cmp di,(offset DMD_NAME)+DMD_NAME_LEN
jb SetName10 ; don't overflow if name too long
ret
SetName30:
dec di
xor ax,ax
SetName40:
stosb ; zero the '.'
cmp di,(offset DMD_NAME)+DMD_NAME_LEN
jb SetName40 ; zero the rest of the name
ret
if DOS5
GetVersion:
;----------
; On Entry:
; DS:SI -> start of name
; CX = length
; On Exit:
; AX = dos version to return
;
les di,ss:setverPtr
mov ax,es
or ax,di ; check for a setver list
jnz GetVersion30
GetVersion10:
mov ax,ss:dos_version ; better use default version
ret
GetVersion20:
mov al,es:0FFFFh[di] ; skip the name
cbw
inc ax ! inc ax ; skip the version
add di,ax ; try the next entry
GetVersion30:
mov al,es:byte ptr [di] ; get length field
test al,al ; end of the list ?
jz GetVersion10
inc di ; point at potential name
cmp al,cl ; do the lengths match ?
jne GetVersion20
xor bx,bx ; start scan with 1st character
GetVersion40:
mov ax,ds:[bx+si] ; get a character from filename
call dbcs_lead ; is it a DBCS character ?
jne GetVersion50
inc bx ; we will skip 2 characters
cmp ax,es:[bx+di] ; do both character match ?
jmps GetVersion60
GetVersion50:
call toupper ; upper case it
mov ah,al ; save it
mov al,es:[bx+di] ; get a character from setver list
call toupper ; upper case it
cmp al,ah ; do we match ?
GetVersion60:
jne GetVersion20 ; no, try next name in list
inc bx ; we match, have we done them all ?
cmp bx,cx ; check against length
jb GetVersion40
mov ax,es:[bx+di] ; get version number from setver list
ret
endif
eject
;
; GET_DATA reads the EXE header using the handle passed in BX
;
get_execdata:
; On Entry:
; BX = handle
; ES:SI = buffer
; On Exit:
; CY set if error, AX = error code
; BX/SI preserved
mov ah,MS_X_READ
mov cx,EXE_LENGTH ; read the exe header
mov dx,si ; ES:DX -> buffer
call dos_entry ; try and read the data
jc gd_exit ; Error Exit
mov EXE_FINAL[si],0200h ; Force value to Full Page
call check_exe ; all done if it's an .EXE
jnc gd_exit
mov ax,(MS_X_LSEEK*256)+2 ; it's a .COM
xor cx,cx ; seek to end of file
xor dx,dx
call dos_entry ; get file length in DX:AX
jc gd_exit
xchg al,ah ! mov ah,dl ; DX:AX / 512
shr dx,1 ! rcr ax,1
inc ax ; Handle Final Partial Page
mov EXE_SIZE[si],ax ; No. of 512 Byte Pages
xor ax,ax
mov EXE_HEADER[si],ax ; Load Image starts a 0000
mov EXE_RELCNT[si],ax ; No Relocation Items
dec ax ; Force Maximum Memory Allocation
mov EXE_MAXPARA[si],ax ; to the .COM
mov EXE_MINPARA[si],0010h ; give it at least an extra 100h
; bytes for the Default Stack
gd_exit:
ret
eject
;
; Determine if the file to be loaded is a DOS EXE format file
; if YES then return with the carry flag reset. Assume that the
; header has already been read into EXE_HEADER
;
public check_exe
check_exe:
cmp EXE_SIGNATURE[si],'ZM' ; look for exe signature
jz check_e10
cmp EXE_SIGNATURE[si],'MZ' ; look for exe signature
jz check_e10
stc ; flag the error
check_e10:
ret
;
; IMAGE_SIZE assumes SI points to a valid EXE header and from this
; it calculates the size of the load image and returns this value
; in paragraphs in DX. AX and CX are corrupted.
;
Public image_size
image_size:
mov dx,EXE_SIZE[si] ; No of 512 pages in System Image
dec dx ; Adjust for Final Partial Page
mov cl,5 ! shl dx,cl ; No. 512 Byte Blocks to Para
sub dx,EXE_HEADER[si] ; Remove the Header Size
mov ax,EXE_FINAL[si]
add ax,15
dec cl ! shr ax,cl ; AX is Partial Block in PARA
add dx,ax ; DX is Image Size in PARA's
ret
mem_alloc:
mov ah,MS_M_ALLOC ; call DOS to allocate
jmp dos_entry ; some memory
mem_setblock:
mov ah,MS_M_SETBLOCK ; call DOS to ajust
jmp dos_entry ; a memory block
conditional_mem_free:
; On Entry:
; CX = para to free
; (0 = none to free)
; On Exit:
; None
;
jcxz cmem_free10 ; only free up allocated
push ds ; memory
mov ds,cx
mov ah,MS_M_FREE ; free up a memory block
call dos_entry
pop ds
cmem_free10:
ret
point_param_block:
;-----------------
; On Entry:
; None
; On Exit:
; CL = subfunction number (callers AL)
; ES:DI -> parameter block (callers ES:BX)
; AX corrupted
;
les di,int21regs_ptr ; point at callers registers
mov cl,es:reg_AL[di] ; CL = subfunction# (range-checked)
mov ax,es:reg_BX[di]
mov es,es:reg_ES[di] ; callers ES:BX -> parameter block
xchg ax,di ; ES:DI -> parameter block
ret
PCMODE_DATA DSEG WORD
extrn current_dsk:byte
extrn current_psp:word
extrn retcode:word ; Complete return code passed to F4B
extrn user_retcode:byte ; User retcode set by funcs 4C and 31
extrn system_retcode:byte ; System retcode returns the cause of
extrn switch_char:byte
extrn mem_strategy:byte ; memory allocation strategy
extrn int21AX:word ; Int 21's AX
extrn indos_flag:byte
extrn int21regs_ptr:dword
extrn int21regs_off:word
extrn int21regs_seg:word
extrn prev_int21regs_off:word
extrn prev_int21regs_seg:word
extrn error_flag:byte
extrn exe_buffer:word
extrn valid_flg:byte
extrn retry_off:word
extrn retry_sp:word
extrn last_drv:byte
extrn exec_stub:dword
extrn func4B05_stub:dword
if DOS5
extrn dos_version:word
extrn setverPtr:dword
endif
eject
; To improve Network performance the EXE relocation items are
; now read into the following buffer. All the data items contained
; between RELOC_BUF and RELOC_SIZE are destroyed by the LOADIMAGE
; sub-routine when it relocates a DOS .EXE file.
;
; Only variables which are unused after the LOADIMAGE function can
; be placed in this buffer.
;
; ******** Start of .EXE Relocation Buffer ********
;
; We can re-use the MSNET pathname buffers during an EXEC
extrn reloc_buf:byte
extrn load_file:byte
extrn RELOC_CNT:abs
;
; ******** End of .EXE Relocation Buffer ********
;
extrn exit_type:byte
extrn term_psp:word
extrn load_handle:word
extrn load_env:word ; Paragraph of the new environment
extrn load_envsize:word ; Size of new environment
extrn load_psp:word ; Paragraph of the new PSP.
extrn load_image:word ; Paragraph of the Load Image.
extrn load_top:word ; Last paragraph of Allocated Memory
extrn load_max:word ; ditto, but not messed with
extrn exe_loadhigh:byte ; load high flag
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -