mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-25 17:34:06 +00:00
225 lines
5.7 KiB
Plaintext
225 lines
5.7 KiB
Plaintext
;****************************************************************
|
|
;* *
|
|
;* Queue system subroutines: Q System must be owned *
|
|
;* before calling any of the following routines *
|
|
;* *
|
|
;****************************************************************
|
|
|
|
queverify: ; check QLR for existence of QD address
|
|
;--------- ---------------------------------------
|
|
; entry: U_WRKSEG:DX = offset of QPB
|
|
; exit: CX = 0 if queue is found
|
|
; CX = E_NO_QUEUE error code, if not
|
|
; BX=SI=QD offset
|
|
; ES,DX preserved
|
|
|
|
push es ;save UDA
|
|
mov es,u_wrkseg
|
|
mov bx,dx ;ES:BX->QPB
|
|
mov bx,es:qpb_qaddr[bx] ;get QD from user's QPB
|
|
pop es ;restore UDA
|
|
lea si,qlr-q_link
|
|
qv_nxt:
|
|
mov si,q_link[si] ;SI addresses of valid QDs
|
|
test si,si ! jz qv_nqf
|
|
cmp bx,si ! jne qv_nxt
|
|
xor cx,cx ! ret ;BX=SI=QD offset, return success
|
|
qv_nqf:
|
|
mov cx,e_no_queue ;couldn't find the queue
|
|
ret
|
|
|
|
getqdaddr:
|
|
;----------
|
|
; entry: DX = offset of QD in U_WRKSEG
|
|
; exit: DI = offset of QD in SYSDAT
|
|
;
|
|
; If QD address is within SYSDAT use it.
|
|
; Else get a QD from QDUL and set QF_TABLE flag.
|
|
; If Q_NMSGS=0 in QD then return error.
|
|
; If 0 length buffer needed, zero the Q_BUF field.
|
|
; If buffer space is within SYSDAT use it. Else get buffer
|
|
; from QMAU. Return the QD address within SYSDAT.
|
|
|
|
push dx ;save QD offset
|
|
mov bx,qdlen
|
|
call sysdat_chk
|
|
jcxz g_qul ;CX=0 if not within SYSDAT
|
|
mov ax,u_wrkseg ;# of paragraphs to U_WRKSEG
|
|
mov bx,ds
|
|
sub ax,bx ;from SYSDAT
|
|
mov cl,4 ! shl ax,cl ;make into # of bytes
|
|
pop di ;DI=QD in U_WRKSEG
|
|
add di,ax ;make QD relative to SYSDAT
|
|
jmps g_qd
|
|
g_qul:
|
|
mov di,qul ;get QD from QUL
|
|
test di,di ;DI=unused QD
|
|
jnz g_gotqd
|
|
pop dx
|
|
mov cx,e_no_qd ;no QD available
|
|
ret
|
|
g_gotqd:
|
|
mov ax,q_link[di]
|
|
mov qul,ax
|
|
pop si ;SI=QD in U_WRKSEG
|
|
push di ;save SYSDAT QD
|
|
mov cx,qdlen/2
|
|
; ES=UDA, DS=SYSDAT
|
|
mov ax,ds
|
|
mov ds,u_wrkseg ; DS:SI = QD in U_WRKSEG
|
|
push es ! mov es,ax ; ES:DI = QD in SYSDAT
|
|
rep movsw ; copy QD into QD in SYSDAT
|
|
mov ax,es ! mov ds,ax
|
|
pop es ; ES=UDA, DS=SYSDAT
|
|
pop di ; SYSDAT:DI -> New QD
|
|
or q_flags[di],qf_table ; Set "from table" flag
|
|
|
|
g_qd: ;DI=QD in SYSDAT
|
|
xor cx,cx ;CX=0
|
|
cmp q_nmsgs[di],cx ;must have one or more msgs
|
|
jne g_buflen ;or illegal queue
|
|
mov cx,e_no_qbuf
|
|
jmps g_qdfree
|
|
g_buflen: ;if MX or buffer length is zero
|
|
test q_flags[di],qf_mx ;0 Q_BUF field and return
|
|
jnz g_mx ;CX=0 to indicate success
|
|
cmp q_msglen[di],cx
|
|
jne g_getbuf
|
|
g_mx:
|
|
mov q_buf[di],cx
|
|
ret
|
|
g_getbuf: ;non 0 length buffer needed
|
|
cmp q_buf[di],0 ;is there a buffer specified?
|
|
je g_buf
|
|
mov ax,q_msglen[di] ;yes make sure it fits in SYSDAT
|
|
mul q_nmsgs[di] ;AX=needed buffer space
|
|
mov bx,ax
|
|
mov dx,q_buf[di]
|
|
call sysdat_chk
|
|
jcxz g_buf ;CX=0 not within SYSDAT
|
|
mov ax,u_wrkseg ;# of paragraphs to U_WRKSEG
|
|
mov bx,ds
|
|
sub ax,bx ;from SYSDAT
|
|
mov cl,4 ! shl ax,cl ;make into # of bytes
|
|
add q_buf[di],ax ;make buffer relative to SYSDAT
|
|
xor cx,cx ;indicate success
|
|
ret
|
|
|
|
g_buf: ;allocate buffer space to queue
|
|
call qspace
|
|
jcxz g_ret
|
|
mov cx,e_no_qbuf ;no buffer space
|
|
g_qdfree:
|
|
mov ax,qul ;error return QD to QUL
|
|
mov q_link[di],ax
|
|
mov qul,di ;CX = error code
|
|
g_ret:
|
|
ret
|
|
|
|
|
|
sysdat_chk:
|
|
;----------
|
|
; entry: DX = offset of data structure to check
|
|
; relative to U_WRKSEG
|
|
; BX = length of data structure
|
|
; exit: CX <> 0 if within SYSDAT
|
|
; or wrap around
|
|
; CX = 0 if not within SYSDAT
|
|
; SI,DI preserved
|
|
|
|
; Check data structure for being within SYSDAT
|
|
; Also check that data structure doesn't wrap
|
|
; around at 64K, or 1 megabyte.
|
|
|
|
add dx,bx ;find end of data structure
|
|
jc sc_no ;check for 64K wrap around
|
|
add dx,0fh
|
|
mov cl,4 ;round up to next paragraph
|
|
shr dx,cl ;1st paragraph after struct relative
|
|
add dx,u_wrkseg ;to U_WRKSEG
|
|
jc sc_no ;next paragraph after struct
|
|
;check for 1 MB wrap around
|
|
mov ax,sysdat
|
|
cmp dx,ax ;check for below SYSDAT
|
|
jb sc_no
|
|
add ax,1000h ;check for above SYSDAT
|
|
cmp ax,endseg ;must be within 64k and ENDSEG
|
|
jb sc_end ;(use the smaller of the 2)
|
|
mov ax,endseg
|
|
sc_end:
|
|
cmp dx,ax ;DX=next paragraph,
|
|
ja sc_no
|
|
mov cl,1 ;indicate within SYSDAT
|
|
ret
|
|
sc_no:
|
|
xor cx,cx
|
|
ret
|
|
|
|
qspace:
|
|
;------
|
|
; entry: DI = QD address
|
|
; exit: CX = 0 if ok else error code
|
|
; DI preserved
|
|
; Allocate buffer space for QD
|
|
; The QMAU describes the Memory Allocation Unit
|
|
; for the queues. QMAU is set up by GENCCPM or GENSYS.
|
|
|
|
mov ax,q_msglen[di] ;compute size of buffer
|
|
mul q_nmsgs[di] ;AX=size of request
|
|
xor cx,cx
|
|
push cx ! push cx ! push ax ;call MALLOC
|
|
push ax ! push cx ;with MPB on stack
|
|
mov dx,sp ! mov ax,ss
|
|
mov ds,ax
|
|
mov bx,offset qmau
|
|
push di ;save QD
|
|
mov cx,f_maualloc ;go through OSIF to
|
|
call osif ;get U_WRKSEG=SS
|
|
pop di ;DI=QD
|
|
mov ds,sysdat
|
|
cmp cx,0 ! jne qspace_ret
|
|
mov bp,sp
|
|
mov ax,mpb_start[bp]
|
|
mov q_buf[di],ax ;address of buffer
|
|
|
|
qspace_ret:
|
|
add sp,10 ;pop MPB from stack
|
|
ret
|
|
|
|
remqd:
|
|
;-----
|
|
; Place QD on queue unused list
|
|
; entry: DS:DI = QD address
|
|
; exit: none
|
|
|
|
mov ax,q_flags[di]
|
|
and ax,qf_table ! jz rqd_exit
|
|
mov ax,qul ! mov q_link[di],ax
|
|
mov qul,di
|
|
jmps qrelease
|
|
rqd_exit:
|
|
ret
|
|
|
|
|
|
qrelease:
|
|
;--------
|
|
; entry: DI = QD address
|
|
; exit : none
|
|
;
|
|
; Release buffer space for QD.
|
|
; If the released space is ajacent to another
|
|
; free area, they are joined in the SAT table.
|
|
; The QMAU describes the Memory Allocation Unit
|
|
; for the queues. QMAU is set up by GENCCPM or GENSYS.
|
|
|
|
|
|
mov ax,q_buf[di]
|
|
mov cx,offset qmau
|
|
push ax ! push ax ! push cx ;MFPB on stack
|
|
mov cx,f_maufree
|
|
mov dx,sp ! mov ax,ss ! mov ds,ax
|
|
call osif
|
|
add sp,6 ;pop MFPB from stack
|
|
mov ds,cs:sysdat ;DS=SYSDAT
|
|
ret
|