Files
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

361 lines
11 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;*****************************************************
;*
;* 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