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