Subversion Repositories Kolibri OS

Rev

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

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