mirror of
https://github.com/microsoft/MS-DOS.git
synced 2024-11-25 15:15:47 +00:00
648 lines
18 KiB
NASM
648 lines
18 KiB
NASM
|
TITLE MISC - Miscellanious routines for MS-DOS
|
|||
|
NAME MISC
|
|||
|
;
|
|||
|
; Miscellaneous system calls most of which are CAVEAT
|
|||
|
;
|
|||
|
; $SLEAZEFUNC
|
|||
|
; $SLEAZEFUNCDL
|
|||
|
; $GET_INDOS_FLAG
|
|||
|
; $GET_IN_VARS
|
|||
|
; $GET_DEFAULT_DPB
|
|||
|
; $GET_DPB
|
|||
|
; $DISK_RESET
|
|||
|
; $SETDPB
|
|||
|
; $Dup_PDB
|
|||
|
; $CREATE_PROCESS_DATA_BLOCK
|
|||
|
; SETMEM
|
|||
|
;
|
|||
|
.xlist
|
|||
|
;
|
|||
|
; get the appropriate segment definitions
|
|||
|
;
|
|||
|
INCLUDE DOSSEG.ASM
|
|||
|
|
|||
|
CODE SEGMENT BYTE PUBLIC 'CODE'
|
|||
|
ASSUME SS:DOSGROUP,CS:DOSGROUP
|
|||
|
|
|||
|
.xcref
|
|||
|
INCLUDE DOSSYM.ASM
|
|||
|
INCLUDE DEVSYM.ASM
|
|||
|
.cref
|
|||
|
.list
|
|||
|
|
|||
|
|
|||
|
ifndef Kanji
|
|||
|
Kanji equ 0
|
|||
|
endif
|
|||
|
|
|||
|
ENTRYPOINTSEG EQU 0CH
|
|||
|
MAXDIF EQU 0FFFH
|
|||
|
SAVEXIT EQU 10
|
|||
|
|
|||
|
i_need LASTBUFFER,DWORD
|
|||
|
i_need INDOS,BYTE
|
|||
|
i_need SYSINITVAR,BYTE
|
|||
|
i_need CurrentPDB,WORD
|
|||
|
i_need CreatePDB,BYTE
|
|||
|
i_need EXIT_TYPE,BYTE
|
|||
|
i_need EXIT_CODE,WORD
|
|||
|
i_need LASTENT,WORD
|
|||
|
i_need THISDPB,DWORD
|
|||
|
i_need ATTRIB,BYTE
|
|||
|
i_need EXTFCB,BYTE
|
|||
|
i_need DMAADD,DWORD
|
|||
|
i_need DIRSTART,WORD
|
|||
|
i_need CURBUF,DWORD
|
|||
|
i_need USER_SP,WORD
|
|||
|
i_need ENTLAST,WORD
|
|||
|
i_need THISDRV,BYTE
|
|||
|
|
|||
|
ASSUME SS:DOSGROUP
|
|||
|
|
|||
|
BREAK <SleazeFunc -- get a pointer to media byte>
|
|||
|
|
|||
|
;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
|
|||
|
; C A V E A T P R O G R A M M E R ;
|
|||
|
; ;
|
|||
|
procedure $SLEAZEFUNC,NEAR
|
|||
|
ASSUME DS:NOTHING,ES:NOTHING
|
|||
|
|
|||
|
; Inputs:
|
|||
|
; None
|
|||
|
; Function:
|
|||
|
; Return Stuff sort of like old get fat call
|
|||
|
; Outputs:
|
|||
|
; DS:BX = Points to FAT ID byte (IBM only)
|
|||
|
; GOD help anyone who tries to do ANYTHING except
|
|||
|
; READ this ONE byte.
|
|||
|
; DX = Total Number of allocation units on disk
|
|||
|
; CX = Sector size
|
|||
|
; AL = Sectors per allocation unit
|
|||
|
; = -1 if bad drive specified
|
|||
|
|
|||
|
MOV DL,0
|
|||
|
entry $SLEAZEFUNCDL
|
|||
|
PUSH SS
|
|||
|
POP DS
|
|||
|
ASSUME DS:DOSGROUP
|
|||
|
MOV AL,DL
|
|||
|
invoke GETTHISDRV
|
|||
|
MOV AL,-1
|
|||
|
JC BADSLDRIVE
|
|||
|
invoke FATREAD
|
|||
|
MOV DX,ES:[BP.dpb_max_cluster]
|
|||
|
DEC DX
|
|||
|
MOV AL,ES:[BP.dpb_cluster_mask]
|
|||
|
INC AL
|
|||
|
MOV CX,ES:[BP.dpb_sector_size]
|
|||
|
ADD BP,dpb_media
|
|||
|
BADSLDRIVE:
|
|||
|
invoke get_user_stack
|
|||
|
ASSUME DS:NOTHING
|
|||
|
MOV [SI.user_CX],CX
|
|||
|
MOV [SI.user_DX],DX
|
|||
|
MOV [SI.user_BX],BP
|
|||
|
MOV [SI.user_DS],ES
|
|||
|
return
|
|||
|
$SLEAZEFUNC ENDP
|
|||
|
; ;
|
|||
|
; C A V E A T P R O G R A M M E R ;
|
|||
|
;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BREAK <$ABORT -- Terminate a process>
|
|||
|
procedure $ABORT,NEAR
|
|||
|
ASSUME DS:NOTHING,ES:NOTHING
|
|||
|
|
|||
|
; Inputs:
|
|||
|
; CS:00 must point to valid program header block
|
|||
|
; Function:
|
|||
|
; Restore terminate and Cntrl-C addresses, flush buffers
|
|||
|
; and transfer to the terminate address
|
|||
|
; Returns:
|
|||
|
; TO THE TERMINATE ADDRESS
|
|||
|
|
|||
|
XOR AL,AL
|
|||
|
MOV [exit_type],exit_abort
|
|||
|
|
|||
|
;
|
|||
|
; abort_inner must have AL set as the exit code!
|
|||
|
;
|
|||
|
entry abort_inner
|
|||
|
MOV AH,[exit_type]
|
|||
|
MOV [exit_code],AX
|
|||
|
invoke Get_user_stack
|
|||
|
MOV DS,[SI.user_CS] ; set up old interrupts
|
|||
|
XOR AX,AX
|
|||
|
MOV ES,AX
|
|||
|
MOV SI,SAVEXIT
|
|||
|
MOV DI,addr_int_terminate
|
|||
|
MOVSW
|
|||
|
MOVSW
|
|||
|
MOVSW
|
|||
|
MOVSW
|
|||
|
MOVSW
|
|||
|
MOVSW
|
|||
|
transfer reset_environment
|
|||
|
$ABORT ENDP
|
|||
|
|
|||
|
BREAK <$Dir_Search_First -- Start a directory search>
|
|||
|
procedure $DIR_SEARCH_FIRST,NEAR
|
|||
|
ASSUME DS:NOTHING,ES:NOTHING
|
|||
|
|
|||
|
; Inputs:
|
|||
|
; DS:DX Points to unopenned FCB
|
|||
|
; Function:
|
|||
|
; Directory is searched for first matching entry and the directory
|
|||
|
; entry is loaded at the disk transfer address
|
|||
|
; Returns:
|
|||
|
; AL = -1 if no entries matched, otherwise 0
|
|||
|
|
|||
|
invoke GETFILE
|
|||
|
ASSUME DS:DOSGROUP
|
|||
|
SAVPLCE:
|
|||
|
; Search-for-next enters here to save place and report
|
|||
|
; findings.
|
|||
|
MOV DL,0 ; Do not XOR!!!
|
|||
|
JC KILLSRCH
|
|||
|
OR AH,AH ; Is it I/O device?
|
|||
|
JS KILLIT ; If so, sign bit will end search
|
|||
|
MOV AX,[LASTENT]
|
|||
|
INC DL
|
|||
|
KILLIT:
|
|||
|
MOV ES:[DI.FILDIRENT],AX
|
|||
|
MOV AX,WORD PTR [THISDPB]
|
|||
|
MOV ES:[DI.fcb_DRVBP],AX
|
|||
|
MOV AX,WORD PTR [THISDPB+2]
|
|||
|
MOV ES:[DI.fcb_DRVBP+2],AX
|
|||
|
MOV AX,[DIRSTART]
|
|||
|
MOV ES:[DI.fcb_DRVBP+4],AX
|
|||
|
; Information in directory entry must be copied into the first
|
|||
|
; 33 bytes starting at the disk transfer address.
|
|||
|
MOV SI,BX
|
|||
|
LES DI,[DMAADD]
|
|||
|
MOV AX,00FFH
|
|||
|
CMP AL,[EXTFCB]
|
|||
|
JNZ NORMFCB
|
|||
|
STOSW
|
|||
|
INC AL
|
|||
|
STOSW
|
|||
|
STOSW
|
|||
|
MOV AL,[ATTRIB]
|
|||
|
STOSB
|
|||
|
NORMFCB:
|
|||
|
MOV AL,[THISDRV]
|
|||
|
INC AL
|
|||
|
STOSB ; Set drive number
|
|||
|
OR DL,DL
|
|||
|
JZ DOSRELATIVE
|
|||
|
MOV DS,WORD PTR [CURBUF+2]
|
|||
|
ASSUME DS:NOTHING
|
|||
|
DOSRELATIVE:
|
|||
|
|
|||
|
IF KANJI
|
|||
|
MOVSW
|
|||
|
CMP BYTE PTR ES:[DI-2],5
|
|||
|
JNZ NOTKTRAN
|
|||
|
MOV BYTE PTR ES:[DI-2],0E5H
|
|||
|
NOTKTRAN:
|
|||
|
MOV CX,15
|
|||
|
ELSE
|
|||
|
MOV CX,16
|
|||
|
ENDIF
|
|||
|
|
|||
|
REP MOVSW ; Copy 32 bytes of directory entry
|
|||
|
XOR AL,AL
|
|||
|
return
|
|||
|
|
|||
|
ASSUME DS:NOTHING
|
|||
|
KILLSRCH1:
|
|||
|
PUSH DS
|
|||
|
POP ES ; Make ES:DI point to the FCB
|
|||
|
KILLSRCH:
|
|||
|
MOV AX,-1
|
|||
|
MOV WORD PTR ES:[DI.FILDIRENT],AX
|
|||
|
return
|
|||
|
$DIR_SEARCH_FIRST ENDP
|
|||
|
|
|||
|
BREAK <$Dir_Search_Next -- Find next matching directory entry>
|
|||
|
procedure $DIR_SEARCH_NEXT,NEAR
|
|||
|
ASSUME DS:NOTHING,ES:NOTHING
|
|||
|
|
|||
|
; Inputs:
|
|||
|
; DS:DX points to unopenned FCB returned by $DIR_SEARCH_FIRST
|
|||
|
; Function:
|
|||
|
; Directory is searched for the next matching entry and the directory
|
|||
|
; entry is loaded at the disk transfer address
|
|||
|
; Returns:
|
|||
|
; AL = -1 if no entries matched, otherwise 0
|
|||
|
|
|||
|
invoke MOVNAMENOSET
|
|||
|
ASSUME ES:DOSGROUP
|
|||
|
MOV DI,DX
|
|||
|
JC NEAR PTR KILLSRCH1
|
|||
|
MOV AX,[DI.FILDIRENT]
|
|||
|
LES BP,DWORD PTR [DI.fcb_DRVBP]
|
|||
|
OR AX,AX
|
|||
|
JS NEAR PTR KILLSRCH1
|
|||
|
MOV BX,[DI.fcb_DRVBP+4]
|
|||
|
PUSH DX
|
|||
|
PUSH DS
|
|||
|
PUSH AX
|
|||
|
MOV WORD PTR [THISDPB],BP
|
|||
|
MOV WORD PTR [THISDPB+2],ES
|
|||
|
invoke SetDirSrch
|
|||
|
ASSUME DS:DOSGROUP
|
|||
|
POP AX
|
|||
|
MOV [ENTLAST],-1
|
|||
|
invoke GetEnt
|
|||
|
invoke NextEnt
|
|||
|
POP ES
|
|||
|
ASSUME ES:NOTHING
|
|||
|
POP DI
|
|||
|
JMP SAVPLCE
|
|||
|
$DIR_SEARCH_NEXT ENDP
|
|||
|
|
|||
|
BREAK <$Get_FCB_File_Length -- Return size of file in current records>
|
|||
|
procedure $GET_FCB_FILE_LENGTH,NEAR
|
|||
|
ASSUME DS:NOTHING,ES:NOTHING
|
|||
|
|
|||
|
; Inputs:
|
|||
|
; DS:DX points to unopenned FCB
|
|||
|
; Function:
|
|||
|
; Set random record field to size of file
|
|||
|
; Returns:
|
|||
|
; AL = -1 if no entries matched, otherwise 0
|
|||
|
|
|||
|
invoke GETFILE
|
|||
|
ASSUME DS:DOSGROUP
|
|||
|
MOV AL,-1
|
|||
|
retc
|
|||
|
ADD DI,fcb_RR ; Write size in RR field
|
|||
|
MOV CX,WORD PTR ES:[DI.fcb_RECSIZ-fcb_RR]
|
|||
|
OR CX,CX
|
|||
|
JNZ RECOK
|
|||
|
MOV CX,128
|
|||
|
RECOK:
|
|||
|
XOR DX,DX ; Intialize size to zero
|
|||
|
INC SI
|
|||
|
INC SI ; Point to length field
|
|||
|
MOV DS,WORD PTR [CURBUF+2]
|
|||
|
ASSUME DS:NOTHING
|
|||
|
MOV AX,[SI+2] ; Get high word of size
|
|||
|
DIV CX
|
|||
|
PUSH AX ; Save high part of result
|
|||
|
LODSW ; Get low word of size
|
|||
|
DIV CX
|
|||
|
OR DX,DX ; Check for zero remainder
|
|||
|
POP DX
|
|||
|
JZ DEVSIZ
|
|||
|
INC AX ; Round up for partial record
|
|||
|
JNZ DEVSIZ ; Propagate carry?
|
|||
|
INC DX
|
|||
|
DEVSIZ:
|
|||
|
STOSW
|
|||
|
MOV AX,DX
|
|||
|
STOSB
|
|||
|
MOV AL,0
|
|||
|
CMP CX,64
|
|||
|
JAE RET14 ; Only 3-byte field if fcb_RECSIZ >= 64
|
|||
|
MOV ES:[DI],AH
|
|||
|
RET14: return
|
|||
|
$GET_FCB_FILE_LENGTH ENDP
|
|||
|
|
|||
|
BREAK <$Get_Fcb_Position -- Set random record field to current position>
|
|||
|
procedure $GET_FCB_POSITION,NEAR
|
|||
|
ASSUME DS:NOTHING,ES:NOTHING
|
|||
|
|
|||
|
; Inputs:
|
|||
|
; DS:DX points to openned FCB
|
|||
|
; Function:
|
|||
|
; Sets random record field to be same as current record fields
|
|||
|
; Returns:
|
|||
|
; None
|
|||
|
|
|||
|
invoke GETREC
|
|||
|
MOV WORD PTR [DI+fcb_RR],AX
|
|||
|
MOV [DI+fcb_RR+2],DL
|
|||
|
CMP [DI.fcb_RECSIZ],64
|
|||
|
JAE RET16
|
|||
|
MOV [DI+fcb_RR+2+1],DH ; Set 4th byte only if record size < 64
|
|||
|
RET16: return
|
|||
|
$GET_FCB_POSITION ENDP
|
|||
|
|
|||
|
BREAK <$Disk_Reset -- Flush out all dirty buffers>
|
|||
|
procedure $DISK_RESET,NEAR
|
|||
|
ASSUME DS:NOTHING,ES:NOTHING
|
|||
|
|
|||
|
; Inputs:
|
|||
|
; None
|
|||
|
; Function:
|
|||
|
; Flush and invalidate all buffers
|
|||
|
; Returns:
|
|||
|
; Nothing
|
|||
|
|
|||
|
PUSH SS
|
|||
|
POP DS
|
|||
|
ASSUME DS:DOSGROUP
|
|||
|
MOV AL,-1
|
|||
|
invoke FLUSHBUF
|
|||
|
MOV WORD PTR [LASTBUFFER+2],-1
|
|||
|
MOV WORD PTR [LASTBUFFER],-1
|
|||
|
invoke SETVISIT
|
|||
|
ASSUME DS:NOTHING
|
|||
|
NBFFR: ; Free ALL buffers
|
|||
|
MOV [DI.VISIT],1 ; Mark as visited
|
|||
|
CMP BYTE PTR [DI.BUFDRV],-1
|
|||
|
JZ SKPBF ; Save a call to PLACEBUF
|
|||
|
MOV WORD PTR [DI.BUFDRV],00FFH
|
|||
|
invoke SCANPLACE
|
|||
|
SKPBF:
|
|||
|
invoke SKIPVISIT
|
|||
|
JNZ NBFFR
|
|||
|
return
|
|||
|
$DISK_RESET ENDP
|
|||
|
|
|||
|
procedure $RAW_CON_IO,NEAR ; System call 6
|
|||
|
ASSUME DS:NOTHING,ES:NOTHING
|
|||
|
|
|||
|
; Inputs:
|
|||
|
; DL = -1 if input
|
|||
|
; else DL is output character
|
|||
|
; Function:
|
|||
|
; Input or output raw character from console, no echo
|
|||
|
; Returns:
|
|||
|
; AL = character
|
|||
|
|
|||
|
MOV AL,DL
|
|||
|
CMP AL,-1
|
|||
|
JNZ RAWOUT
|
|||
|
LES DI,DWORD PTR [user_SP] ; Get pointer to register save area
|
|||
|
XOR BX,BX
|
|||
|
invoke GET_IO_FCB
|
|||
|
retc
|
|||
|
MOV AH,1
|
|||
|
invoke IOFUNC
|
|||
|
JNZ RESFLG
|
|||
|
invoke SPOOLINT
|
|||
|
OR BYTE PTR ES:[DI.user_F],40H ; Set user's zero flag
|
|||
|
XOR AL,AL
|
|||
|
return
|
|||
|
|
|||
|
RESFLG:
|
|||
|
AND BYTE PTR ES:[DI.user_F],0FFH-40H ; Reset user's zero flag
|
|||
|
|
|||
|
RILP:
|
|||
|
invoke SPOOLINT
|
|||
|
entry $RAW_CON_INPUT ; System call 7
|
|||
|
|
|||
|
; Inputs:
|
|||
|
; None
|
|||
|
; Function:
|
|||
|
; Input raw character from console, no echo
|
|||
|
; Returns:
|
|||
|
; AL = character
|
|||
|
|
|||
|
XOR BX,BX
|
|||
|
invoke GET_IO_FCB
|
|||
|
retc
|
|||
|
MOV AH,1
|
|||
|
invoke IOFUNC
|
|||
|
JZ RILP
|
|||
|
XOR AH,AH
|
|||
|
invoke IOFUNC
|
|||
|
return
|
|||
|
;
|
|||
|
; Output the character in AL to stdout
|
|||
|
;
|
|||
|
entry RAWOUT
|
|||
|
|
|||
|
PUSH BX
|
|||
|
MOV BX,1
|
|||
|
|
|||
|
invoke GET_IO_FCB
|
|||
|
JC RAWRET1
|
|||
|
|
|||
|
TEST [SI.fcb_DEVID],080H ; output to file?
|
|||
|
JZ RAWNORM ; if so, do normally
|
|||
|
PUSH DS
|
|||
|
PUSH SI
|
|||
|
LDS SI,DWORD PTR [SI.fcb_FIRCLUS] ; output to special?
|
|||
|
TEST BYTE PTR [SI+SDEVATT],ISSPEC
|
|||
|
POP SI
|
|||
|
POP DS
|
|||
|
JZ RAWNORM ; if not, do normally
|
|||
|
INT int_fastcon ; quickly output the char
|
|||
|
JMP SHORT RAWRET
|
|||
|
RAWNORM:
|
|||
|
|
|||
|
CALL RAWOUT3
|
|||
|
RAWRET: CLC
|
|||
|
RAWRET1:
|
|||
|
POP BX
|
|||
|
return
|
|||
|
|
|||
|
;
|
|||
|
; Output the character in AL to handle in BX
|
|||
|
;
|
|||
|
entry RAWOUT2
|
|||
|
|
|||
|
invoke GET_IO_FCB
|
|||
|
retc
|
|||
|
RAWOUT3:
|
|||
|
PUSH AX
|
|||
|
JMP SHORT RAWOSTRT
|
|||
|
ROLP:
|
|||
|
invoke SPOOLINT
|
|||
|
RAWOSTRT:
|
|||
|
MOV AH,3
|
|||
|
CALL IOFUNC
|
|||
|
JZ ROLP
|
|||
|
POP AX
|
|||
|
MOV AH,2
|
|||
|
CALL IOFUNC
|
|||
|
CLC ; Clear carry indicating successful
|
|||
|
return
|
|||
|
$RAW_CON_IO ENDP
|
|||
|
|
|||
|
ASSUME DS:NOTHING,ES:NOTHING
|
|||
|
; This routine is called at DOS init
|
|||
|
|
|||
|
procedure OUTMES,NEAR ; String output for internal messages
|
|||
|
LODS CS:BYTE PTR [SI]
|
|||
|
CMP AL,"$"
|
|||
|
retz
|
|||
|
invoke OUT
|
|||
|
JMP SHORT OUTMES
|
|||
|
return
|
|||
|
OutMes ENDP
|
|||
|
ASSUME SS:DOSGROUP
|
|||
|
|
|||
|
BREAK <$Parse_File_Descriptor -- Parse an arbitrary string into an FCB>
|
|||
|
procedure $PARSE_FILE_DESCRIPTOR,NEAR
|
|||
|
ASSUME DS:NOTHING,ES:NOTHING
|
|||
|
|
|||
|
; Inputs:
|
|||
|
; DS:SI Points to a command line
|
|||
|
; ES:DI Points to an empty FCB
|
|||
|
; Bit 0 of AL = 1 At most one leading separator scanned off
|
|||
|
; = 0 Parse stops if separator encountered
|
|||
|
; Bit 1 of AL = 1 If drive field blank in command line - leave FCB
|
|||
|
; = 0 " " " " " " - put 0 in FCB
|
|||
|
; Bit 2 of AL = 1 If filename field blank - leave FCB
|
|||
|
; = 0 " " " - put blanks in FCB
|
|||
|
; Bit 3 of AL = 1 If extension field blank - leave FCB
|
|||
|
; = 0 " " " - put blanks in FCB
|
|||
|
; Function:
|
|||
|
; Parse command line into FCB
|
|||
|
; Returns:
|
|||
|
; AL = 1 if '*' or '?' in filename or extension, 0 otherwise
|
|||
|
; DS:SI points to first character after filename
|
|||
|
|
|||
|
invoke MAKEFCB
|
|||
|
PUSH SI
|
|||
|
invoke get_user_stack
|
|||
|
POP [SI.user_SI]
|
|||
|
return
|
|||
|
$PARSE_FILE_DESCRIPTOR ENDP
|
|||
|
|
|||
|
BREAK <$Create_Process_Data_Block,SetMem -- Set up process data block>
|
|||
|
;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
|
|||
|
; C A V E A T P R O G R A M M E R ;
|
|||
|
; ;
|
|||
|
procedure $Dup_PDB,NEAR
|
|||
|
ASSUME DS:NOTHING,ES:NOTHING
|
|||
|
MOV BYTE PTR [CreatePDB], 0FFH ; indicate a new process
|
|||
|
$Dup_PDB ENDP
|
|||
|
|
|||
|
|
|||
|
procedure $CREATE_PROCESS_DATA_BLOCK,NEAR
|
|||
|
ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
|
|||
|
|
|||
|
; Inputs:
|
|||
|
; DX = Segment number of new base
|
|||
|
; Function:
|
|||
|
; Set up program base and copy term and ^C from int area
|
|||
|
; Returns:
|
|||
|
; None
|
|||
|
; Called at DOS init
|
|||
|
|
|||
|
MOV ES,DX
|
|||
|
TEST BYTE PTR [CreatePDB],0FFh
|
|||
|
JZ create_PDB_old
|
|||
|
MOV DS,[CurrentPDB]
|
|||
|
JMP SHORT Create_copy
|
|||
|
|
|||
|
Create_PDB_old:
|
|||
|
invoke get_user_stack
|
|||
|
MOV DS,[SI.user_CS]
|
|||
|
|
|||
|
Create_copy:
|
|||
|
XOR SI,SI ; copy all 80h bytes
|
|||
|
MOV DI,SI
|
|||
|
MOV CX,80H
|
|||
|
REP MOVSW
|
|||
|
|
|||
|
TEST BYTE PTR [CreatePDB],0FFh ; Shall we create a process?
|
|||
|
JZ Create_PDB_cont ; nope, old style call
|
|||
|
;
|
|||
|
; Here we set up for a new process...
|
|||
|
;
|
|||
|
|
|||
|
PUSH CS
|
|||
|
POP DS
|
|||
|
ASSUME DS:DOSGROUP
|
|||
|
XOR BX,BX ; dup all jfns
|
|||
|
MOV CX,FilPerProc
|
|||
|
|
|||
|
Create_dup_jfn:
|
|||
|
PUSH ES ; save new PDB
|
|||
|
invoke get_jfn_pointer ; ES:DI is jfn
|
|||
|
JC create_skip ; not a valid jfn
|
|||
|
PUSH ES ; save him
|
|||
|
PUSH DI
|
|||
|
invoke get_sf_from_jfn ; get sf pointer
|
|||
|
JC create_no_inc
|
|||
|
INC ES:[DI].sf_ref_count ; new fh
|
|||
|
|
|||
|
create_no_inc:
|
|||
|
POP DI
|
|||
|
POP ES ; get old jfn
|
|||
|
MOV AL,ES:[DI] ; get sfn
|
|||
|
POP ES
|
|||
|
PUSH ES
|
|||
|
MOV AL,ES:[BX] ; copy into new place!
|
|||
|
|
|||
|
create_skip:
|
|||
|
POP ES
|
|||
|
INC BX ; next jfn...
|
|||
|
LOOP create_dup_jfn
|
|||
|
|
|||
|
PUSH [CurrentPDB] ; get current process
|
|||
|
POP BX
|
|||
|
PUSH BX
|
|||
|
POP ES:[PDB_Parent_PID] ; stash in child
|
|||
|
MOV [CurrentPDB],ES
|
|||
|
ASSUME DS:NOTHING
|
|||
|
MOV DS,BX
|
|||
|
;
|
|||
|
; end of new process create
|
|||
|
;
|
|||
|
Create_PDB_cont:
|
|||
|
MOV BYTE PTR [CreatePDB],0h ; reset flag
|
|||
|
MOV AX,DS:[2] ; set up size for fall through
|
|||
|
|
|||
|
entry SETMEM
|
|||
|
ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
|
|||
|
|
|||
|
; Inputs:
|
|||
|
; AX = Size of memory in paragraphs
|
|||
|
; DX = Segment
|
|||
|
; Function:
|
|||
|
; Completely prepares a program base at the
|
|||
|
; specified segment.
|
|||
|
; Called at DOS init
|
|||
|
; Outputs:
|
|||
|
; DS = DX
|
|||
|
; ES = DX
|
|||
|
; [0] has INT int_abort
|
|||
|
; [2] = First unavailable segment ([ENDMEM])
|
|||
|
; [5] to [9] form a long call to the entry point
|
|||
|
; [10] to [13] have exit address (from int_terminate)
|
|||
|
; [14] to [17] have ctrl-C exit address (from int_ctrl_c)
|
|||
|
; [18] to [21] have fatal error address (from int_fatal_abort)
|
|||
|
; DX,BP unchanged. All other registers destroyed.
|
|||
|
|
|||
|
XOR CX,CX
|
|||
|
MOV DS,CX
|
|||
|
MOV ES,DX
|
|||
|
MOV SI,addr_int_terminate
|
|||
|
MOV DI,SAVEXIT
|
|||
|
MOV CX,6
|
|||
|
REP MOVSW
|
|||
|
MOV ES:[2],AX
|
|||
|
SUB AX,DX
|
|||
|
CMP AX,MAXDIF
|
|||
|
JBE HAVDIF
|
|||
|
MOV AX,MAXDIF
|
|||
|
HAVDIF:
|
|||
|
MOV BX,ENTRYPOINTSEG
|
|||
|
SUB BX,AX
|
|||
|
MOV CL,4
|
|||
|
SHL AX,CL
|
|||
|
MOV DS,DX
|
|||
|
MOV WORD PTR DS:[PDB_CPM_Call+1],AX
|
|||
|
MOV WORD PTR DS:[PDB_CPM_Call+3],BX
|
|||
|
MOV DS:[PDB_Exit_Call],(int_abort SHL 8) + mi_INT
|
|||
|
MOV BYTE PTR DS:[PDB_CPM_Call],mi_Long_CALL
|
|||
|
MOV WORD PTR DS:[PDB_Call_System],(int_command SHL 8) + mi_INT
|
|||
|
MOV BYTE PTR DS:[PDB_Call_System+2],mi_Long_RET
|
|||
|
return
|
|||
|
|
|||
|
$CREATE_PROCESS_DATA_BLOCK ENDP
|
|||
|
do_ext
|
|||
|
|
|||
|
CODE ENDS
|
|||
|
END
|
|||
|
|