Files
Digital-Research-Source-Code/CPM OPERATING SYSTEMS/CPM 86/CONCURRENT/CCPM-86 2.0 SOURCE/kern/sysent.rtm
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

298 lines
7.9 KiB
Plaintext

;********************************************************
;* *
;* SYSTEM ENTRY FUNCTIONS *
;* *
;********************************************************
;========== =========================
poll_entry: ; Poll device - DL=device
;========== =========================
mov ax,rlr
mov bx,ax
mov p_wait[bx],dx
mov dx,offset plr
mov bl,ps_poll
jmp sleep_entry
;=========== ===================
delay_entry: ;Delay - DX = ticks
;=========== ===================
mov bx,rlr
mov p_stat[bx],ps_delay
mov u_dparam,dx
xor bx,bx ;return success after coming back into
jmp dsptch ;context from the dispatcher
;=============== ==============
dispatch_entry: ;Call dispatch
;=============== ==============
xor bx,bx ;return success ala DELAY_ENTRY:
jmp pdisp
;=============== ===========================
set_prior_entry: ;Set Priority - DX=priority
;=============== ===========================
mov bx,rlr
mov p_prior[bx],dl
xor bx,bx ;return success ala DELAY_ENTRY:
jmp pdisp
;======== ==================
pd_entry: ;Return addr of PD
;======== ==================
mov u_retseg,ds
mov bx,rlr
ret
;================ ============================
creat_proc_entry: ;Create Process - DX->new PD
;================ ============================
call proc_creat ! jmp pdisp
;=========== ==============================
sleep_entry: ;Put Calling PD on System List
;=========== ==============================
; entry: DX = list root to sleep on
; BL = sleep status passed to the dispatcher in
; the PD.P_WAIT field and becomes the PD.STATUS
; when sleeping
; interrupts are typically off to ensure
; the PD sleeps on the specified list
; before another process runs.
; exit: BX = 0 to indicate success after return from dispatcher
; if entered with interrupts off the process will return
; from the dispatcher with them still off
mov ax,rlr ! mov si,ax
mov ax,dx ! mov u_dparam,ax
mov p_scratch[si],bl
mov p_stat[si],ps_sleep
xor bx,bx
jmp dsptch
;============ ==============================
wakeup_entry: ;wakeup top PD in System List
;============ ==============================
; entry: DX = List Root Address
; exit: first PD on list is the last entry on the DRL
; Puting the process on the end of the DRL allows the
; process to run before equal priority processes waking up
; from flag sets, i.e., interrupts.
; To work, the dispatcher must disable interrupts
; from when the last process on the DRL is placed on the
; RLR to when the process is back in context and
; turns on the interrupt flag.
pushf ! cli
mov bx,dx ! mov si,[bx] ;SI=PD to wake
test si,si ! jz wke_out ;check for a process to wake up
mov ax,p_link[si] ;take PD off list
mov [bx],ax ;set list root to next PD
mov di,offset drl - p_link ;go to the end of DRL
xor ax,ax ;AX=0
wu_drl:
cmp p_link[di],ax
je wu_drlend
mov di,p_link[di] ! jmps wu_drl
wu_drlend:
mov p_link[di],si ;make waking PD last on DRL
mov p_link[si],ax ;0 the end of the DRL
mov p_stat[si],ps_run ;new status
call pdisp
wke_out:
popf ! ret
;========== ========================
sync_entry: ;Obtain mutual exclusion
;========== ========================
; entry: interrupts on or off
; BX = Sync Parameter Block
; exit: ownership of Sync Parameter Block,
; interrupt state unchanged
; Obtain ownership of mutually exclusive section of code
; without using MXqueues. A process only sleeps temporarily
; on a SYNC structure. A process that obtains the
; SYNC must call UNSYNC when finished with the
; protected data structure and before sleeping or
; calling SYNC with on a different SYNC structure.
mov ax,rlr
mov si,ax ;AX=SI calling process
pushf ! cli
xchg ax,sy_owner[bx] ;AX=owner
test ax,ax ;0 nobody owns it
jz s_got_it
cmp ax,si ;do we already own it ?
je s_got_it
mov sy_owner[bx],ax ;restore owner
lea dx,sy_wait[bx] ;list to sleep on
mov bl,ps_sync ;sleep with sync status
call sleep_entry
;awaken with sync ownership
s_got_it:
popf ! ret ;we own the SPB
;============ ==========================
unsync_entry: ;release mutual exlclusion
;============ ==========================
;
; entry: BX = Sync Parameter Block
; exit: SYNC_OWNER changed to the PD in the SY_NEXT
; field if SY_NEXT is non 0. The PD in the SY_NEXT
; must have a 0 P_LINK. If SY_NEXT=0, the SY_OWNER
; field is changed to the first PD on the SY_WAIT
; list. If SY_WAIT is 0, SY_OWNER becomes 0.
mov ax,rlr
cmp ax,sy_owner[bx] ;do we own it ?
jne us_ret
xor ax,ax
pushf ! cli ;no other process can change SYNC or DRL
xchg ax,sy_next[bx] ;0 SY_NEXT field
test ax,ax ;assigned next process ?
jz us_wait
mov si,ax
jmps us_own
us_wait:
mov si,sy_wait[bx] ;give the sync to first waiting process
test si,si ;no waiting PD ?
jz us_zero
mov ax,p_link[si]
mov sy_wait[bx],ax
mov p_link[si],0
us_own:
mov p_stat[si],ps_run
mov ax,drl
mov p_link[si],ax ;put process on DRL
mov drl,si
us_zero:
mov sy_owner[bx],si ;SI=0 or process to now own sync
popf ;allow interrupts
us_ret: ;wait for next dispatch
ret
;================= ============================
assign_sync_entry: ;give away mutual exlclusion
;================= ============================
; interrupts on
; entry:
; BX = Sync Parameter Block
; DX = address of list root, assign
; SPB to first PD on list
; exit: none
;
mov ax,rlr
cmp sy_owner[bx],ax ;check that we own the resource
jne as_ret
mov si,dx ;SI=list root
pushf ! cli ;no other process can run
mov di,[si] ;get first PD from list
test di,di ;test for 0 list
jz as_done
mov ax,p_link[di] ;take PD off list
mov [si],ax
mov p_link[di],0 ;0 link of NEXT PD
;status is still PS_SLEEP.
;if TEMPKEEP is on ABORT_SPEC
;will just turn on CTLC flag.
;if no TEMPKEEP, ABORT_SPEC
;will not find PD on the U_DPARAM
;list and will fail.
mov sy_next[bx],di ;see UN_SYNC_ENTRY
;for use of SYNC_NEXT field
as_done:
popf
as_ret:
ret
;==============
no_abort_entry:
;==============
; Keep the calling process from being aborted by
; using the PF_TEMPKEEP flag.
; Turn on the PF_TEMPKEEP flag and
; increment the P_TKEEPCNT.
; entry: none
; exit: PD fields altered
; interrupt state unaltered
; This code must be exclusive of ABORT_SPEC's testing
; and acting on the PD flags.
mov ax,rlr
mov si,ax
na_spec:
cmp p_tkcnt[si],0
jne na_saved
test p_flag[si],pf_tempkeep
jz na_saved
or p_tkcnt[si],80h ;save orignal TEMPKEEP in MSB
na_saved: ;until rest of O.S. is fixed
or p_flag[si],pf_tempkeep
inc p_tkcnt[si]
ret
;===================
no_abort_spec_entry:
;===================
; Keep the specified process from being aborted by setting
; its TEMPKEEP flag.
; entry: DX=PD address, interrupts off
; exit: PD TEMPKEEP turned on, TKCNT incremented
mov si,dx
jmps na_spec
;==============
ok_abort_entry:
;==============
; Allow the calling process to be aborted if
; the PF_TEMPKEEP flag is keeping it from being aborted.
; P_TKCNT is decremented in the PD, if P_TKCNT
; is = 0 then PF_TEMPKEEP is turned off and PF_CTLC
; flag is tested.
; Interrupts should be turned off if an NO_ABORT_SPEC
; can be performed on a process running this code.
; entry: none
; exit: PD fields altered
mov ax,rlr
mov si,ax
mov al,p_tkcnt[si]
and al,07FH ;high bit is original TEMPKEEP
dec al
jz oa_restore ;assume
dec p_tkcnt[si] ;no borrow from MSB
ret
oa_restore:
test p_tkcnt[si],80H ;was TEMPKEEP on originally ?
jnz oa_ret ;if it was don't chk CTLC here
;turn off TEMPKEEP
and p_flag[si],not pf_tempkeep
test p_flag[si],pf_ctlc
jz oa_ret
mov dx,0ffffh ;if PF_CTLC is set ok to
call terminate_entry ;terminate even if SYS PD,
;see ABT_CHK in ABORT.RTM
;terminate may fail if
;KEEP was set while
oa_ret: ;TEMPKEEP was also set.
mov p_tkcnt[si],0
ret