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

309 lines
8.1 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.

;********************************************************
;* *
;* 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:
if netversion
and p_tkcnt[si],80H ;was TEMPKEEP on originally ?
endif
if not netversion
test p_tkcnt[si],80h
endif
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
if netversion
push si
call terminate_entry ;terminate even if SYS PD,
pop si
endif ;see ABT_CHK in ABORT.RTM
;terminate may fail if
;KEEP was set while
if not netversion
call terminate_entry
endif
oa_ret: ;TEMPKEEP was also set.
mov p_tkcnt[si],0
ret