Subversion Repositories Kolibri OS

Rev

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