Subversion Repositories Kolibri OS

Rev

Rev 665 | Rev 1059 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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.  
  10.  
  11. align 4
  12. init_events:
  13.            stdcall kernel_alloc, 512*EVENT_SIZE
  14.            mov [events], eax
  15.            xor eax, eax
  16.            mov [event_uid], eax
  17.            not eax
  18.            mov edi, event_map
  19.            mov [event_start], edi
  20.            mov ecx, 64/4
  21.            cld
  22.            rep stosd
  23.            mov [event_end], edi
  24.            ret
  25.  
  26. align 4
  27. proc alloc_event
  28.  
  29.            pushfd
  30.            cli
  31.            mov ebx, [event_start]
  32.            mov ecx, [event_end]
  33. .l1:
  34.            bsf eax,[ebx]
  35.            jnz .found
  36.            add ebx,4
  37.            cmp ebx, ecx
  38.            jb .l1
  39.            popfd
  40.            xor eax,eax
  41.            ret
  42. .found:
  43.            btr [ebx], eax
  44.            mov [event_start],ebx
  45.            inc [event_uid]
  46.  
  47.            sub ebx, event_map
  48.            lea eax,[eax+ebx*8]
  49.  
  50.            lea ebx, [eax+eax*4]
  51.            shl eax,5
  52.            lea eax,[eax+ebx*4]   ;eax*=52 (EVENT_SIZE)
  53.            add eax, [events]
  54.            mov ebx, [event_uid]
  55.            popfd
  56.            ret
  57. endp
  58.  
  59. align 4
  60. free_event:
  61.            sub eax, [events]
  62.            mov ecx, EVENT_SIZE
  63.            mov ebx, event_map
  64.            cdq
  65.            div ecx
  66.  
  67.            pushfd
  68.            cli
  69.            bts [ebx], eax
  70.            shr eax, 3
  71.            and eax, not 3
  72.            add eax, ebx
  73.            cmp [event_start], eax
  74.            ja @f
  75.            popfd
  76.            ret
  77. @@:
  78.            mov [event_start], eax
  79.            popfd
  80.            ret
  81.  
  82. EVENT_WATCHED    equ 0x10000000
  83. EVENT_SIGNALED   equ 0x20000000
  84. MANUAL_RESET     equ 0x40000000
  85. MANUAL_DESTROY   equ 0x80000000
  86.  
  87.  
  88. ; param
  89. ;  eax= event data
  90. ;  ebx= flags
  91. ;
  92. ; retval
  93. ;  eax= event
  94. ;  edx= id
  95.  
  96. create_event:
  97.            .flags  equ  esp+4
  98.            .data   equ  esp
  99.  
  100.            push ebx
  101.            push eax
  102.  
  103.            call alloc_event
  104.            test eax, eax
  105.            jz .fail
  106.  
  107.            mov [eax+APPOBJ.magic], 'EVNT'
  108.            mov [eax+APPOBJ.destroy], destroy_event.internal
  109.            mov [eax+EVENT.id], ebx
  110.  
  111.            mov ebx, [CURRENT_TASK]
  112.            shl ebx, 5
  113.            mov ebx, [CURRENT_TASK+ebx+4]
  114.            mov [eax+APPOBJ.pid], ebx
  115.            mov edx, [.flags]
  116.            mov [eax+EVENT.state], edx
  117.  
  118.            mov esi, [.data]
  119.            test esi, esi
  120.            jz @F
  121.            lea edi, [eax+EVENT.code]
  122.            mov ecx, 6
  123.            cld
  124.            rep movsd
  125. @@:
  126.            mov ecx, [current_slot]
  127.            add ecx, APP_OBJ_OFFSET
  128.  
  129.            pushfd
  130.            cli
  131.            mov edx, [ecx+APPOBJ.fd]
  132.            mov [eax+APPOBJ.fd], edx
  133.            mov [eax+APPOBJ.bk], ecx
  134.            mov [ecx+APPOBJ.fd], eax
  135.            mov [edx+APPOBJ.bk], eax
  136.            popfd
  137.            mov edx, [eax+EVENT.id]
  138. .fail:
  139.            add esp, 8
  140.            ret
  141.  
  142. restore .flags
  143. restore .data
  144.  
  145. ; param
  146. ;  eax= event
  147. ;  ebx= id
  148.  
  149. destroy_event:
  150.  
  151.            cmp [eax+APPOBJ.magic], 'EVNT'
  152.            jne .fail
  153.            cmp [eax+EVENT.id], ebx
  154.            jne .fail
  155. .internal:
  156.            mov ebx, [eax+APPOBJ.fd]
  157.            mov ecx, [eax+APPOBJ.bk]
  158.            mov [ebx+APPOBJ.bk], ecx
  159.            mov [ecx+APPOBJ.fd], ebx
  160. .force:
  161.            xor edx, edx             ;clear common header
  162.            mov [eax], edx
  163.            mov [eax+4], edx
  164.            mov [eax+8], edx
  165.            mov [eax+12], edx
  166.            mov [eax+16], edx
  167.  
  168.            call free_event          ;release object memory
  169. .fail:
  170.            ret
  171.  
  172. align 4
  173. proc send_event stdcall pid:dword, event:dword
  174.            locals
  175.              slot     dd ?
  176.            endl
  177.  
  178.            mov eax, [pid]
  179.            call pid_to_slot
  180.            test eax, eax
  181.            jz .fail
  182.  
  183.            shl eax, 8
  184.            cmp [SLOT_BASE+eax+APPDATA.ev_count], 32
  185.            ja .fail
  186.  
  187.            mov [slot], eax
  188.  
  189.            call alloc_event
  190.            test eax, eax
  191.            jz .fail
  192.  
  193.            lea edi, [eax+EVENT.code]
  194.            mov ecx, 6
  195.            mov esi, [event]
  196.            cld
  197.            rep movsd
  198.  
  199.            mov ecx, [slot]
  200.            add ecx, SLOT_BASE+APP_EV_OFFSET
  201.  
  202.            mov [eax+APPOBJ.magic], 'EVNT'
  203.            mov [eax+APPOBJ.destroy], destroy_event
  204.            mov ebx, [pid]
  205.            mov [eax+APPOBJ.pid], ebx
  206.            mov [eax+EVENT.state], EVENT_SIGNALED
  207.  
  208.            pushfd
  209.            cli                         ;insert event into
  210.            mov edx, [ecx+APPOBJ.fd]    ;events list
  211.            mov [eax+APPOBJ.fd], edx    ;and set events flag
  212.            mov [eax+APPOBJ.bk], ecx
  213.            mov [ecx+APPOBJ.fd], eax
  214.            mov [edx+APPOBJ.bk], eax
  215.            inc [ecx+APPDATA.ev_count-APP_EV_OFFSET]
  216.            or  [ecx+APPDATA.event_mask-APP_EV_OFFSET], EVENT_EXTENDED
  217.            popfd
  218. .fail:
  219.            ret
  220. endp
  221.  
  222. ; timeout ignored
  223.  
  224. align 4
  225. proc get_event_ex stdcall, p_ev:dword, timeout:dword
  226.  
  227. .wait:
  228.            mov edx,[current_slot]
  229. ;           cmp [SLOT_BASE+edx+APPDATA.ev_count], 0
  230. ;           je .switch
  231.  
  232.            add edx, APP_EV_OFFSET
  233.  
  234.            mov eax, [edx+APPOBJ.fd]
  235.            cmp eax, edx
  236.            je .switch
  237.  
  238.            lea esi, [eax+EVENT.code]
  239.            mov edi, [p_ev]                ;copy event data
  240.            mov ecx, 6
  241.            cld
  242.            rep movsd
  243.  
  244.            and dword [edi-24], 0xFF00FFFF ;clear priority field
  245.                                          ;
  246.            test [eax+EVENT.state], MANUAL_RESET
  247.            jnz .done
  248.  
  249.            pushfd
  250.            cli                         ;remove event from events
  251.            mov ebx, [eax+APPOBJ.fd]    ;list (reset event)
  252.            mov ecx, [eax+APPOBJ.bk]    ;and clear events flag
  253.            mov [ebx+APPOBJ.bk], ecx    ;if no active events
  254.            mov [ecx+APPOBJ.fd], ebx
  255.  
  256.            and [eax+EVENT.state], not (EVENT_SIGNALED+EVENT_WATCHED)
  257.  
  258.            dec [edx+APPDATA.ev_count-APP_EV_OFFSET]
  259.            jnz @F
  260.            and [edx+APPDATA.event_mask-APP_EV_OFFSET], not EVENT_EXTENDED
  261. @@:
  262.            popfd
  263.  
  264.            test [eax+EVENT.state], MANUAL_DESTROY
  265.            jz .destroy
  266.  
  267.            add edx, (APP_OBJ_OFFSET-APP_EV_OFFSET)
  268.  
  269.            pushfd
  270.            cli
  271.            mov ebx, [edx+APPOBJ.fd]  ;insert event into
  272.            mov [eax+APPOBJ.fd], ebx  ;objects list
  273.            mov [eax+APPOBJ.bk], edx
  274.            mov [edx+APPOBJ.fd], eax
  275.            mov [ebx+APPOBJ.bk], eax
  276.            popfd
  277. .done:
  278.            ret
  279.  
  280. .destroy:
  281.            call destroy_event.force
  282.            ret
  283. .switch:
  284.            mov eax, [TASK_BASE]
  285.            mov [eax+TASKDATA.state], byte 5
  286.            call change_task
  287.            jmp .wait
  288. endp
  289.  
  290. ; param
  291. ;  eax= event
  292. ;  ebx= id
  293.  
  294. align 4
  295. wait_event:
  296.            .event equ esp
  297.            push eax
  298. .wait:
  299.            cmp [eax+APPOBJ.magic], 'EVNT'
  300.            jne .done
  301.            cmp [eax+EVENT.id], ebx
  302.            jne .done
  303.  
  304.            test [eax+EVENT.state], EVENT_SIGNALED
  305.            jz .switch
  306.  
  307.            test [eax+EVENT.state], MANUAL_RESET
  308.            jnz .done
  309.  
  310.            mov edx,[current_slot]
  311.  
  312.            pushfd
  313.            cli                         ;remove event from events
  314.            mov ebx, [eax+APPOBJ.fd]    ;list (reset event)
  315.            mov ecx, [eax+APPOBJ.bk]    ;and clear events flag
  316.            mov [ebx+APPOBJ.bk], ecx    ;if no active events
  317.            mov [ecx+APPOBJ.fd], ebx
  318.            dec [edx+APPDATA.ev_count]
  319.            jnz @F
  320.            and [edx+APPDATA.event_mask], not EVENT_EXTENDED
  321. @@:
  322.            and [eax+EVENT.state], not (EVENT_SIGNALED+EVENT_WATCHED)
  323.            popfd
  324.  
  325.            test [eax+EVENT.state], MANUAL_DESTROY
  326.            jz .destroy
  327.  
  328.            add edx, APP_OBJ_OFFSET
  329.  
  330.            pushfd
  331.            cli
  332.            mov ecx, [edx+APPOBJ.fd]  ;insert event into
  333.            mov [eax+APPOBJ.fd], ecx  ;objects list
  334.            mov [eax+APPOBJ.bk], edx
  335.            mov [edx+APPOBJ.fd], eax
  336.            mov [ecx+APPOBJ.bk], eax
  337.            popfd
  338. .done:
  339.            add esp, 4
  340.            ret
  341. .destroy:
  342.            call destroy_event.force
  343.            add esp, 4
  344.            ret
  345. .switch:
  346.            or [eax+EVENT.state], EVENT_WATCHED
  347.            mov eax, [TASK_BASE]
  348.            mov [eax+TASKDATA.state], byte 5
  349.            call change_task
  350.            mov eax, [.event]
  351.            jmp .wait
  352. restore .event
  353.  
  354. ; param
  355. ;  eax= event
  356. ;  ebx= id
  357. ;  ecx= flags
  358. ;  edx= event data
  359.  
  360. raise_event:
  361.            .event equ esp
  362.            push eax
  363.  
  364.            cmp [eax+APPOBJ.magic], 'EVNT'
  365.            jne .fail
  366.            cmp [eax+EVENT.id], ebx
  367.            jne .fail
  368.  
  369.            mov eax, [eax+APPOBJ.pid]
  370.            call pid_to_slot
  371.            test eax, eax
  372.            jz .fail
  373.  
  374.            mov esi, edx
  375.            test esi, esi
  376.            mov edx, [.event]
  377.            jz @F
  378.  
  379.            push ecx
  380.            lea edi, [edx+EVENT.code]
  381.            mov ecx, 6
  382.            cld
  383.            rep movsd
  384.            pop ecx
  385. @@:
  386.            test [edx+EVENT.state], EVENT_SIGNALED
  387.            jnz .done
  388.  
  389.            test ecx, EVENT_WATCHED
  390.            jz @F
  391.            test [edx+EVENT.state], EVENT_WATCHED
  392.            jz .done
  393. @@:
  394.            shl eax, 8
  395.            add eax, SLOT_BASE+APP_EV_OFFSET
  396.  
  397.            pushfd
  398.            cli
  399.            mov ebx, [edx+APPOBJ.fd]
  400.            mov ecx, [edx+APPOBJ.bk]
  401.            mov [ebx+APPOBJ.bk], ecx
  402.            mov [ecx+APPOBJ.fd], ebx
  403.  
  404.            mov ecx, [eax+APPOBJ.fd]
  405.            mov [edx+APPOBJ.fd], ecx
  406.            mov [edx+APPOBJ.bk], eax
  407.            mov [eax+APPOBJ.fd], edx
  408.            mov [ecx+APPOBJ.bk], edx
  409.            or [edx+EVENT.state], EVENT_SIGNALED
  410.  
  411.            inc [eax+APPDATA.ev_count-APP_EV_OFFSET]
  412.            or  [eax+APPDATA.event_mask-APP_EV_OFFSET], EVENT_EXTENDED
  413.            popfd
  414. .fail:
  415. .done:
  416.            add esp, 4
  417.            ret
  418. restore .event
  419.  
  420. ; param
  421. ;  eax= event
  422. ;  ebx= id
  423. align 4
  424. clear_event:
  425.            .event equ esp
  426.            push eax
  427.  
  428.            cmp [eax+APPOBJ.magic], 'EVNT'
  429.            jne .fail
  430.            cmp [eax+EVENT.id], ebx
  431.            jne .fail
  432.  
  433.            mov eax, [eax+APPOBJ.pid]
  434.            call pid_to_slot
  435.            test eax, eax
  436.            jz .fail
  437.  
  438.            shl eax, 8
  439.            add eax, SLOT_BASE+APP_EV_OFFSET
  440.            mov edx, [.event]
  441.            pushfd
  442.            cli                         ;remove event from events
  443.            mov ebx, [edx+APPOBJ.fd]    ;list (reset event)
  444.            mov ecx, [edx+APPOBJ.bk]    ;and clear events flag
  445.            mov [ebx+APPOBJ.bk], ecx    ;if no active events
  446.            mov [ecx+APPOBJ.fd], ebx
  447.  
  448.            and [edx+EVENT.state], not (EVENT_SIGNALED+EVENT_WATCHED)
  449.  
  450.            dec [eax+APPDATA.ev_count-APP_EV_OFFSET]
  451.            jnz @F
  452.            and [eax+APPDATA.event_mask-APP_EV_OFFSET], not EVENT_EXTENDED
  453. @@:
  454.            add eax, (APP_OBJ_OFFSET-APP_EV_OFFSET)
  455.  
  456.            mov ecx, [eax+APPOBJ.fd]  ;insert event into
  457.            mov [edx+APPOBJ.fd], ecx  ;objects list
  458.            mov [edx+APPOBJ.bk], eax
  459.            mov [eax+APPOBJ.fd], edx
  460.            mov [ecx+APPOBJ.bk], edx
  461.            popfd
  462. .fail:
  463. .done:
  464.            add esp, 4
  465.            ret
  466. restore .event
  467.  
  468. sys_getevent:
  469.  
  470.         call    get_event_for_app
  471.         mov     [esp + 32],eax
  472.         ret
  473.  
  474. sys_waitforevent:
  475.         or      ebx, 0xFFFFFFFF         ; infinite timeout
  476.         jmp     @f
  477.  
  478. sys_wait_event_timeout:
  479.         add     ebx, [timer_ticks]
  480. @@:
  481.         mov     eax, [current_slot]
  482.         mov     [eax + APPDATA.wait_timeout], ebx
  483.         call    get_event_for_app
  484.         test    eax, eax
  485.         jnz     eventoccur
  486.  
  487.         mov     eax, [TASK_BASE]
  488.         mov     [eax+TASKDATA.state], byte 5
  489.         call    change_task
  490.  
  491.         mov     eax, [event_sched]
  492. eventoccur:
  493.         mov     [esp+32], eax
  494.         ret
  495.  
  496. sys_sendwindowmsg:
  497.         dec     eax
  498.         jnz     .ret
  499.         cmp     ebx, 3
  500.         jz      .sendbtn
  501.         cmp     ebx, 2
  502.         jnz     .ret
  503. .sendkey:
  504.         pushf
  505.         cli
  506.         movzx   eax, byte [KEY_COUNT]
  507.         cmp     al, 120
  508.         jae     .overflow
  509.         inc     eax
  510.         mov     [KEY_COUNT], al
  511.         mov     [KEY_COUNT+eax], cl
  512.         jmp     .ok
  513. .overflow:
  514.         popf
  515.         mov     dword [esp+36], 1
  516.         ret
  517. .sendbtn:
  518.         pushf
  519.         cli
  520.         cmp     byte [BTN_COUNT], 0
  521.         jnz     .overflow
  522.         mov     byte [BTN_COUNT], 1
  523.         mov     [BTN_BUFF], ecx
  524. .ok:
  525.         popf
  526.         and     dword [esp+36], 0
  527. .ret:
  528.         ret
  529.  
  530. get_event_for_app:
  531.  
  532.      pushad
  533.  
  534.      mov   edi,[TASK_BASE]              ; WINDOW REDRAW
  535.      test  [edi+TASKDATA.event_mask], 1
  536.      jz    no_eventoccur1
  537.      ;mov   edi,[TASK_BASE]
  538.      cmp   [edi-twdw+WDATA.fl_redraw],byte 0
  539.      je    no_eventoccur1
  540.      popad
  541.      mov   eax,1
  542.      ret
  543.    no_eventoccur1:
  544.  
  545.      ;mov   edi,[TASK_BASE]              ; KEY IN BUFFER
  546.      test  [edi+TASKDATA.event_mask],dword 2
  547.      jz    no_eventoccur2
  548.      mov   ecx, [CURRENT_TASK]
  549.      movzx edx,word [WIN_STACK+ecx*2]
  550.      mov   eax, [TASK_COUNT]
  551.      cmp   eax,edx
  552.      jne   no_eventoccur2x
  553.      cmp   [KEY_COUNT],byte 0
  554.      je    no_eventoccur2x
  555.    eventoccur2:
  556.      popad
  557.      mov   eax,2
  558.      ret
  559.    no_eventoccur2x:
  560.         mov     eax, hotkey_buffer
  561. @@:
  562.         cmp     [eax], ecx
  563.         jz      eventoccur2
  564.         add     eax, 8
  565.         cmp     eax, hotkey_buffer+120*8
  566.         jb      @b
  567.    no_eventoccur2:
  568.  
  569.      ;mov   edi,[TASK_BASE]              ; BUTTON IN BUFFER
  570.      test  [edi+TASKDATA.event_mask],dword 4
  571.      jz    no_eventoccur3
  572.      cmp   [BTN_COUNT],byte 0
  573.      je    no_eventoccur3
  574.      mov   ecx, [CURRENT_TASK]
  575.      movzx edx, word [WIN_STACK+ecx*2]
  576.      mov   eax, [TASK_COUNT]
  577.      cmp   eax,edx
  578.      jnz   no_eventoccur3
  579.      popad
  580.      mov   eax,[BTN_BUFF]
  581.      cmp   eax,65535
  582.      je    no_event_1
  583.      mov   eax,3
  584.      ret
  585.  
  586.     no_event_1:
  587.      mov   [window_minimize],1
  588.      mov   [BTN_COUNT],byte 0
  589.      xor   eax, eax
  590.      ret
  591.  
  592. no_eventoccur3:
  593.  
  594.      ;mov   edi,[TASK_BASE]              ; mouse event
  595.      mov eax, [CURRENT_TASK]
  596.      shl eax, 8
  597.      add eax, SLOT_BASE
  598.      test  [edi+TASKDATA.event_mask],dword 00100000b
  599.      jz    no_mouse_event
  600.  
  601.      test  [eax+APPDATA.event_mask],dword 00100000b
  602.      jz    no_mouse_event
  603.      and   [eax+APPDATA.event_mask],dword (not 00100000b)
  604.      popad
  605.      mov   eax,6
  606.      ret
  607. no_mouse_event:
  608.  
  609.      ;mov   edi,[TASK_BASE]              ; DESKTOP BACKGROUND REDRAW
  610.      test  [edi+TASKDATA.event_mask], 16
  611.      jz    no_eventoccur5
  612. ;     cmp   [REDRAW_BACKGROUND],byte 2
  613. ;     jnz   no_eventoccur5
  614.      test  [eax+APPDATA.event_mask], 16
  615.      jz    no_eventoccur5
  616.      and   [eax+APPDATA.event_mask], not 16
  617.      popad
  618.      mov   eax,5
  619.      ret
  620. no_eventoccur5:
  621.  
  622.      ;mov   edi,[TASK_BASE]              ; IPC
  623.      test  [edi+TASKDATA.event_mask],dword 01000000b
  624.      jz    no_ipc
  625.      test  [eax+APPDATA.event_mask],dword 01000000b
  626.      jz    no_ipc
  627.      and   [eax+APPDATA.event_mask],dword 0xffffffff-01000000b
  628.      popad
  629.      mov   eax,7
  630.      ret
  631. no_ipc:
  632.  
  633.      ;mov   edi,[TASK_BASE]              ; STACK
  634.      test  [edi+TASKDATA.event_mask],dword 10000000b
  635.      jz    no_stack_event
  636.      test  [eax+APPDATA.event_mask],dword 10000000b
  637.      jz    no_stack_event
  638.      and   [eax+APPDATA.event_mask],dword 0xffffffff-10000000b
  639.      popad
  640.      mov   eax,8
  641.      ret
  642. no_stack_event:
  643.  
  644.      test  byte [edi+TASKDATA.event_mask+1], 1          ; DEBUG
  645.      jz    .test_IRQ
  646.      test  byte [eax+APPDATA.event_mask+1], byte 1
  647.      jz    .test_IRQ
  648.      and   byte [eax+APPDATA.event_mask+1], not 1
  649.      popad
  650.      mov   eax, 9
  651.      ret
  652.  
  653. ;.test_ext:
  654. ;     mov   eax, [CURRENT_TASK]
  655. ;     shl   eax, 8
  656. ;     test  dword [eax+SLOT_BASE+APPDATA.event_mask], EVENT_EXTENDED
  657. ;     jz .test_IRQ
  658. ;     popad
  659. ;     mov eax, 10
  660. ;     ret
  661.  
  662. .test_IRQ:
  663.      cmp   dword [edi+TASKDATA.event_mask], 0xFFFF
  664.      jbe   no_events
  665.  
  666.      mov   esi,IRQ_SAVE              ; IRQ'S AND DATA
  667.      mov   ebx,0x00010000
  668.      xor   ecx, ecx
  669.    irq_event_test:
  670.      mov   edi,[TASK_BASE]
  671.      test  [edi+TASKDATA.event_mask],ebx
  672.      jz    no_irq_event
  673.      mov   edi,ecx
  674.      shl   edi,2
  675.      add   edi,irq_owner
  676.      mov   edx,[edi]
  677.      mov   eax,[TASK_BASE]
  678.      mov   eax,[eax+TASKDATA.pid]
  679.      cmp   edx,eax
  680.      jne   no_irq_event
  681.      cmp   [esi],dword 0
  682.      jz    no_irq_event
  683.      mov   eax,ecx
  684.      add   eax,16
  685.      mov   [esp+28],eax
  686.      popad
  687.      ret
  688.     no_irq_event:
  689.      add   esi,0x1000
  690.      shl   ebx,1
  691.      inc   ecx
  692.      cmp   ecx,16
  693.      jb    irq_event_test
  694.  
  695.    no_events:
  696.      popad
  697.      xor   eax, eax
  698.      ret
  699.  
  700.  
  701.  
  702.