📄 rxdosexe.asm
字号:
shl cx, 1
push cx ; save bytes actually to read
xor di, di ; load at _StartSeg:0000
lea bx, offset _diskAccess [ bp ] ; build access control block
call readLogicalBuffer ; Access buffer: ss: bx
call computeChecksum
add word ptr [ _CheckSum ][ bp ], ax
pop cx ; bytes read
pop bx ; paras read
pop ax ; previous file offset
pop dx
add ax, cx ; incr position by bytes read
adc dx, 0000
pop cx ; segment loaded
add cx, bx ; increment by paras read
mov es, cx ; set new read segment
sub word ptr [ _SizePara ][ bp ], bx ; subtract paragraphs used.
jnz loadExe_Program08
xor di, di ; load at _StartSeg:0000
mov cx, word ptr [ _exeHeader. exeExtraBytes ][ bp ]
and cx, (PARAGRAPH - 1) ; last 15 bytes
jz loadExe_Program20 ; if none to read -->
lea bx, offset _diskAccess [ bp ] ; build access control block
call readLogicalBuffer ; Access buffer: ss: bx
call computeChecksum
add word ptr [ _CheckSum ][ bp ], ax
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; address relocation blocks
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
loadExe_Program20:
mov ax, word ptr [ _exeHeader. exeRelocItems ][ bp ]
or ax, ax
jz loadExe_Program32
loadExe_Program28:
setES ss
mov cx, 4
xor dx, dx
mov ax, word ptr [ _exeHeader. exeRelocTable ][ bp ]
lea di, offset _relocitem [ bp ]
lea bx, offset _diskAccess [ bp ] ; build access control block
call readLogicalBuffer ; Access buffer: ss: bx
call computeChecksum
add word ptr [ _CheckSum ][ bp ], ax
getdarg dx, bx, _relocitem ; get reloc item
getarg ax, _RelocFactor ; starting segment
add dx, ax
mov es, dx
add word ptr es:[ bx ], ax ; relocate load module
add word ptr [ _exeHeader. exeRelocTable ][ bp ], 4
dec word ptr [ _exeHeader. exeRelocItems ][ bp ]
jnz loadExe_Program28
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; execute
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
loadExe_Program32:
mov ax, word ptr [ _CheckSum ][ bp ]
add ax, word ptr [ _exeHeader. exeChecksum ][ bp ]
mov al, byte ptr [ _Mode ][ bp ] ; if load overlay
getdarg cx, dx, _returnSize ; return size
call ifOverlayLoader ; set up ret args if overlay
ifz loadExe_Program50 ; no need to build return stack -->
getarg es, _programPSP ; child process' PSP
mov dx, word ptr [ _exeHeader. exeInitSS ][ bp ]
add dx, word ptr [ _StartSegment ][ bp ]
mov si, word ptr [ _exeHeader. exeInitSP ][ bp ]
sub si, 2 ; top value minus 1 word
mov word ptr es:[ pspUserStack. _pointer ], si
mov word ptr es:[ pspUserStack. _segment ], dx
setES dx ; child program's stack seg
sub si, _Flags
mov bx, word ptr ss:[ _RxDOS_CurrentInstance ]
mov word ptr ss:[ _pointer ][ bx ], si
mov word ptr ss:[ _segment ][ bx ], dx ; where new process' startup stack will exist (COM)
or si, si
pushf
pop word ptr es:[ _Flags ][ si ]
mov dx, word ptr [ _StartSegment ][ bp ]
add dx, word ptr [ _exeHeader. exeInitCS ][ bp ]
mov ax, word ptr [ _exeHeader. exeInitIP ][ bp ]
mov word ptr es:[ _IP ][ si ], ax
mov word ptr es:[ _CS ][ si ], dx
getarg bx, _programPSP ; child process' PSP
mov word ptr es:[ _ExtraSegment ][ si ], bx
mov word ptr es:[ _DataSegment ][ si ], bx
mov word ptr es:[ _BP ][ si ], 0000
mov word ptr es:[ _DI ][ si ], 0000
mov word ptr es:[ _SI ][ si ], 0000
mov word ptr es:[ _DX ][ si ], 0000
getdarg dx, ax, _returnSize
mov word ptr es:[ _CX ][ si ], ax
mov word ptr es:[ _BX ][ si ], dx
mov word ptr es:[ _AX ][ si ], 0000
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; copy startup command line to _PSP
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
getarg ax, _programPSP ; child process' PSP
mov word ptr [ _RxDOS_CurrentPSP ], ax ; change running PSP
clc
loadExe_Program50:
Return
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Determine if file is EXE formatted ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; Input: ;
; ss:bx disk access block ;
; ;
; Output: ;
; zr file is an EXE ;
; nz file is not an EXE ;
;...............................................................;
checkEXEHeader:
Entry
defbytes _exeHeader, sizeEXEHEADER
xor dx, dx
xor ax, ax ; file pointer to beg of file
mov cx, sizeEXEHEADER
lea di, offset _exeHeader [ bp ]
call readLogicalBuffer ; Access buffer: ss: bx
cmp word ptr [ _exeHeader. exeSignature ][ bp ], EXE_SIGNATURE
Return
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Copy Current PSP ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; Usage: ;
; es PSP segment address to update ;
;...............................................................;
copyCurrentPSP:
SaveSegments
mov ax, word ptr ss:[ _RxDOS_CurrentPSP ] ; current PSP
or ax, ax ; any current PSP ?
jz copyCurrentPSP_36 ; no -->
xor si, si
xor di, di
mov ds, ax ; current PSP
mov cx, ( sizePSP / 2 )
rep movsw
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; duplicate all file handles (except for no inherit)
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
mov ax, word ptr ss:[ _RxDOS_CurrentPSP ]
mov word ptr es:[ pspParentId ], ax ; parent PSP address
mov cx, sizePSPHandleTable
mov bx, offset PSPHandleTable
mov word ptr es:[ pspFileHandleCount ], cx
mov word ptr es:[ pspFileHandlePtr. _segment ], es
mov word ptr es:[ pspFileHandlePtr. _pointer ], bx
copyCurrentPSP_08:
xor ax, ax
mov al, byte ptr es:[ bx ] ; get old handle
cmp al, -1 ; if entry not set
jz copyCurrentPSP_14 ; skip around -->
push es
push bx
call FindSFTbyHandle ; get corresponding SFT (es: di )
test word ptr es:[ sftDevInfo ][ di ], sftNoInherit
jnz copyCurrentPSP_12 ; if no inherit -->
inc word ptr es:[ sftRefCount ][ di ] ; bump in use count
pop bx
pop es
jmp short copyCurrentPSP_14
copyCurrentPSP_12:
pop bx
pop es
mov byte ptr es:[ bx ], -1 ; free SFT in copy of psp
copyCurrentPSP_14:
inc bx
cmp bx, offset (PSPHandleTable + sizePSPHandleTable)
jl copyCurrentPSP_08
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; done
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
copyCurrentPSP_36:
RestoreSegments
ret
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Create New Program Seg Prefix ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; Input: ;
; es start address of PSP ;
; cx allocate size ;
; dx:ax EXEC BLOCK address ;
; ;
; Output: ;
; es updated es: ;
;...............................................................;
createPSP:
Entry
def _AllocSize, cx
ddef _ExecBlock, dx, ax
push ds
mov ax, es
add ax, (sizePSP / PARAGRAPH) ; always a fixed size
push ax ; address of PSP to return
xor di, di
mov ax, word ptr ss:[ _RxDOS_CurrentPSP ]
or ax, ax ; any parent ?
jnz createPSP_08 ; yes, copy parent -->
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; init a blank PSP
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
xor ax, ax
mov cx, (sizePSP / 2) ; always a fixed size
rep stosw ; clear/ zero.
mov ax, -1
mov di, offset pspHandleTable
mov cx, (sizePSPHandleTable / 2)
rep stosw ; init handle table
mov dx, 1
mov al, byte ptr ss:[ stdRedirec_Aux * sizeStdRedirec ]. stdDeviceAssignTable. stdIOHandle
mov byte ptr es:[ pspHandleTable.STDAUX ], al
call incrRefCount
mov al, byte ptr ss:[ stdRedirec_Prn * sizeStdRedirec ]. stdDeviceAssignTable. stdIOHandle
mov byte ptr es:[ pspHandleTable.STDPRN ], al
call incrRefCount
mov al, byte ptr ss:[ stdRedirec_Con * sizeStdRedirec ]. stdDeviceAssignTable. stdIOHandle
mov byte ptr es:[ pspHandleTable.STDIN ], al
mov byte ptr es:[ pspHandleTable.STDOUT ], al
mov byte ptr es:[ pspHandleTable.STDERR ], al
mov dx, 3
call incrRefCount
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -