Subversion Repositories Kolibri OS

Rev

Rev 1161 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1159 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
4
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa      ;;
5
;; Distributed under terms of the GNU General Public License    ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
8
$Revision: 671 $
9
 
1198 clevermous 10
uglobal
1159 hidnplayr 11
align 4
1198 clevermous 12
  event_start   dd ?
13
  event_end     dd ?
14
  event_uid     dd 0
15
endg
16
EV_SPACE   = 512
17
FreeEvents = event_start-EVENT.fd    ; "виртуальный" event, используются только поля:
18
                                     ;  FreeEvents.fd=event_start и FreeEvents.bk=event_end
19
align 4
20
init_events:                                       ;; used from kernel.asm
21
        stdcall kernel_alloc,EV_SPACE*EVENT.size
22
        or      eax,eax
23
        jz      .fail
24
      ; eax - current event, ebx - previos event below
25
        mov     ecx,EV_SPACE         ; current - in allocated space
26
        mov     ebx,FreeEvents       ; previos - начало списка
27
        push    ebx                  ; оно же и конец потом будет
28
  @@:   mov     [ebx+EVENT.fd],eax
29
        mov     [eax+EVENT.bk],ebx
30
        mov     ebx,eax              ; previos <- current
31
        add     eax,EVENT.size       ; new current
32
        loop    @b
33
        pop     eax                  ; вот оно концом и стало
34
        mov     [ebx+EVENT.fd],eax
35
        mov     [eax+EVENT.bk],ebx
36
.fail:  ret
1159 hidnplayr 37
 
1198 clevermous 38
EVENT_WATCHED    equ 0x10000000 ;бит 28
39
EVENT_SIGNALED   equ 0x20000000 ;бит 29
40
MANUAL_RESET     equ 0x40000000 ;бит 30
41
MANUAL_DESTROY   equ 0x80000000 ;бит 31
42
 
1159 hidnplayr 43
align 4
1198 clevermous 44
create_event:                                      ;; EXPORT use
45
;info:
46
;   Переносим EVENT из списка FreeEvents в список ObjList текущего слота
47
;   EVENT.state устанавливаем из ecx, EVENT.code косвенно из esi (если esi<>0)
48
;param:
49
;   esi - event data
50
;   ecx - flags
51
;retval:
52
;   eax - event (=0 => fail)
53
;   edx - uid
54
;scratched: ebx,ecx,esi,edi
55
        mov     ebx,[current_slot]
56
        add     ebx,APP_OBJ_OFFSET
57
        mov     edx,[TASK_BASE]
58
        mov     edx,[edx+TASKDATA.pid]
59
        pushfd
60
        cli
1159 hidnplayr 61
 
1198 clevermous 62
set_event:                                         ;; INTERNAL use !!! don't use for Call
63
;info:
64
;   Берем новый event из FreeEvents, заполняем его поля, как указано в ecx,edx,esi
65
;   и устанавливаем в список, указанный в ebx.
66
;   Возвращаем сам event (в eax), и его uid (в edx)
67
;param:
68
;   ebx - start-chain "virtual" event for entry new event Right of him
69
;   ecx - flags      (copied to EVENT.state)
70
;   edx - pid        (copied to EVENT.pid)
71
;   esi - event data (copied to EVENT.code indirect, =0 => skip)
72
;retval:
73
;   eax - event (=0 => fail)
74
;   edx - uid
75
;scratched: ebx,ecx,esi,edi
76
        mov     eax,FreeEvents
77
        cmp     eax,[eax+EVENT.fd]
78
        jne     @f  ; not empty ???
79
        pushad
80
        call    init_events
81
        popad
82
        jz      RemoveEventTo.break ; POPF+RET
83
  @@:   mov     eax,[eax+EVENT.fd]
84
        mov     [eax+EVENT.magic],'EVNT'
85
        mov     [eax+EVENT.destroy],destroy_event.internal
86
        mov     [eax+EVENT.state],ecx
87
        mov     [eax+EVENT.pid],edx
88
        inc     [event_uid]
89
        Mov     [eax+EVENT.id],edx,[event_uid]
90
        or      esi,esi
91
        jz      RemoveEventTo
92
        lea     edi,[eax+EVENT.code]
93
        mov     ecx,EVENT.codesize/4
94
        cld
95
        rep     movsd
1159 hidnplayr 96
 
1198 clevermous 97
RemoveEventTo:                                     ;; INTERNAL use !!! don't use for Call
98
;param:
99
;   eax - указатель на event, КОТОРЫЙ вставляем
100
;   ebx - указатель на event, ПОСЛЕ которого вставляем
101
;scratched: ebx,ecx
102
        mov     ecx,eax              ; ecx=eax=Self,      ebx=NewLeft
103
        xchg    ecx,[ebx+EVENT.fd]   ; NewLeft.fd=Self,   ecx=NewRight
104
        cmp     eax,ecx              ; стоп, себе думаю...
105
        je      .break               ; - а не дурак ли я?
106
        mov     [ecx+EVENT.bk],eax   ; NewRight.bk=Self
107
        xchg    ebx,[eax+EVENT.bk]   ; Self.bk=NewLeft,   ebx=OldLeft
108
        xchg    ecx,[eax+EVENT.fd]   ; Self.fd=NewRight,  ecx=OldRight
109
        mov     [ebx+EVENT.fd],ecx   ; OldLeft.fd=OldRight
110
        mov     [ecx+EVENT.bk],ebx   ; OldRight.bk=OldLeft
111
.break: popfd
112
        ret
1159 hidnplayr 113
 
1198 clevermous 114
align 4
115
NotDummyTest:                                      ;; INTERNAL use (not returned for fail !!!)
116
        pop     edi
117
        call    DummyTest ; not returned for fail !!!
118
        mov     ebx,eax
119
        mov     eax,[ebx+EVENT.pid]
120
        push    edi
121
.small: ; криво как-то...
122
        pop     edi
123
        pushfd
124
        cli
125
        call    pid_to_slot ; saved all registers (eax - retval)
126
        shl     eax,8
127
        jz      RemoveEventTo.break ; POPF+RET
128
        jmp     edi ; штатный возврат
1159 hidnplayr 129
 
130
align 4
1198 clevermous 131
raise_event:                                       ;; EXPORT use
132
;info:
133
;   Устанавливаем данные EVENT.code
134
;   Если там флаг EVENT_SIGNALED уже активен - больше ничего
135
;   Иначе: этот флаг взводится, за исключением случая наличия флага EVENT_WATCHED в edx
136
;   В этом случае EVENT_SIGNALED взводится лишь при наличие EVENT_WATCHED в самом событии
137
;param:
138
;   eax - event
139
;   ebx - uid (for Dummy testing)
140
;   edx - flags
141
;   esi - event data (=0 => skip)
142
;scratched: ebx,ecx,esi,edi
143
        call    NotDummyTest ; not returned for fail !!!
144
        or      esi,esi
145
        jz      @f
146
        lea     edi,[ebx+EVENT.code]
147
        mov     ecx,EVENT.codesize/4
148
        cld
149
        rep     movsd
150
  @@:
151
        test    byte[ebx+EVENT.state+3], EVENT_SIGNALED shr 24
152
        jnz     RemoveEventTo.break  ; POPF+RET
153
        bt      edx, 28 ;EVENT_WATCHED
154
        jnc     @f
155
        test    byte[ebx+EVENT.state+3], EVENT_WATCHED  shr 24
156
        jz      RemoveEventTo.break  ; POPF+RET
157
  @@:
158
        or      byte[ebx+EVENT.state+3], EVENT_SIGNALED shr 24
159
        add     eax,SLOT_BASE+APP_EV_OFFSET
160
        xchg    eax,ebx
161
        jmp     RemoveEventTo
1159 hidnplayr 162
 
1198 clevermous 163
align 4
164
clear_event:                                       ;; EXPORT use
165
;info:
1159 hidnplayr 166
;
1198 clevermous 167
;param:
168
;   eax - event
169
;   ebx - uid (for Dummy testing)
170
;scratched: ebx,ecx
171
        call    NotDummyTest ; not returned for fail !!!
172
        add     eax,SLOT_BASE+APP_OBJ_OFFSET
173
        and     byte[ebx+EVENT.state+3], not((EVENT_SIGNALED+EVENT_WATCHED)shr 24)
174
        xchg    eax,ebx
175
        jmp     RemoveEventTo
1159 hidnplayr 176
 
1198 clevermous 177
align 4
178
send_event:                                        ;; EXPORT use
179
;info:
180
;   Создает новый EVENT (вытаскивает из списка FreeEvents) в списке EventList
181
;   целевого слота (eax=pid), с данными из esi косвенно, и state=EVENT_SIGNALED
182
;param:
183
;   eax - slots pid, to sending new event
184
;   esi - pointer to sending data (in code field of new event)
185
;retval:
186
;   eax - event (=0 => fail)
187
;   edx - uid
188
;warning:
189
;   may be used as CDECL with such prefix...
190
;       mov     esi,[esp+8]
191
;       mov     eax,[esp+4]
192
;   but not as STDCALL :(
193
;scratched: ebx,ecx,esi,edi
194
        mov     edx,eax
195
        call    NotDummyTest.small ; not returned for fail !!!
196
        lea     ebx,[eax+SLOT_BASE+APP_EV_OFFSET]
197
        mov     ecx,EVENT_SIGNALED
198
        jmp     set_event
1159 hidnplayr 199
 
1198 clevermous 200
align 4
201
DummyTest:                                         ;; INTERNAL use (not returned for fail !!!)
202
;param:
203
;   eax - event
204
;   ebx - uid (for Dummy testing)
205
        cmp     [eax+EVENT.magic],'EVNT'
206
        jne     @f
207
        cmp     [eax+EVENT.id],ebx
208
        je      .ret
209
  @@:   pop     eax
210
        xor     eax,eax
211
.ret:   ret
1159 hidnplayr 212
 
213
 
1198 clevermous 214
align 4
215
Wait_events:
216
        or      ebx,-1 ; infinite timeout
217
Wait_events_ex:
218
;info:
219
;   Ожидание "абстрактного" события через перевод слота в 5-ю позицию.
220
;   Абстрактность заключена в том, что факт события определяется функцией APPDATA.wait_test,
221
;   которая задается клиентом и может быть фактически любой.
222
;   Это позволяет shed-у надежно определить факт события, и не совершать "холостых" переключений,
223
;   предназначенных для разборок типа "свой/чужой" внутри задачи.
224
;param:
225
;   edx - wait_test, клиентская ф-я тестирования (адрес кода)
226
;   ecx - wait_param, дополнительный параметр, возможно необходимый для [wait_test]
227
;   ebx - wait_timeout
228
;retval:
229
;   eax - результат вызова [wait_test] (=0 => timeout)
230
;scratched: esi
231
        mov     esi,[current_slot]
232
        mov     [esi+APPDATA.wait_param],ecx
233
        pushad
234
        mov     ebx,esi;пока это вопрос, чего куды сувать..........
235
        pushfd  ; это следствие общей концепции: пусть ф-я тестирования имеет
236
        cli     ; право рассчитывать на закрытые прерывания, как при вызове из shed
237
        call    edx
238
        popfd
239
        mov     [esp+28],eax
240
        popad
241
        or      eax,eax
242
        jnz     @f   ;RET
243
        mov     [esi+APPDATA.wait_test],edx
244
        mov     [esi+APPDATA.wait_timeout],ebx
245
        Mov     [esi+APPDATA.wait_begin],eax,[timer_ticks]
246
        mov     eax,[TASK_BASE]
247
        mov     [eax+TASKDATA.state], 5
248
        call    change_task
249
        mov     eax,[esi+APPDATA.wait_param]
250
  @@:   ret
1159 hidnplayr 251
 
1198 clevermous 252
align 4
253
wait_event:                                        ;; EXPORT use
254
;info:
255
;   Ожидание флага EVENT_SIGNALED в совершенно конкретном Event
256
;   (устанавливаемого, надо полагать, через raise_event)
257
;   При активном флаге MANUAL_RESET - больше ничего
258
;   Иначе: флаги EVENT_SIGNALED и EVENT_WATCHED у полученного события сбрасываются,
259
;   и, при активном MANUAL_DESTROY - перемещается в список ObjList текущего слота,
260
;   а при не активном - уничтожается штатно (destroy_event.internal)
261
;param:
262
;   eax - event
263
;   ebx - uid (for Dummy testing)
264
;scratched: ecx,edx,esi
265
        call    DummyTest
266
        mov     ecx,eax              ; wait_param
267
        mov     edx, get_event_alone ; wait_test
268
        call    Wait_events          ; timeout ignored
269
        jmp     wait_finish
1159 hidnplayr 270
 
1198 clevermous 271
align 4
272
get_event_ex:                                      ;; f68:14
273
;info:
274
;   Ожидание любого события в очереди EventList текущего слота
275
;   Данные события code - копируются в память приложения (косвенно по edi)
276
;   При активном флаге MANUAL_RESET - больше ничего
277
;   Иначе: флаги EVENT_SIGNALED и EVENT_WATCHED у полученного события сбрасываются,
278
;   и, при активном MANUAL_DESTROY - перемещается в список ObjList текущего слота,
279
;   а при не активном - уничтожается штатно (destroy_event.internal)
280
;param:
281
;   edi - адрес в коде приложения для копирования данных из EVENT.code
282
;retval:
283
;   eax - собственно EVENT (будем называть это его хэндлом)
284
;scratched: ebx,ecx,edx,esi,edi
285
        mov     edx, get_event_queue ; wait_test
286
        call    Wait_events          ; timeout ignored
287
        lea     esi,[eax+EVENT.code]
288
        mov     ecx,EVENT.codesize/4
289
        cld
290
        rep     movsd
291
        mov     [edi-EVENT.codesize+2],cl ;clear priority field
292
wait_finish:
293
        test    byte[eax+EVENT.state+3], MANUAL_RESET shr 24
294
        jnz     get_event_queue.ret  ; RET
295
        and     byte[eax+EVENT.state+3], not((EVENT_SIGNALED+EVENT_WATCHED)shr 24)
296
        test    byte[eax+EVENT.state+3], MANUAL_DESTROY shr 24
297
        jz      destroy_event.internal
298
        mov     ebx,[current_slot]
299
        add     ebx,APP_OBJ_OFFSET
300
        pushfd
301
        cli
302
        jmp     RemoveEventTo
1159 hidnplayr 303
 
1198 clevermous 304
align 4
305
destroy_event:                                     ;; EXPORT use
306
;info:
307
;   Переносим EVENT в список FreeEvents, чистим поля magic,destroy,pid,id
308
;param:
309
;   eax - event
310
;   ebx - uid (for Dummy testing)
311
;retval:
312
;   eax - адрес объекта EVENT (=0 => fail)
313
;scratched: ebx,ecx
314
        call    DummyTest ; not returned for fail !!!
1159 hidnplayr 315
.internal:
1198 clevermous 316
        xor     ecx,ecx   ; clear common header
317
        pushfd
318
        cli
319
        mov     [eax+EVENT.magic],ecx
320
        mov     [eax+EVENT.destroy],ecx
321
        mov     [eax+EVENT.pid],ecx
322
        mov     [eax+EVENT.id],ecx
323
        mov     ebx,FreeEvents
324
        jmp     RemoveEventTo
1159 hidnplayr 325
 
326
align 4
1198 clevermous 327
get_event_queue:
328
;info:
329
;   клиентская ф-я тестирования для get_event_ex
330
;warning:
331
;  -don't use [TASK_BASE],[current_slot],[CURRENT_TASK] - it is not for your slot
332
;  -may be assumed, that interrupt are disabled
333
;  -it is not restriction for scratched registers
334
;param:
335
;   ebx - адрес APPDATA слота тестирования
336
;retval:
337
;   eax - адрес объекта EVENT (=0 => fail)
338
        add     ebx,APP_EV_OFFSET
339
        mov     eax,[ebx+APPOBJ.bk]  ; выбираем с конца, по принципу FIFO
340
        cmp     eax,ebx  ; empty ???
341
        je      get_event_alone.ret0
342
.ret:   ret
1159 hidnplayr 343
 
344
align 4
1198 clevermous 345
get_event_alone:
346
;info:
347
;   клиентская ф-я тестирования для wait_event
348
;warning:
349
;  -don't use [TASK_BASE],[current_slot],[CURRENT_TASK] - it is not for your slot
350
;  -may be assumed, that interrupt are disabled
351
;  -it is not restriction for scratched registers
352
;param:
353
;   ebx - адрес APPDATA слота тестирования
354
;retval:
355
;   eax - адрес объекта EVENT (=0 => fail)
356
        mov     eax,[ebx+APPDATA.wait_param]
357
        test    byte[eax+EVENT.state+3], EVENT_SIGNALED shr 24
358
        jnz     .ret
359
        or      byte[eax+EVENT.state+3], EVENT_WATCHED shr 24
360
.ret0:  xor     eax,eax ; NO event!!!
361
.ret:   ret
1159 hidnplayr 362
 
363
align 4
1198 clevermous 364
sys_sendwindowmsg:                                 ;; f72
365
        dec     ebx
366
        jnz     .ret ;subfunction==1 ?
367
       ;pushfd  ;а нафига?
368
        cli
369
        sub     ecx,2
370
        je      .sendkey
371
        loop    .retf
372
.sendbtn:
373
        cmp     byte[BTN_COUNT],1
374
        jae     .result ;overflow
375
        inc     byte[BTN_COUNT]
376
        mov     [BTN_BUFF],edx
377
        jmp     .result
378
.sendkey:
379
        movzx   eax,byte[KEY_COUNT]
380
        cmp     al,120
381
        jae     .result ;overflow
382
        inc     byte[KEY_COUNT]
383
        mov     [KEY_COUNT+1+eax],dl
384
.result:
385
        setae   byte[esp+32] ;считаем, что исходно: dword[esp+32]==72
386
.retf: ;popfd
387
.ret:   ret
1159 hidnplayr 388
 
389
align 4
1198 clevermous 390
sys_getevent:                                      ;; f11
391
        mov     ebx,[current_slot] ;пока это вопрос, чего куды сувать..........
392
        pushfd  ; это следствие общей концепции: пусть ф-я тестирования имеет
393
        cli     ; право рассчитывать на закрытые прерывания, как при вызове из shed
1159 hidnplayr 394
        call    get_event_for_app
1198 clevermous 395
        popfd
396
        mov     [esp+32],eax
397
        ret
1159 hidnplayr 398
 
1198 clevermous 399
align 4
400
sys_waitforevent:                                  ;; f10
401
        or      ebx,-1 ; infinite timeout
402
sys_wait_event_timeout:                            ;; f23
403
        mov     edx,get_event_for_app ; wait_test
404
        call    Wait_events_ex        ; ebx - timeout
405
        mov     [esp+32],eax
406
        ret
1159 hidnplayr 407
 
1198 clevermous 408
align 4
409
get_event_for_app:                                 ;; used from f10,f11,f23
410
;info:
411
;   клиентская ф-я тестирования для приложений (f10,f23)
412
;warning:
413
;  -don't use [TASK_BASE],[current_slot],[CURRENT_TASK] - it is not for your slot
414
;  -may be assumed, that interrupt are disabled
415
;  -it is not restriction for scratched registers
416
;param:
417
;   ebx - адрес APPDATA слота тестирования
418
;retval:
419
;   eax - номер события (=0 => no events)
420
        movzx   edi,bh                ; bh  is assumed as [CURRENT_TASK]
421
        shl     edi,5
422
        add     edi,CURRENT_TASK      ; edi is assumed as [TASK_BASE]
423
        mov     ecx,[edi+TASKDATA.event_mask]
424
.loop: ; пока не исчерпаем все биты маски
425
        bsr     eax,ecx        ; находим ненулевой бит маски (31 -> 0)
426
        jz      .no_events     ; исчерпали все биты маски, но ничего не нашли ???
427
        btr     ecx,eax        ; сбрасываем проверяемый бит маски
428
       ; переходим на обработчик этого (eax) бита
429
        cmp     eax,16
430
        jae     .IRQ           ; eax=[16..31]=retvals, events irq0..irq15
431
        cmp     eax,9
432
        jae     .loop          ; eax=[9..15], ignored
433
        cmp     eax,3
434
        je      .loop          ; eax=3, ignored
435
        ja      .FlagAutoReset ; eax=[4..8], retvals=eax+1
436
        cmp     eax,1
437
        jae     .BtKy          ; eax=[1,2],  retvals=eax+1
438
.WndRedraw:                    ; eax=0, retval WndRedraw=1
439
        cmp     [edi-twdw+WDATA.fl_redraw],al ;al==0
440
        jne     .result
441
        jmp     .loop
442
  .no_events:
443
        xor     eax,eax
1159 hidnplayr 444
        ret
1198 clevermous 445
.IRQ:
446
;TODO: сделать так же, как и для FlagAutoReset (BgrRedraw,Mouse,IPC,Stack,Debug)
447
        mov     edx,[irq_owner+eax*4-64] ; eax==16+irq
448
        cmp     edx,[edi+TASKDATA.pid]
449
        jne     .loop
450
        mov     edx,eax
451
        shl     edx,12
452
        cmp     dword[IRQ_SAVE+edx-0x10000],0 ; edx==(16+irq)*0x1000
453
        je      .loop          ; empty ???
454
        ret     ; retval = eax
455
.FlagAutoReset: ; retvals: BgrRedraw=5, Mouse=6, IPC=7, Stack=8, Debug=9
456
        btr     [ebx+APPDATA.event_mask],eax
457
        jnc     .loop
458
  .result:      ; retval = eax+1
1159 hidnplayr 459
        inc     eax
460
        ret
1198 clevermous 461
  .BtKy:
462
        movzx   edx,bh
463
        movzx   edx, word[WIN_STACK+edx*2]
464
        je      .Keys          ; eax=1, retval Keys=2
465
.Buttons:                      ; eax=2, retval Buttons=3
466
        cmp     byte[BTN_COUNT],0
467
        je      .loop          ; empty ???
468
        cmp     edx,[TASK_COUNT]
469
        jne     .loop          ; not Top ???
470
        cmp     dword[BTN_BUFF],0xFFFF ;-ID for Minimize-Button of Form
471
        jne     .result
472
        mov     [window_minimize],1
473
        dec     byte[BTN_COUNT]
474
        jmp     .loop
475
.Keys:    ; eax==1
476
        cmp     edx,[TASK_COUNT]
477
        jne     @f             ; not Top ???
478
        cmp     [KEY_COUNT],al ; al==1
479
        jae     .result        ; not empty ???
480
  @@:   mov     edx, hotkey_buffer
481
  @@:   cmp     [edx],bh       ; bh - slot for testing
482
        je      .result
483
        add     edx,8
484
        cmp     edx, hotkey_buffer+120*8
1159 hidnplayr 485
        jb      @b
1198 clevermous 486
        jmp     .loop
487
;end.