;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; RDOS operating system ; Copyright (C) 1988-2000, Leif Ekblad ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2 of the License, or ; (at your option) any later version. The only exception to this rule ; is for commercial usage in embedded systems. For information on ; usage in commercial embedded systems, contact embedded@rdos.net ; ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with this program; if not, write to the Free Software ; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ; ; The author of this program may be contacted at leif@rdos.net ; ; WAIT.ASM ; Abortable single & multiple wait functionality ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; NAME timer GateSize = 16 INCLUDE protseg.def INCLUDE ..\driver.def INCLUDE ..\user.def INCLUDE ..\os.def INCLUDE system.def INCLUDE system.inc INCLUDE ..\user.inc INCLUDE ..\os.inc INCLUDE ..\handle.inc INCLUDE ..\wait.inc wait_handle_seg STRUC wh_handle_base handle_header <> wh_section section_typ <> wh_obj_list DW ? wh_thread DW ? wh_running DB ? wait_handle_seg ENDS .386p code SEGMENT byte public use16 'CODE' assume cs:code ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: delete_wait ; ; DESCRIPTION: Delete contents in wait handle ; ; PARAMETERS: DS:BX Wait struct ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; delete_wait Proc near mov dx,ds:[bx].wh_obj_list or dx,dx jz delete_wait_done delete_wait_loop: mov es,dx mov dx,es:wo_next FreeMem or dx,dx jnz delete_wait_loop delete_wait_done: ret delete_wait Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: CreateWait ; ; DESCRIPTION: Create a wait handle ; ; RETURNS: BX Wait handle ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; create_wait_name DB 'Create Wait', 0 create_wait Proc far push ds push cx ; mov cx,SIZE wait_handle_seg AllocateHandle mov [bx].hh_sign,WAIT_HANDLE mov [bx].wh_obj_list,0 mov [bx].wh_running,0 InitSection ds:[bx].wh_section mov bx,[bx].hh_handle clc ; pop cx pop ds retf32 create_wait ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: CloseWait ; ; DESCRIPTION: Close a wait handle ; ; PARAMETERS: BX Wait handle ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; close_wait_name DB 'Close Wait', 0 close_wait Proc far push ds push ax ; mov ax,WAIT_HANDLE DerefHandle jc close_wait_done ; call delete_wait ; FreeHandle clc close_wait_done: pop ax pop ds retf32 close_wait ENDP PAGE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: delete_handle ; ; DESCRIPTION: BX Wait handle ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; delete_handle Proc far push ds push ax push bx ; mov ax,WAIT_HANDLE DerefHandle jc delete_handle_done ; call delete_wait delete_handle_done: pop bx pop ax pop ds ret delete_handle Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: IsWaitIdle ; ; DESCRIPTION: Check if wait is idle ; ; PARAMETERS: BX Wait handle ; ; RETURNS: NC ; ECX Non-idle ID ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; is_wait_idle_name DB 'Is Wait Idle', 0 is_wait_idle Proc far push ds push es push eax push ebx push dx ; xor ecx,ecx mov ax,WAIT_HANDLE DerefHandle jc is_wait_idle_done ; movzx ebx,bx EnterSection ds:[ebx].wh_section mov dx,ds:[bx].wh_obj_list or dx,dx jz is_wait_idle_ok_leave is_wait_idle_loop: mov es,dx call es:wo_idle_proc jc is_wait_idle_fail_leave ; mov dx,es:wo_next or dx,dx jnz is_wait_idle_loop is_wait_idle_ok_leave: LeaveSection ds:[ebx].wh_section clc jmp is_wait_idle_done is_wait_idle_fail_leave: mov ecx,es:wo_id LeaveSection ds:[ebx].wh_section stc is_wait_idle_done: pop dx pop ebx pop eax pop es pop ds retf32 is_wait_idle Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: WaitWithoutTimeout ; ; DESCRIPTION: Wait without timeout ; ; PARAMETERS: BX Wait handle ; ; RETURNS: ECX Signalled ID ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; wait_no_timeout_name DB 'Wait Without Timeout', 0 wait_no_timeout Proc far push ds push es push eax push ebx push dx ; xor ecx,ecx mov ax,WAIT_HANDLE DerefHandle jc wait_no_timeout_done ; movzx ebx,bx EnterSection ds:[ebx].wh_section mov al,ds:[bx].wh_running or al,al jnz wait_no_timeout_stopped_leave ; GetThread mov ds:[bx].wh_thread,ax ClearSignal mov dx,ds:[bx].wh_obj_list or dx,dx jz wait_no_timeout_start_leave wait_no_timeout_start_loop: mov es,dx mov es:wo_thread,ax mov es:wo_signalled,0 call es:wo_init_proc mov dx,es:wo_next or dx,dx jnz wait_no_timeout_start_loop wait_no_timeout_start_leave: inc ds:[bx].wh_running LeaveSection ds:[ebx].wh_section wait_no_timeout_do: WaitForSignal ; EnterSection ds:[ebx].wh_section mov al,ds:[bx].wh_running or al,al jz wait_no_timeout_stopped_leave ; dec ds:[bx].wh_running mov ax,ds:[bx].wh_obj_list or ax,ax jz wait_no_timeout_stopped_leave wait_no_timeout_stop_loop: mov es,ax mov ax,es:wo_signalled or ax,ax jnz wait_no_timeout_stop_signalled ; call es:wo_abort_proc jmp wait_no_timeout_stop_next wait_no_timeout_stop_signalled: or ecx,ecx jnz wait_no_timeout_stop_next ; mov ecx,es:wo_id call es:wo_clear_proc wait_no_timeout_stop_next: mov ax,es:wo_next or ax,ax jnz wait_no_timeout_stop_loop wait_no_timeout_stopped_leave: LeaveSection ds:[ebx].wh_section clc wait_no_timeout_done: pop dx pop ebx pop eax pop es pop ds retf32 wait_no_timeout Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: timeout_wait ; ; DESCRIPTION: Timeout on wait ; ; PARAMETERS: CX thread to signal ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; timeout_wait Proc far mov bx,cx Signal ret timeout_wait Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: WaitWithTimeout ; ; DESCRIPTION: Wait with timeout ; ; PARAMETERS: BX Wait handle ; EDX:EAX Timeout time ; ; RETURNS: ECX Signalled ID ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; wait_timeout_name DB 'Wait With Timeout', 0 wait_timeout Proc far push ds push es push eax push ebx push dx push di ; push ax xor ecx,ecx mov ax,WAIT_HANDLE DerefHandle pop ax jc wait_timeout_done ; movzx ebx,bx EnterSection ds:[ebx].wh_section push ax mov al,ds:[bx].wh_running or al,al pop ax jnz wait_timeout_stopped_leave ; push eax push edx GetThread mov ds:[bx].wh_thread,ax ClearSignal mov dx,ds:[bx].wh_obj_list or dx,dx jz wait_timeout_start_timer wait_timeout_start_loop: mov es,dx mov es:wo_thread,ax mov es:wo_signalled,0 call es:wo_init_proc mov dx,es:wo_next or dx,dx jnz wait_timeout_start_loop wait_timeout_start_timer: GetThread mov cx,ax mov ax,cs mov es,ax pop edx pop eax ; push bx mov bx,cx mov di,OFFSET timeout_wait StartTimer pop bx ; inc ds:[bx].wh_running LeaveSection ds:[ebx].wh_section wait_timeout_do: WaitForSignal ; push bx mov bx,cx StopTimer pop bx ; xor ecx,ecx EnterSection ds:[ebx].wh_section mov al,ds:[bx].wh_running or al,al jz wait_timeout_stopped_leave ; dec ds:[bx].wh_running mov ax,ds:[bx].wh_obj_list or ax,ax jz wait_timeout_stopped_leave wait_timeout_stop_loop: mov es,ax mov ax,es:wo_signalled or ax,ax jnz wait_timeout_stop_signalled ; call es:wo_abort_proc jmp wait_timeout_stop_next wait_timeout_stop_signalled: or ecx,ecx jnz wait_timeout_stop_next ; mov ecx,es:wo_id call es:wo_clear_proc wait_timeout_stop_next: mov ax,es:wo_next or ax,ax jnz wait_timeout_stop_loop wait_timeout_stopped_leave: LeaveSection ds:[ebx].wh_section clc wait_timeout_done: pop di pop dx pop ebx pop eax pop es pop ds retf32 wait_timeout Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: StopWait ; ; DESCRIPTION: Stop a wait ; ; PARAMETERS: BX Wait handle ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; stop_wait_name DB 'Stop Wait', 0 stop_wait Proc far push ds push es push eax push ebx ; mov ax,WAIT_HANDLE DerefHandle jc stop_wait_done ; movzx ebx,bx EnterSection ds:[ebx].wh_section mov al,ds:[bx].wh_running or al,al jz stop_wait_leave ; dec ds:[bx].wh_running mov ax,ds:[bx].wh_obj_list or ax,ax jz stop_wait_signal stop_wait_loop: mov es,ax mov ax,es:wo_signalled or ax,ax jnz stop_wait_next ; call es:wo_abort_proc stop_wait_next: mov ax,es:wo_next or ax,ax jnz stop_wait_loop stop_wait_signal: push bx mov bx,ds:[bx].wh_thread Signal pop bx stop_wait_leave: LeaveSection ds:[ebx].wh_section clc stop_wait_done: pop ebx pop eax pop es pop ds retf32 stop_wait Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: AddWait ; ; DESCRIPTION: Add a generic wait object ; ; PARAMETERS: AX Extra bytes needed in wait object ; BX Wait handle ; ECX Signalled ID ; ES:DI Method table ; ; RETURNS: ES Wait object ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; add_wait_name DB 'Add Wait', 0 add_wait Proc far push ds push fs push eax push ebx push cx push si push di ; mov si,es mov fs,si mov si,di ; push ax mov ax,WAIT_HANDLE DerefHandle pop ax jc add_wait_done ; movzx ebx,bx EnterSection ds:[ebx].wh_section ; movzx eax,ax add eax,SIZE wait_obj_header AllocateSmallGlobalMem ; mov es:wo_id,ecx mov di,OFFSET wo_init_proc mov cx,4 rep movs dword ptr es:[di],fs:[si] ; mov ax,ds:[bx].wh_obj_list mov es:wo_next,ax mov ds:[bx].wh_obj_list,es ; LeaveSection ds:[ebx].wh_section clc add_wait_done: pop di pop si pop cx pop ebx pop eax pop fs pop ds ret add_wait Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: RemoveWait ; ; DESCRIPTION: Remove a wait object ; ; PARAMETERS: BX Wait handle ; ECX Signal ID ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; remove_wait_name DB 'Remove Wait', 0 remove_wait Proc far push ds push es push ax push ebx push dx ; mov ax,WAIT_HANDLE DerefHandle jc remove_wait_done ; movzx ebx,bx EnterSection ds:[ebx].wh_section ; xor dx,dx mov ax,ds:[bx].wh_obj_list remove_wait_loop: or ax,ax jz remove_wait_leave ; mov es,ax cmp ecx,es:wo_id je remove_wait_do ; mov dx,es mov ax,es:wo_next jmp remove_wait_loop remove_wait_do: mov ax,es:wo_next FreeMem or dx,dx jz remove_wait_head ; mov es,dx mov es:wo_next,ax jmp remove_wait_loop remove_wait_head: mov ds:[bx].wh_obj_list,ax jmp remove_wait_loop remove_wait_leave: LeaveSection ds:[ebx].wh_section clc remove_wait_done: pop dx pop ebx pop ax pop es pop ds retf32 remove_wait Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: SignalWait ; ; DESCRIPTION: Signal object ; ; PARAMETERS: ES object ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; signal_wait_name DB 'Signal Wait',0 signal_wait Proc far push bx inc es:wo_signalled mov bx,es:wo_thread Signal pop bx ret signal_wait Endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; NAME: init ; ; DESCRIPTION: Init device-driver ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; init PROC far push ds push es pusha mov bx,wait_code_sel InitDevice ; mov ax,cs mov ds,ax mov es,ax ; mov ax,WAIT_HANDLE mov di,OFFSET delete_handle RegisterHandle ; mov si,OFFSET add_wait mov di,OFFSET add_wait_name mov ax,add_wait_nr RegisterOsGate ; mov si,OFFSET signal_wait mov di,OFFSET signal_wait_name mov ax,signal_wait_nr RegisterOsGate ; mov si,OFFSET create_wait mov di,OFFSET create_wait_name xor dx,dx mov ax,create_wait_nr RegisterBimodalUserGate ; mov si,OFFSET close_wait mov di,OFFSET close_wait_name xor dx,dx mov ax,close_wait_nr RegisterBimodalUserGate ; mov si,OFFSET is_wait_idle mov di,OFFSET is_wait_idle_name xor dx,dx mov ax,is_wait_idle_nr RegisterBimodalUserGate ; mov si,OFFSET wait_no_timeout mov di,OFFSET wait_no_timeout_name xor dx,dx mov ax,wait_no_timeout_nr RegisterBimodalUserGate ; mov si,OFFSET wait_timeout mov di,OFFSET wait_timeout_name xor dx,dx mov ax,wait_timeout_nr RegisterBimodalUserGate ; mov si,OFFSET stop_wait mov di,OFFSET stop_wait_name xor dx,dx mov ax,stop_wait_nr RegisterBimodalUserGate ; mov si,OFFSET remove_wait mov di,OFFSET remove_wait_name xor dx,dx mov ax,remove_wait_nr RegisterBimodalUserGate ; popa pop es pop ds ret init ENDP code ENDS END init