mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-24 17:04:19 +00:00
361 lines
11 KiB
Plaintext
361 lines
11 KiB
Plaintext
;*****************************************************
|
||
;*
|
||
;* SUPERVISOR INTERFACE ROUTINES
|
||
;*
|
||
;*****************************************************
|
||
|
||
;=========
|
||
user_entry:
|
||
;=========
|
||
; User Entry Point - enter here from a INT 224
|
||
;
|
||
; REGISTER USAGE
|
||
; ENTRY EXIT
|
||
; ----- ----
|
||
; CL - Function Code AX - Copy of BX
|
||
; DX - Param BX - Return
|
||
; DS - Seg Addr CX - Error Code
|
||
; ES - Segment Return
|
||
;
|
||
; DS,SI,DI,BP preserved through call
|
||
;
|
||
; SETUP FOR MPM ENVIRONMENT
|
||
; -------------------------
|
||
; contents of users stack
|
||
; Flags
|
||
; CS
|
||
; IP <- u_stack_ss,_sp
|
||
; DS = Sysdat Segment
|
||
; ES -> user_data_area (UDA)
|
||
; DX -> function parameter
|
||
; u_wrkseg == user's DS
|
||
; u_retseg == user's ES
|
||
;interrupts are off
|
||
;set up MPM,CCPM environment
|
||
cld ! mov ax,ds ;AX = user's DS
|
||
mov ds,sysdat
|
||
mov bx,rlr
|
||
mov ds,p_uda[bx] ;DS = UDA segment
|
||
mov ds:u_retseg,es ;save user's ES
|
||
|
||
;U_INSYS is count of times
|
||
;through this entry point
|
||
cmp ds:u_insys,0 ! jne noswt ;change stacks to UDA stack
|
||
;if U_INSYS = 0
|
||
;otherwise leave stack alone
|
||
|
||
;U_WRKSEG where is user's entry DS
|
||
;is saved
|
||
mov ds:u_wrkseg,ax ;wipe out earlier u_wrkseg
|
||
mov ds:u_stack_ss,ss
|
||
mov ds:u_stack_sp,sp
|
||
mov ax,ds
|
||
mov ss,ax ! mov sp,ulen ;stack starts at end of UDA
|
||
jmps uecont
|
||
noswt:
|
||
push ds:u_wrkseg ;save current u_wrkseg on UDA stack
|
||
mov ds:u_wrkseg,ax
|
||
|
||
uecont:
|
||
sti
|
||
inc ds:u_insys
|
||
mov ax,ds ! mov es,ax ;register moves are faster than
|
||
mov ds,sysdat ;push and pop, DS=SYSDAT,ES=UDA
|
||
push si ! push di ! push bp
|
||
|
||
mov u_func,cl ;record function number in UDA
|
||
xor ch,ch ;call function and do
|
||
call netchk ;netwrk chk, returns BX, ES, CX
|
||
|
||
coret:
|
||
pop bp ! pop di ! pop si
|
||
mov ax,es ;setup user's environment and return
|
||
mov ds,ax ;DS = UDA segment
|
||
mov es,ds:u_retseg ;restore ES from entry unless
|
||
;function returns a segment value
|
||
mov ax,ds:u_wrkseg ;AX = user's entry DS
|
||
cli
|
||
dec ds:u_insys ! jnz nstk ;switch back to user's stack
|
||
;if U_INSYS = 0
|
||
push bx ! push ds ! push cx ;See if process should be suspended.
|
||
mov ds,sysdat ;Since it's on its way out, it doesn't
|
||
mov bx,rlr ;own any critical regions and we can
|
||
;put it to sleep until its console is
|
||
;switched into the foreground.
|
||
mov ax,p_sflag[bx]
|
||
test ax,psf_suspend ;is this a suspendable process ?
|
||
jz coret1 ;no...
|
||
mov es,p_uda[bx] ;Set up ES = UDA
|
||
mov al,p_cns[bx]
|
||
xor ah,ah ! xor bh,bh ;get vccb's state
|
||
mov bx,ccblen ! mul bx
|
||
mov bx,ccb ! add bx,ax
|
||
mov ax, c_state[bx]
|
||
test ax,csm_suspend ;is it to be suspended now ?
|
||
jz coret1 ;no...
|
||
mov bx,rlr
|
||
push dx
|
||
mov dx, offset splr ;get suspend list for sleep_entry
|
||
mov ud_param,dx
|
||
mov cx, f_sleep ;call to RTM to place in list
|
||
xor bh,bh
|
||
mov bl,ps_ciowait ;user ciowait instead of suspend
|
||
call osif ;so the abort code will work
|
||
pop dx
|
||
coret1:
|
||
pop cx ! pop ds ! pop bx
|
||
mov ax,ds:u_wrkseg
|
||
mov es,ds:u_retseg
|
||
coret2:
|
||
mov ss,ds:u_stack_ss
|
||
mov sp,ds:u_stack_sp
|
||
jmps ueout
|
||
nstk:
|
||
sti
|
||
pop ds:u_wrkseg ;restore previous U_WRKSEG if not
|
||
;going back to user's stack
|
||
ueout: mov ds,ax ;DS = user's entry DS
|
||
mov ax,bx ;parameter return BX = AX
|
||
inc ax
|
||
jz u_err1 ;CX=error code if AX,BX=0FFFFH
|
||
xor cx,cx ;CX always 0 if no error
|
||
u_err1:
|
||
dec ax
|
||
iret ;back to user ...
|
||
;restore interrupts as they
|
||
;were on entry
|
||
|
||
sysfunc: ; call system function
|
||
;------- -----------------------
|
||
; entry: if CH <> 0 then CH is module number
|
||
; (usually 1:SUP, 2:RTM, 3:MEM, 4:CIO, 5:BDOS)
|
||
; network check is bypassed
|
||
; if CH = 0 then network check is done
|
||
; CL = function #
|
||
; DX = arg
|
||
; BX = arg
|
||
; exit: BX = return value
|
||
; ES = segment return value
|
||
; CX = error code if BX = 0FFFFH
|
||
|
||
test ch,ch ! jz netchk ;network or local
|
||
mov ax,cx ! jmps localfunc ;in local module
|
||
|
||
|
||
illfunc: ;illegal function number
|
||
jmp i_ent
|
||
|
||
netchk:
|
||
; enter here for network check
|
||
; check for function numbers represented in function table,
|
||
; ENTTAB_TABLE. Table space is saved by making the functions
|
||
; contiguous as we check the range.
|
||
; The table has entries for functions 0-80, 98-116, 128-164.
|
||
; Numbers 70-97, 117-127, 165-255 are not in the table.
|
||
; Illegal functions in this table return the error codes
|
||
; not implemented (1) or illegal function number (2).
|
||
; Function not in the table return the illegal function number
|
||
; code.
|
||
; To add a new user function modify the files SYSDAT.DAT and
|
||
; MODFUNC.DEF as well as the ranges immediately
|
||
; below. All of the modules SUP,RTM,MEM,CIO,BDOS,SYSDAT must
|
||
; then be reassembled.
|
||
if netversion
|
||
mov ax,cx
|
||
cmp al,80 ! jbe okfunc
|
||
sub al,17 ! cmp al,81 ! jb illfunc
|
||
cmp al,99 ! jbe okfunc
|
||
sub al,11
|
||
;
|
||
; 3.1M patch for illegal function numbers 117-127
|
||
;
|
||
cmp al,100 ! jb illfunc ;117 -127 are now 89 -99
|
||
cmp al,136 ! ja illfunc
|
||
;
|
||
; end of 3.1M patch
|
||
;
|
||
endif
|
||
if not netversion
|
||
cmp cl,80 ! jbe okfunc
|
||
sub cl,17 ! cmp cl,81 ! jb illfunc ;98-116 are now 81-99
|
||
cmp cl,99 ! jbe okfunc ;128-164 are now 100-136
|
||
sub cl,11
|
||
;
|
||
; 3.1M patch for illegal functions 117-127
|
||
;
|
||
cmp cl,100 ! jb illfunc ;117 -127 are now 89 - 99
|
||
cmp cl,136 ! ja illfunc
|
||
;
|
||
; end of 3.1M patch
|
||
;
|
||
endif
|
||
okfunc:
|
||
if netversion
|
||
shl ax,1
|
||
mov si,ax
|
||
mov ax,word ptr sysent[si]
|
||
test ah,net_bit
|
||
jz localfunc
|
||
and ah, not net_bit
|
||
mov bl,module_map
|
||
test bl,netmod_bit
|
||
je localfunc
|
||
push ax
|
||
callf dword ptr .netmod
|
||
cmp al,0ffh
|
||
pop ax
|
||
je localfunc
|
||
mov ax,bx
|
||
ret
|
||
endif
|
||
if not netversion
|
||
;CL is now 0 - num entries
|
||
;- 1 in entry table
|
||
mov si,cx ! shl si,1 ;times 2 for entry table
|
||
add si,offset sysent ;AH high nibble flags
|
||
mov ax,enttab_entry[si] ;AH low nibble module
|
||
;AL function number
|
||
;within module
|
||
test ah,net_bit ! jz localfunc ;not a network function
|
||
and ah,not net_bit ;turn off network bit
|
||
mov al,module_map
|
||
test al,netmod_bit ! je localfunc ;network module is not there
|
||
push ax
|
||
callf dword ptr .netmod ;call network CL = func
|
||
cmp al,true ;if AL=0FFH do func locally
|
||
pop ax ;in addition over network
|
||
jne localfunc
|
||
mov ax,bx ! ret
|
||
endif
|
||
|
||
localfunc: ;not over the network
|
||
cmp ah,sup ! je insup ;AH=module, AL=function
|
||
mov cl,ah
|
||
mov ch,module_map ! shr ch,cl ;does module exist ?
|
||
jnc badmod
|
||
xor ch,ch ! dec cx ;make module 0 relative
|
||
shl cx,1 ! shl cx,1 ! shl cx,1 ;* 8
|
||
mov si,cx ! mov cl,al ;func # in CL
|
||
callf dword ptr module_table[si]
|
||
ret
|
||
badmod:
|
||
jmp n_imp
|
||
insup:
|
||
xor ah,ah
|
||
shl ax,1 ! mov si,ax ; mov cx,ax
|
||
jmp cs:supfunc[si]
|
||
|
||
;=====
|
||
entry: ; Supervisor module entry point
|
||
;===== -------------------------------
|
||
;
|
||
; Arrive here usually on a CALLF using address
|
||
; at SYSDAT:4. Note: flag set is handled specially.
|
||
;
|
||
; entry: if CH <> 0 then CH is module number
|
||
; (usually 1:SUP, 2:RTM, 3:MEM, 4:CIO, 5:BDOS)
|
||
; network check is bypassed
|
||
; if CH = 0 then network check is done;
|
||
; CL = function #. If CH = 0 then CL is treated
|
||
; as a function number used with an INT 224:
|
||
; it is a USER function.
|
||
; If CH is not 0 then CL is the function number
|
||
; within the module specified by CH.
|
||
; The file MODFUNC.DEF contains the equates
|
||
; used for accessing functions from within the O.S.
|
||
; These functions are INTERNAL functions.
|
||
; Note the INTERNAL functions are a superset of
|
||
; the USER functions. The equates for USER
|
||
; functions in MODFUNC.DEF have a 0 for the high byte
|
||
; forcing network checking from this entry point.
|
||
; An example: if f_conin (from MODFUNC.DEF) is
|
||
; equal to 0001H. A Console output call to this
|
||
; entry point thus result in CH = 0, CL = 1.
|
||
; DX = arg
|
||
; BX = arg
|
||
;
|
||
; exit: BX = return value
|
||
; ES = segment return value
|
||
; CX = error code if BX = 0FFFFH
|
||
|
||
|
||
cmp cx,f_flagset ! jne notfs ;flag set is exception:
|
||
mov cx,f_inflagset ;do not go over network,
|
||
call sysfunc ;make path shorter,
|
||
mov ax,bx ;parameter return BX = AX
|
||
inc ax ;AX=0FFFFH if error
|
||
jz u_err2 ;CX= error code if AX,BX=0FFFFH
|
||
xor cx,cx ;CX=0 if no error
|
||
u_err2:
|
||
dec ax ;set AX back to 0 or 0FFFFH
|
||
retf ;DS must equal system
|
||
notfs: ;data segment
|
||
|
||
;mov u_unused,cx ;save 16 bit function number
|
||
call osif ! retf
|
||
|
||
osif: ;point SUP uses to get
|
||
;to other modules
|
||
push u_wrkseg ;save current u_wrkseg
|
||
mov ax,ds
|
||
mov u_wrkseg,ax
|
||
mov ax,sysdat
|
||
mov ds,ax
|
||
call sysfunc
|
||
mov ax,u_wrkseg
|
||
mov ds,ax
|
||
pop u_wrkseg
|
||
mov ax,bx ;BX,CX are return codes
|
||
inc ax ;AX=0FFFFH if error
|
||
jz u_err3 ;CX= error code if AX,BX=0FFFFH
|
||
xor cx,cx ;CX=0 if no error
|
||
u_err3:
|
||
dec ax ;set AX back to 0 or 0FFFFH
|
||
ret
|
||
|
||
|
||
;=========
|
||
user_retf:
|
||
;=========
|
||
; If a user process does a RETF to terminate,
|
||
; the process ends here. The Load function sets up
|
||
; the default stack to point here.
|
||
|
||
mov bx,rlr
|
||
and p_flag[bx],not pf_keep+pf_tempkeep+pf_ctlc+pf_sys
|
||
mov cx,f_terminate
|
||
xor dx,dx
|
||
int osint ;make sure the terminate
|
||
;succeed by reseting the
|
||
;the keep,tempkeep,ctlc,sys flags
|
||
|
||
;======
|
||
xiosif:
|
||
;======
|
||
callf dword ptr .xiosmod ! ret
|
||
|
||
;*****************************************************
|
||
;*
|
||
;* Supervisor function table
|
||
;*
|
||
;*****************************************************
|
||
|
||
org ((offset $)+1) AND 0fffeh ;Word Boundary
|
||
|
||
supfunc dw n_imp ; 0-not implemented
|
||
dw i_ent ; 1-illegal function number
|
||
dw bver_ent ; 2-(12)get BDOS version
|
||
dw cbios_ent ; 3-(50)call bios
|
||
dw load_ent ; 4-(59)user load function
|
||
dw cli_ent ; 5-(150)CLI
|
||
dw rpl_ent ; 6-(151)Call RPL
|
||
dw parse_ent ; 7-(152)parse filename
|
||
dw sdat_ent ; 8-(154)get sysdat addr
|
||
dw tod_ent ; 9-(155)get tod addr
|
||
dw load ; 10-load function
|
||
dw over_ent ; 11-O.S. version number
|
||
dw chain_ent ; 12-(47)Program Chain
|
||
dw ser_ent ; 13-(107)return serial
|
||
dw cload_ent ; 14-chain load function
|
||
|
||
|