
;*****************************************************
;*
;*		Flag Management
;*
;* FLAGS-flag table offset      NFLAGS-number of flags
;*
;* Format of Flag Table Entry:
;*	+-------------+------+
;*	|  flag       |ignore|
;*	+-------------+------+
;*	flag -	0ffffh, flag is off
;*		0fffeh, flag is set
;*		0xxxxh, PD that is waiting
;*	ignore-	0ffh, normal case
;*		0xxh, number of flags to ignore-1
;*
;*	GENSYS initializes the flag table with 0ffh's.
;*
;*****************************************************

;==============   ==========================
flag_set_entry:	; Set Logical Interrupt Flag
;==============   ==========================
; NOTE: the flagset routine can be called from outside
;	the operating system through an interrupt
;	routine.  UDA variables cannot be used.  This
;	is the only function an interrupt routine can
;	call.
;
;	input:	DL = flag number
;	output:	BX = 0 if okay,0ffffh if Error
;		CX = Error Code:0,e_flag_ovrrun

	call flag_valid
	cmp flg_ignore[si],flag_zig ! je fs_set
	    dec flg_ignore[si] ! jmp flag_exit
fs_set:	cmp bx,flag_on ! jne fs_non
	    mov cx,e_flag_ovrrun ! jmp flag_bexit
fs_non:	cmp bx,flag_off ! jne fs_noff
	    mov flg_pd[si],flag_on
	    jmp flag_exit
fs_noff:mov ax,drl ! mov p_link[bx],ax
	mov drl,bx ! mov p_stat[bx],ps_run
	mov flg_pd[si],flag_off
	jmp flag_exit

;===============   ===============================
flag_wait_entry: ; Wait for Logical Interrupt Flag
;===============   ===============================
;	input:	DL = flag number
;	output:	BX = 0 if everything okay
;		BX = 0ffffh if Error
;		CX = Error Code:0,e_flag_underrun

	call flag_valid
	cmp bx,flag_on ! jne fw_non
	    mov flg_pd[si],flag_off
	    jmp flag_exit
fw_non:	cmp bx,flag_off ! jne fw_noff
	    mov bx,rlr
	    mov p_stat[bx],ps_flagwait
	    mov u_dparam,si
	    call dsptch ! jmp flag_exit
fw_noff:mov cx,e_flag_underrun ! jmp flag_bexit

flag_valid:	; Check validity of flag number
;----------       -----------------------------
;	output: SI = ptr to flag entry
;		BX = contents of flag entry
;		clear interrupt flag - Flags on stack

	pop ax ! pushf
	cmp dl,nflags ! jb flag_good
	    mov cx,e_ill_flag ! jmp flag_bexit
flag_good:
	mov dh,0 ! push ax ! cli
	mov ax,dx ! mov bx,flglen ! mul bx
	mov si,flags ! add si,ax
	mov bx,[si] ! ret

flag_exit:	; Successful Exit
;---------        ---------------
	sub bx,bx ! mov cx,bx ! popf ! ret

flag_bexit:	; Exit with Error
;----------       ---------------
	mov bx,0ffffh ! popf ! ret
