mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-25 17:34:06 +00:00
449 lines
10 KiB
Plaintext
449 lines
10 KiB
Plaintext
;*****************************************************
|
||
;*
|
||
;* Character I/O ownership routines
|
||
;*
|
||
;*****************************************************
|
||
|
||
;===============
|
||
lstattach_entry:
|
||
;===============
|
||
xor cx,cx ;unconditional attach code
|
||
jmps lcb_verify
|
||
|
||
;===============
|
||
clstattch_entry:
|
||
;===============
|
||
mov cx,0ffffh ;conditional attach code
|
||
|
||
lcb_verify:
|
||
;----------
|
||
push cx
|
||
mov si,u_lstccb ;U_LSTCCB=0 if not yet initialized
|
||
test si,si ! jnz lcb_ok
|
||
call getlcbadr
|
||
mov u_lstccb,si
|
||
lcb_ok:
|
||
pop cx ;restore attach code
|
||
jmps cioattach
|
||
|
||
;===============
|
||
conattach_entry:
|
||
;===============
|
||
xor cx,cx ;unconditional attach code
|
||
jmps ccb_verify
|
||
|
||
;===============
|
||
cconattch_entry:
|
||
;===============
|
||
mov cx,0ffffh ;conditional attach code
|
||
ccb_verify:
|
||
push cx
|
||
mov si,u_conccb
|
||
test si,si ! jnz ccb_ok
|
||
call getccbadr
|
||
mov u_conccb,si
|
||
ccb_ok:
|
||
pop cx ;conditional attach if 0ffffh
|
||
;jmps cioattach
|
||
|
||
;=========
|
||
cioattach: ;NOTE: PIN does attaches also for ^P
|
||
;=========
|
||
; Attach calling process to default ciodev.
|
||
; if ciodev is being used, sleep on c_queue
|
||
; until another process detaches from device
|
||
; and calling process is next in queue.
|
||
; input: SI = CCB address of device
|
||
; DI = offset of dev number in PD
|
||
; CX = 0ffffh if conditional
|
||
|
||
mov ax,rlr ! mov bx,ax
|
||
; BX = PD addr
|
||
; SI = CCB addr
|
||
; CX = Condition Flag
|
||
pushf ! cli
|
||
cmp bx,c_attach[si] ! je ca_ret ;we already own it
|
||
cmp c_attach[si],0 ! je ca_atch ;nobody owns it, we'll take it
|
||
jcxz ca_sleep ;somebody else owns it
|
||
popf ! mov bx,0ffffh ;or it is a mimic list (0ffffh)
|
||
mov cx,e_no_attach ! ret ;- no attach in either case
|
||
ca_sleep:
|
||
push dx ;save DH=cons #
|
||
lea dx,c_queue[si] ;unconditional if CX=0
|
||
mov bl,ps_ciowait
|
||
push si
|
||
mov cx,f_sleep ! call osif
|
||
pop si ! pop dx ! popf ! xor cx,cx
|
||
jmps cioattach
|
||
ca_atch: mov c_attach[si],bx
|
||
ca_ret: popf ! xor bx,bx ! ret
|
||
|
||
;===============
|
||
lstdetach_entry:
|
||
;===============
|
||
call lcb_verify ;ensure U_LSTCCB is non zero
|
||
|
||
lst_det:
|
||
mov bx,rlr
|
||
pushf ! cli
|
||
cmp c_attach[si],0 ! je cd_ret
|
||
cmp c_attach[si],bx ! je ld_detach
|
||
popf ! mov bx,0ffffh
|
||
mov cx, e_not_owner ! ret
|
||
ld_detach:
|
||
mov ax,c_queue[si]
|
||
mov c_attach[si],ax
|
||
mov cx,f_wakeup
|
||
lea dx,c_queue[si]
|
||
call osif
|
||
jmps cd_ret
|
||
|
||
;===============
|
||
condetach_entry:
|
||
;===============
|
||
call ccb_verify ;ensure U_CONCCB is non zero
|
||
;jmps ciodetach
|
||
|
||
;=========
|
||
ciodetach: ;NOTE PIN also does detaching for ^P
|
||
;=========
|
||
; Detach Calling process from default ciodev.
|
||
; If current owner of ciodev then zero c_attach
|
||
; and wakeup the c_queue list to give another
|
||
; process the ciodev.
|
||
; input: SI = CCB addr of device
|
||
|
||
mov bx,rlr
|
||
; SI = CCB address
|
||
; BX = PD address
|
||
pushf ! cli
|
||
cmp c_attach[si],0 ! je cd_ret
|
||
cmp c_attach[si],bx ! je cd_detach
|
||
popf ! mov bx,0ffffh
|
||
mov cx,e_not_owner ! ret
|
||
cd_detach:
|
||
and c_state[si],not (csm_suspend ); turn off suspend mode
|
||
mov ax,c_queue[si]
|
||
mov c_attach[si],ax
|
||
mov cx,f_wakeup
|
||
lea dx,c_queue[si]
|
||
call osif
|
||
cd_ret:
|
||
popf
|
||
xor bx,bx ! ret
|
||
|
||
|
||
;===============
|
||
conassign_entry:
|
||
;===============
|
||
; Attach specified console to specified process
|
||
;
|
||
; entry: U_WRKSEG:DX -> ACB
|
||
;
|
||
; +-----+-----+-----+-----+
|
||
; | CNS |Match| PD Addr |
|
||
; +-----+-----+-----+-----+-----+-----+-----+-----+
|
||
; | Name |
|
||
; +-----+-----+-----+-----+-----+-----+-----+-----+
|
||
;
|
||
; CNS - console to assign
|
||
; Match - if not 0,
|
||
; PD's default console must match acb_cns
|
||
; PD Addr - PD address to assign to
|
||
; Name - use PD name to assign, if PD addr=0
|
||
; Name - use PD name to assign, if PD addr=1,
|
||
; but also ensure DSKLD flag is off
|
||
; (DiSK LoaD is set when PD was created
|
||
; from disk transient, RSPs have DSKLD=0)
|
||
; Should check for DSKLD=1 if PD addr = 0
|
||
; but we may have compatibility issues
|
||
;
|
||
; exit: BX = 0 if success, 0ffffh if failure
|
||
; CX = Error Code
|
||
|
||
push dx ;save ACB
|
||
mov bx,offset thrd_spb ;get ownership of thread
|
||
mov cx,f_sync
|
||
call osif
|
||
pop di ;U_WRKSEG:DI->ACB
|
||
mov indisp,true ;stop dispatching
|
||
|
||
push ds ;save SYSDAT
|
||
mov ds,u_wrkseg
|
||
cmp acb_pd[di],1 ;name or address match ?
|
||
jbe as_name
|
||
|
||
mov bx,acb_pd[di] ;find by PD address
|
||
pop ds ;DS=SYSDAT
|
||
mov si,(offset thrdrt)-p_thread
|
||
as_next1: ;verify PD is on thread
|
||
mov si,p_thread[si]
|
||
test si,si ! jz as_nom ;no match if end of thread
|
||
cmp bx,si ! je as_found_id
|
||
jmps as_next1
|
||
as_found_id:
|
||
call as_chk ;check console match
|
||
jcxz as_mok ;match ok
|
||
jmps as_nom ;no match
|
||
|
||
as_name: ;look for PD by name on thread
|
||
pop ds ;DS=SYSDAT
|
||
mov bx,(offset thrdrt)-p_thread
|
||
as_next2: ;look for PD by name on thread
|
||
push di ;save ACB
|
||
lea dx,acb_name[di] ;U_WRKSEG:DI->ACB
|
||
mov ds,u_wrkseg ;DS:DX->ASCII name
|
||
mov cx,f_findpdname
|
||
call osif
|
||
mov ds,sysdat
|
||
pop di ;ACB
|
||
jcxz as_okname ;CX<>0 if no match
|
||
|
||
as_nom:
|
||
mov cx,e_no_pdname ;couldn't find PD specified
|
||
jmps as_err ;by ACB on thread list
|
||
as_okname:
|
||
;matched PD by name check by ACB
|
||
call as_chk ;BX->PD matched by name
|
||
jcxz as_mok
|
||
;console or DSKLD didn't match
|
||
jmps as_next2 ;search for another PD
|
||
|
||
as_mok: ;match OK, found the PD
|
||
push bx ! push di ;BX=matched PD, DI=ACB
|
||
mov bx,offset thrd_spb
|
||
mov cx,f_unsync
|
||
call osif
|
||
pop di ! pop ax ;DI=ACB, AX=matched PD
|
||
mov ds,u_wrkseg
|
||
push ax ;save matched PD
|
||
mov al,acb_cns[di]
|
||
mov ds,sysdat
|
||
call getccbadr_spec ;SI=CCB on return
|
||
mov bx,rlr ;BX=running process
|
||
pop ax ;AX=matched PD
|
||
|
||
cmp c_attach[si],0 ;and change CCB
|
||
je as_ok ;CCB must be unused (0) or
|
||
cmp c_attach[si],bx ;running process must own it
|
||
je as_ok
|
||
mov cx,e_not_owner
|
||
as_err:
|
||
push cx ;save error code
|
||
call as_ok_disp
|
||
mov bx,offset thrd_spb
|
||
mov cx,f_unsync
|
||
call osif
|
||
pop cx
|
||
mov bx,0ffffh
|
||
ret
|
||
as_ok:
|
||
mov c_attach[si],ax ;new owner
|
||
push ax ! push si ;save owner and CCB
|
||
call as_ok_disp ;allow dispatches
|
||
pop si ! pop ax
|
||
mov bx,ax ;AX=BX=new owner
|
||
add si,c_queue-p_link ;go down CCB queue for PD
|
||
mov di,si ;DI=SI=address of CCB.QUEUE
|
||
as_nqpd:
|
||
cmp p_link[si],0 ;look on C_QUEUE for PD being
|
||
jz as_gexit ;assigned the console
|
||
cmp p_link[si],bx
|
||
je as_qfix
|
||
mov si,p_link[si]
|
||
jmps as_nqpd ;next PD
|
||
as_qfix:
|
||
mov ax,p_link[bx] ;take PD out of C_QUEUE
|
||
mov p_link[si],ax
|
||
mov si,p_link[di] ;SI = first PD on C_QUEUE
|
||
mov p_link[di],bx ;put PD in front of C_QUEUE
|
||
mov p_link[bx],si ;attach rest of list
|
||
mov dx,di ;pass C_QUEUE address to wakeup
|
||
mov cx,f_wakeup
|
||
call osif
|
||
as_gexit:
|
||
xor bx,bx
|
||
ret
|
||
|
||
as_ok_disp:
|
||
;----------
|
||
; entry: none
|
||
; exit: none
|
||
; Allow dispatching
|
||
|
||
mov indisp,false
|
||
pushf ! cli
|
||
cmp drl,0 ! je as_nwake
|
||
mov cx,f_dispatch
|
||
call osif
|
||
as_nwake:
|
||
popf ! ret
|
||
|
||
as_chk:
|
||
;------
|
||
; check PD against Assign Control Block parameters
|
||
; entry: BX = PD to check
|
||
; U_WRKSEG:DI = ACB
|
||
; exit: CX = 0 if assign match
|
||
; CX <> 0 if no match
|
||
; CX,AX used
|
||
|
||
xor cx,cx
|
||
push es ;save UDA
|
||
mov es,u_wrkseg
|
||
mov ax,es:acb_pd[di]
|
||
cmp ax,1 ;if >1 then matching on PD address
|
||
ja asc_cns
|
||
dec ax
|
||
jnz asc_cns
|
||
test p_flag[bx],pf_dskld ;RSP, DSKLD must be off
|
||
jnz asc_no
|
||
asc_cns:
|
||
cmp es:acb_match[di],0 ;console match requested ?
|
||
je asc_ok
|
||
mov al,es:acb_cns[di] ;must match on console
|
||
cmp al,p_cns[bx]
|
||
je asc_ok
|
||
asc_no:
|
||
inc cx
|
||
asc_ok:
|
||
pop es ;ES=UDA
|
||
ret
|
||
|
||
;=============== =====================
|
||
getdefcon_entry: ; Get Default Console
|
||
;=============== =====================
|
||
|
||
mov si,rlr
|
||
xor bh,bh ! mov bl,p_cns[si]
|
||
ret
|
||
|
||
;=============== ==================
|
||
getdeflst_entry: ; Get Default List
|
||
;=============== ==================
|
||
|
||
mov si,rlr
|
||
xor bh,bh ! mov bl,p_lst[si]
|
||
ret
|
||
|
||
;=============== =====================
|
||
setdefcon_entry: ; Set Default Console
|
||
;=============== =====================
|
||
|
||
cmp dl,ncondev
|
||
jb sd_good
|
||
mov cx,e_ill_cns
|
||
mov bx,0ffffh ! ret
|
||
sd_good:
|
||
mov si,rlr
|
||
mov p_cns[si],dl
|
||
call getccbadr
|
||
mov u_conccb,si
|
||
xor bx,bx
|
||
ret
|
||
|
||
;=============== ==================
|
||
setdeflst_entry: ; Set Default List
|
||
;=============== ==================
|
||
|
||
cmp dl,nlstdev
|
||
jb sdl_good
|
||
mov cx,e_ill_lst
|
||
mov bx,0ffffh ! ret
|
||
sdl_good:
|
||
mov si,rlr
|
||
mov p_lst[si],dl
|
||
call getlcbadr
|
||
mov u_lstccb,si
|
||
xor bx,bx
|
||
ret
|
||
|
||
|
||
getccbadr:
|
||
;---------
|
||
; get CCB for calling process' console device
|
||
; input: None
|
||
; output: SI = address of CCB
|
||
; BX = running PD address
|
||
|
||
mov bx,rlr
|
||
mov al,p_cns[bx]
|
||
|
||
getccbadr_spec: ;AL is console number
|
||
xor ah,ah ;when called from ASSIGN
|
||
mov si,ccb
|
||
mov cl,2
|
||
shl ax,cl
|
||
add si,ax ;+4
|
||
add si,ax ;+4 = 8
|
||
add si,ax ;+4 =12
|
||
mov cl,3
|
||
shl ax,cl
|
||
add si,ax ;+32 =44
|
||
ret
|
||
|
||
getlcbadr:
|
||
;---------
|
||
; Get LCB for calling process list device
|
||
; entry: None
|
||
; output: SI = address of LCB
|
||
; BX = PD address
|
||
|
||
mov bx,rlr
|
||
xor ah,ah
|
||
mov al,p_lst[bx]
|
||
cmp al,nlst ; range check on # legal list dev's
|
||
jbe lcb_cont
|
||
mov al,0 ; if out of range, normalize to zero
|
||
mov p_lst[bx],al
|
||
lcb_cont:
|
||
mov si,lcb
|
||
push ax ;lcb#
|
||
shl ax,1 ;2*lcb#
|
||
add si,ax ;lcbadr + 2*lcb#
|
||
pop ax ;lcb#
|
||
mov cl,3
|
||
shl ax,cl ;8*lcb#
|
||
add si,ax ;lcbadr + 2*lcb# + 8*lcb#
|
||
ret
|
||
|
||
|
||
;=======
|
||
cioterm:
|
||
;=======
|
||
; Detach Calling process from all character devices.
|
||
; Called only from the dispatcher
|
||
|
||
mov al,ncondev
|
||
mov si,ccb
|
||
nxtccb: cmp al,0 ! je ct_dlcb
|
||
cmp si,u_conccb ! jne ct_dccb
|
||
and c_flag[si],not (cf_conout + cf_vout + cf_bufp)
|
||
mov cx,f_wakeup ;release proc waiting for XIOS conout
|
||
lea dx,c_cosleep[si]
|
||
push ax ! push si
|
||
call osif
|
||
pop si ! pop ax
|
||
ct_dccb:
|
||
push ax ! push si
|
||
call ciodetach
|
||
pop si ! pop ax
|
||
dec al
|
||
add si,ccblen
|
||
jmps nxtccb
|
||
|
||
ct_dlcb:
|
||
mov al,nlstdev
|
||
mov si,lcb
|
||
ct_nlcb:
|
||
cmp al,0 ! je ct_ret
|
||
push ax ! push si
|
||
call lst_det
|
||
;call ciodetach
|
||
pop si ! pop ax
|
||
dec al
|
||
add si,lcblen
|
||
jmps ct_nlcb
|
||
|
||
ct_ret: xor bx,bx ! ret
|
||
|