;***************************************************** ;* ;* Flag Management ;* ;* FLAGS-flag table offset NFLAGS-number of flags ;* ;* Format of Flag Table Entry: ;* +-------------+------+ ;* | flag |ignore| ;* +-------------+------+ ;* flag - 00000h, flag can be allocated ;* flag - 0ffffh, flag is off but is allocated to some ;* function. ;* 0fffeh, flag is set ;* 0xxxxh, PD that is waiting ;* ignore- 0ffh, normal case ;* 0xxh, number of flags to ignore-1 ;* ;* GENSYS initializes the flags reserved by the system ;* and the XIOS header to 0ffh's. The rest of the ;* flags are initialized to 0 by GENSYS. ;* ;***************************************************** ;============ ;getfree_flag: ;============ ; input: DX = 0 then allocate a flag ; else ; if DH = 0FFH then release flag number ; DL (0 relative) ; output: ; BX = flag allocated if getting a flag ; or 0FFFFH if no flag is available ; BX = 0FFFFH if attempting to release a ; no existent flag ; CX = 0 no error ; CX = 4 if illegal flag number ; CX = 27H if no more flags to allocate ; ; Flags reserved by CCP/M or MP/M and the XIOS ; header, cannot be released. ; ;turn off interrupts ; ; test dx,dx ! jz rf_alloc ; inc dh ! jnz rf_enum ; cmp dl,nrsv_flags ! jbe rf_enum ; cmp dl,nflags ! jae rf_enum ; xor ax,ax ! mov bx,ax ! mov cx,ax ; mov al,dl ; add al,dl ! add al,dl ; mov si,ax ! mov word ptr flags[si],0 ; mov byte ptr flags 2[si],0 ; ret ;rf_alloc: ; mov si,flags ! xor ax,ax ; mov bx,ax ! mov cx,nflags ;rf_nxt: ; cmp ax,[si] ! je rf_foundone ;got one ; add si,3 ! inc bx ; loop rf_nxt ; mov cx,e_noflags ! jmps rf_err ;rf_foundone: ; mov cx,ax ;0 CX ; dec ax ; mov [si],ax ;set the 3 bytes to 0ffh ; mov 2[si],al ; ret ;rf_enum: ; mov cx,e_illflag ;rf_err: ; mov bx,0ffffh ; ret ;============== ========================== flag_set_entry: ; Set Logical Interrupt Flag ;============== ========================== ; NOTE: the flagset routine can (must?) 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 = if error: e_flag_ovrrun call flag_valid cmp cl,flag_tick ! jne notick mov bx,dlr test bx,bx ! jz dlr_null ;no process waiting dec p_wait[bx] ! jnz nxt_tick nxt_tpd: mov si,p_link[bx] ! mov dlr,si ;SI,DLR=next waiting PD mov p_stat[bx],ps_run ;put PD done waiting mov ax,drl ! mov p_link[bx],ax ;on DRL mov drl,bx test si,si ! jz dlr_null ;SI=next waiting PD cmp p_wait[si],0 ! jnz nxt_tick mov bx,si ! jmps nxt_tpd;another process was waiting ;the same number of ticks nxt_tick: jmp flag_exit ;wait for next tick dlr_null: ;DLR is empty turn off mov tick,false ! jmp flag_exit ;XIOS tick flag no_tick: 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 or p_flag[bx],pf_resource ;12/4/83 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 ;---------- ----------------------------- ; entry: DL = flag number ; output: SI = ptr to flag entry ; BX = contents of flag entry ; CL = flag number ; clear interrupt flag - Flags on stack pop ax ! pushf ;AX=return address cmp dl,nflags ! jb flag_good flag_bad: mov cx,e_ill_flag ! jmp flag_bexit ;flags and next return flag_good: ;address on stack mov cl,dl ;save flag number xor dh,dh ! push ax ! cli ;return to fset/fwait on stack mov ax,dx ;multiply flag number mov bx,ax ;times 3 add ax,ax ;*2 add ax,bx ;*3 mov si,flags ! add si,ax mov bx,[si] ;test bx,bx ;FLAG field cannot be 0 ;jz flag_bad ret flag_exit: ; Successful Exit ;--------- --------------- ; entry: flags and return from flagset or flagwait on stack xor bx,bx ! popf ! ret flag_bexit: ; Exit with Error ;---------- --------------- ; entry: flags and return from flagset or flagwait on stack xor bx,bx ! dec bx popf ! ret