mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-25 01:14:21 +00:00
238 lines
6.8 KiB
Plaintext
238 lines
6.8 KiB
Plaintext
|
||
;*****************************************************
|
||
;*
|
||
;* Queue Routines
|
||
;*
|
||
;*****************************************************
|
||
|
||
;=========== =======================
|
||
makeq_entry: ; Create a System Queue
|
||
;=========== =======================
|
||
; input : DX = address of QD in u_wrkseg
|
||
; u_wrkseg = segment of QD
|
||
; output: BX = 0 if okay , 0ffffh if error
|
||
; CX = Error Code
|
||
|
||
call getqdaddr ! mov di,dx ;DI->QD addr
|
||
cmp cx,0 ! je qm_chk
|
||
mov bx,0ffffh ! ret
|
||
;Make sure this queue doesn't already exist
|
||
qm_chk: pushf ! cli
|
||
push es ! mov es,sysdat
|
||
mov si,(offset qlr)-q_link
|
||
qm_nxt: mov si,q_link[si]
|
||
cmp si,0 ! je qm_go
|
||
push di ! push si ! mov cx,qnamsiz/2
|
||
add di,q_name ! add si,q_name
|
||
repe cmpsw
|
||
pop si ! pop di ! jne qm_nxt
|
||
;Names match
|
||
mov bx,0ffffh ! mov cx,e_q_inuse
|
||
pop es ! popf ! ret
|
||
qm_go: pop es
|
||
;We have a QD initialize it
|
||
mov dx,0 ! mov q_dq[di],dx
|
||
mov q_nq[di],dx ! mov q_msgcnt[di],dx
|
||
mov q_msgout[di],dx
|
||
;put it on QLR
|
||
mov ax,qlr ! mov q_link[di],ax
|
||
mov qlr,di ! sub bx,bx
|
||
mov cx,bx ! popf ! ret
|
||
|
||
;=========== ======================
|
||
openq_entry: ; Find an active Queue
|
||
;=========== ======================
|
||
; input: DX = address of QPB
|
||
; segment is u_wrkseg
|
||
; output: Fills QPB with appropriate info
|
||
; BX = 0 if okay, 0ffffh if not
|
||
; CX = Error Code
|
||
|
||
pushf ! cli
|
||
push es ! mov es,u_wrkseg
|
||
mov si,(offset qlr)-q_link ! mov di,dx
|
||
qo_nqd: mov si,q_link[si]
|
||
cmp si,0 ! je qo_noq
|
||
push di ! push si ! mov cx,qnamsiz/2
|
||
add si,q_name ! add di,qpb_name
|
||
repe cmpsw
|
||
pop si ! pop di ! jne qo_nqd
|
||
;Names match
|
||
mov es:qpb_qaddr[di],si
|
||
sub bx,bx ! mov cx,bx
|
||
pop es ! popf ! ret
|
||
qo_noq: ;No name matches
|
||
mov cx,e_no_queue ! mov bx,0ffffh
|
||
pop es ! popf ! ret
|
||
|
||
;============= =======================
|
||
deleteq_entry: ; Delete a System Queue
|
||
;============= =======================
|
||
; Takes a qd off the qlr and places it in the qul.
|
||
; input: DX = offset of QPB
|
||
; in u_wrkseg
|
||
; output: BX = 0 if ok, 0ffffh if bad
|
||
; CX = Error Code
|
||
|
||
pushf ! cli
|
||
push es ! mov es,u_wrkseg
|
||
mov di,dx ! add di,qpb_qaddr
|
||
mov di,es:[di]
|
||
mov ax,q_dq[di] ! mov dx,q_nq[di]
|
||
add dx,ax ! jnz qd_use
|
||
mov bx,(offset qlr)-q_link
|
||
qd_nqd: mov si,q_link[bx]
|
||
cmp si,0 ! jz qd_noq
|
||
cmp si,di ! jne qd_neq
|
||
mov ax,q_link[si]!mov q_link[bx],ax
|
||
call remqd
|
||
mov bx,0 ! mov cx,bx
|
||
pop es ! jmps qd_e
|
||
qd_neq: mov bx,si ! jmps qd_nqd
|
||
qd_noq: mov cx,e_q_notactive ! jmps qd_be
|
||
qd_use: pop ax ! mov cx,e_q_inuse
|
||
qd_be: mov bx,0ffffh
|
||
qd_e: popf ! ret
|
||
|
||
;=========== ============
|
||
readq_entry: ; Read Queue
|
||
;=========== ============
|
||
mov ax,0 ! jmps readq
|
||
|
||
;============
|
||
creadq_entry: ; Conditional Read Queue
|
||
;============
|
||
mov ax,0ffffh
|
||
; jmps readq
|
||
|
||
readq: ; Read message from queue
|
||
;----- -------------------------
|
||
; If no buffer is available, the process is placed into the DQ list
|
||
; of the queue and waits until another process writes into the queue.
|
||
; input: DX = address of qpb in u_wrkseg
|
||
; AX = 0ffffh if conditional
|
||
; 0 if not
|
||
; output: BX = 0 if okay
|
||
; 0ffffh if error
|
||
; CX = Error Code
|
||
|
||
push ax ! call queverify ! pop ax
|
||
cmp cx,0 ! je qr_ver
|
||
mov bx,0ffffh ! ret
|
||
qr_ver: push es ! mov es,u_wrkseg
|
||
mov si,dx ;es:[si]->QPB
|
||
mov bx,es:qpb_qaddr[si] ;bx->QD
|
||
mov di,es:qpb_buffptr[si] ;es:[di]->buff
|
||
pushf ! cli
|
||
mov cx,q_msgcnt[bx]
|
||
cmp cx,0 ! jne qr_gmsg
|
||
inc ax ! jnz qr_wait
|
||
mov bx,0ffffh ! mov cx,e_q_empty
|
||
popf ! pop es ! jmps qr_exit
|
||
qr_wait: lea dx,q_dq[bx] ;DX=addr of DQ List
|
||
mov bx,rlr ! mov p_stat[bx],ps_dq ;status=DQ
|
||
popf ! pop es ! push si
|
||
mov cx,f_sleep ! call mpmif ;Sleep on DQ List
|
||
pop dx ! jmps qr_ver
|
||
qr_gmsg:mov cx,q_msglen[bx]
|
||
cmp cx,0 ! jne qr_lmsg
|
||
mov cx,q_flags[bx] ; msglen=0
|
||
and cx,qf_mx ! jz qr_finish
|
||
mov ax,rlr ;Its a MX queue
|
||
mov q_buf[bx],ax ;BUF = PD addr (owner)
|
||
jmps qr_finish
|
||
qr_lmsg: ; msglen > 0
|
||
mov ax,q_msgout[bx] ! push ax
|
||
mul cx ! add ax,q_buf[bx]
|
||
mov si,ax ! rep movsb
|
||
pop ax ! inc ax
|
||
cmp ax,q_nmsgs[bx] ! jne qr_nend
|
||
mov ax,0
|
||
qr_nend:mov q_msgout[bx],ax
|
||
qr_finish:
|
||
dec q_msgcnt[bx] ! popf
|
||
mov si,bx ! pop es
|
||
lea dx,q_nq[si] ;DX = NQ List
|
||
mov cx,f_wakeup ;Wakeup a process
|
||
call mpmif ; waiting to write
|
||
mov cx,0 ! mov bx,cx
|
||
qr_exit:ret
|
||
|
||
;============ =============
|
||
writeq_entry: ; Write Queue
|
||
;============ =============
|
||
mov ax,0 ! jmps writeq
|
||
|
||
;============= =========================
|
||
cwriteq_entry: ; conditional Write Queue
|
||
;============= =========================
|
||
mov ax,0ffffh
|
||
;jmps writeq
|
||
|
||
writeq: ; Write message into queue
|
||
;------ --------------------------
|
||
; If no buffer is available, the process is placed into the NQ list
|
||
; of the queue and waits until another process reads from the queue.
|
||
; input: DX = address of qpb in u_wrkseg
|
||
; BX = pd address
|
||
; AX = 0ffffh if conditional
|
||
; 0 if not
|
||
; output: BX = 0 if okay
|
||
; 0ffffh if error
|
||
; CX = Error Code
|
||
|
||
push ax ! call queverify ! pop ax
|
||
cmp cx,0 ! je qw_ver
|
||
mov bx,0ffffh ! ret
|
||
qw_ver: push es ! mov es,u_wrkseg
|
||
mov di,dx ; es:[di]->QPB
|
||
mov bx,es:qpb_qaddr[di] ; bx -> QD
|
||
mov si,es:qpb_buffptr[di] ; es:[si]->QPB.buff
|
||
pushf ! cli
|
||
mov cx,q_msgcnt[bx]
|
||
cmp cx,q_nmsgs[bx] ! jne qw_gbuf
|
||
inc ax ! jnz qw_wait
|
||
popf ! pop es ! mov bx,0ffffh
|
||
mov cx,e_q_full ! jmps qw_exit
|
||
qw_wait: lea dx,q_nq[bx] ;DX = NQ List
|
||
mov bx,rlr ! mov p_stat[bx],ps_nq ;status=NQ
|
||
popf ! pop es ! push si
|
||
mov cx,f_sleep ! call mpmif ;Sleep on NQ List
|
||
pop dx ! jmps qw_ver ;try again
|
||
qw_gbuf:mov cx,q_msglen[bx] ;there is a buffer
|
||
cmp cx,0 ! je qw_fin
|
||
mov ax,q_msgout[bx] ! add ax,q_msgcnt[bx]
|
||
cmp ax,q_nmsgs[bx] ! jb qw_move
|
||
sub ax,q_nmsgs[bx]
|
||
qw_move: mul cx ! add ax,q_buf[bx]
|
||
mov di,ax ;DI=start of new msg
|
||
push ds ! push es ! pop ds ! pop es
|
||
rep movsb ; copy message
|
||
push ds ! push es ! pop ds ! pop es
|
||
qw_fin: inc q_msgcnt[bx]
|
||
mov cx,q_flags[bx] ! and cx,qf_mx
|
||
jz qw_nomx
|
||
mov q_buf[bx],0 ;an MX queue,no owner
|
||
qw_nomx:mov si,bx ! popf ! pop es
|
||
lea dx,q_dq[si] ;DX = DQ List
|
||
mov cx,f_wakeup ;Wakeup a process trying
|
||
call mpmif ; to read a message
|
||
sub bx,bx ! mov cx,bx
|
||
qw_exit:ret
|
||
|
||
|
||
queverify: ; check QLR for existence of QD address
|
||
;--------- ---------------------------------------
|
||
; input: DX = offset of QPB
|
||
; output: CX = error code
|
||
|
||
push ds ! mov ds,u_wrkseg
|
||
mov bx,dx ! mov si,qpb_qaddr[bx] ! pop ds
|
||
mov bx,offset qlr
|
||
qv_nxt: mov bx,q_link[bx]
|
||
cmp bx,0 ! jne qv_chk
|
||
mov cx,e_no_queue ! ret
|
||
qv_chk: cmp bx,si ! je qv_fnd
|
||
jmps qv_nxt
|
||
qv_fnd: mov cx,0 ! ret
|
||
|