Subversion Repositories Kolibri OS

Rev

Rev 8199 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;const int
  2. KOLIBRI_BORDER_SIZE = 4;
  3. ;const int
  4. KOLIBRI_HEADER_SIZE = 20;
  5.  
  6. ;const int
  7. KOLIBRI_THREAD_DATA_USER     = 0; // Thread data begin from the user dword
  8. ;const int
  9. KOLIBRI_THREAD_DATA_ST_BEGIN = 1; // Stack beginning follows after the user dword
  10. ;const int
  11. KOLIBRI_THREAD_DATA_NEXT     = 2;
  12. ;const int
  13. KOLIBRI_THREAD_DATA_PID     = 3;
  14. ;const int
  15. KOLIBRI_THREAD_DATA_FLAG     = 4;
  16. ;const int
  17. KOLIBRI_THREAD_DATA_X       = 5;
  18. ;const int
  19. KOLIBRI_THREAD_DATA_Y       = 6;
  20. ;const int
  21. KOLIBRI_THREAD_DATA_C_WINDOW = 7;
  22. ;const int
  23. KOLIBRI_THREAD_DATA_C_HEADER = 8;
  24. ;const int
  25. KOLIBRI_THREAD_DATA_C_BORDER = 9;
  26. ;const int
  27. KOLIBRI_THREAD_DATA_C_TITLE  = 10;
  28. ;const int
  29. KOLIBRI_THREAD_DATA_TITLE    = 11;
  30. ;const int
  31. KOLIBRI_THREAD_DATA_PICTURE  = 12;
  32. ;const int
  33. KOLIBRI_THREAD_DATA_SZ_PICT  = 13;
  34. ;const int
  35. KOLIBRI_THREAD_DATA_LAST_SX  = 14;
  36. ;const int
  37. KOLIBRI_THREAD_DATA_LAST_SY  = 15;
  38. ;const int
  39. KOLIBRI_THREAD_DATA_LEN     = 16;
  40.  
  41. ;const int
  42. KOLIBRI_MUTEX_MAX_TIME_WAIT  = 20;
  43.  
  44. ;/***
  45.  
  46. macro segment name
  47. {
  48.   segment name
  49.   if name eq _init_ | name eq _INIT_
  50. Kolibri_SegmentInit:
  51.   else if name eq _exit_ | name eq _EXIT_
  52. Kolibri_SegmentExit:
  53.   end if
  54. }
  55.  
  56. macro endseg  name
  57. {
  58.   if name eq _init_ | name eq _INIT_
  59. Kolibri_SegmentInitEnd:
  60.   else if name eq _exit_ | name eq _EXIT_
  61. Kolibri_SegmentExitEnd:
  62.   end if
  63.   endseg  name
  64. }
  65.  
  66. macro Kolibri_Put_MovEaxVal_Ret address,val
  67. {
  68.   mov  byte [address],0xB8
  69.   mov  dword [address+4],0xC089C300
  70.   mov  dword [address+1],val
  71. }
  72.  
  73. proc @Kolibri@Main$qv
  74.   and  esp,not 3
  75.   sub  esp,1024
  76.   mov  eax,SF_THREAD_INFO
  77.   mov  ebx,esp
  78.   mov  ecx,-1
  79.   int  0x40
  80.   mov  ebx,[esp+26]
  81.   mov  edx,[esp+30]
  82.   lea  eax,[ebx-0x20]
  83.   add  esp,1024
  84.   cmp  esp,eax
  85.   cmova esp,eax
  86.   and  esp,not 3
  87.   xor  eax,eax
  88.   cld
  89.   mov  edi,@Kolibri@_ThreadTable
  90.   mov  ecx,256
  91.   rep stosd
  92.   mov  esi,@Kolibri@GetPid$qv
  93.   mov  edi,@Kolibri@_ThreadSavedBegProc
  94.   movsd
  95.   movsd
  96.   mov  esi,@Kolibri@GetThreadData$qv
  97.   movsd
  98.   movsd
  99.   Kolibri_Put_MovEaxVal_Ret  @Kolibri@GetPid$qv,edx
  100. if defined KolibriHeapInit
  101.   call KolibriHeapInit  ; Initialize a dynamic heap
  102. end if
  103.   xor  eax,eax
  104.   push eax
  105.   push eax
  106.   call @Kolibri@ThreadMain$qpvt1
  107. .ThreadFinish:
  108.   add  esp,8
  109. if defined KolibriHeapFreeAndThreadFinish
  110.   test eax,eax
  111.   jz   .ThreadFinish_end
  112.   push dword @Kolibri@_ExitProcessNow
  113.   push eax
  114.   call KolibriHeapFreeAndThreadFinish   ; Free the given memory and finish the thread,
  115. end if                                 ; should exit process if second argument points to not zero.
  116. .ThreadFinish_end:
  117.   or   eax,-1
  118.   int  0x40
  119. endp
  120.  
  121. proc @Kolibri@ThreadMain$qpvt1
  122.   xchg ebx,[esp+4]
  123.   xchg ebp,[esp+8]
  124.   push esi edi
  125.   sub  esp,KOLIBRI_THREAD_DATA_LEN*4
  126.   mov  [esp],ebx
  127.   mov  [esp+4],ebp
  128.   mov  eax,SF_SET_EVENTS_MASK
  129.   mov  ebx,0x27
  130.   int  0x40
  131.   mov  ebx,esp
  132.   cmp  byte [@Kolibri@_ThreadSavedBegProc],0x90
  133.   jz   .main_else_first_check
  134.   Kolibri_Put_MovEaxVal_Ret  @Kolibri@GetThreadData$qv,esp
  135. if defined Kolibri_SegmentInit & defined Kolibri_SegmentInitEnd
  136.   push Kolibri_SegmentInitEnd
  137.   push Kolibri_SegmentInit
  138.   jmp  .main_after_first_check
  139. end if
  140. .main_else_first_check:
  141.   xor  eax,eax
  142.   push eax eax
  143. .main_after_first_check:
  144.   push ebx
  145.   call @@Kolibri@_CallStart$qppvpvt2
  146.   add  esp,12
  147.   test al,al
  148.   jnz  .main_test_close_first
  149.   jmp  .main_end
  150. .main_close_first:
  151.   btr  dword [esp+KOLIBRI_THREAD_DATA_FLAG*4],31
  152. if defined @@KolibriOnClose$qppv
  153.   push esp
  154.   call @@KolibriOnClose$qppv
  155.   pop  ecx
  156.   test al,al
  157.   jnz  .main_end
  158. end if
  159. .main_test_close_first:
  160.   cmp  dword [esp+KOLIBRI_THREAD_DATA_FLAG*4],0
  161.   jl   .main_close_first
  162.   push esp
  163.   push dword 1
  164.   call @Kolibri@Redraw$qippv
  165.   add  esp,8
  166. .main_paint_msg:
  167.   or   dword [esp+KOLIBRI_THREAD_DATA_FLAG*4],3
  168.   sub  esp,1024
  169.   mov  eax,SF_THREAD_INFO
  170.   mov  ebx,esp
  171.   mov  ecx,-1
  172.   int  0x40
  173.   mov  eax,[esp+34]
  174.   mov  ebx,[esp+38]
  175.   mov  ecx,[esp+42]
  176.   mov  edx,[esp+46]
  177.   add  esp,1024
  178.   cmp  ecx,[esp+KOLIBRI_THREAD_DATA_LAST_SX*4]
  179.   jnz  .main_size
  180.   cmp  edx,[esp+KOLIBRI_THREAD_DATA_LAST_SY*4]
  181.   jz   .main_paint
  182. .main_size:
  183.   mov  [esp+KOLIBRI_THREAD_DATA_LAST_SX*4],ecx
  184.   mov  [esp+KOLIBRI_THREAD_DATA_LAST_SY*4],edx
  185. if defined @@KolibriOnSize$qpippv
  186.   push edx
  187.   push ecx
  188.   push ebx
  189.   push eax
  190.   lea  ecx,[esp+16]
  191.   mov  edx,esp
  192.   push ecx
  193.   push edx
  194.   call @@KolibriOnSize$qpippv
  195.   add  esp,24
  196. end if
  197.   test dword [esp+KOLIBRI_THREAD_DATA_FLAG*4],3
  198.   jz   .main_cycle
  199. .main_paint:
  200.   cmp  dword [esp+KOLIBRI_THREAD_DATA_FLAG*4],0
  201.   jl   .main_close
  202.   push esp
  203.   push dword 0
  204.   call @Kolibri@Redraw$qippv
  205.   add  esp,8
  206. .main_cycle:
  207.   mov  eax,SF_CHECK_EVENT
  208. .main_message:
  209.   cmp  dword [esp+KOLIBRI_THREAD_DATA_FLAG*4],0
  210.   jl   .main_close
  211.   int  0x40
  212.   test eax,eax
  213.   jnz  .main_on_message
  214.   cmp  dword [esp+KOLIBRI_THREAD_DATA_FLAG*4],0
  215.   jne  .main_paint
  216. if defined @@KolibriOnIdle$qppv
  217.   push esp
  218.   call @@KolibriOnIdle$qppv
  219.   pop  ecx
  220. else
  221.   or eax,-1
  222. end if
  223.   test eax,eax
  224.   jz   .main_cycle
  225.   jl   .main_wait_message
  226.   mov  ebx,eax
  227.   mov  eax,SF_WAIT_EVENT_TIMEOUT
  228.   jmp  .main_message
  229. .main_wait_message:
  230.   mov  eax,SF_WAIT_EVENT
  231.   jmp  .main_message
  232. if defined @@KolibriOnKeyPress$qppv
  233. .main_key_press:
  234.   push esp
  235.   call @@KolibriOnKeyPress$qppv
  236.   pop  ecx
  237.   jmp  .main_cycle
  238. end if
  239. if defined @@KolibriOnMouse$qppv
  240. .main_mouse:
  241.   push esp
  242.   call @@KolibriOnMouse$qppv
  243.   pop  ecx
  244.   jmp  .main_cycle
  245. end if
  246.  
  247. align 4
  248. .main_on_message:
  249.   dec  eax
  250.   jz   .main_paint_msg
  251.   dec  eax
  252. if defined @@KolibriOnKeyPress$qppv
  253.   jz   .main_key_press
  254. else
  255.   jz   .main_cycle
  256. end if
  257.   cmp  eax,4
  258. if defined @@KolibriOnMouse$qppv
  259.   jz   .main_mouse
  260. else
  261.   jz   .main_cycle
  262. end if
  263.   dec  eax
  264.   jnz  .main_cycle
  265.  
  266. align 4
  267. .main_button:
  268.   mov  eax,SF_GET_BUTTON
  269.   int  0x40
  270.   shr  eax,8
  271.   cmp  eax,1
  272.   je   .main_close
  273. if defined @@KolibriOnButton$qlppv
  274.   push esp
  275.   push eax
  276.   call @@KolibriOnButton$qlppv
  277.   add  esp,8
  278. end if
  279.   jmp  .main_cycle
  280. .main_close:
  281.   btr  dword [esp+KOLIBRI_THREAD_DATA_FLAG*4],31
  282. if defined @@KolibriOnClose$qppv
  283.   push esp
  284.   call @@KolibriOnClose$qppv
  285.   pop  ecx
  286.   test al,al
  287.   jz   .main_button
  288. end if
  289. .main_end:
  290.   mov  ebx,esp
  291.   lock dec dword [@Kolibri@_ThreadNumber]
  292. if defined Kolibri_SegmentExit & defined Kolibri_SegmentExitEnd
  293.   jnz  .main_else_last_check
  294.   push Kolibri_SegmentExitEnd
  295.   push Kolibri_SegmentExit
  296.   jmp  .main_after_last_check
  297. end if
  298. .main_else_last_check:
  299.   xor  eax,eax
  300.   push eax
  301.   push eax
  302. .main_after_last_check:
  303.   push ebx
  304.   call @@Kolibri@_RemoveThreadData$qppvpvt2
  305.   add  esp,12
  306.   lock inc dword [@Kolibri@_ThreadScanCount+4]
  307.   mov  ebx,1
  308.   jmp  .main_end_wait
  309. .main_end_wait_loop:
  310.   mov  eax,SF_SLEEP
  311.   int  0x40
  312.   shl  ebx,1
  313.   cmp  ebx,KOLIBRI_MUTEX_MAX_TIME_WAIT
  314.   jna  .main_end_wait
  315.   mov  ebx,KOLIBRI_MUTEX_MAX_TIME_WAIT
  316. .main_end_wait:
  317.   cmp  dword [@Kolibri@_ExitProcessNow],0
  318.   jnz  @Kolibri@ExitProcess$qv
  319.   cmp  dword [@Kolibri@_ThreadScanCount],0
  320.   jnz  .main_end_wait_loop
  321.   lock dec dword [@Kolibri@_ThreadScanCount+4]
  322.   mov  ebp,[esp+4]
  323.   mov  ebx,[esp]
  324.   add  esp,KOLIBRI_THREAD_DATA_LEN*4
  325.   mov  eax,ebp
  326.   pop  edi esi
  327.   xchg ebp,[esp+8]
  328.   xchg ebx,[esp+4]
  329.   ret
  330. endp
  331.  
  332. macro call func
  333. {
  334.   if func eq __chkstk
  335.         sub  esp,eax
  336.   else
  337.         call func
  338.   end if
  339. }
  340.  
  341. proc @Kolibri@Redraw$qippv
  342.   push ebp
  343.   mov  ebp,[esp+12]
  344.   mov  edx,[ebp+KOLIBRI_THREAD_DATA_FLAG*4]
  345.   cmp  dword [esp+8],0
  346.   jl   .redraw_only_inv
  347.   jz   .redraw_no_frame
  348.   or   dl,2
  349. .redraw_no_frame:
  350.   bt   edx,30
  351.   jnc  .redraw_begin
  352.   or   dl,1
  353.   mov  [ebp+KOLIBRI_THREAD_DATA_FLAG*4],edx
  354.   jmp  .redraw_end
  355. .redraw_only_inv:
  356.   test dl,3
  357.   jnz  .redraw_no_frame
  358. .redraw_end:
  359.   pop  ebp
  360.   ret
  361. .redraw_begin:
  362.   push ebx esi edi
  363.   and  dword [ebp+KOLIBRI_THREAD_DATA_FLAG*4],0xFFFFFFFC
  364.   test dl,2
  365.   jz   .redraw_picture
  366.   mov  eax,SF_REDRAW
  367.   mov  ebx,SSF_BEGIN_DRAW
  368.   int  0x40
  369.   xor  eax,eax
  370.   mov  ebx,[ebp+KOLIBRI_THREAD_DATA_X*4]
  371.   mov  ecx,[ebp+KOLIBRI_THREAD_DATA_Y*4]
  372.   mov  edx,[ebp+KOLIBRI_THREAD_DATA_C_WINDOW*4]
  373.   mov  esi,[ebp+KOLIBRI_THREAD_DATA_C_HEADER*4]
  374.   mov  edi,[ebp+KOLIBRI_THREAD_DATA_C_BORDER*4]
  375.   int  0x40
  376.   mov  edx,[ebp+KOLIBRI_THREAD_DATA_TITLE*4]
  377.   test edx,edx
  378.   jz   .window_defined
  379.   mov  edi,edx
  380.   mov  ecx,0xFFFFFFFF
  381.   xor  al,al
  382.   cld
  383.   repnz scas byte [edi]
  384.   not  ecx
  385.   mov  esi,ecx
  386.   dec  esi
  387.   jz   .window_defined
  388.   mov  eax,SF_DRAW_TEXT
  389.   mov  ebx,0x00070005
  390.   mov  ecx,[ebp+KOLIBRI_THREAD_DATA_C_TITLE*4]
  391.   or   ecx,1 shl 28 ;make big font
  392.   int  0x40
  393. .window_defined:
  394. .redraw_picture:
  395.   mov  eax,SF_REDRAW
  396.   mov  ebx,SSF_END_DRAW
  397.   int  0x40
  398.   mov  esi,[ebp+KOLIBRI_THREAD_DATA_PICTURE*4]
  399.   test esi,esi
  400.   jz   .redraw_end_draw
  401.   mov  ecx,[ebp+KOLIBRI_THREAD_DATA_SZ_PICT*4]
  402.   jecxz .redraw_end_draw
  403.   mov  al,byte [ebp+KOLIBRI_THREAD_DATA_C_WINDOW*4+3]
  404.   and  al,15
  405.   mov  edx,KOLIBRI_BORDER_SIZE*65536+KOLIBRI_HEADER_SIZE
  406.   cmp  al,3
  407.   jnz  .redraw_no_skin
  408.   mov  eax,SF_STYLE_SETTINGS
  409.   mov  ebx,SSF_GET_SKIN_HEIGHT
  410.   int  0x40
  411.   mov  dx,ax
  412. .redraw_no_skin:
  413.   mov  eax,SF_PUT_IMAGE
  414.   mov  ebx,esi
  415.   int  0x40
  416. .redraw_end_draw:
  417.   pop  edi esi ebx ebp
  418.   ret
  419. endp
  420.  
  421. proc @Kolibri@MoveWindow$qxpxi uses ebx esi
  422.   mov  eax,[esp+12]
  423.   mov  ebx,[eax]
  424.   mov  ecx,[eax+4]
  425.   mov  edx,[eax+8]
  426.   mov  esi,[eax+12]
  427.   mov  eax,SF_CHANGE_WINDOW
  428.   int  0x40
  429.   ret
  430. endp
  431.  
  432. proc @Kolibri@ExitDebug$qv
  433.   push dword [@Kolibri@DebugPrefix]
  434.   call @Kolibri@DebugPutString$qpxc
  435.   mov   dword [esp],Kolibri_debug_string
  436.   call @Kolibri@DebugPutString$qpxc
  437.   pop   ecx
  438.   jmp  @Kolibri@ExitProcess$qv
  439. endp
  440.  
  441. proc @Kolibri@ExitProcess$qv
  442.   lock bts dword [@Kolibri@_ExitProcessNow],0
  443.   jc   .exit_process_wait
  444.   sub  esp,1024
  445.   mov  eax,SF_THREAD_INFO
  446.   mov  ebx,esp
  447.   mov  ecx,-1
  448.   int  0x40
  449.   mov  esi,eax
  450.   mov  edi,[esp+30]
  451. .exit_process_loop:
  452.   mov  eax,SF_THREAD_INFO
  453.   mov  ebx,esp
  454.   mov  ecx,esi
  455.   int  0x40
  456.   mov  eax,[esp+30]
  457.   cmp  eax,edi
  458.   jz   .exit_process_continue
  459.   mov  ebx,eax
  460.   or   bl,15
  461.   inc  ebx
  462.   jz   .exit_process_continue
  463.   mov  ebx,eax
  464.   call Kolibri_HashInt
  465.   movzx eax,al
  466.   mov  eax,dword [@Kolibri@_ThreadTable+eax*4]
  467.   jmp  .exit_process_test
  468. .exit_process_next:
  469.   mov  eax,dword [eax+KOLIBRI_THREAD_DATA_NEXT*4]
  470. .exit_process_test:
  471.   test eax,eax
  472.   jz   .exit_process_continue
  473.   cmp  ebx,[eax+KOLIBRI_THREAD_DATA_PID*4]
  474.   jnz  .exit_process_next
  475.   mov  eax,SF_SYSTEM
  476.   mov  ebx,SSF_TERMINATE_THREAD
  477.   mov  ecx,esi
  478.   int  0x40
  479. .exit_process_continue:
  480.   dec  esi
  481.   jnl  .exit_process_loop
  482.   add  esp,1024
  483.   mov  dword [@Kolibri@_ExitProcessNow],-1
  484. if defined EMULATOR
  485.   int3
  486.   call 0x76543210
  487. end if
  488. .exit_process_end:
  489.   mov  dword [@Kolibri@_ThreadMutex],0
  490.   or   eax,-1
  491.   int  0x40
  492. .exit_process_wait:
  493.   mov  eax,SF_SLEEP
  494.   mov  ebx,1
  495. .exit_process_wait_loop:
  496.   cmp  dword [@Kolibri@_ExitProcessNow],0
  497.   jl   .exit_process_end
  498.   int  0x40
  499.   shl  ebx,1
  500.   cmp  ebx,KOLIBRI_MUTEX_MAX_TIME_WAIT
  501.   jna  .exit_process_wait_loop
  502.   mov  ebx,KOLIBRI_MUTEX_MAX_TIME_WAIT
  503.   jmp  .exit_process_wait_loop
  504. endp
  505.  
  506. proc @Kolibri@ExitThread$qppv,@Kolibri@ThreadMain$qpvt1
  507.   mov  esp,[esp+4]
  508.   jmp  Kolibri_main_end
  509. endp
  510.  
  511. proc @Kolibri@ReturnMessageLoop$qppv,@Kolibri@ThreadMain$qpvt1
  512.   mov  esp,[esp+4]
  513.   bt   dword [esp+KOLIBRI_THREAD_DATA_FLAG*4],30
  514.   jc   Kolibri_main_end
  515.   jmp  Kolibri_main_cycle
  516. endp
  517.  
  518. proc @Kolibri@Delay$qui uses ebx
  519.   mov  eax,SF_SLEEP
  520.   mov  ebx,[esp+8]
  521.   int  0x40
  522.   ret
  523. endp
  524.  
  525. proc @Kolibri@Clock$qv uses ebx
  526.   mov  eax,SF_SYSTEM_GET
  527.   mov  ebx,SSF_TIME_COUNT
  528.   int  0x40
  529.   ret
  530. endp
  531.  
  532. proc @Kolibri@DrawButton$qllllll uses ebx esi
  533.   mov  eax,SF_DEFINE_BUTTON
  534.   mov  ebx,[esp+12-2+8]
  535.   mov  bx,[esp+20+8]
  536.   mov  ecx,[esp+16-2+8]
  537.   mov  cx,[esp+24+8]
  538.   mov  edx,[esp+4+8]
  539.   mov  esi,[esp+8+8]
  540.   int  0x40
  541.   ret
  542. endp
  543.  
  544. proc @Kolibri@GetPackedTime$qv
  545.   mov  eax,SF_GET_SYS_TIME
  546.   int  0x40
  547.   ret
  548. endp
  549.  
  550. proc @Kolibri@GetTime$qpi
  551.   mov  eax,SF_GET_SYS_TIME
  552.   int  0x40
  553.   mov  edx,[esp+4]
  554.   movzx ecx,al
  555.   shr  ecx,4
  556.   and  al,0x0F
  557.   imul ecx,10
  558.   add  cl,al
  559.   mov  dword [edx+8],ecx
  560.   mov  cl,ah
  561.   shr  ecx,4
  562.   and  ah,0x0F
  563.   imul ecx,10
  564.   add  cl,ah
  565.   mov  dword [edx+4],ecx
  566.   bswap eax
  567.   mov  cl,ah
  568.   shr  ecx,4
  569.   and  ah,0x0F
  570.   imul ecx,10
  571.   add  cl,ah
  572.   mov  dword [edx],ecx
  573.   ret
  574. endp
  575.  
  576. proc @Kolibri@GetPackedDate$qv
  577.   mov  eax,SF_GET_SYS_DATE
  578.   int  0x40
  579.   ret
  580. endp
  581.  
  582. proc @Kolibri@GetDate$qpi
  583.   mov  eax,SF_GET_SYS_DATE
  584.   int  0x40
  585.   mov  edx,[esp+4]
  586.   movzx ecx,al
  587.   shr  ecx,4
  588.   and  al,0x0F
  589.   imul ecx,10
  590.   add  cl,al
  591.   mov  dword [edx+4],ecx
  592.   mov  cl,ah
  593.   shr  ecx,4
  594.   and  ah,0x0F
  595.   imul ecx,10
  596.   add  cl,ah
  597.   mov  dword [edx],ecx
  598.   bswap eax
  599.   mov  cl,ah
  600.   shr  ecx,4
  601.   and  ah,0x0F
  602.   imul ecx,10
  603.   add  cl,ah
  604.   mov  dword [edx+8],ecx
  605.   ret
  606. endp
  607.  
  608. proc @Kolibri@ReadCommonColors$qpui uses ebx
  609.   mov  eax,SF_STYLE_SETTINGS
  610.   mov  ebx,SSF_GET_COLORS
  611.   mov  ecx,[esp+8]
  612.   mov  edx,40
  613.   int  0x40
  614.   ret
  615. endp
  616.  
  617. proc @Kolibri@DrawText$qssipxc uses ebx
  618.   mov  eax,SF_DRAW_TEXT
  619.   mov  ebx,[esp+8-2]
  620.   mov  bx,[esp+12]
  621.   mov  ecx,[esp+16]
  622.   or   ecx,0x80000000
  623.   mov  edx,[esp+20]
  624.   int  0x40
  625.   ret
  626. endp
  627.  
  628. proc @Kolibri@SetWindowCaption$qpxc uses ebx
  629.   mov  eax,SF_SET_CAPTION
  630.   mov  ebx,2
  631.   mov  ecx,[esp+8]
  632.   int  0x40
  633.   ret
  634. endp
  635.  
  636. proc @Kolibri@GetProcessInfo$qpuipct1t1piui uses ebx esi edi
  637.   sub  esp,1024
  638.   mov  eax,SF_THREAD_INFO
  639.   mov  ebx,esp
  640.   mov  ecx,[1024+12+24+esp]
  641.   int  0x40
  642.   xor  edi,edi
  643.   or   edi,[1024+12+4+esp]
  644.   jz   .get_proc_info_no_usecpu
  645.   mov  ecx,[esp]
  646.   mov  [edi],ecx
  647.   xor  edi,edi
  648. .get_proc_info_no_usecpu:
  649.   or   edi,[1024+12+8+esp]
  650.   jz   .get_proc_info_no_name
  651.   lea  esi,[esp+10]
  652.   cld
  653.   movsd
  654.   movsd
  655.   movsd
  656.   mov  byte [edi],0
  657.   xor  edi,edi
  658. .get_proc_info_no_name:
  659.   or   edi,[1024+12+12+esp]
  660.   jz   .get_proc_info_no_mem
  661.   mov  ecx,[esp+26]
  662.   mov  [edi],ecx
  663.   xor  edi,edi
  664. .get_proc_info_no_mem:
  665.   or   edi,[1024+12+16+esp]
  666.   jz   .get_proc_info_no_pid
  667.   mov  ecx,[esp+30]
  668.   mov  [edi],ecx
  669.   xor  edi,edi
  670. .get_proc_info_no_pid:
  671.   or   edi,[1024+12+20+esp]
  672.   jz   .get_proc_info_no_rect
  673.   lea  esi,[esp+34]
  674.   cld
  675.   movsd
  676.   movsd
  677.   movsd
  678.   movsd
  679.   xor  edi,edi
  680. .get_proc_info_no_rect:
  681.   add  esp,1024
  682.   ret
  683. endp
  684.  
  685. proc @Kolibri@GetPid$qv uses ebx
  686.   sub  esp,1024
  687.   mov  eax,SF_THREAD_INFO
  688.   mov  ebx,esp
  689.   mov  ecx,-1
  690.   int  0x40
  691.   mov  eax,[esp+30]
  692.   add  esp,1024
  693.   ret
  694. endp
  695.  
  696. proc @Kolibri@GetPid$qppv
  697.   mov  ecx,[esp+4]
  698.   mov  eax,[ecx+KOLIBRI_THREAD_DATA_PID*4]
  699.   ret
  700. endp
  701.  
  702. proc @Kolibri@_HashByte$qui
  703. @Kolibri@_HashWord$qui:
  704. @Kolibri@_HashDword$qui:
  705.   mov  eax,[esp+4]
  706. Kolibri_HashInt:
  707.   mul  dword [Kolibri_hash_int_val0]
  708.   xor  eax,edx
  709.   bswap eax
  710.   mul  dword [Kolibri_hash_int_val1]
  711.   shrd eax,edx,14
  712.   bswap eax
  713.   lea  eax,[eax+4*eax]
  714.   ror  eax,9
  715.   ret
  716. endp
  717.  
  718. if defined @Kolibri@_HashByte$qui | defined @Kolibri@_HashWord$qui | defined @Kolibri@_HashDword$qui
  719. Kolibri_hash_int_val0:
  720.   dd   0xA82F94C5
  721. Kolibri_hash_int_val1:
  722.   dd   0x9193780B
  723. end if
  724.  
  725. proc @Kolibri@GetThreadData$qv
  726.   call @Kolibri@GetPid$qv
  727.   push eax
  728.   call @Kolibri@GetThreadData$qui
  729.   pop  ecx
  730.   ret
  731. endp
  732.  
  733. proc @Kolibri@GetThreadData$qui
  734.   mov  eax,[esp+4]
  735.   call Kolibri_HashInt
  736.   movzx eax,al
  737.   cmp  dword [@Kolibri@_ThreadScanCount+4],0
  738.   jnz  .get_thread_data_wait
  739. .get_thread_data_nowait:
  740.   lock inc dword [@Kolibri@_ThreadScanCount]
  741.   mov  eax,dword [@Kolibri@_ThreadTable+eax*4]
  742.   mov  ecx,[esp+4]
  743.   jmp  .get_thread_data_test
  744. .get_thread_data_loop:
  745.   mov  eax,dword [eax+KOLIBRI_THREAD_DATA_NEXT*4]
  746. .get_thread_data_test:
  747.   test eax,eax
  748.   jz   .get_thread_data_end
  749.   cmp  ecx,[eax+KOLIBRI_THREAD_DATA_PID*4]
  750.   jnz  .get_thread_data_loop
  751. .get_thread_data_end:
  752.   lock dec dword [@Kolibri@_ThreadScanCount]
  753.   ret
  754. .get_thread_data_wait:
  755.   push eax ebx
  756.   mov  eax,SF_SLEEP
  757.   mov  ebx,1
  758. .get_thread_data_wait_loop:
  759.   int  0x40
  760.   cmp  dword [@Kolibri@_ThreadScanCount+4],0
  761.   jz   .get_thread_data_wait_end
  762.   shl  ebx,1
  763.   cmp  ebx,KOLIBRI_MUTEX_MAX_TIME_WAIT
  764.   jna  .get_thread_data_wait_loop
  765.   mov  ebx,KOLIBRI_MUTEX_MAX_TIME_WAIT
  766.   jmp  .get_thread_data_wait_loop
  767. .get_thread_data_wait_end:
  768.   pop  ebx eax
  769.   jmp .get_thread_data_nowait
  770. endp
  771.  
  772. proc @Kolibri@_GetSkinHeader$qv uses ebx
  773.   mov  eax,SF_STYLE_SETTINGS
  774.   mov  ebx,SSF_GET_SKIN_HEIGHT
  775.   int  0x40
  776.   ret
  777. endp
  778.  
  779. proc @Kolibri@GetScreenSize$qrust1
  780.   mov  eax,SF_GET_SCREEN_SIZE
  781.   int  0x40
  782.   mov  ecx,[esp+8]
  783.   mov  word [ecx],ax
  784.   mov  ecx,[esp+4]
  785.   shr  eax,16
  786.   mov  word [ecx],ax
  787.   ret
  788. endp
  789.  
  790. proc Kolibri_MutexLockNoWait
  791.   pop  eax
  792.   xor  al,al
  793.   ret
  794. endp
  795.  
  796. proc Kolibri_MutexLockWait uses ebx
  797.   mov  eax,SF_SLEEP
  798.   xor  ebx,ebx
  799. .lock_wait_cycle:
  800.   int  0x40
  801.   shl  byte [ecx],1
  802.   jz   .lock_wait_cycle
  803.   mov  al,1
  804.   ret
  805. endp
  806.  
  807. proc Kolibri_MutexLockWaitTime
  808.   cmp  dword [esp+12],0
  809.   jng  .MutexLockWait
  810.   push ebx edx
  811.   mov  edx,[esp+20]
  812.   mov  eax,SF_SYSTEM_GET
  813.   mov  ebx,SSF_TIME_COUNT
  814.   int  0x40
  815.   add  edx,eax
  816. .lock_wait_time_cycle:
  817.   mov  eax,SF_SLEEP
  818.   xor  ebx,ebx
  819.   int  0x40
  820.   shl  byte [ecx],1
  821.   jnz  .lock_wait_time_ret_true
  822.   mov  eax,SF_SYSTEM_GET
  823.   mov  ebx,SSF_TIME_COUNT
  824.   int  0x40
  825.   cmp  eax,edx
  826.   js   .lock_wait_time_cycle
  827.   pop  edx ebx eax
  828.   xor  al,al
  829.   ret
  830. .lock_wait_time_ret_true:
  831.   pop  edx ebx
  832.   mov  al,1
  833.   ret
  834. endp
  835.  
  836. proc Kolibri_MutexLock
  837.   shl  byte [ecx],1
  838.   jnz  .lock_first
  839.   call eax
  840. .lock_first:
  841.   mov  al,1
  842.   ret
  843. endp
  844.  
  845. proc @Kolibri@TryLock$qp14Kolibri@TMutex
  846.   mov  eax,Kolibri_MutexLockNoWait
  847.   mov  ecx,[esp+4]
  848.   jmp  Kolibri_MutexLock
  849. endp
  850.  
  851. proc @Kolibri@Lock$qp14Kolibri@TMutex
  852.   mov  eax,Kolibri_MutexLockWait
  853.   mov  ecx,[esp+4]
  854.   jmp  Kolibri_MutexLock
  855. endp
  856.  
  857. proc @Kolibri@LockTime$qp14Kolibri@TMutexi
  858.   mov  eax,Kolibri_MutexLockWaitTime
  859.   mov  ecx,[esp+4]
  860.   jmp  Kolibri_MutexLock
  861. endp
  862.  
  863. proc @Kolibri@UnLock$qp14Kolibri@TMutex
  864.   mov  ecx,[esp+4]
  865.   shr  byte [ecx],1
  866.   jz   .unlock_pause
  867.   ret
  868. .unlock_pause:
  869.   mov  byte [ecx],0x40
  870.   push ebx
  871.   mov  eax,SF_SLEEP
  872.   xor  ebx,ebx
  873.   int  0x40
  874.   pop  ebx
  875.   ret
  876. endp
  877.  
  878. proc Kolibri_MutexLockRec
  879.   shl  byte [ecx],1
  880.   jng  .lock_first
  881.   cmp  dword [ecx+4],edx
  882.   jz   .lock_rec_self
  883.   call eax
  884. .lock_rec_first:
  885.   mov  al,1
  886.   mov  dword [ecx+4],edx
  887.   ret
  888. .lock_rec_self:
  889.   mov  al,1
  890.   add  dword [ecx],0x100
  891.   jc   .lock_rec_overflow
  892.   ret
  893. .lock_rec_overflow:
  894.   push dword [@Kolibri@DebugPrefix]
  895.   call @Kolibri@DebugPutString$qpxc
  896.   mov  dword [esp],Kolibri_try_lock_rec_overflow_string
  897.   call @Kolibri@DebugPutString$qpxc
  898.   pop  ecx
  899.   jmp  @Kolibri@ExitDebug$qv
  900. endp
  901.  
  902. proc @Kolibri@TryLock$qp16Kolibri@TRecMutexui
  903.   mov  eax,Kolibri_MutexLockNoWait
  904.   mov  ecx,[esp+4]
  905.   mov  edx,[esp+8]
  906.   jmp  Kolibri_MutexLockRec
  907. endp
  908.  
  909. proc @Kolibri@Lock$qp16Kolibri@TRecMutexui
  910.   mov  eax,Kolibri_MutexLockWait
  911.   mov  ecx,[esp+4]
  912.   mov  edx,[esp+8]
  913.   jmp  Kolibri_MutexLockRec
  914. endp
  915.  
  916. proc @Kolibri@LockTime$qp16Kolibri@TRecMutexiui
  917.   mov  eax,Kolibri_MutexLockWaitTime
  918.   mov  ecx,[esp+4]
  919.   mov  edx,[esp+12]
  920.   jmp  Kolibri_MutexLockRec
  921. endp
  922.  
  923. proc @Kolibri@UnLock$qp16Kolibri@TRecMutexui
  924.   mov  ecx,[esp+4]
  925.   mov  edx,[esp+8]
  926.   cmp  dword [ecx+4],edx
  927.   jnz  .unlock_rec_notlocked
  928.   sub  dword [ecx],0x100
  929.   jnc  .unlock_rec_end
  930.   add dword [ecx],0x100
  931.   shl byte [ecx],1
  932.   shr byte [ecx],2
  933.   jng  .unlock_rec_pause
  934. .unlock_rec_end:
  935.   ret
  936. .unlock_rec_pause:
  937.   mov  byte [ecx],0x20
  938.   push ebx
  939.   mov  eax,SF_SLEEP
  940.   xor  ebx,ebx
  941.   int  0x40
  942.   pop  ebx
  943.   ret
  944. .unlock_rec_notlocked:
  945.   push dword [@Kolibri@DebugPrefix]
  946.   call @Kolibri@DebugPutString$qpxc
  947.   mov  dword [esp],Kolibri_unlock_rec_notlocked_string
  948.   call @Kolibri@DebugPutString$qpxc
  949.   pop  ecx
  950.   jmp  @Kolibri@ExitDebug$qv
  951. endp
  952.  
  953. proc @Kolibri@DebugPutChar$qc
  954.   mov  cl,byte [esp+4]
  955.   cmp  cl,13
  956.   jz   .debug_put_char_ret
  957.   push ebx
  958.   cmp  cl,10
  959.   jz   .debug_put_char_enter
  960. .debug_put_char_after_cmp:
  961.   mov  eax,SF_BOARD
  962.   mov  ebx,SSF_DEBUG_WRITE
  963.   int  0x40
  964.   pop  ebx
  965. .debug_put_char_ret:
  966.   ret
  967. .debug_put_char_enter:
  968.   mov  cl,13
  969.   mov  eax,SF_BOARD
  970.   mov  ebx,SSF_DEBUG_WRITE
  971.   int  0x40
  972.   mov  cl,10
  973.   jmp  .debug_put_char_after_cmp
  974. endp
  975.  
  976. proc @Kolibri@DebugPutString$qpxc uses esi
  977.   push dword 0
  978.   mov  esi,dword [esp+12]
  979.   jmp  .debug_put_string_test
  980. .debug_put_string_loop:
  981.   mov  dword [esp],eax
  982.   call @Kolibri@DebugPutChar$qc
  983.   inc  esi
  984. .debug_put_string_test:
  985.   xor  eax,eax
  986.   or   al,[esi]
  987.   test al,al
  988.   jnz  .debug_put_string_loop
  989.   pop  ecx
  990.   ret
  991. endp
  992.  
  993. proc @Kolibri@GetKey$qv
  994.   mov  eax,SF_GET_KEY
  995.   int  0x40
  996.   test al,al
  997.   jnz  .get_key_eof
  998.   movzx eax,ah
  999.   ret
  1000. .get_key_eof:
  1001.   mov  eax,SF_TERMINATE_PROCESS
  1002.   ret
  1003. endp
  1004.  
  1005. proc @Kolibri@GetMouseButton$qv uses ebx
  1006.   mov  eax,SF_MOUSE_GET
  1007.   mov  ebx,SSF_BUTTON
  1008.   int  0x40
  1009.   ret
  1010. endp
  1011.  
  1012. proc @Kolibri@GetMousePosition$qrst1o uses ebx
  1013.   mov  eax,SF_MOUSE_GET
  1014.   xor  ebx,ebx ;SSF_SCREEN_POSITION
  1015.   cmp  byte [esp+16],0
  1016.   jnz  .get_mouse_pos_absolute
  1017.   inc  ebx
  1018. .get_mouse_pos_absolute:
  1019.   int  0x40
  1020.   mov  ecx,[esp+12]
  1021.   mov  word [ecx],ax
  1022.   mov  ecx,[esp+8]
  1023.   shr  eax,16
  1024.   mov  word [ecx],ax
  1025.   ret
  1026. endp
  1027.  
  1028. proc @Kolibri@WasThreadCreated$qv
  1029.   cmp  byte [@Kolibri@_ThreadSavedBegProc],0x90
  1030.   setz al
  1031.   ret
  1032. endp
  1033.  
  1034. proc @Kolibri@CreateThread$qpvuit1
  1035.   push ebx
  1036.   mov  edx,[esp+16]
  1037.   mov  ebx,[esp+12]
  1038.   test edx,edx
  1039.   jnz  .create_thread_after_new
  1040. if defined KolibriHeapAlloc
  1041.   cmp  ebx,4096
  1042.   jnb  .create_thread_alloc
  1043.   mov  ebx,STACKSIZE
  1044. .create_thread_alloc:
  1045.   push ebx
  1046.   call KolibriHeapAlloc  ; Create new dynamic memory of the given size
  1047.   pop  ecx
  1048.   test eax,eax
  1049.   jnz  .create_thread_mem_created
  1050. end if
  1051.   or   eax,-1
  1052.   jmp  .create_thread_end
  1053. .create_thread_mem_created:
  1054.   lea  edx,[eax+ebx]
  1055. .create_thread_after_new:
  1056.   neg  ebx
  1057.   jz   .create_thread_test_first
  1058.   add  ebx,edx
  1059. .create_thread_test_first:
  1060.   cmp  byte [@Kolibri@_ThreadSavedBegProc],0x90
  1061.   jnz  .create_thread_init
  1062. .create_thread_fill_stack:
  1063.   lock inc dword [@Kolibri@_ThreadNumber]
  1064.   and  edx,not 3
  1065.   sub  edx,12
  1066.   mov  ecx,[esp+8]
  1067.   mov  dword [edx+8],ebx
  1068.   mov  dword [edx+4],ecx
  1069.   mov  dword [edx],Kolibri_ThreadFinish
  1070.   mov  eax,SF_CREATE_THREAD
  1071.   mov  ebx,1
  1072.   mov  ecx,@Kolibri@ThreadMain$qpvt1
  1073.   int  0x40
  1074.   mov  ebx,eax
  1075.   or   bl,15
  1076.   inc  ebx
  1077.   jnz  .create_thread_end
  1078.   lock dec dword [@Kolibri@_ThreadNumber]
  1079. if defined KolibriHeapFree
  1080.   or   ebx,[edx+8]
  1081.   jz   .create_thread_end
  1082.   push ebx
  1083.   call KolibriHeapFree  ; Delete the given dynamic memory
  1084.   pop  ecx
  1085. end if
  1086. .create_thread_end:
  1087.   pop  ebx
  1088.   ret
  1089. .create_thread_init:
  1090.   push esi edi
  1091.   cld
  1092.   mov  esi,@Kolibri@_ThreadSavedBegProc
  1093.   mov  edi,@Kolibri@GetPid$qv
  1094.   movsd
  1095.   movsd
  1096.   mov  edi,@Kolibri@GetThreadData$qv
  1097.   movsd
  1098.   movsd
  1099.   mov  eax,0x90909090
  1100.   mov  edi,@Kolibri@_ThreadSavedBegProc
  1101.   stosd
  1102.   stosd
  1103.   stosd
  1104.   stosd
  1105.   pop  edi esi
  1106.   jmp  .create_thread_fill_stack
  1107. endp
  1108.  
  1109. proc @Kolibri@_FileAccess$qp21Kolibri@FileInfoBlock uses ebx
  1110.   mov  eax,SF_FILE
  1111.   mov  ebx,[esp+8]
  1112.   int  0x40
  1113.   mov  ecx,[esp+8]
  1114.   mov  [ecx],ebx
  1115.   ret
  1116. endp
  1117.  
  1118. if defined Kolibri_debug_string
  1119. Kolibri_debug_string:
  1120.   db 'Abnormal program termination.',10,0
  1121. end if
  1122.  
  1123. if defined Kolibri_MutexLockRec
  1124. Kolibri_try_lock_rec_overflow_string:
  1125.   db 'Recursive mutex lock count overflow.',10,0
  1126. end if
  1127.  
  1128. if defined @Kolibri@UnLock$qp16Kolibri@TRecMutexui
  1129. Kolibri_unlock_rec_notlocked_string:
  1130.   db 'Recursive mutex unlock error.',10,0
  1131. end if
  1132.  
  1133. include "kos_lib.inc"
  1134.  
  1135. ;/**/
  1136.  
  1137.