Subversion Repositories Kolibri OS

Rev

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

  1.  
  2. HEAP_BASE equ 0x01000000
  3. ;HEAP_SIZE equ 0x01000000
  4.  
  5. struc MEM_BLOCK
  6. {  .next_block  dd ?
  7.    .prev_block  dd ? ;+4
  8.    .list_next   dd ? ;+8
  9.    .list_prev   dd ? ;+12
  10.    .base        dd ? ;+16
  11.    .size        dd ? ;+20
  12.    .flags       dd ? ;+24
  13.    .handle      dd ? ;+28
  14. }
  15.  
  16. FREE_BLOCK      equ  4
  17. USED_BLOCK      equ  8
  18.  
  19. virtual at 0
  20.   MEM_BLOCK MEM_BLOCK
  21. end virtual
  22.  
  23. MEM_BLOCK_SIZE equ 8*4
  24.  
  25. block_next   equ MEM_BLOCK.next_block
  26. block_prev   equ MEM_BLOCK.prev_block
  27. list_next    equ MEM_BLOCK.list_next
  28. list_prev    equ MEM_BLOCK.list_prev
  29. block_base   equ MEM_BLOCK.base
  30. block_size   equ MEM_BLOCK.size
  31. block_flags  equ MEM_BLOCK.flags
  32.  
  33. macro calc_index op
  34. {          shr op, 12
  35.            dec op
  36.            cmp op, 63
  37.            jna @f
  38.            mov op, 63
  39. @@:
  40. }
  41.  
  42. macro remove_from_list op
  43. {          mov edx, [op+list_next]
  44.            mov ecx, [op+list_prev]
  45.            test edx, edx
  46.            jz @f
  47.            mov [edx+list_prev], ecx
  48. @@:
  49.            test ecx, ecx
  50.            jz @f
  51.            mov [ecx+list_next], edx
  52. @@:
  53.            mov [op+list_next],0
  54.            mov [op+list_prev],0
  55. }
  56.  
  57. macro remove_from_free op
  58. {
  59.            remove_from_list op
  60.  
  61.            mov eax, [op+block_size]
  62.            calc_index eax
  63.            cmp [mem_block_list+eax*4], op
  64.            jne @f
  65.            mov [mem_block_list+eax*4], edx
  66. @@:
  67.            cmp [mem_block_list+eax*4], 0
  68.            jne @f
  69.            btr [mem_block_mask], eax
  70. @@:
  71. }
  72.  
  73. macro remove_from_used op
  74. {
  75.            remove_from_list op
  76.            cmp [mem_used_list], op
  77.            jne @f
  78.            mov [mem_used_list], edx
  79. @@:
  80. }
  81.  
  82. align 4
  83. proc init_kernel_heap
  84.  
  85.            mov ecx, 64/4
  86.            mov edi, mem_block_list
  87.            xor eax, eax
  88.            cld
  89.            rep stosd
  90.  
  91.            mov ecx, 512/4
  92.            mov edi, mem_block_map
  93.            not eax
  94.            rep stosd
  95.  
  96.            mov [mem_block_start], mem_block_map
  97.            mov [mem_block_end], mem_block_map+512
  98.            mov [mem_block_arr], HEAP_BASE
  99.  
  100.            stdcall alloc_pages, dword 32
  101.            mov ecx, 32
  102.            mov edx, eax
  103.            mov edi, HEAP_BASE
  104.  
  105. .l1:
  106.            stdcall map_page,edi,edx,PG_SW
  107.            add edi, 0x1000
  108.            add edx, 0x1000
  109.            dec ecx
  110.            jnz .l1
  111.  
  112.            mov edi, HEAP_BASE
  113.            mov ebx, edi
  114.            add ebx, MEM_BLOCK_SIZE
  115.            xor eax, eax
  116.            mov [edi+block_next], ebx
  117.            mov [edi+block_prev], eax
  118.            mov [edi+list_next], eax
  119.            mov [edi+list_prev], eax
  120.            mov [edi+block_base], HEAP_BASE
  121.            mov [edi+block_size], 4096*MEM_BLOCK_SIZE
  122.            mov [edi+block_flags], USED_BLOCK
  123.  
  124.            mov [ebx+block_next], eax
  125.            mov [ebx+block_prev], eax
  126.            mov [ebx+list_next], eax
  127.            mov [ebx+block_base], HEAP_BASE+4096*MEM_BLOCK_SIZE
  128.  
  129.            mov ecx, [MEM_AMOUNT]
  130.            sub ecx, 0x01000000 + 4096*MEM_BLOCK_SIZE
  131.            mov [heap_size], ecx
  132.            mov [heap_free], ecx
  133.            mov [ebx+block_size], ecx
  134.            mov [ebx+block_flags], FREE_BLOCK
  135.  
  136.            mov [mem_block_mask], eax
  137.            mov [mem_block_mask+4],0x80000000
  138.  
  139.            mov [mem_used_list], eax
  140.            mov [mem_block_list+63*4], ebx
  141.            mov byte [mem_block_map], 0xFC
  142.            mov [heap_blocks], 4095
  143.            mov [free_blocks], 4095
  144.            ret
  145. endp
  146.  
  147. align 4
  148. proc get_block stdcall, index:dword
  149.  
  150.            mov eax, 63
  151.            mov ecx, [index]
  152.            cmp ecx, eax
  153.            jna @f
  154.            ;cmova ecx, eax
  155.            mov ecx, eax
  156. @@:
  157.            xor esi, esi
  158.            xor ebx, ebx
  159.            xor edx, edx
  160.            not edx
  161.  
  162.            cmp ecx, 32
  163.            jb .bit_test
  164.  
  165.            sub ecx, 32
  166.            add ebx, 32
  167.            add esi, 4
  168.  
  169. .bit_test:
  170.            shl edx, cl
  171.            and edx, [mem_block_mask+esi]
  172.            jz .high_mask
  173.            bsf eax, edx
  174.            add ebx, eax
  175.            mov eax, [mem_block_list+ebx*4]
  176.            ret
  177.  
  178. .high_mask:
  179.  
  180.            add esi, 4
  181.            add ebx, 32
  182.            test esi, 0xFFFFFFF8
  183.            jnz .big_error
  184.            mov edx, [mem_block_mask+esi]
  185.            and edx, edx
  186.            jz .high_mask
  187.            bsf eax, edx
  188.            add ebx, eax
  189.            mov eax, [mem_block_list+ebx*4]
  190.            ret
  191.  
  192. .big_error:
  193.            xor eax, eax
  194.            ret
  195. endp
  196.  
  197. align 4
  198. proc alloc_mem_block
  199.  
  200.            pushfd
  201.            cli
  202.            mov ebx, [mem_block_start]
  203.            mov ecx, [mem_block_end]
  204. .l1:
  205.            bsf eax,[ebx];
  206.            jnz found
  207.            add ebx,4
  208.            cmp ebx, ecx
  209.            jb .l1
  210.            popfd
  211.            xor eax,eax
  212.            ret
  213.  
  214. found:
  215.            btr [ebx], eax
  216.            mov [mem_block_start],ebx
  217.            sub ebx, mem_block_map
  218.            shl ebx, 3
  219.            add eax,ebx
  220.            shl eax, 5
  221.            add eax, [mem_block_arr]
  222.            dec [free_blocks]
  223.            popfd
  224.            ret
  225. endp
  226.  
  227. proc free_mem_block
  228.            pushfd
  229.            cli
  230.            sub eax, [mem_block_arr]
  231.            shr eax, 5
  232.  
  233.            mov ebx, mem_block_map
  234.            bts [ebx], eax
  235.            inc [free_blocks]
  236.            shr eax, 3
  237.            and eax, not 3
  238.            add eax, ebx
  239.            cmp [mem_block_start], eax
  240.            ja @f
  241.            popfd
  242.            ret
  243. @@:
  244.            mov [mem_block_start], eax
  245.            popfd
  246.            ret
  247. .err:
  248.            xor eax, eax
  249.            popfd
  250.            ret
  251. endp
  252.  
  253. align 4
  254. proc alloc_kernel_space stdcall, size:dword
  255.            local block_ind:DWORD
  256.  
  257.            pushfd
  258.            cli
  259.  
  260.            mov eax, [size]
  261.            add eax, 0xFFF
  262.            and eax, 0xFFFFF000;
  263.            mov [size], eax
  264.            cmp eax, [heap_free]
  265.            ja .error
  266.  
  267.            shr eax, 12
  268.            sub eax, 1
  269.  
  270.            mov [block_ind], eax
  271.  
  272.            stdcall get_block, eax
  273.            and eax, eax
  274.            jz .error
  275.  
  276.            mov edi, eax           ;edi - pBlock
  277.  
  278.            cmp [edi+block_flags], FREE_BLOCK
  279.            jne .error
  280.  
  281.            mov [block_ind], ebx   ;index of allocated block
  282.  
  283.            mov eax, [edi+block_size]
  284.            cmp eax, [size]
  285.            je .m_eq_size
  286.  
  287.            call alloc_mem_block
  288.            and eax, eax
  289.            jz .error
  290.  
  291.            mov esi, eax           ;esi - splitted block
  292.  
  293.            mov [esi+block_next], edi
  294.            mov eax, [edi+block_prev]
  295.            mov [esi+block_prev], eax
  296.            mov [edi+block_prev], esi
  297.            mov [esi+list_next], 0
  298.            mov [esi+list_prev], 0
  299.            and eax, eax
  300.            jz @f
  301.            mov [eax+block_next], esi
  302. @@:
  303.            mov ebx, [edi+block_base]
  304.            mov [esi+block_base], ebx
  305.            mov edx, [size]
  306.            mov [esi+block_size], edx
  307.            add [edi+block_base], edx
  308.            sub [edi+block_size], edx
  309.  
  310.            mov eax, [edi+block_size]
  311.            shr eax, 12
  312.            sub eax, 1
  313.            cmp eax, 63
  314.            jna @f
  315.            mov eax, 63
  316. @@:
  317.            cmp eax, [block_ind]
  318.            je .m_eq_ind
  319.  
  320.            mov ebx, [edi+list_next]
  321.            test ebx, ebx
  322.            jz @f
  323.  
  324.            mov [ebx+list_prev], edi
  325. @@:
  326.            mov ecx, [block_ind]
  327.            mov [mem_block_list+ecx*4], ebx
  328.  
  329.            and ebx, ebx
  330.            jnz @f
  331.            btr [mem_block_mask], ecx
  332. @@:
  333.            mov edx, [mem_block_list+eax*4]
  334.            mov [edi+list_next], edx
  335.            test edx, edx
  336.            jz @f
  337.            mov [edx+list_prev], edi
  338. @@:
  339.            mov [mem_block_list+eax*4], edi
  340.            bts [mem_block_mask], eax
  341. .m_eq_ind:
  342.            mov ebx, [mem_used_list]
  343.            mov [esi+list_next], ebx
  344.            test ebx, ebx
  345.            jz @f
  346.            mov [ebx+list_prev], esi
  347. @@:
  348.            mov [esi+block_flags], USED_BLOCK
  349.            mov [mem_used_list], esi
  350.            mov eax, [esi+block_base]
  351.            mov ebx, [size]
  352.            sub [heap_free], ebx
  353.            popfd
  354.            ret
  355.  
  356. .m_eq_size:
  357.            remove_from_list edi
  358.            mov [mem_block_list+ecx*4], edx
  359.            and edx, edx
  360.            jnz @f
  361.            mov ecx, [block_ind]
  362.            btr [mem_block_mask], ecx
  363. @@:
  364.            mov ebx, [mem_used_list]
  365.            mov [edi+list_next], ebx
  366.            test ebx, ebx
  367.            jnz @f
  368.            mov [ebx+list_prev], edi
  369. @@:
  370.            mov [mem_used_list], edi
  371.            mov [edi+block_flags], USED_BLOCK
  372.            mov eax, [edi+block_base]
  373.            mov ebx, [size]
  374.            sub [heap_free], ebx
  375.            popfd
  376.            ret
  377. .error:
  378.            xor eax, eax
  379.            popfd
  380.            ret
  381. endp
  382.  
  383. align 4
  384. proc free_kernel_space stdcall, base:dword
  385.  
  386.            mov eax, [base]
  387.            mov esi, [mem_used_list]
  388. @@:
  389.            test esi, esi
  390.            jz .fail
  391.  
  392.            cmp [esi+block_base], eax
  393.            je .found
  394.            mov esi, [esi+list_next]
  395.            jmp @b
  396. .found:
  397.            cmp [esi+block_flags], USED_BLOCK
  398.            jne .fail
  399.  
  400.            mov eax, [esi+block_size]
  401.            add [heap_free], eax
  402.  
  403.            mov edi, [esi+block_next]
  404.            test edi, edi
  405.            jz .prev
  406.  
  407.            cmp [edi+block_flags], FREE_BLOCK
  408.            jne .prev
  409.  
  410.            remove_from_free edi
  411.  
  412.            mov edx, [edi+block_next]
  413.            mov [esi+block_next], edx
  414.            test edx, edx
  415.            jz @f
  416.  
  417.            mov [edx+block_prev], esi
  418. @@:
  419.            mov ecx, [edi+block_size]
  420.            add [esi+block_size], ecx
  421.  
  422.            mov eax, edi
  423.            call free_mem_block
  424. .prev:
  425.            mov edi, [esi+block_prev]
  426.            test edi, edi
  427.            jz .insert
  428.  
  429.            cmp [edi+block_flags], FREE_BLOCK
  430.            jne .insert
  431.  
  432.            remove_from_used esi
  433.  
  434.            mov edx, [esi+block_next]
  435.            mov [edi+block_next], edx
  436.            test edx, edx
  437.            jz @f
  438.            mov [edx+block_prev], edi
  439. @@:
  440.            mov eax, esi
  441.            call free_mem_block
  442.  
  443.            mov ecx, [edi+block_size]
  444.            mov eax, [esi+block_size]
  445.            add eax, ecx
  446.            mov [edi+block_size], eax
  447.  
  448.            calc_index eax
  449.            calc_index ecx
  450.            cmp eax, ecx
  451.            je .m_eq
  452.  
  453.            push ecx
  454.            remove_from_list edi
  455.            pop ecx
  456.  
  457.            cmp [mem_block_list+ecx*4], edi
  458.            jne @f
  459.            mov [mem_block_list+ecx*4], edx
  460. @@:
  461.            cmp [mem_block_list+ecx*4], 0
  462.            jne @f
  463.            btr [mem_block_mask], ecx
  464. @@:
  465.            mov esi, [mem_block_list+eax*4]
  466.            mov [mem_block_list+eax*4], edi
  467.            mov [edi+list_next], esi
  468.            test esi, esi
  469.            jz @f
  470.            mov [esi+list_prev], edi
  471. @@:
  472.            bts [mem_block_mask], eax
  473. .m_eq:
  474.            xor eax, eax
  475.            not eax
  476.            ret
  477. .insert:
  478.            remove_from_used esi
  479.  
  480.            mov eax, [esi+block_size]
  481.            calc_index eax
  482.  
  483.            mov edi, [mem_block_list+eax*4]
  484.            mov [mem_block_list+eax*4], esi
  485.            mov [esi+list_next], edi
  486.            test edi, edi
  487.            jz @f
  488.            mov [edi+list_prev], esi
  489. @@:
  490.            bts [mem_block_mask], eax
  491.            mov [esi+block_flags],FREE_BLOCK
  492.            xor eax, eax
  493.            not eax
  494.            ret
  495. .fail:
  496.            xor eax, eax
  497.            ret
  498. endp
  499.  
  500. align 4
  501. proc kernel_alloc stdcall, size:dword
  502.            locals
  503.              lin_addr    dd ?
  504.              pages_count dd ?
  505.            endl
  506.  
  507.            mov eax, [size]
  508.            add eax, 0xFFF
  509.            and eax, 0xFFFFF000;
  510.            mov [size], eax
  511.            and eax, eax
  512.            jz .error
  513.            mov ebx, eax
  514.            shr ebx, 12
  515.            mov [pages_count], ebx
  516.  
  517.            stdcall alloc_kernel_space, eax
  518.            and eax, eax
  519.            jz .error
  520.            mov [lin_addr], eax
  521.  
  522.            mov ecx, [pages_count]
  523.            mov edx, eax
  524.            mov ebx, ecx
  525.  
  526.            shr ecx, 3
  527.            jz .next
  528.  
  529.            and ebx, not 7
  530.            push ebx
  531.            stdcall alloc_pages, ebx
  532.            pop ecx                   ; yes ecx!!!
  533.            and eax, eax
  534.            jz .error
  535.  
  536.            mov edi, eax
  537.            mov edx, [lin_addr]
  538. @@:
  539.            stdcall map_page,edx,edi,dword PG_SW
  540.            add edx, 0x1000
  541.            add edi, 0x1000
  542.            dec ecx
  543.            jnz @B
  544. .next:
  545.            mov ecx, [pages_count]
  546.            and ecx, 7
  547.            jz .end
  548.  
  549. @@:        push ecx
  550.            call alloc_page
  551.            pop ecx
  552.            test eax, eax
  553.            jz .error
  554.  
  555.            stdcall map_page,edx,eax,dword PG_SW
  556.            add edx, 0x1000
  557.            dec ecx
  558.            jnz @B
  559. .end:
  560.            mov eax, [lin_addr]
  561.            ret
  562.  
  563. .error:
  564.            xor eax, eax
  565.            ret
  566. endp
  567.  
  568. align 4
  569. proc kernel_free stdcall, base:dword
  570.            locals
  571.              size  dd ?
  572.            endl
  573.  
  574.            mov eax, [base]
  575.            mov esi, [mem_used_list]
  576. @@:
  577.            test esi, esi
  578.            jz .fail
  579.  
  580.            cmp [esi+block_base], eax
  581.            je .found
  582.            mov esi, [esi+list_next]
  583.            jmp @b
  584. .found:
  585.            cmp [esi+block_flags], USED_BLOCK
  586.            jne .fail
  587.  
  588.            mov ecx, [esi+block_size];
  589.            mov [size], ecx
  590.  
  591.            stdcall free_kernel_space, [base]
  592.            test eax, eax
  593.            jz .fail
  594.  
  595.            mov ecx, [size]
  596.            mov edi, [base]
  597.  
  598.            shr ecx, 12
  599.            mov esi, edi
  600.            shr edi, 10
  601.            add edi, pages_tab
  602.            xor edx, edx
  603. .release:
  604.            mov eax, [edi]
  605.            test eax, 1
  606.            jz .next
  607.  
  608.            call free_page
  609.            mov [edi],edx
  610. .next:
  611.            invlpg [esi]
  612.            add esi, 0x1000
  613.            add edi, 4
  614.            dec ecx
  615.            jnz .release
  616. .fail:
  617.            ret
  618. endp
  619.  
  620. restore block_next
  621. restore block_prev
  622. restore block_list
  623. restore block_base
  624. restore block_size
  625. restore block_flags
  626.  
  627. ;;;;;;;;;;;;;;      USER     ;;;;;;;;;;;;;;;;;
  628.  
  629. align 4
  630. proc init_heap stdcall, heap_size:dword
  631.            locals
  632.              tab_count dd ?
  633.            endl
  634.  
  635.            mov edx, [heap_size]
  636.            and edx, edx
  637.            jz .exit
  638.            add edx, 4095
  639.            and edx, not 4095
  640.            mov [heap_size], edx
  641.            add edx, 0x003FFFFF
  642.            and edx, not 0x003FFFFF
  643.            shr edx, 22
  644.            mov [tab_count], edx
  645.  
  646.            mov ebx,[CURRENT_TASK]
  647.            shl ebx,8
  648.            mov esi, [PROC_BASE+0x8c+ebx]
  649.            add esi, 0x003FFFFF
  650.            and esi, not 0x003FFFFF
  651.            mov edi, esi
  652.            mov [PROC_BASE+0x18+ebx], esi
  653.            add esi, [heap_size]
  654.            mov [PROC_BASE+0x1C+ebx], esi
  655.  
  656.            mov eax, cr3
  657.            and eax, not 0xFFF
  658.            stdcall map_page,[current_pdir],eax,dword PG_SW
  659.  
  660.            add edi, new_app_base
  661. @@:
  662.            call alloc_page
  663.            test eax, eax
  664.            jz .exit
  665.  
  666.            stdcall map_page_table, [current_pdir], edi, eax
  667.            add edi, 0x00400000
  668.            dec edx
  669.            jnz @B
  670.  
  671.            mov ecx, [tab_count]
  672.            shl ecx, 12-2
  673.            mov ebx,[CURRENT_TASK]
  674.            shl ebx,8
  675.            mov edi, [PROC_BASE+0x18+ebx]
  676.            add edi, new_app_base
  677.            shr edi, 10
  678.            mov esi, edi
  679.            add edi, pages_tab
  680.            xor eax, eax
  681.            cld
  682.            rep stosd
  683.  
  684.            stdcall map_page,[current_pdir],dword PG_UNMAP
  685.  
  686.            mov ebx, [heap_size]
  687.            mov eax, ebx
  688.            sub eax, 4096
  689.            or ebx, FREE_BLOCK
  690.            mov [pages_tab+esi], ebx
  691.  
  692.            ret
  693. .exit:
  694.            xor eax, eax
  695.            ret
  696. endp
  697.  
  698. align 4
  699. proc user_alloc stdcall, alloc_size:dword
  700.  
  701.            mov ecx, [alloc_size]
  702.            add ecx, (4095+4096)
  703.            and ecx, not 4095
  704.  
  705.            mov ebx, [CURRENT_TASK]
  706.            shl ebx, 8
  707.            mov esi, dword [ebx+PROC_BASE+0x18]; heap_base
  708.            mov edi, dword [ebx+PROC_BASE+0x1C]; heap_top
  709.            add esi, new_app_base
  710.            add edi, new_app_base
  711.  
  712. l_0:
  713.            cmp esi, edi
  714.            jae m_exit
  715.  
  716.            mov ebx, esi
  717.            shr ebx, 12
  718.            mov eax, [pages_tab+ebx*4]
  719.            test eax, FREE_BLOCK
  720.            jz test_used
  721.            and eax, 0xFFFFF000
  722.            cmp eax, ecx    ;alloc_size
  723.            jb  m_next
  724.  
  725.            mov edx, esi
  726.            add edx, ecx
  727.            sub eax, ecx;
  728.            or eax, FREE_BLOCK
  729.            shr edx, 12
  730.            mov [pages_tab+edx*4], eax
  731.  
  732.            or ecx, USED_BLOCK
  733.            mov [pages_tab+ebx*4], ecx
  734.            shr ecx, 12
  735.            dec ecx
  736.            inc ebx
  737. @@:
  738.            mov dword [pages_tab+ebx*4], 2
  739.            inc ebx
  740.            dec ecx
  741.            jnz @B
  742.  
  743.            mov eax, esi
  744.            add eax, 4096
  745.            sub eax, new_app_base
  746.            ret
  747. m_next:
  748.            add esi, eax
  749.            jmp l_0
  750. test_used:
  751.            test eax, USED_BLOCK
  752.            jz m_exit
  753.  
  754.            and eax, 0xFFFFF000
  755.            add esi, eax
  756.            jmp l_0
  757. m_exit:
  758.            xor eax, eax
  759.            ret
  760. endp
  761.  
  762. align 4
  763. proc user_free stdcall, base:dword
  764.  
  765.            mov esi, [base]
  766.            test esi, esi
  767.            jz .exit
  768.  
  769.            sub esi, 4096
  770.            shr esi, 12
  771.            mov eax, [pages_tab+esi*4]
  772.            test eax, USED_BLOCK
  773.            jz @f
  774.  
  775.            and eax, not 4095
  776.            mov ecx, eax
  777.            or eax, FREE_BLOCK
  778.            mov [pages_tab+esi*4], eax
  779.            inc esi
  780.            sub ecx, 4096
  781.            shr ecx, 12
  782. .release:
  783.            mov eax, [pages_tab+esi*4]
  784.            call free_page
  785.            inc esi
  786.            dec ecx
  787.            jnz .release
  788. @@:
  789.            mov ebx, [CURRENT_TASK]
  790.            shl ebx, 8
  791.            mov esi, dword [ebx+PROC_BASE+0x18]; heap_base
  792.            mov edi, dword [ebx+PROC_BASE+0x1C]; heap_top
  793.            shr esi, 12
  794.            shr edi, 12
  795. @@:
  796.            mov eax, [pages_tab+esi*4]
  797.            test eax, USED_BLOCK
  798.            jz .test_free
  799.            shr eax, 12
  800.            add esi, eax
  801.            jmp @B
  802. .test_free:
  803.            test eax, FREE_BLOCK
  804.            jz .err
  805.            mov edx, eax
  806.            shr edx, 12
  807.            add edx, esi
  808.            cmp edx, edi
  809.            jae .exit
  810.  
  811.            mov ebx, [pages_tab+edx*4]
  812.            test ebx, USED_BLOCK
  813.            jz .next_free
  814.  
  815.            shr ebx, 12
  816.            add edx, ebx
  817.            mov esi, edx
  818.            jmp @B
  819. .next_free:
  820.            test ebx, FREE_BLOCK
  821.            jz .err
  822.            and dword [pages_tab+edx*4], 0
  823.            add eax, ebx
  824.            and eax, not 4095
  825.            or eax, FREE_BLOCK
  826.            mov [pages_tab+esi*4], eax
  827.            jmp @B
  828. .exit:
  829.            xor eax, eax
  830.            inc eax
  831.            ret
  832. .err:
  833.            xor eax, eax
  834.            ret
  835. endp
  836.  
  837.  
  838. ;proc new_mem_resize stdcall, new_size:dword
  839. ;
  840. ;           stdcall wait_mutex, pg_data.pg_mutex
  841. ;
  842. ;           mov edi, [new_size]
  843. ;           add edi,4095
  844. ;           and edi,not 4095
  845. ;           mov [new_size], edi
  846.  
  847. ;           mov    edx,[CURRENT_TASK]
  848. ;           shl    edx,8
  849. ;           mov    esi, [PROC_BASE+0x8c+edx]
  850. ;           add esi, 4095
  851. ;           and esi, not 4095
  852.  
  853. ;           cmp edi, esi
  854. ;           jae .expand
  855.  
  856. ;           shr edi, 12
  857. ;           shr esi, 12
  858. ;
  859. ;@@:        mov eax, [pages_tab+0x4000+edi*4]
  860. ;           test eax, 1
  861. ;           jz .next
  862. ;           mov dword [pages_tab+0x4000+edi*4], 2
  863. ;           mov ebx, edi
  864. ;           shl ebx, 12
  865. ;           invlpg [ebx+std_application_base_address]
  866. ;           call free_page
  867. ;
  868. ;.next:     add edi, 1
  869. ;           cmp edi, esi
  870. ;           jb @B
  871. ;
  872. ;.update_size:
  873.  
  874. ;           mov ebx, [new_size]
  875. ;           mov    [PROC_BASE+0x8c+edx],ebx
  876. ;
  877. ;;search threads and update
  878. ;;application memory size infomation
  879. ;           mov    ecx,[PROC_BASE+0xb8+edx]
  880. ;           mov    eax,2
  881.  
  882. ;.search_threads:
  883. ;;eax = current slot
  884. ;;ebx = new memory size
  885. ;;ecx = page directory
  886. ;           cmp    eax,[TASK_COUNT]
  887. ;           jg     .search_threads_end
  888. ;           mov    edx,eax
  889. ;           shl    edx,5
  890. ;           cmp    word [CURRENT_TASK+edx+0xa],9 ;if slot empty?
  891. ;           jz     .search_threads_next
  892. ;           shl    edx,3
  893. ;           cmp    [PROC_BASE+edx+0xb8],ecx     ;if it is our thread?
  894. ;           jnz    .search_threads_next
  895. ;           mov    [PROC_BASE+edx+0x8c],ebx     ;update memory size
  896. ;.search_threads_next:
  897. ;           inc    eax
  898. ;           jmp    .search_threads
  899. ;.search_threads_end:
  900. ;           xor eax, eax
  901. ;           dec [pg_data.pg_mutex]
  902. ;           ret
  903. ;
  904. ;
  905. ;.expand:
  906. ;           add edi, new_app_base
  907. ;           add esi, new_app_base
  908. ;
  909. ;.grow:     call alloc_page
  910. ;           test eax, eax
  911. ;           jz .exit
  912. ;           stdcall map_page,esi,eax,dword PG_UW
  913.  
  914. ;           push edi
  915. ;           mov edi, esi
  916. ;           xor eax, eax
  917. ;           mov ecx, 1024
  918. ;           cld
  919. ;           rep stosd
  920. ;           pop edi
  921.  
  922. ;           add esi, 0x1000
  923. ;           cmp esi, edi
  924. ;           jna .grow
  925. ;           jmp .update_size
  926. ;.exit:
  927. ;           xor eax, eax
  928. ;           inc eax
  929. ;           dec [pg_data.pg_mutex]
  930. ;           ret
  931. ;endp
  932.  
  933.  
  934. align 4
  935. proc alloc_dll
  936.            pushf
  937.            cli
  938.            bsf eax, [dll_map]
  939.            jnz .find
  940.            popf
  941.            xor eax, eax
  942.            ret
  943. .find:
  944.            btr [dll_map], eax
  945.            popf
  946.            shl eax, 5
  947.            add eax, dll_tab
  948.            ret
  949. endp
  950.  
  951. align 4
  952. proc alloc_service
  953.            pushf
  954.            cli
  955.            bsf eax, [srv_map]
  956.            jnz .find
  957.            popf
  958.            xor eax, eax
  959.            ret
  960.  
  961. .find:     btr [srv_map], eax
  962.            popf
  963.            shl eax,5
  964.            add eax, srv_tab
  965.            ret
  966. endp
  967.  
  968. if NEW
  969.  
  970. align 16
  971. new_services:
  972.          cmp eax, 10
  973.          jb .fail
  974.          ja @f
  975.  
  976.          push dword [ebp+8+new_app_base]
  977.          call get_mem_info
  978.          mov [esp+36], eax
  979.          ret
  980. @@:
  981.          cmp eax, 11
  982.          ja @f
  983.  
  984.          push dword [ebp+8+new_app_base]
  985.          call init_heap
  986.          mov [esp+36], eax
  987.          ret
  988. @@:
  989.          cmp eax, 12
  990.          ja @f
  991.  
  992.          push dword [ebp+8+new_app_base]
  993.          call user_alloc
  994.          mov [esp+36], eax
  995.          ret
  996. @@:
  997.          cmp eax, 13
  998.          ja @f
  999.  
  1000.          push dword [ebp+8+new_app_base]
  1001.          call user_free
  1002.          mov [esp+36], eax
  1003.          ret
  1004.  
  1005. @@:
  1006.          cmp eax, 14
  1007.          ja @f
  1008.          mov eax, [ebp+8+new_app_base]
  1009.          add eax,new_app_base
  1010.          stdcall get_notify, eax
  1011.          ret
  1012. ;@@:
  1013. ;         cmp eax, 15
  1014. ;         ja @f
  1015. ;         call set_notify
  1016. ;         ret
  1017. @@:
  1018.          cmp eax, 16
  1019.          ja @f
  1020.  
  1021.          mov eax, [ebp+8+new_app_base]
  1022.          add eax, new_app_base
  1023.          stdcall get_service, eax
  1024.          mov [esp+36], eax
  1025.          ret
  1026. @@:
  1027.          cmp eax, 17
  1028.          ja @f
  1029.          stdcall srv_handler,[ebp+8+new_app_base],\
  1030.                           [ebp+12+new_app_base],\
  1031.                           [ebp+16+new_app_base]
  1032.          mov [esp+36], eax
  1033.          ret
  1034. ;@@:
  1035. ;         cmp eax, 20
  1036. ;         ja @f
  1037. ;         call CreateSound
  1038. ;         mov [esp+36], eax
  1039. ;         ret
  1040.  
  1041. @@:
  1042. .fail:
  1043.          xor eax, eax
  1044.          mov [esp+36], eax
  1045.          ret
  1046.  
  1047. proc strncmp stdcall, str1:dword, str2:dword, count:dword
  1048.  
  1049.         mov ecx,[count]
  1050.         jecxz .end
  1051.  
  1052.         mov ebx,ecx
  1053.  
  1054.         mov edi,[str1]
  1055.         mov esi,edi
  1056.         xor eax,eax
  1057.         repne scasb
  1058.         neg ecx             ; cx = count - strlen
  1059.         add ecx,ebx         ; strlen + count - strlen
  1060.  
  1061. .okay:
  1062.         mov edi,esi
  1063.         mov esi,[str2]
  1064.         repe cmpsb
  1065.         mov al,[esi-1]
  1066.         xor ecx,ecx
  1067.  
  1068.         cmp al,[edi-1]
  1069.         ja .str2_big
  1070.         je .end
  1071.  
  1072. .str1_big:
  1073.         sub ecx,2
  1074.  
  1075. .str2_big:
  1076.         not ecx
  1077. .end:
  1078.         mov eax,ecx
  1079.         ret
  1080. endp
  1081.  
  1082.  
  1083. proc get_proc stdcall, exp:dword, sz_name:dword
  1084.  
  1085.            mov edx, [exp]
  1086. .next:
  1087.            mov eax, [edx]
  1088.            test eax, eax
  1089.            jz .end
  1090.  
  1091.            push edx
  1092.            stdcall strncmp, eax, [sz_name], 16
  1093.            pop edx
  1094.            test eax, eax
  1095.            jz .ok
  1096.  
  1097.            add edx,8
  1098.            jmp .next
  1099. .ok:
  1100.            mov eax, [edx+4]
  1101. .end:
  1102.            ret
  1103. endp
  1104.  
  1105. proc link_dll stdcall, exp:dword, imp:dword
  1106.          mov esi, [imp]
  1107.  
  1108. .next:
  1109.          mov eax, [esi]
  1110.          test eax, eax
  1111.          jz .end
  1112.  
  1113.          push esi
  1114.          stdcall get_proc, [exp], eax
  1115.          pop esi
  1116.  
  1117.          test eax, eax
  1118.          jz @F
  1119.  
  1120.          mov [esi], eax
  1121. @@:
  1122.          add esi, 4
  1123.          jmp .next
  1124. .end:
  1125.          ret
  1126. endp
  1127.  
  1128. end if
  1129.  
  1130.  
  1131.  
  1132.