7,695 → 7,481 |
|
$Revision: 671 $ |
|
|
uglobal |
align 4 |
init_events: |
stdcall kernel_alloc, 512*EVENT_SIZE |
mov [events], eax |
xor eax, eax |
mov [event_uid], eax |
not eax |
mov edi, event_map |
mov [event_start], edi |
mov ecx, 64/4 |
cld |
rep stosd |
mov [event_end], edi |
ret |
|
event_start dd ? |
event_end dd ? |
event_uid dd 0 |
endg |
EV_SPACE = 512 |
FreeEvents = event_start-EVENT.fd ; "âèðòóàëüíûé" event, èñïîëüçóþòñÿ òîëüêî ïîëÿ: |
; FreeEvents.fd=event_start è FreeEvents.bk=event_end |
align 4 |
proc alloc_event |
init_events: ;; used from kernel.asm |
stdcall kernel_alloc,EV_SPACE*EVENT.size |
or eax,eax |
jz .fail |
; eax - current event, ebx - previos event below |
mov ecx,EV_SPACE ; current - in allocated space |
mov ebx,FreeEvents ; previos - íà÷àëî ñïèñêà |
push ebx ; îíî æå è êîíåö ïîòîì áóäåò |
@@: mov [ebx+EVENT.fd],eax |
mov [eax+EVENT.bk],ebx |
mov ebx,eax ; previos <- current |
add eax,EVENT.size ; new current |
loop @b |
pop eax ; âîò îíî êîíöîì è ñòàëî |
mov [ebx+EVENT.fd],eax |
mov [eax+EVENT.bk],ebx |
.fail: ret |
|
pushfd |
cli |
mov ebx, [event_start] |
mov ecx, [event_end] |
.l1: |
bsf eax,[ebx] |
jnz .found |
add ebx,4 |
cmp ebx, ecx |
jb .l1 |
popfd |
xor eax,eax |
ret |
.found: |
btr [ebx], eax |
mov [event_start],ebx |
inc [event_uid] |
EVENT_WATCHED equ 0x10000000 ;áèò 28 |
EVENT_SIGNALED equ 0x20000000 ;áèò 29 |
MANUAL_RESET equ 0x40000000 ;áèò 30 |
MANUAL_DESTROY equ 0x80000000 ;áèò 31 |
|
sub ebx, event_map |
lea eax,[eax+ebx*8] |
|
lea ebx, [eax+eax*4] |
shl eax,5 |
lea eax,[eax+ebx*4] ;eax*=52 (EVENT_SIZE) |
add eax, [events] |
mov ebx, [event_uid] |
popfd |
ret |
endp |
|
align 4 |
free_event: |
sub eax, [events] |
mov ecx, EVENT_SIZE |
mov ebx, event_map |
cdq |
div ecx |
|
create_event: ;; EXPORT use |
;info: |
; Ïåðåíîñèì EVENT èç ñïèñêà FreeEvents â ñïèñîê ObjList òåêóùåãî ñëîòà |
; EVENT.state óñòàíàâëèâàåì èç ecx, EVENT.code êîñâåííî èç esi (åñëè esi<>0) |
;param: |
; esi - event data |
; ecx - flags |
;retval: |
; eax - event (=0 => fail) |
; edx - uid |
;scratched: ebx,ecx,esi,edi |
mov ebx,[current_slot] |
add ebx,APP_OBJ_OFFSET |
mov edx,[TASK_BASE] |
mov edx,[edx+TASKDATA.pid] |
pushfd |
cli |
bts [ebx], eax |
shr eax, 3 |
and eax, not 3 |
add eax, ebx |
cmp [event_start], eax |
ja @f |
popfd |
ret |
@@: |
mov [event_start], eax |
popfd |
ret |
|
EVENT_WATCHED equ 0x10000000 |
EVENT_SIGNALED equ 0x20000000 |
MANUAL_RESET equ 0x40000000 |
MANUAL_DESTROY equ 0x80000000 |
|
|
; param |
; eax= event data |
; ebx= flags |
; |
; retval |
; eax= event |
; edx= id |
|
create_event: |
.flags equ esp+4 |
.data equ esp |
|
push ebx |
push eax |
|
call alloc_event |
test eax, eax |
jz .fail |
|
mov [eax+APPOBJ.magic], 'EVNT' |
mov [eax+APPOBJ.destroy], destroy_event.internal |
mov [eax+EVENT.id], ebx |
|
mov ebx, [CURRENT_TASK] |
shl ebx, 5 |
mov ebx, [CURRENT_TASK+ebx+4] |
mov [eax+APPOBJ.pid], ebx |
mov edx, [.flags] |
mov [eax+EVENT.state], edx |
|
mov esi, [.data] |
test esi, esi |
jz @F |
set_event: ;; INTERNAL use !!! don't use for Call |
;info: |
; Áåðåì íîâûé event èç FreeEvents, çàïîëíÿåì åãî ïîëÿ, êàê óêàçàíî â ecx,edx,esi |
; è óñòàíàâëèâàåì â ñïèñîê, óêàçàííûé â ebx. |
; Âîçâðàùàåì ñàì event (â eax), è åãî uid (â edx) |
;param: |
; ebx - start-chain "virtual" event for entry new event Right of him |
; ecx - flags (copied to EVENT.state) |
; edx - pid (copied to EVENT.pid) |
; esi - event data (copied to EVENT.code indirect, =0 => skip) |
;retval: |
; eax - event (=0 => fail) |
; edx - uid |
;scratched: ebx,ecx,esi,edi |
mov eax,FreeEvents |
cmp eax,[eax+EVENT.fd] |
jne @f ; not empty ??? |
pushad |
call init_events |
popad |
jz RemoveEventTo.break ; POPF+RET |
@@: mov eax,[eax+EVENT.fd] |
mov [eax+EVENT.magic],'EVNT' |
mov [eax+EVENT.destroy],destroy_event.internal |
mov [eax+EVENT.state],ecx |
mov [eax+EVENT.pid],edx |
inc [event_uid] |
Mov [eax+EVENT.id],edx,[event_uid] |
or esi,esi |
jz RemoveEventTo |
lea edi, [eax+EVENT.code] |
mov ecx, 6 |
mov ecx,EVENT.codesize/4 |
cld |
rep movsd |
@@: |
mov ecx, [current_slot] |
add ecx, APP_OBJ_OFFSET |
|
pushfd |
cli |
mov edx, [ecx+APPOBJ.fd] |
mov [eax+APPOBJ.fd], edx |
mov [eax+APPOBJ.bk], ecx |
mov [ecx+APPOBJ.fd], eax |
mov [edx+APPOBJ.bk], eax |
popfd |
mov edx, [eax+EVENT.id] |
.fail: |
add esp, 8 |
RemoveEventTo: ;; INTERNAL use !!! don't use for Call |
;param: |
; eax - óêàçàòåëü íà event, ÊÎÒÎÐÛÉ âñòàâëÿåì |
; ebx - óêàçàòåëü íà event, ÏÎÑËÅ êîòîðîãî âñòàâëÿåì |
;scratched: ebx,ecx |
mov ecx,eax ; ecx=eax=Self, ebx=NewLeft |
xchg ecx,[ebx+EVENT.fd] ; NewLeft.fd=Self, ecx=NewRight |
cmp eax,ecx ; ñòîï, ñåáå äóìàþ... |
je .break ; - à íå äóðàê ëè ÿ? |
mov [ecx+EVENT.bk],eax ; NewRight.bk=Self |
xchg ebx,[eax+EVENT.bk] ; Self.bk=NewLeft, ebx=OldLeft |
xchg ecx,[eax+EVENT.fd] ; Self.fd=NewRight, ecx=OldRight |
mov [ebx+EVENT.fd],ecx ; OldLeft.fd=OldRight |
mov [ecx+EVENT.bk],ebx ; OldRight.bk=OldLeft |
.break: popfd |
ret |
|
restore .flags |
restore .data |
|
; param |
; eax= event |
; ebx= id |
|
destroy_event: |
|
cmp [eax+APPOBJ.magic], 'EVNT' |
jne .fail |
cmp [eax+EVENT.id], ebx |
jne .fail |
.internal: |
mov ebx, [eax+APPOBJ.fd] |
mov ecx, [eax+APPOBJ.bk] |
mov [ebx+APPOBJ.bk], ecx |
mov [ecx+APPOBJ.fd], ebx |
.force: |
xor edx, edx ;clear common header |
mov [eax], edx |
mov [eax+4], edx |
mov [eax+8], edx |
mov [eax+12], edx |
mov [eax+16], edx |
|
call free_event ;release object memory |
.fail: |
ret |
|
align 4 |
proc send_event stdcall pid:dword, event:dword |
locals |
slot dd ? |
endl |
|
mov eax, [pid] |
call pid_to_slot |
test eax, eax |
jz .fail |
|
NotDummyTest: ;; INTERNAL use (not returned for fail !!!) |
pop edi |
call DummyTest ; not returned for fail !!! |
mov ebx,eax |
mov eax,[ebx+EVENT.pid] |
push edi |
.small: ; êðèâî êàê-òî... |
pop edi |
pushfd |
cli |
call pid_to_slot ; saved all registers (eax - retval) |
shl eax, 8 |
cmp [SLOT_BASE+eax+APPDATA.ev_count], 32 |
ja .fail |
jz RemoveEventTo.break ; POPF+RET |
jmp edi ; øòàòíûé âîçâðàò |
|
mov [slot], eax |
|
call alloc_event |
test eax, eax |
jz .fail |
|
lea edi, [eax+EVENT.code] |
mov ecx, 6 |
mov esi, [event] |
align 4 |
raise_event: ;; EXPORT use |
;info: |
; Óñòàíàâëèâàåì äàííûå EVENT.code |
; Åñëè òàì ôëàã EVENT_SIGNALED óæå àêòèâåí - áîëüøå íè÷åãî |
; Èíà÷å: ýòîò ôëàã âçâîäèòñÿ, çà èñêëþ÷åíèåì ñëó÷àÿ íàëè÷èÿ ôëàãà EVENT_WATCHED â edx |
;  ýòîì ñëó÷àå EVENT_SIGNALED âçâîäèòñÿ ëèøü ïðè íàëè÷èå EVENT_WATCHED â ñàìîì ñîáûòèè |
;param: |
; eax - event |
; ebx - uid (for Dummy testing) |
; edx - flags |
; esi - event data (=0 => skip) |
;scratched: ebx,ecx,esi,edi |
call NotDummyTest ; not returned for fail !!! |
or esi,esi |
jz @f |
lea edi,[ebx+EVENT.code] |
mov ecx,EVENT.codesize/4 |
cld |
rep movsd |
@@: |
test byte[ebx+EVENT.state+3], EVENT_SIGNALED shr 24 |
jnz RemoveEventTo.break ; POPF+RET |
bt edx, 28 ;EVENT_WATCHED |
jnc @f |
test byte[ebx+EVENT.state+3], EVENT_WATCHED shr 24 |
jz RemoveEventTo.break ; POPF+RET |
@@: |
or byte[ebx+EVENT.state+3], EVENT_SIGNALED shr 24 |
add eax,SLOT_BASE+APP_EV_OFFSET |
xchg eax,ebx |
jmp RemoveEventTo |
|
mov ecx, [slot] |
add ecx, SLOT_BASE+APP_EV_OFFSET |
|
mov [eax+APPOBJ.magic], 'EVNT' |
mov [eax+APPOBJ.destroy], destroy_event |
mov ebx, [pid] |
mov [eax+APPOBJ.pid], ebx |
mov [eax+EVENT.state], EVENT_SIGNALED |
|
pushfd |
cli ;insert event into |
mov edx, [ecx+APPOBJ.fd] ;events list |
mov [eax+APPOBJ.fd], edx ;and set events flag |
mov [eax+APPOBJ.bk], ecx |
mov [ecx+APPOBJ.fd], eax |
mov [edx+APPOBJ.bk], eax |
inc [ecx+APPDATA.ev_count-APP_EV_OFFSET] |
or [ecx+APPDATA.event_mask-APP_EV_OFFSET], EVENT_EXTENDED |
popfd |
.fail: |
ret |
endp |
|
; timeout ignored |
|
align 4 |
proc get_event_ex stdcall, p_ev:dword, timeout:dword |
|
.wait: |
mov edx,[current_slot] |
; cmp [SLOT_BASE+edx+APPDATA.ev_count], 0 |
; je .switch |
|
add edx, APP_EV_OFFSET |
|
mov eax, [edx+APPOBJ.fd] |
cmp eax, edx |
je .switch |
|
lea esi, [eax+EVENT.code] |
mov edi, [p_ev] ;copy event data |
mov ecx, 6 |
cld |
rep movsd |
|
and dword [edi-24], 0xFF00FFFF ;clear priority field |
clear_event: ;; EXPORT use |
;info: |
; |
test [eax+EVENT.state], MANUAL_RESET |
jnz .done |
;param: |
; eax - event |
; ebx - uid (for Dummy testing) |
;scratched: ebx,ecx |
call NotDummyTest ; not returned for fail !!! |
add eax,SLOT_BASE+APP_OBJ_OFFSET |
and byte[ebx+EVENT.state+3], not((EVENT_SIGNALED+EVENT_WATCHED)shr 24) |
xchg eax,ebx |
jmp RemoveEventTo |
|
pushfd |
cli ;remove event from events |
mov ebx, [eax+APPOBJ.fd] ;list (reset event) |
mov ecx, [eax+APPOBJ.bk] ;and clear events flag |
mov [ebx+APPOBJ.bk], ecx ;if no active events |
mov [ecx+APPOBJ.fd], ebx |
align 4 |
send_event: ;; EXPORT use |
;info: |
; Ñîçäàåò íîâûé EVENT (âûòàñêèâàåò èç ñïèñêà FreeEvents) â ñïèñêå EventList |
; öåëåâîãî ñëîòà (eax=pid), ñ äàííûìè èç esi êîñâåííî, è state=EVENT_SIGNALED |
;param: |
; eax - slots pid, to sending new event |
; esi - pointer to sending data (in code field of new event) |
;retval: |
; eax - event (=0 => fail) |
; edx - uid |
;warning: |
; may be used as CDECL with such prefix... |
; mov esi,[esp+8] |
; mov eax,[esp+4] |
; but not as STDCALL :( |
;scratched: ebx,ecx,esi,edi |
mov edx,eax |
call NotDummyTest.small ; not returned for fail !!! |
lea ebx,[eax+SLOT_BASE+APP_EV_OFFSET] |
mov ecx,EVENT_SIGNALED |
jmp set_event |
|
and [eax+EVENT.state], not (EVENT_SIGNALED+EVENT_WATCHED) |
|
dec [edx+APPDATA.ev_count-APP_EV_OFFSET] |
jnz @F |
and [edx+APPDATA.event_mask-APP_EV_OFFSET], not EVENT_EXTENDED |
@@: |
popfd |
|
test [eax+EVENT.state], MANUAL_DESTROY |
jz .destroy |
|
add edx, (APP_OBJ_OFFSET-APP_EV_OFFSET) |
|
pushfd |
cli |
mov ebx, [edx+APPOBJ.fd] ;insert event into |
mov [eax+APPOBJ.fd], ebx ;objects list |
mov [eax+APPOBJ.bk], edx |
mov [edx+APPOBJ.fd], eax |
mov [ebx+APPOBJ.bk], eax |
popfd |
.done: |
ret |
|
.destroy: |
call destroy_event.force |
ret |
.switch: |
mov eax, [TASK_BASE] |
mov [eax+TASKDATA.state], byte 5 |
call change_task |
jmp .wait |
endp |
|
; param |
; eax= event |
; ebx= id |
|
align 4 |
wait_event: |
.event equ esp |
push eax |
.wait: |
cmp [eax+APPOBJ.magic], 'EVNT' |
jne .done |
DummyTest: ;; INTERNAL use (not returned for fail !!!) |
;param: |
; eax - event |
; ebx - uid (for Dummy testing) |
cmp [eax+EVENT.magic],'EVNT' |
jne @f |
cmp [eax+EVENT.id], ebx |
jne .done |
je .ret |
@@: pop eax |
xor eax,eax |
.ret: ret |
|
test [eax+EVENT.state], EVENT_SIGNALED |
jz .switch |
|
test [eax+EVENT.state], MANUAL_RESET |
jnz .done |
|
mov edx,[current_slot] |
|
pushfd |
cli ;remove event from events |
mov ebx, [eax+APPOBJ.fd] ;list (reset event) |
mov ecx, [eax+APPOBJ.bk] ;and clear events flag |
mov [ebx+APPOBJ.bk], ecx ;if no active events |
mov [ecx+APPOBJ.fd], ebx |
dec [edx+APPDATA.ev_count] |
jnz @F |
and [edx+APPDATA.event_mask], not EVENT_EXTENDED |
@@: |
and [eax+EVENT.state], not (EVENT_SIGNALED+EVENT_WATCHED) |
align 4 |
Wait_events: |
or ebx,-1 ; infinite timeout |
Wait_events_ex: |
;info: |
; Îæèäàíèå "àáñòðàêòíîãî" ñîáûòèÿ ÷åðåç ïåðåâîä ñëîòà â 5-þ ïîçèöèþ. |
; Àáñòðàêòíîñòü çàêëþ÷åíà â òîì, ÷òî ôàêò ñîáûòèÿ îïðåäåëÿåòñÿ ôóíêöèåé APPDATA.wait_test, |
; êîòîðàÿ çàäàåòñÿ êëèåíòîì è ìîæåò áûòü ôàêòè÷åñêè ëþáîé. |
; Ýòî ïîçâîëÿåò shed-ó íàäåæíî îïðåäåëèòü ôàêò ñîáûòèÿ, è íå ñîâåðøàòü "õîëîñòûõ" ïåðåêëþ÷åíèé, |
; ïðåäíàçíà÷åííûõ äëÿ ðàçáîðîê òèïà "ñâîé/÷óæîé" âíóòðè çàäà÷è. |
;param: |
; edx - wait_test, êëèåíòñêàÿ ô-ÿ òåñòèðîâàíèÿ (àäðåñ êîäà) |
; ecx - wait_param, äîïîëíèòåëüíûé ïàðàìåòð, âîçìîæíî íåîáõîäèìûé äëÿ [wait_test] |
; ebx - wait_timeout |
;retval: |
; eax - ðåçóëüòàò âûçîâà [wait_test] (=0 => timeout) |
;scratched: esi |
mov esi,[current_slot] |
mov [esi+APPDATA.wait_param],ecx |
pushad |
mov ebx,esi;ïîêà ýòî âîïðîñ, ÷åãî êóäû ñóâàòü.......... |
pushfd ; ýòî ñëåäñòâèå îáùåé êîíöåïöèè: ïóñòü ô-ÿ òåñòèðîâàíèÿ èìååò |
cli ; ïðàâî ðàññ÷èòûâàòü íà çàêðûòûå ïðåðûâàíèÿ, êàê ïðè âûçîâå èç shed |
call edx |
popfd |
|
test [eax+EVENT.state], MANUAL_DESTROY |
jz .destroy |
|
add edx, APP_OBJ_OFFSET |
|
pushfd |
cli |
mov ecx, [edx+APPOBJ.fd] ;insert event into |
mov [eax+APPOBJ.fd], ecx ;objects list |
mov [eax+APPOBJ.bk], edx |
mov [edx+APPOBJ.fd], eax |
mov [ecx+APPOBJ.bk], eax |
popfd |
.done: |
add esp, 4 |
ret |
.destroy: |
call destroy_event.force |
add esp, 4 |
ret |
.switch: |
or [eax+EVENT.state], EVENT_WATCHED |
mov [esp+28],eax |
popad |
or eax,eax |
jnz @f ;RET |
mov [esi+APPDATA.wait_test],edx |
mov [esi+APPDATA.wait_timeout],ebx |
Mov [esi+APPDATA.wait_begin],eax,[timer_ticks] |
mov eax, [TASK_BASE] |
mov [eax+TASKDATA.state], byte 5 |
mov [eax+TASKDATA.state], 5 |
call change_task |
mov eax, [.event] |
jmp .wait |
restore .event |
mov eax,[esi+APPDATA.wait_param] |
@@: ret |
|
; param |
; eax= event |
; ebx= id |
; ecx= flags |
; edx= event data |
align 4 |
wait_event: ;; EXPORT use |
;info: |
; Îæèäàíèå ôëàãà EVENT_SIGNALED â ñîâåðøåííî êîíêðåòíîì Event |
; (óñòàíàâëèâàåìîãî, íàäî ïîëàãàòü, ÷åðåç raise_event) |
; Ïðè àêòèâíîì ôëàãå MANUAL_RESET - áîëüøå íè÷åãî |
; Èíà÷å: ôëàãè EVENT_SIGNALED è EVENT_WATCHED ó ïîëó÷åííîãî ñîáûòèÿ ñáðàñûâàþòñÿ, |
; è, ïðè àêòèâíîì MANUAL_DESTROY - ïåðåìåùàåòñÿ â ñïèñîê ObjList òåêóùåãî ñëîòà, |
; à ïðè íå àêòèâíîì - óíè÷òîæàåòñÿ øòàòíî (destroy_event.internal) |
;param: |
; eax - event |
; ebx - uid (for Dummy testing) |
;scratched: ecx,edx,esi |
call DummyTest |
mov ecx,eax ; wait_param |
mov edx, get_event_alone ; wait_test |
call Wait_events ; timeout ignored |
jmp wait_finish |
|
raise_event: |
.event equ esp |
push eax |
|
cmp [eax+APPOBJ.magic], 'EVNT' |
jne .fail |
cmp [eax+EVENT.id], ebx |
jne .fail |
|
mov eax, [eax+APPOBJ.pid] |
call pid_to_slot |
test eax, eax |
jz .fail |
|
mov esi, edx |
test esi, esi |
mov edx, [.event] |
jz @F |
|
push ecx |
lea edi, [edx+EVENT.code] |
mov ecx, 6 |
align 4 |
get_event_ex: ;; f68:14 |
;info: |
; Îæèäàíèå ëþáîãî ñîáûòèÿ â î÷åðåäè EventList òåêóùåãî ñëîòà |
; Äàííûå ñîáûòèÿ code - êîïèðóþòñÿ â ïàìÿòü ïðèëîæåíèÿ (êîñâåííî ïî edi) |
; Ïðè àêòèâíîì ôëàãå MANUAL_RESET - áîëüøå íè÷åãî |
; Èíà÷å: ôëàãè EVENT_SIGNALED è EVENT_WATCHED ó ïîëó÷åííîãî ñîáûòèÿ ñáðàñûâàþòñÿ, |
; è, ïðè àêòèâíîì MANUAL_DESTROY - ïåðåìåùàåòñÿ â ñïèñîê ObjList òåêóùåãî ñëîòà, |
; à ïðè íå àêòèâíîì - óíè÷òîæàåòñÿ øòàòíî (destroy_event.internal) |
;param: |
; edi - àäðåñ â êîäå ïðèëîæåíèÿ äëÿ êîïèðîâàíèÿ äàííûõ èç EVENT.code |
;retval: |
; eax - ñîáñòâåííî EVENT (áóäåì íàçûâàòü ýòî åãî õýíäëîì) |
;scratched: ebx,ecx,edx,esi,edi |
mov edx, get_event_queue ; wait_test |
call Wait_events ; timeout ignored |
lea esi,[eax+EVENT.code] |
mov ecx,EVENT.codesize/4 |
cld |
rep movsd |
pop ecx |
@@: |
test [edx+EVENT.state], EVENT_SIGNALED |
jnz .done |
|
test ecx, EVENT_WATCHED |
jz @F |
test [edx+EVENT.state], EVENT_WATCHED |
jz .done |
@@: |
shl eax, 8 |
add eax, SLOT_BASE+APP_EV_OFFSET |
|
mov [edi-EVENT.codesize+2],cl ;clear priority field |
wait_finish: |
test byte[eax+EVENT.state+3], MANUAL_RESET shr 24 |
jnz get_event_queue.ret ; RET |
and byte[eax+EVENT.state+3], not((EVENT_SIGNALED+EVENT_WATCHED)shr 24) |
test byte[eax+EVENT.state+3], MANUAL_DESTROY shr 24 |
jz destroy_event.internal |
mov ebx,[current_slot] |
add ebx,APP_OBJ_OFFSET |
pushfd |
cli |
mov ebx, [edx+APPOBJ.fd] |
mov ecx, [edx+APPOBJ.bk] |
mov [ebx+APPOBJ.bk], ecx |
mov [ecx+APPOBJ.fd], ebx |
jmp RemoveEventTo |
|
mov ecx, [eax+APPOBJ.fd] |
mov [edx+APPOBJ.fd], ecx |
mov [edx+APPOBJ.bk], eax |
mov [eax+APPOBJ.fd], edx |
mov [ecx+APPOBJ.bk], edx |
or [edx+EVENT.state], EVENT_SIGNALED |
|
inc [eax+APPDATA.ev_count-APP_EV_OFFSET] |
or [eax+APPDATA.event_mask-APP_EV_OFFSET], EVENT_EXTENDED |
popfd |
.fail: |
.done: |
add esp, 4 |
ret |
restore .event |
|
; param |
; eax= event |
; ebx= id |
align 4 |
clear_event: |
.event equ esp |
push eax |
|
cmp [eax+APPOBJ.magic], 'EVNT' |
jne .fail |
cmp [eax+EVENT.id], ebx |
jne .fail |
|
mov eax, [eax+APPOBJ.pid] |
call pid_to_slot |
test eax, eax |
jz .fail |
|
shl eax, 8 |
add eax, SLOT_BASE+APP_EV_OFFSET |
mov edx, [.event] |
destroy_event: ;; EXPORT use |
;info: |
; Ïåðåíîñèì EVENT â ñïèñîê FreeEvents, ÷èñòèì ïîëÿ magic,destroy,pid,id |
;param: |
; eax - event |
; ebx - uid (for Dummy testing) |
;retval: |
; eax - àäðåñ îáúåêòà EVENT (=0 => fail) |
;scratched: ebx,ecx |
call DummyTest ; not returned for fail !!! |
.internal: |
xor ecx,ecx ; clear common header |
pushfd |
cli ;remove event from events |
mov ebx, [edx+APPOBJ.fd] ;list (reset event) |
mov ecx, [edx+APPOBJ.bk] ;and clear events flag |
mov [ebx+APPOBJ.bk], ecx ;if no active events |
mov [ecx+APPOBJ.fd], ebx |
cli |
mov [eax+EVENT.magic],ecx |
mov [eax+EVENT.destroy],ecx |
mov [eax+EVENT.pid],ecx |
mov [eax+EVENT.id],ecx |
mov ebx,FreeEvents |
jmp RemoveEventTo |
|
and [edx+EVENT.state], not (EVENT_SIGNALED+EVENT_WATCHED) |
align 4 |
get_event_queue: |
;info: |
; êëèåíòñêàÿ ô-ÿ òåñòèðîâàíèÿ äëÿ get_event_ex |
;warning: |
; -don't use [TASK_BASE],[current_slot],[CURRENT_TASK] - it is not for your slot |
; -may be assumed, that interrupt are disabled |
; -it is not restriction for scratched registers |
;param: |
; ebx - àäðåñ APPDATA ñëîòà òåñòèðîâàíèÿ |
;retval: |
; eax - àäðåñ îáúåêòà EVENT (=0 => fail) |
add ebx,APP_EV_OFFSET |
mov eax,[ebx+APPOBJ.bk] ; âûáèðàåì ñ êîíöà, ïî ïðèíöèïó FIFO |
cmp eax,ebx ; empty ??? |
je get_event_alone.ret0 |
.ret: ret |
|
dec [eax+APPDATA.ev_count-APP_EV_OFFSET] |
jnz @F |
and [eax+APPDATA.event_mask-APP_EV_OFFSET], not EVENT_EXTENDED |
@@: |
add eax, (APP_OBJ_OFFSET-APP_EV_OFFSET) |
align 4 |
get_event_alone: |
;info: |
; êëèåíòñêàÿ ô-ÿ òåñòèðîâàíèÿ äëÿ wait_event |
;warning: |
; -don't use [TASK_BASE],[current_slot],[CURRENT_TASK] - it is not for your slot |
; -may be assumed, that interrupt are disabled |
; -it is not restriction for scratched registers |
;param: |
; ebx - àäðåñ APPDATA ñëîòà òåñòèðîâàíèÿ |
;retval: |
; eax - àäðåñ îáúåêòà EVENT (=0 => fail) |
mov eax,[ebx+APPDATA.wait_param] |
test byte[eax+EVENT.state+3], EVENT_SIGNALED shr 24 |
jnz .ret |
or byte[eax+EVENT.state+3], EVENT_WATCHED shr 24 |
.ret0: xor eax,eax ; NO event!!! |
.ret: ret |
|
mov ecx, [eax+APPOBJ.fd] ;insert event into |
mov [edx+APPOBJ.fd], ecx ;objects list |
mov [edx+APPOBJ.bk], eax |
mov [eax+APPOBJ.fd], edx |
mov [ecx+APPOBJ.bk], edx |
popfd |
.fail: |
.done: |
add esp, 4 |
ret |
restore .event |
align 4 |
sys_sendwindowmsg: ;; f72 |
dec ebx |
jnz .ret ;subfunction==1 ? |
;pushfd ;à íàôèãà? |
cli |
sub ecx,2 |
je .sendkey |
loop .retf |
.sendbtn: |
cmp byte[BTN_COUNT],1 |
jae .result ;overflow |
inc byte[BTN_COUNT] |
mov [BTN_BUFF],edx |
jmp .result |
.sendkey: |
movzx eax,byte[KEY_COUNT] |
cmp al,120 |
jae .result ;overflow |
inc byte[KEY_COUNT] |
mov [KEY_COUNT+1+eax],dl |
.result: |
setae byte[esp+32] ;ñ÷èòàåì, ÷òî èñõîäíî: dword[esp+32]==72 |
.retf: ;popfd |
.ret: ret |
|
sys_getevent: |
|
align 4 |
sys_getevent: ;; f11 |
mov ebx,[current_slot] ;ïîêà ýòî âîïðîñ, ÷åãî êóäû ñóâàòü.......... |
pushfd ; ýòî ñëåäñòâèå îáùåé êîíöåïöèè: ïóñòü ô-ÿ òåñòèðîâàíèÿ èìååò |
cli ; ïðàâî ðàññ÷èòûâàòü íà çàêðûòûå ïðåðûâàíèÿ, êàê ïðè âûçîâå èç shed |
call get_event_for_app |
popfd |
mov [esp + 32],eax |
ret |
|
sys_waitforevent: |
or ebx, 0xFFFFFFFF ; infinite timeout |
jmp @f |
|
sys_wait_event_timeout: |
add ebx, [timer_ticks] |
@@: |
mov eax, [current_slot] |
mov [eax + APPDATA.wait_timeout], ebx |
call get_event_for_app |
test eax, eax |
jnz eventoccur |
|
mov eax, [TASK_BASE] |
mov [eax+TASKDATA.state], byte 5 |
call change_task |
|
mov eax, [event_sched] |
eventoccur: |
align 4 |
sys_waitforevent: ;; f10 |
or ebx,-1 ; infinite timeout |
sys_wait_event_timeout: ;; f23 |
mov edx,get_event_for_app ; wait_test |
call Wait_events_ex ; ebx - timeout |
mov [esp+32], eax |
ret |
|
sys_sendwindowmsg: |
dec eax |
jnz .ret |
cmp ebx, 3 |
jz .sendbtn |
cmp ebx, 2 |
jnz .ret |
.sendkey: |
pushf |
cli |
movzx eax, byte [KEY_COUNT] |
cmp al, 120 |
jae .overflow |
align 4 |
get_event_for_app: ;; used from f10,f11,f23 |
;info: |
; êëèåíòñêàÿ ô-ÿ òåñòèðîâàíèÿ äëÿ ïðèëîæåíèé (f10,f23) |
;warning: |
; -don't use [TASK_BASE],[current_slot],[CURRENT_TASK] - it is not for your slot |
; -may be assumed, that interrupt are disabled |
; -it is not restriction for scratched registers |
;param: |
; ebx - àäðåñ APPDATA ñëîòà òåñòèðîâàíèÿ |
;retval: |
; eax - íîìåð ñîáûòèÿ (=0 => no events) |
movzx edi,bh ; bh is assumed as [CURRENT_TASK] |
shl edi,5 |
add edi,CURRENT_TASK ; edi is assumed as [TASK_BASE] |
mov ecx,[edi+TASKDATA.event_mask] |
.loop: ; ïîêà íå èñ÷åðïàåì âñå áèòû ìàñêè |
bsr eax,ecx ; íàõîäèì íåíóëåâîé áèò ìàñêè (31 -> 0) |
jz .no_events ; èñ÷åðïàëè âñå áèòû ìàñêè, íî íè÷åãî íå íàøëè ??? |
btr ecx,eax ; ñáðàñûâàåì ïðîâåðÿåìûé áèò ìàñêè |
; ïåðåõîäèì íà îáðàáîò÷èê ýòîãî (eax) áèòà |
cmp eax,16 |
jae .IRQ ; eax=[16..31]=retvals, events irq0..irq15 |
cmp eax,9 |
jae .loop ; eax=[9..15], ignored |
cmp eax,3 |
je .loop ; eax=3, ignored |
ja .FlagAutoReset ; eax=[4..8], retvals=eax+1 |
cmp eax,1 |
jae .BtKy ; eax=[1,2], retvals=eax+1 |
.WndRedraw: ; eax=0, retval WndRedraw=1 |
cmp [edi-twdw+WDATA.fl_redraw],al ;al==0 |
jne .result |
jmp .loop |
.no_events: |
xor eax,eax |
ret |
.IRQ: |
;TODO: ñäåëàòü òàê æå, êàê è äëÿ FlagAutoReset (BgrRedraw,Mouse,IPC,Stack,Debug) |
mov edx,[irq_owner+eax*4-64] ; eax==16+irq |
cmp edx,[edi+TASKDATA.pid] |
jne .loop |
mov edx,eax |
shl edx,12 |
cmp dword[IRQ_SAVE+edx-0x10000],0 ; edx==(16+irq)*0x1000 |
je .loop ; empty ??? |
ret ; retval = eax |
.FlagAutoReset: ; retvals: BgrRedraw=5, Mouse=6, IPC=7, Stack=8, Debug=9 |
btr [ebx+APPDATA.event_mask],eax |
jnc .loop |
.result: ; retval = eax+1 |
inc eax |
mov [KEY_COUNT], al |
mov [KEY_COUNT+eax], cl |
jmp .ok |
.overflow: |
popf |
mov dword [esp+36], 1 |
ret |
.sendbtn: |
pushf |
cli |
.BtKy: |
movzx edx,bh |
movzx edx, word[WIN_STACK+edx*2] |
je .Keys ; eax=1, retval Keys=2 |
.Buttons: ; eax=2, retval Buttons=3 |
cmp byte [BTN_COUNT], 0 |
jnz .overflow |
mov byte [BTN_COUNT], 1 |
mov [BTN_BUFF], ecx |
.ok: |
popf |
and dword [esp+36], 0 |
.ret: |
ret |
|
get_event_for_app: |
|
pushad |
|
mov edi,[TASK_BASE] ; WINDOW REDRAW |
test [edi+TASKDATA.event_mask], 1 |
jz no_eventoccur1 |
;mov edi,[TASK_BASE] |
cmp [edi-twdw+WDATA.fl_redraw],byte 0 |
je no_eventoccur1 |
popad |
mov eax,1 |
ret |
no_eventoccur1: |
|
;mov edi,[TASK_BASE] ; KEY IN BUFFER |
test [edi+TASKDATA.event_mask],dword 2 |
jz no_eventoccur2 |
mov ecx, [CURRENT_TASK] |
movzx edx,word [WIN_STACK+ecx*2] |
mov eax, [TASK_COUNT] |
cmp eax,edx |
jne no_eventoccur2x |
cmp [KEY_COUNT],byte 0 |
je no_eventoccur2x |
eventoccur2: |
popad |
mov eax,2 |
ret |
no_eventoccur2x: |
mov eax, hotkey_buffer |
@@: |
cmp [eax], ecx |
jz eventoccur2 |
add eax, 8 |
cmp eax, hotkey_buffer+120*8 |
je .loop ; empty ??? |
cmp edx,[TASK_COUNT] |
jne .loop ; not Top ??? |
cmp dword[BTN_BUFF],0xFFFF ;-ID for Minimize-Button of Form |
jne .result |
mov [window_minimize],1 |
dec byte[BTN_COUNT] |
jmp .loop |
.Keys: ; eax==1 |
cmp edx,[TASK_COUNT] |
jne @f ; not Top ??? |
cmp [KEY_COUNT],al ; al==1 |
jae .result ; not empty ??? |
@@: mov edx, hotkey_buffer |
@@: cmp [edx],bh ; bh - slot for testing |
je .result |
add edx,8 |
cmp edx, hotkey_buffer+120*8 |
jb @b |
no_eventoccur2: |
|
;mov edi,[TASK_BASE] ; BUTTON IN BUFFER |
test [edi+TASKDATA.event_mask],dword 4 |
jz no_eventoccur3 |
cmp [BTN_COUNT],byte 0 |
je no_eventoccur3 |
mov ecx, [CURRENT_TASK] |
movzx edx, word [WIN_STACK+ecx*2] |
mov eax, [TASK_COUNT] |
cmp eax,edx |
jnz no_eventoccur3 |
popad |
mov eax,[BTN_BUFF] |
cmp eax,65535 |
je no_event_1 |
mov eax,3 |
ret |
|
no_event_1: |
mov [window_minimize],1 |
mov [BTN_COUNT],byte 0 |
xor eax, eax |
ret |
|
no_eventoccur3: |
|
;mov edi,[TASK_BASE] ; mouse event |
mov eax, [CURRENT_TASK] |
shl eax, 8 |
add eax, SLOT_BASE |
test [edi+TASKDATA.event_mask],dword 00100000b |
jz no_mouse_event |
|
test [eax+APPDATA.event_mask],dword 00100000b |
jz no_mouse_event |
and [eax+APPDATA.event_mask],dword (not 00100000b) |
popad |
mov eax,6 |
ret |
no_mouse_event: |
|
;mov edi,[TASK_BASE] ; DESKTOP BACKGROUND REDRAW |
test [edi+TASKDATA.event_mask], 16 |
jz no_eventoccur5 |
; cmp [REDRAW_BACKGROUND],byte 2 |
; jnz no_eventoccur5 |
test [eax+APPDATA.event_mask], 16 |
jz no_eventoccur5 |
and [eax+APPDATA.event_mask], not 16 |
popad |
mov eax,5 |
ret |
no_eventoccur5: |
|
;mov edi,[TASK_BASE] ; IPC |
test [edi+TASKDATA.event_mask],dword 01000000b |
jz no_ipc |
test [eax+APPDATA.event_mask],dword 01000000b |
jz no_ipc |
and [eax+APPDATA.event_mask],dword 0xffffffff-01000000b |
popad |
mov eax,7 |
ret |
no_ipc: |
|
;mov edi,[TASK_BASE] ; STACK |
test [edi+TASKDATA.event_mask],dword 10000000b |
jz no_stack_event |
test [eax+APPDATA.event_mask],dword 10000000b |
jz no_stack_event |
and [eax+APPDATA.event_mask],dword 0xffffffff-10000000b |
popad |
mov eax,8 |
ret |
no_stack_event: |
|
test byte [edi+TASKDATA.event_mask+1], 1 ; DEBUG |
jz .test_IRQ |
test byte [eax+APPDATA.event_mask+1], byte 1 |
jz .test_IRQ |
and byte [eax+APPDATA.event_mask+1], not 1 |
popad |
mov eax, 9 |
ret |
|
;.test_ext: |
; mov eax, [CURRENT_TASK] |
; shl eax, 8 |
; test dword [eax+SLOT_BASE+APPDATA.event_mask], EVENT_EXTENDED |
; jz .test_IRQ |
; popad |
; mov eax, 10 |
; ret |
|
.test_IRQ: |
cmp dword [edi+TASKDATA.event_mask], 0xFFFF |
jbe no_events |
|
mov esi,IRQ_SAVE ; IRQ'S AND DATA |
mov ebx,0x00010000 |
xor ecx, ecx |
irq_event_test: |
mov edi,[TASK_BASE] |
test [edi+TASKDATA.event_mask],ebx |
jz no_irq_event |
mov edi,ecx |
shl edi,2 |
add edi,irq_owner |
mov edx,[edi] |
mov eax,[TASK_BASE] |
mov eax,[eax+TASKDATA.pid] |
cmp edx,eax |
jne no_irq_event |
cmp [esi],dword 0 |
jz no_irq_event |
mov eax,ecx |
add eax,16 |
mov [esp+28],eax |
popad |
ret |
no_irq_event: |
add esi,0x1000 |
shl ebx,1 |
inc ecx |
cmp ecx,16 |
jb irq_event_test |
|
no_events: |
popad |
xor eax, eax |
ret |
|
|
|
jmp .loop |
;end. |