mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-25 09:24:19 +00:00
298 lines
7.9 KiB
Plaintext
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
|