Subversion Repositories Kolibri OS

Rev

Rev 3 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. if ~defined newprocess_inc
  2. newprocess_inc_fix:
  3. newprocess_inc fix newprocess_inc_fix
  4. include "mem.inc"
  5. include "memmanag.inc"
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7. ;;Working with new types of processes.
  8. ;;Author: Khalyavin Andrey halyavin@land.ru
  9. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  10. iglobal
  11.     new_process_loading db 'K : New Process - loading',13,10,0
  12.     new_process_running db 'K : New Process - done',13,10,0
  13.     start_not_enough_memory db 'K : New Process - not enough memory',13,10,0
  14. endg
  15. ;-----------------------------------------------------------------------------
  16.  
  17. find_new_process_place:
  18. ;input:
  19. ;  none
  20. ;result:
  21. ;  eax=[new_process_place]<>0 - ok
  22. ;      0 - failed.
  23. ;This function find least empty slot.
  24. ;It doesn't increase [0x3004]!
  25.     mov    eax,0x3000+second_base_address
  26.     push   ebx
  27.     mov    ebx,[0x3004]
  28.     inc    ebx
  29.     shl    ebx,5
  30.     add    ebx,eax               ;ebx - address of process information for (last+1) slot
  31. .newprocessplace:
  32. ;eax = address of process information for current slot
  33.     cmp    eax,ebx
  34.     jz     .endnewprocessplace   ;empty slot after high boundary
  35.     add    eax,0x20
  36.     cmp    word [eax+0xa],9      ;check process state, 9 means that process slot is empty
  37.     jnz    .newprocessplace
  38. .endnewprocessplace:
  39.     mov    ebx,eax
  40.     sub    eax,0x3000+second_base_address
  41.     shr    eax,5                 ;calculate slot index
  42.     cmp    eax,256
  43.     jge    .failed               ;it should be <256
  44.     mov    word [ebx+0xa],9      ;set process state to 9 (for slot after hight boundary)
  45.     mov    [new_process_place],eax ;save process slot
  46.     pop    ebx
  47.     ret    
  48. .failed:
  49.     xor    eax,eax
  50.     pop    ebx
  51.     ret
  52. ;-----------------------------------------------------------------------------
  53. safe_sti:
  54.     cmp    byte [0xe000], 1
  55.     jne    @f
  56.     sti
  57.  @@:ret
  58.  
  59. new_start_application_floppy:
  60. ;input:
  61. ;  eax - pointer to filename
  62. ;  ebx - parameters to pass
  63. ;result:
  64. ;  eax - pid of new process
  65. ;        or 0 if call fails.
  66.     pushad
  67.     mov    esi,new_process_loading
  68.     call   sys_msg_board_str     ;write to debug board
  69.    
  70. ;wait application_table_status mutex
  71. .table_status:    
  72.     cli
  73.     cmp    [application_table_status],0
  74.     jz     .stf
  75.     sti
  76.     call   change_task
  77.     jmp    .table_status
  78. .stf:
  79.     call   set_application_table_status
  80. ;we can change system tables now
  81.     push   edi
  82.     push   ebx
  83.     push   eax
  84.     call   find_new_process_place ;find empty process slot
  85.     sti
  86.     test   eax,eax
  87.     jz     .failed
  88.  
  89.     mov    edi,eax
  90.     shl    edi,8
  91.     add    edi,0x80000
  92.     mov    ecx,256/4
  93.     xor    eax,eax
  94.     cld
  95.     rep    stosd                 ;clean extended information about process
  96.    
  97. ;set new process name
  98.     mov    eax,[esp+8]
  99. .find_last_byte:
  100.     cmp    byte [eax],0    
  101.     jz     .find_last_byte_end
  102.     inc    eax
  103.     jmp    .find_last_byte
  104. .find_last_byte_end:    
  105.     sub    eax,11                ;last 11 bytes = application name
  106. ;    mov    eax,[esp]             ;eax - pointer to file name
  107.     mov    ebx,[new_process_place]
  108.     shl    ebx,8
  109.     add    ebx,0x80000
  110.     mov    ecx,11
  111.     call   memmove
  112.      
  113. ;read header of file
  114.     mov    eax,[esp]
  115.     mov    ebx,1                 ;index of first block
  116.     mov    ecx,2                 ;number of blocks
  117.     mov    edx,0x90000           ;temp area
  118.     mov    esi,12                ;file name length
  119.     mov    edi,[esp+8]
  120. ;    cli
  121.     call   floppy_fileread       ;read file from FD
  122. ;    sti
  123.     cmp    eax,0
  124.     jne    .cleanfailed
  125. ;check MENUET signature    
  126.     cmp    [0x90000],dword 'MENU'
  127.     jnz    .cleanfailed
  128.     cmp    [0x90004],word 'ET'
  129.     jnz    .cleanfailed
  130.    
  131.     call   get_app_params        ;parse header fields
  132.     cmp    esi,0
  133.     jz     .cleanfailed
  134.    
  135.     mov    eax,[new_process_place]
  136.     call   create_app_cr3_table   ;create page directory for new process
  137.     test   eax,eax
  138.     jz     .cleanfailed_mem
  139.    
  140.     call   MEM_Get_Linear_Address ;calculate linear address of it
  141.    
  142.     mov    ebx,std_application_base_address
  143.     mov    ecx,[app_mem]
  144.     add    ecx,4095
  145.     shr    ecx,12
  146.     mov    edx,eax
  147.     call   mem_alloc_specified_region ;allocate memory for application
  148.     test   eax,eax
  149.     jz     .cleanfailed_mem
  150.    
  151.     mov    eax,[edx+(std_application_base_address shr 20)]
  152.     and    eax,not (4096-1)      ;eax - physical address of first (for application memory) page table
  153.     call   MEM_Get_Linear_Address
  154.     mov    edx,eax
  155.  
  156. ;read file
  157.     mov    ebx,1
  158.     mov    esi,12                ;length of file name
  159. .loop1:
  160. ;edx = linear address of current page table entry
  161. ;ebx = index of current block in file
  162.     push   edx
  163.     mov    eax,[edx]
  164.     and    eax,not (4096-1)
  165.     call   MEM_Get_Linear_Address
  166.     mov    edx,eax               ;read file block to current page
  167.     mov    eax,[esp+4]           ;restore pointer to file name
  168.     mov    ecx,8                 ;number of blocks read
  169.     push   ebx
  170.     mov    edi,[esp+16]    
  171. ;    cli
  172.     call   floppy_fileread
  173. ;ebx=file size    
  174. ;    sti
  175.     pop    ecx
  176.     shr    ebx,9
  177.     cmp    ecx,ebx
  178.     jg     .endloop1             ;if end of file?
  179.     mov    ebx,ecx
  180.     test   eax,eax              
  181.     jnz    .endloop1             ;check io errors
  182.     pop    edx
  183.     add    ebx,8                 ;go to next page
  184.     add    edx,4
  185.     jmp    .loop1
  186.    
  187. .endloop1:
  188.     add    esp,8+4                 ;pop linear address of page table entry and pointer to file name
  189.     call   new_start_application_fl.add_app_parameters
  190.     mov    [esp+28],eax
  191.     popad
  192.     ret
  193. .cleanfailed_mem:
  194.     mov    esi,start_not_enough_memory
  195.     call   sys_msg_board_str
  196. .cleanfailed:                    ;clean process name
  197.     mov    edi,[new_process_place]
  198.     shl    edi,8
  199.     add    edi,0x80000
  200.     mov    ecx,11
  201.     mov    eax,' '
  202.     cld
  203.     rep    stosb
  204. .failed:
  205.     add    esp,8+4
  206.     mov    [application_table_status],0
  207.     popad
  208.     sti
  209.     mov    eax,-1
  210.     ret  
  211.  
  212. ;-----------------------------------------------------------------------------    
  213. new_start_application_fl:
  214. ;input:
  215. ;  eax - pointer to filename
  216. ;  ebx - parameters to pass
  217. ;result:
  218. ;  eax - pid of new process
  219. ;        or 0 if call fails.
  220.     pushad
  221.     mov    esi,new_process_loading
  222.     call   sys_msg_board_str     ;write to debug board
  223.    
  224. ;wait application_table_status mutex
  225. .table_status:    
  226.     cli
  227.     cmp    [application_table_status],0
  228.     jz     .stf
  229.     sti
  230.     call   change_task
  231.     jmp    .table_status
  232. .stf:
  233.     call   set_application_table_status
  234. ;we can change system tables now    
  235.     push   ebx
  236.     push   eax
  237.     call   find_new_process_place ;find empty process slot
  238.     call   safe_sti
  239.     test   eax,eax
  240.     jz     .failed
  241.  
  242.     mov    edi,eax
  243.     shl    edi,8
  244.     add    edi,0x80000
  245.     mov    ecx,256/4
  246.     xor    eax,eax
  247.     cld
  248.     rep    stosd                 ;clean extended information about process
  249.    
  250. ;set new process name
  251.     mov    eax,[esp]             ;eax - pointer to file name
  252.     mov    ebx,[new_process_place]
  253.     shl    ebx,8
  254.     add    ebx,0x80000
  255.     mov    ecx,11
  256.     call   memmove
  257.      
  258. ;read header of file
  259.     mov    ebx,1                 ;index of first block
  260.     mov    ecx,2                 ;number of blocks
  261.     mov    edx,0x90000           ;temp area
  262.     mov    esi,12                ;file name length
  263.     cli
  264.     call   fileread              ;read file from RD
  265.     call   safe_sti
  266.     cmp    eax,0
  267.     jne    .cleanfailed
  268. ;check MENUET signature    
  269.     cmp    [0x90000],dword 'MENU'
  270.     jnz    .cleanfailed
  271.     cmp    [0x90004],word 'ET'
  272.     jnz    .cleanfailed
  273.    
  274.     call   get_app_params        ;parse header fields
  275.     cmp    esi,0
  276.     jz     .failed
  277.    
  278.     mov    eax,[new_process_place]
  279.     call   create_app_cr3_table   ;create page directory for new process
  280.     test   eax,eax
  281.     jz     .cleanfailed_mem
  282.    
  283.     call   MEM_Get_Linear_Address ;calculate linear address of it
  284.    
  285.     mov    ebx,std_application_base_address
  286.     mov    ecx,[app_mem]
  287.     add    ecx,4095
  288.     shr    ecx,12
  289.     mov    edx,eax
  290.     call   mem_alloc_specified_region ;allocate memory for application
  291.     test   eax,eax
  292.     jz     .cleanfailed_mem
  293.    
  294.     mov    eax,[edx+(std_application_base_address shr 20)]
  295.     and    eax,not (4096-1)      ;eax - physical address of first (for application memory) page table
  296.     call   MEM_Get_Linear_Address
  297.     mov    edx,eax
  298.  
  299. ;read file
  300.     mov    ebx,1
  301.     mov    esi,12                ;length of file name
  302. .loop1:
  303. ;edx = linear address of current page table entry
  304. ;ebx = index of current block in file
  305.     push   edx
  306.     mov    eax,[edx]
  307.     and    eax,not (4096-1)
  308.     call   MEM_Get_Linear_Address
  309.     mov    edx,eax               ;read file block to current page
  310.     mov    eax,[esp+4]           ;restore pointer to file name
  311.     mov    ecx,8                 ;number of blocks read
  312.     push   ebx
  313.     cli
  314.     call   fileread
  315. ;ebx=file size    
  316.     call   safe_sti
  317.     pop    ecx
  318.     shr    ebx,9
  319.     cmp    ecx,ebx
  320.     jg     .endloop1             ;if end of file?
  321.     mov    ebx,ecx
  322.     test   eax,eax              
  323.     jnz    .endloop1             ;check io errors
  324.     pop    edx
  325.     add    ebx,8                 ;go to next page
  326.     add    edx,4
  327.     jmp    .loop1
  328.    
  329. .endloop1:
  330.     add    esp,8                 ;pop linear address of page table entry and pointer to file name
  331.     call   .add_app_parameters
  332.     mov    [esp+28],eax
  333.     popad
  334.     ret
  335.    
  336. .cleanfailed_mem:
  337.     mov    esi,start_not_enough_memory
  338.     call   sys_msg_board_str
  339. .cleanfailed:                    ;clean process name
  340.     mov    edi,[new_process_place]
  341.     shl    edi,8
  342.     add    edi,0x80000
  343.     mov    ecx,11
  344.     mov    eax,' '
  345.     cld
  346.     rep    stosb
  347. .failed:
  348.     add    esp,8
  349.     mov    [application_table_status],0
  350.     popad
  351.     call   safe_sti
  352.     mov    eax,-1
  353.     ret
  354.        
  355. .add_app_parameters:
  356. ;input:
  357. ;  [esp] - pointer to parameters
  358. ;  [esp+4]-[esp+36] pushad registers.
  359. ;result
  360. ;  eax - pid of new process
  361. ;        or zero if failed
  362.     cli
  363.     mov    ebx,[new_process_place]
  364.     cmp    ebx,[0x3004]
  365.     jle    .noinc
  366.     inc    dword [0x3004]        ;update number of processes
  367. .noinc:
  368.  
  369. ;   mov    ebx,[new_process_place]
  370. ;set 0x8c field of extended information about process
  371. ;(size of application memory)
  372.     shl    ebx,8
  373.     mov    eax,[app_mem]
  374.     mov    [second_base_address+0x80000+0x8c+ebx],eax            
  375. ;set 0x10 field of information about process
  376. ;(application base address)    
  377. ;    mov    ebx,[new_process_place]
  378. ;    shl    ebx,5
  379.     shr    ebx,3
  380.     mov    dword [second_base_address+0x3000+ebx+0x10],std_application_base_address
  381.  
  382. ;add command line parameters
  383. .add_command_line:
  384.     mov    edx,[app_i_param]
  385.     test   edx,edx
  386.     jz     .no_command_line      ;application don't need parameters
  387.     mov    eax,[esp+4]
  388.     test   eax,eax
  389.     jz     .no_command_line      ;no parameters specified
  390. ;calculate parameter length    
  391.     mov    esi,eax
  392.     xor    ecx,ecx
  393. .command_line_len:
  394.     cmp    byte [esi],0
  395.     jz     .command_line_len_end
  396.     inc    esi
  397.     inc    ecx
  398.     cmp    ecx,256
  399.     jl     .command_line_len
  400.    
  401. .command_line_len_end:
  402. ;ecx - parameter length
  403. ;edx - address of parameters in new process address space
  404.     mov    ebx,eax               ;ebx - address of parameters in our address space
  405.     mov    eax,[new_process_place]
  406.     call   write_process_memory  ;copy parameters to new process address space
  407.    
  408. .no_command_line:
  409.     mov    ebx,[new_process_place]
  410.     mov    eax,ebx
  411.     shl    ebx,5
  412.     add    ebx,0x3000            ;ebx - pointer to information about process
  413.     mov    [ebx+0xe],al          ;set window number on screen = process slot
  414.    
  415.     mov    [ebx],dword 1+2+4     ;set default event flags (see 40 function)
  416.    
  417.     inc    dword [process_number]
  418.     mov    eax,[process_number]
  419.     mov    [ebx+4],eax           ;set PID
  420.    
  421.     mov    ecx,ebx
  422.     add    ecx,draw_data-0x3000  ;ecx - pointer to draw data
  423. ;set draw data to full screen    
  424.     mov    [ecx+0],dword 0      
  425.     mov    [ecx+4],dword 0
  426.     mov    eax,[0xfe00]
  427.     mov    [ecx+8],eax
  428.     mov    eax,[0xfe04]
  429.     mov    [ecx+12],eax
  430. ;set cr3 register in TSS of application    
  431.     mov    ecx,[new_process_place]    
  432.     shl    ecx,8
  433.     mov    eax,[0x800B8+ecx]
  434.     add    eax,8+16              ;add flags
  435.     mov    [l.cr3],eax
  436. ;write cr3 in TSS of System Call Handler    
  437.     mov    ecx,[new_process_place]
  438.     shl    ecx,7
  439.     mov    [0x298000+ecx+l.cr3-tss_sceleton],eax   ;write directy to TSS
  440.    
  441.     mov    eax,[app_start]
  442.     mov    [l.eip],eax           ;set eip in TSS
  443.     mov    eax,[app_esp]
  444.     mov    [l.esp],eax           ;set stack in TSS
  445.    
  446. ;gdt
  447.     ;mov    ebx,[new_process_place]
  448.     ;shl    ebx,3
  449.     mov    ax,app_code           ;ax - selector of code segment
  450.     ;add    ax,bx
  451.     mov    [l.cs],ax
  452.     mov    ax,app_data
  453.     ;add    ax,bx                 ;ax - selector of data segment
  454.     mov    [l.ss],ax
  455.     mov    [l.ds],ax
  456.     mov    [l.es],ax
  457.     mov    [l.fs],ax
  458.     mov    ax,graph_data         ;ax - selector of graphic segment
  459.     mov    [l.gs],ax
  460.     mov    [l.io],word 128
  461.     mov    [l.eflags],dword 0x11202
  462.     mov    [l.ss0],os_data
  463.     mov    ebx,[new_process_place]
  464.     shl    ebx,12
  465.     add    ebx,sysint_stack_data
  466.     mov    [l.esp0],ebx
  467.  
  468. ;copy tss to it place
  469.     mov    eax,tss_sceleton
  470.     mov    ebx,[new_process_place]
  471.     imul   ebx,tss_step
  472.     add    ebx,tss_data          ;ebx - address of application TSS
  473.     mov    ecx,120              
  474.     call   memmove
  475.    
  476. ;Add IO access table - bit array of permitted ports
  477.     or     eax,-1
  478.     mov    edi,[new_process_place]
  479.     imul   edi,tss_step
  480.     add    edi,tss_data+128
  481.     mov    ecx,2048
  482.     cld
  483.     rep    stosd                 ;full access to 2048*8=16384 ports
  484.    
  485.     mov    ecx,ebx               ;ecx - address of application TSS
  486.     mov    edi,[new_process_place]
  487.     shl    edi,3
  488. ;set TSS descriptor
  489.     mov    [edi+gdts+tss0+0],word tss_step ;limit (size)
  490.     mov    [edi+gdts+tss0+2],cx  ;part of offset
  491.     mov    eax,ecx
  492.     shr    eax,16
  493.     mov    [edi+gdts+tss0+4],al  ;part of offset
  494.     mov    [edi+gdts+tss0+7],ah  ;part of offset
  495.     mov    [edi+gdts+tss0+5],word 01010000b*256+11101001b ;system flags
  496.      
  497.  
  498. ;flush keyboard and buttons queue
  499.     mov    [0xf400],byte 0
  500.     mov    [0xf500],byte 0
  501.  
  502.     mov    edi,[new_process_place]
  503.     shl    edi,5
  504.     add    edi,window_data
  505.     mov    ebx,[new_process_place]
  506.     movzx  esi,word [0xC000+ebx*2]
  507.     lea    esi,[0xC400+esi*2]
  508.     call   windowactivate        ;gui initialization
  509.  
  510.     mov    ebx,[new_process_place]
  511.     shl    ebx,5
  512.     mov    [0x3000+ebx+0xa],byte 0 ;set process state - running
  513.    
  514.     mov    esi,new_process_running
  515.     call   sys_msg_board_str     ;output information about succefull startup
  516.    
  517. ;    add    esp,4                 ;pop pointer to parameters
  518. ;    popad
  519.     mov    eax,[process_number]  ;set result
  520.     mov    [application_table_status],0 ;unlock application_table_status mutex
  521.     call   safe_sti
  522.     ret    4
  523. ;-----------------------------------------------------------------------------    
  524. new_sys_threads:
  525. ;eax=1 - create thread
  526. ;   ebx=thread start
  527. ;   ecx=thread stack value
  528. ;result:
  529. ;   eax=pid
  530.     pushad
  531.    
  532.     cmp    eax,1
  533.     jnz    .ret                  ;other subfunctions
  534.     mov    esi,new_process_loading
  535.     call   sys_msg_board_str
  536. ;lock application_table_status mutex
  537. .table_status:    
  538.     cli
  539.     cmp    [application_table_status],0
  540.     je     .stf
  541.     sti
  542.     call   change_task
  543.     jmp    .table_status
  544. .stf:
  545.     call   set_application_table_status
  546. ;find free process slot
  547.  
  548.     call   find_new_process_place
  549.     test   eax,eax
  550.     jz     .failed
  551.    
  552. ;set parameters for thread
  553.     xor    eax,eax
  554.     mov    [app_i_param],eax
  555.     mov    [app_i_icon],eax
  556.     mov    [app_start],ebx
  557.     mov    [app_esp],ecx
  558.  
  559.     mov    esi,[0x3000]
  560.     shl    esi,8
  561.     add    esi,0x80000
  562.     mov    ebx,esi               ;ebx=esi - pointer to extended information about current thread
  563.    
  564.     mov    edi,[new_process_place]
  565.     shl    edi,8
  566.     add    edi,0x80000
  567.     mov    edx,edi               ;edx=edi - pointer to extended infomation about new thread
  568.     mov    ecx,256/4
  569.     rep    stosd                 ;clean extended information about new thread
  570.     mov    edi,edx
  571.     mov    ecx,11
  572.     rep    movsb                 ;copy process name
  573.     mov    eax,[ebx+0x8c]
  574.     mov    [app_mem],eax         ;set memory size
  575.     mov    eax,[ebx+0xb8]
  576.     mov    [edx+0xb8],eax        ;copy page directory
  577. ;    mov    eax,[new_process_place]
  578. ;    mov    ebx,[0x3000]
  579. ;    call   addreference_app_cr3_table
  580.  
  581.     push   0                     ;no parameters
  582.     call    new_start_application_fl.add_app_parameters ;start thread
  583.     mov    [esp+28],eax
  584.     popad
  585.     ret
  586.    
  587. .failed:
  588.     sti
  589.     popad
  590.     mov    eax,-1
  591.     ret    
  592. .ret:
  593.     popad
  594.     ret
  595. ;-----------------------------------------------------------------------------    
  596. new_mem_resize:
  597. ;input:
  598. ;  ebx - new size
  599. ;result:
  600. ;  [esp+36]:=0 - normal
  601. ;  [esp+36]:=1 - error
  602. ;This function set new application memory size.
  603.     mov    esi,ebx               ;save new size
  604.     add    ebx,4095
  605.     and    ebx,not (4096-1)      ;round up size
  606.     mov    ecx,[0x3000]
  607.     shl    ecx,8
  608.     mov    edx,[0x8008C+ecx]    
  609.     add    edx,4095
  610.     and    edx,not (4096-1)      ;old size
  611.     mov    eax,[0x800B8+ecx]
  612.     call   MEM_Get_Linear_Address
  613. ;eax - linear address of page directory    
  614.     call   MEM_Heap_Lock         ;guarantee that two threads willn't
  615.                                  ;change memory size simultaneously
  616.     cmp    ebx,edx
  617. ;    mov    esi,ebx               ;save new size
  618.     jg     .expand
  619.    
  620. .free:
  621.     sub    edx,ebx
  622.     jz     .unlock               ;do nothing
  623.     mov    ecx,edx
  624.     shr    ecx,12
  625.     add    ebx,std_application_base_address
  626.     call   mem_free_specified_region  ;free unnecessary pages
  627.     jmp    .unlock
  628.  
  629. .expand:
  630.     sub    ebx,edx
  631.     mov    ecx,ebx
  632.     shr    ecx,12
  633.     mov    ebx,edx
  634.     add    ebx,std_application_base_address
  635.     call   mem_alloc_specified_region ;alloc necessary pages
  636.     test   eax,eax
  637.     jz     .failed               ;not enough memory
  638.    
  639. .unlock:
  640.     mov    ebx,esi
  641.     mov    eax,[0x3000]
  642.     shl    eax,8
  643.     mov    [eax+0x8008c],ebx     ;write new memory size
  644. ;search threads and update
  645. ;application memory size infomation    
  646.     mov    ecx,[eax+0x800b8]
  647.     mov    eax,2
  648.    
  649. .search_threads:
  650. ;eax = current slot
  651. ;ebx = new memory size
  652. ;ecx = page directory
  653.     cmp    eax,[0x3004]
  654.     jg     .search_threads_end
  655.     mov    edx,eax
  656.     shl    edx,5
  657.     cmp    word [0x3000+edx+0xa],9 ;if slot empty?
  658.     jz     .search_threads_next
  659.     shl    edx,3
  660.     cmp    [edx+0x800b8],ecx     ;if it is our thread?
  661.     jnz    .search_threads_next
  662.     mov    [edx+0x8008c],ebx     ;update memory size
  663. .search_threads_next:
  664.     inc    eax
  665.     jmp    .search_threads
  666. .search_threads_end:
  667.  
  668.     call   MEM_Heap_UnLock
  669.     mov    dword [esp+36],0
  670.     ret
  671.    
  672. .failed:
  673.     call   MEM_Heap_UnLock
  674.     mov    dword [esp+36],1
  675.     ret    
  676. ;-----------------------------------------------------------------------------
  677. pid_to_slot:
  678. ;Input:
  679. ;  eax - pid of process
  680. ;Output:
  681. ;  eax - slot of process or 0 if process don't exists
  682. ;Search process by PID.
  683.     push   ebx
  684.     push   ecx
  685.     mov    ebx,[0x3004]
  686.     shl    ebx,5
  687.     mov    ecx,2*32
  688.    
  689. .loop:
  690. ;ecx=offset of current process info entry
  691. ;ebx=maximum permitted offset
  692.     cmp    byte [second_base_address+0x3000+ecx+0xa],9
  693.     jz     .endloop              ;skip empty slots
  694.     cmp    [second_base_address+0x3000+ecx+0x4],eax ;check PID
  695.     jz     .pid_found
  696. .endloop:
  697.     add    ecx,32
  698.     cmp    ecx,ebx
  699.     jle    .loop
  700.    
  701.     pop    ecx
  702.     pop    ebx
  703.     xor    eax,eax
  704.     ret
  705.    
  706. .pid_found:
  707.     shr    ecx,5
  708.     mov    eax,ecx               ;convert offset to index of slot
  709.     pop    ecx
  710.     pop    ebx
  711.     ret
  712. ;-----------------------------------------------------------------------------    
  713. is_new_process:
  714. ;Input:
  715. ;  eax - process slot
  716. ;Output:
  717. ;  eax=1 - it is new process
  718. ;  eax=0 - it is old process
  719. ;    shl   eax,5
  720. ;    mov   eax,[second_base_address+0x3000+eax+0x10]
  721. ;    cmp   eax,std_application_base_address  ;check base address of application
  722. ;    jz    .new_process
  723. ;    xor   eax,eax
  724. ;    ret
  725.    
  726. ;.new_process:
  727.     mov   eax,1
  728.     ret
  729. ;-----------------------------------------------------------------------------    
  730. write_process_memory:
  731. ;Input:
  732. ;  eax - process slot
  733. ;  ebx - buffer address
  734. ;  ecx - buffer size
  735. ;  edx - start address in other process
  736. ;Output:
  737. ;  eax - number of bytes written
  738.     pushad
  739.     shl  eax,8
  740.     mov  eax,[0x80000+eax+0xB8]
  741.     call MEM_Get_Linear_Address
  742.     mov  ebp,eax
  743. ;ebp=linear address of page directory of other process.    
  744.     add  edx,std_application_base_address  ;convert to linear address
  745.     test ecx,ecx
  746.     jle  .ret
  747.    
  748. .write_loop:
  749. ;ebx = current buffer address
  750. ;ecx>0 = current size
  751. ;edx = current address in other process
  752. ;ebp = linear address of page directory
  753.  
  754.     call MEM_Heap_Lock           ;cli
  755.     mov  esi,edx
  756.     shr  esi,22
  757.     mov  eax,[ebp+4*esi]         ;find page directory entry
  758.     and  eax,not (4096-1)        ;clear flags
  759.     test eax,eax
  760.     jz   .page_not_found
  761.     call MEM_Get_Linear_Address  ;calculate linear address of page table
  762.     test eax,eax
  763.     jz   .page_not_found
  764.     mov  esi,edx
  765.     shr  esi,12
  766.     and  esi,1023                
  767.     mov  eax,[eax+4*esi]         ;find page table entry
  768.     and  eax,not (4096-1)
  769.     test eax,eax
  770.     jz   .page_not_found
  771.     call MEM_Get_Linear_Address  ;calculate linear address of page
  772.     test eax,eax
  773.     jz   .page_not_found
  774.     mov  edi,eax
  775.     call MEM_Add_Reference_Linear;guarantee that page willn't disappear
  776.     call MEM_Heap_UnLock         ;sti
  777.    
  778.     mov  esi,edx
  779.     and  esi,4095
  780.     add  edi,esi                 ;add offset in page
  781. ;edi = linear address corresponding edx in other process
  782.     sub  esi,4096
  783.     neg  esi                     ;esi - number of remaining bytes in page
  784.     cmp  esi,ecx
  785.     jl   .min_ecx
  786.     mov  esi,ecx
  787. .min_ecx:                        ;esi=min(ecx,esi) - number of bytes to write
  788.     sub  ecx,esi
  789.     push ecx
  790.     mov  ecx,esi                 ;ecx - number of bytes to write
  791.     mov  esi,ebx                 ;esi - source, edi - destination
  792.     add  edx,ecx                 ;move pointer in address space of other process
  793.     push edi
  794.    
  795. ;move ecx bytes    
  796.     test ecx,3
  797.     jnz  .not_aligned
  798.     shr  ecx,2
  799.     rep  movsd
  800.     jmp  .next_iter
  801. .not_aligned:
  802.     rep  movsb
  803. .next_iter:
  804.  
  805.     pop  eax                    
  806.     and  eax,not (4096-1)        ;eax - linear address of current page
  807.     call MEM_Free_Page_Linear    ;free reference
  808.     mov  ebx,esi                 ;new pointer to buffer - movsb automaticaly advance it.
  809.     pop  ecx                     ;restore number of remaining bytes
  810.     test ecx,ecx
  811.     jnz  .write_loop
  812. .ret:    
  813.     popad
  814.     mov  eax,ecx
  815.     ret
  816.    
  817. .page_not_found:
  818.     call MEM_Heap_UnLock         ;error has appeared in critical region
  819.     sub  ecx,[esp+24]            ;[esp+24]<-->ecx
  820.     neg  ecx                     ;ecx=number_of_written_bytes
  821.     mov  [esp+28],ecx            ;[esp+28]<-->eax
  822.     popad
  823.     ret    
  824. ;-----------------------------------------------------------------------------    
  825. syscall_test:
  826. ;for testing memory manager from applications.
  827.     mov  edx,ecx
  828.     mov  ecx,ebx
  829.     call trans_address
  830.     mov  ebx,eax
  831.     mov  eax,[0x3000]
  832.     call read_process_memory
  833.     ret
  834. ;-----------------------------------------------------------------------------    
  835. read_process_memory:
  836. ;Input:
  837. ;  eax - process slot
  838. ;  ebx - buffer address
  839. ;  ecx - buffer size
  840. ;  edx - start address in other process
  841. ;Output:
  842. ;  eax - number of bytes read.
  843.     pushad
  844.     shl  eax,8
  845.     mov  eax,[0x80000+eax+0xB8]
  846.     call MEM_Get_Linear_Address
  847.     mov  ebp,eax
  848.     add  edx,std_application_base_address
  849. .read_loop:
  850. ;ebx = current buffer address
  851. ;ecx>0 = current size
  852. ;edx = current address in other process
  853. ;ebp = linear address of page directory
  854.  
  855.     call MEM_Heap_Lock           ;cli
  856.     mov  esi,edx
  857.     shr  esi,22
  858.     mov  eax,[ebp+4*esi]         ;find page directory entry
  859.     and  eax,not (4096-1)
  860.     test eax,eax
  861.     jz   .page_not_found
  862.     call MEM_Get_Linear_Address
  863.     test eax,eax
  864.     jz   .page_not_found
  865.     mov  esi,edx
  866.     shr  esi,12
  867.     and  esi,1023
  868.     mov  eax,[eax+4*esi]         ;find page table entry
  869.     and  eax,not (4096-1)
  870.     test eax,eax
  871.     jz   .page_not_found
  872.     call MEM_Get_Linear_Address  ;calculate linear address of page
  873.     test eax,eax
  874.     jz   .page_not_found
  875.     mov  esi,eax
  876.     call MEM_Add_Reference_Linear;guarantee that page willn't disappear
  877.     call MEM_Heap_UnLock         ;sti
  878.    
  879.     mov  edi,edx
  880.     and  edi,4095                
  881.     add  esi,edi                 ;add offset in page
  882. ;esi = linear address corresponding edx in other process
  883.     sub  edi,4096
  884.     neg  edi
  885.    
  886. ;edi=min(edi,ecx) - number of bytes to copy  
  887.     cmp  edi,ecx
  888.     jl   .min_ecx
  889.     mov  edi,ecx
  890. .min_ecx:
  891.  
  892.     sub  ecx,edi                 ;update size of remaining bytes
  893.     add  edx,edi                 ;update current pointer in other address space.
  894.     push ecx
  895.     mov  ecx,edi                 ;ecx - number of bytes to read
  896.     mov  edi,ebx                 ;esi - source, edi - destination
  897.     push esi
  898. ;move ecx bytes    
  899.     test ecx,3
  900.     jnz  .not_aligned
  901.     shr  ecx,2
  902.     rep  movsd
  903.     jmp  .next_iter
  904. .not_aligned:
  905.     rep  movsb
  906. .next_iter:
  907.     pop  eax
  908.     and  eax,not (4096-1)        ;eax - linear address of current page
  909.     call MEM_Free_Page_Linear    ;free reference
  910.     mov  ebx,edi                 ;new pointer to buffer - movsb automaticaly advance it.
  911.     pop  ecx                     ;restore number of remaining bytes
  912.     test ecx,ecx
  913.     jnz  .read_loop
  914.    
  915.     popad
  916.     mov  eax,ecx
  917.     ret
  918.    
  919. .page_not_found:
  920.     call MEM_Heap_UnLock         ;error has appeared in critical region
  921.     sub  ecx,[esp+24]            ;[esp+24]<-->ecx
  922.     neg  ecx                     ;ecx=number_of_read_bytes
  923.     mov  [esp+28],ecx            ;[esp+28]<-->eax
  924.     popad
  925.     ret
  926. ;-----------------------------------------------------------------------------
  927. check_region:
  928. ;input:
  929. ;  ebx - start of buffer
  930. ;  ecx - size of buffer
  931. ;result:
  932. ;  eax = 1 region lays in app memory
  933. ;  eax = 0 region don't lays in app memory
  934.     mov  eax,[0x3000]
  935.     jmp  check_process_region
  936. ;-----------------------------------------------------------------------------    
  937. check_process_region:
  938. ;input:
  939. ;  eax - slot
  940. ;  ebx - start of buffer
  941. ;  ecx - size of buffer
  942. ;result:
  943. ;  eax = 1 region lays in app memory
  944. ;  eax = 0 region don't lays in app memory
  945.     test ecx,ecx
  946.     jle  .ok
  947.     shl  eax,5
  948.     cmp  word [0x3000+eax+0xa],0
  949.     jnz  .failed
  950.     shl  eax,3
  951.     mov  eax,[0x80000+eax+0xb8]
  952.     test eax,eax
  953.     jz   .failed
  954.     call MEM_Get_Linear_Address
  955.     push ebx
  956.     push ecx
  957.     push edx
  958.     mov  edx,ebx
  959.     and  edx,not (4096-1)
  960.     sub  ebx,edx
  961.     add  ecx,ebx
  962.     mov  ebx,edx
  963.     add  ecx,(4096-1)
  964.     and  ecx,not (4096-1)
  965. .loop:
  966. ;eax - linear address of page directory    
  967. ;ebx - current page
  968. ;ecx - current size
  969.     mov  edx,ebx
  970.     shr  edx,22
  971.     mov  edx,[eax+4*edx]
  972.     and  edx,not (4096-1)
  973.     test edx,edx
  974.     jz   .failed1
  975.     push eax
  976.     mov  eax,edx
  977.     call MEM_Get_Linear_Address
  978.     mov  edx,ebx
  979.     shr  edx,12
  980.     and  edx,(1024-1)
  981.     mov  eax,[eax+4*edx]
  982.     and  eax,not (4096-1)
  983.     test eax,eax
  984.     pop  eax
  985.     jz   .failed1
  986.     add  ebx,4096
  987.     sub  ecx,4096
  988.     jg   .loop
  989.     pop  edx
  990.     pop  ecx
  991.     pop  ebx
  992. .ok:
  993.     mov  eax,1
  994.     ret
  995.    
  996. .failed1:
  997.     pop  edx
  998.     pop  ecx
  999.     pop  ebx
  1000. .failed:
  1001.     xor  eax,eax
  1002.     ret
  1003. ;-----------------------------------------------------------------------------
  1004. new_sys_ipc:
  1005. ;input:
  1006. ;  eax=1 - set ipc buffer area
  1007. ;    ebx=address of buffer
  1008. ;    ecx=size of buffer
  1009. ;  eax=2 - send message
  1010. ;    ebx=PID
  1011. ;    ecx=address of message
  1012. ;    edx=size of message
  1013.     cmp  eax,1
  1014.     jnz  .no_ipc_def
  1015. ;set ipc buffer area    
  1016.     mov  edi,[0x3000]
  1017.     shl  edi,8
  1018.     add  edi,0x80000
  1019.     cli
  1020.     mov  [edi+0xA0],ebx          ;set fields in extended information area
  1021.     mov  [edi+0xA4],ecx
  1022.     sti
  1023.     mov  [esp+36],dword 0        ;success
  1024.     ret
  1025.        
  1026. .no_ipc_def:
  1027.     cmp  eax,2
  1028.     jnz  .no_ipc_send
  1029. ;send message    
  1030.     cli
  1031. ;obtain slot from PID    
  1032.     mov  eax,ebx
  1033.     call pid_to_slot
  1034.     test eax,eax
  1035.     jz   .no_pid
  1036.     mov  ebp,eax
  1037. ;ebp = slot of other process    
  1038.     shl  eax,8
  1039.     mov  edi,[eax+0x80000+0xa0]  ;is ipc area defined?
  1040.     test edi,edi
  1041.     jz   .no_ipc_area
  1042.     mov  esi,[eax+0x80000+0xa4]  ;esi - size of buffer
  1043.     push dword -1                ;temp variable for read_process_memory
  1044.     mov  ebx,esp
  1045.     push ecx
  1046.     push edx
  1047.     mov  ecx,4                   ;read 4 bytes
  1048.     mov  eax,ebp
  1049.     mov  edx,edi                 ;from beginning of buffer.
  1050.     call read_process_memory
  1051.     mov  eax,[esp+8]
  1052.     test eax,eax
  1053.     jnz  .ipc_blocked            ;if dword [buffer]<>0 - ipc blocked now
  1054.     add  edx,4                   ;move to next 4 bytes
  1055.     mov  eax,ebp
  1056.     call read_process_memory     ;read size of occupied space in buffer
  1057.     sub  esi,8
  1058.     sub  esi,[esp]
  1059.     sub  esi,[esp+8]             ;esi=(buffer size)-(occupied size)-(message size)-(header of message size)
  1060.     js   .buffer_overflow        ;esi<0 - not enough memory in buffer
  1061.     mov  esi,[esp+8]             ;previous offset
  1062.     add  dword [esp+8],8
  1063.     mov  edi,[esp]
  1064.     add  [esp+8],edi             ;add (size of message)+(size of header of message) to [buffer+4]
  1065.     mov  eax,ebp
  1066.     call write_process_memory
  1067.     add  edx,esi                
  1068.     sub  edx,4                   ;move to beginning of place for our message
  1069.     mov  eax,[second_base_address+0x3010]
  1070.     mov  eax,[eax+0x4]           ;eax - our PID
  1071.     mov  [esp+8],eax
  1072.     mov  eax,ebp
  1073.     call write_process_memory    ;write PID
  1074.     mov  ebx,esp                 ;address of size of message
  1075.     mov  eax,ebp
  1076.     add  edx,4
  1077.     call write_process_memory    ;write size of message
  1078.     add  edx,4
  1079.     pop  ecx                     ;ecx - size of message
  1080.     pop  eax
  1081.     call trans_address
  1082.     mov  ebx,eax                 ;ebx - linear address of message
  1083.     add  esp,4                   ;pop temporary variable
  1084.     mov  eax,ebp
  1085.     call write_process_memory    ;write message
  1086.     sti
  1087. ;awake other process    
  1088.     shl  ebp,8
  1089.     mov  eax,ebp
  1090.     or   [eax+0x800A8],dword 0x40
  1091.    
  1092.     cmp  dword [check_idle_semaphore],20
  1093.     jge  .ipc_no_cis
  1094.     mov  dword [check_idle_semaphore],5
  1095. .ipc_no_cis:
  1096.     mov  dword [esp+36],0
  1097.     ret
  1098. .no_ipc_send:
  1099.     mov  dword [esp+36],-1
  1100.     ret
  1101. .no_pid:
  1102.     sti
  1103.     mov  dword [esp+36],4
  1104.     ret
  1105. .no_ipc_area:
  1106.     sti
  1107.     mov  dword [esp+36],1
  1108.     ret
  1109. .ipc_blocked:
  1110.     sti
  1111.     add  esp,12
  1112.     mov  dword [esp+36],2
  1113.     ret
  1114. .buffer_overflow:
  1115.     sti
  1116.     add  esp,12
  1117.     mov  dword [esp+36],3
  1118.     ret
  1119. ;-----------------------------------------------------------------------------    
  1120. trans_address:
  1121. ;Input
  1122. ;  eax - application address
  1123. ;Output
  1124. ;  eax - linear address for kernel      
  1125.     add   eax,std_application_base_address
  1126.     ret
  1127. ;-----------------------------------------------------------------------------    
  1128. new_start_application_hd:
  1129. ;eax - file name (kernel address)
  1130. ;ebx - file name length
  1131. ;ecx - work area (kernel address)
  1132. ;ebp - parameters
  1133.     pushad
  1134.    
  1135.     mov    esi,new_process_loading
  1136.     call   sys_msg_board_str     ;write message to message board
  1137.    
  1138. ;lock application_table_status mutex
  1139. .table_status:
  1140.     cli
  1141.     cmp    [application_table_status],0
  1142.     jz     .stf
  1143.     sti
  1144.     call   change_task
  1145.     jmp    .table_status
  1146. .stf:
  1147.     call   set_application_table_status
  1148.    
  1149.     push   ebp
  1150.     push   ebx
  1151.     push   eax
  1152.     push   ecx
  1153.     call   find_new_process_place ;find new process slot
  1154.     sti
  1155.     test   eax,eax
  1156.     jz     .failed
  1157.    
  1158. ;write application name    
  1159.     mov    eax,[esp+4]
  1160. .find_last_byte:
  1161.     cmp    byte [eax],0    
  1162.     jz     .find_last_byte_end
  1163.     inc    eax
  1164.     jmp    .find_last_byte
  1165. .find_last_byte_end:    
  1166.     lea    esi,[eax-11]          ;last 11 bytes = application name
  1167.     mov    edi,[new_process_place]
  1168.     shl    edi,8
  1169.     add    edi,0x80000
  1170.     mov    ecx,11
  1171.     cld
  1172.     rep    movsb                 ;copy name to extended information about process
  1173.    
  1174. ;read header    
  1175.     mov    eax,[esp+4]           ;file name
  1176.     mov    esi,[esp]             ;work area
  1177.     mov    ecx,1                 ;read from first block
  1178.     mov    edx,1                 ;read 1 block
  1179.     call   read_hd_file
  1180.     test   eax,eax
  1181.     jnz    .cleanfailed
  1182.  
  1183.     mov    esi,[esp]
  1184. ;check menuet signature    
  1185.     cmp    [esi+1024+0],dword 'MENU'  ;read_hd_file function write file to +1024 offset
  1186.     jnz    .cleanfailed
  1187.     cmp    [esi+1024+4],word 'ET'
  1188.     jnz    .cleanfailed
  1189.     add    esi,1024
  1190.     mov    edi,0x90000
  1191.     mov    ecx,512/4
  1192.     cld
  1193.     rep    movsd                 ;copy first block to 0x90000 address for get_app_params function
  1194.     call   get_app_params
  1195.     test   esi,esi
  1196.     jz     .cleanfailed
  1197.    
  1198.     mov    eax,[new_process_place]
  1199.     call   create_app_cr3_table  ;create page directory
  1200.     test   eax,eax
  1201.     jz     .cleanfailed_mem
  1202.    
  1203.     call   MEM_Get_Linear_Address
  1204.    
  1205.     mov    ebx,std_application_base_address
  1206.     mov    ecx,[app_mem]
  1207.     add    ecx,4096-1
  1208.     shr    ecx,12
  1209.     mov    edx,eax               ;edx - linear address of page directory
  1210.     call   mem_alloc_specified_region ;allocate memory for application
  1211.     test   eax,eax
  1212.     jz     .cleanfailed_mem
  1213.    
  1214.     add    edx,(std_application_base_address shr 20)
  1215.     mov    eax,[edx]
  1216.     and    eax,not (4096-1)
  1217.     call   MEM_Get_Linear_Address
  1218.     push   edx                   ;save pointer to first page table
  1219.     mov    edx,eax
  1220. ;read file
  1221.     mov    ecx,1
  1222.     xor    ebp,ebp
  1223. .loop1:
  1224. ;[esp] - pointer to current page directory entry
  1225. ;edx - pointer to current page table
  1226. ;ebp - offset in page
  1227. ;ecx - current cluster
  1228.     push   edx
  1229.     mov    eax,[esp+12]          ;file name
  1230.     mov    ebx,[esp+16]          ;file name length
  1231.     mov    esi,[esp+8]           ;work area
  1232.     mov    edx,1                 ;number of blocks to read
  1233.     push   ecx
  1234.     push   ebp
  1235.     cli
  1236.     call   read_hd_file
  1237.     sti
  1238.     pop    ebp
  1239.     test   eax,eax
  1240.     jnz    .endloop1             ;check io errors
  1241.    
  1242.     mov    esi,[esp+8+4]         ;work area
  1243.     add    esi,1024
  1244.     mov    eax,[esp+4]           ;current page table
  1245.     mov    eax,[eax]
  1246.     and    eax,not (4096-1)        
  1247.     call   MEM_Get_Linear_Address;calculate linear page address
  1248.     lea    edi,[eax+ebp]         ;add page offset
  1249.     mov    ecx,512/4
  1250.     cld
  1251.     rep    movsd                 ;copy data
  1252.    
  1253.     pop    ecx
  1254.     inc    ecx                   ;next block
  1255.     mov    eax,[app_i_end] ;todo: precalculate ([app_i_end]+4095)/4096
  1256.     add    eax,512-1
  1257.     shr    eax,9                 ;calculate application image size
  1258.     cmp    ecx,eax
  1259.     jg     .endloop11
  1260.     pop    edx
  1261.     add    ebp,512               ;new offset
  1262.     test   ebp,4096
  1263.     jz     .loop1
  1264.     xor    ebp,ebp
  1265.     add    edx,4                 ;go to next page
  1266.     test   edx,(4096-1)
  1267.     jnz    .loop1
  1268.     add    dword [esp],4         ;go to next directory entry
  1269.     mov    eax,[esp]
  1270.     mov    eax,[eax]
  1271.     and    eax,not (4096-1)
  1272.     call   MEM_Get_Linear_Address
  1273.     mov    edx,eax
  1274.     jmp    .loop1
  1275. .endloop1:
  1276.     add    esp,4                 ;pop ecx
  1277. .endloop11:
  1278.     add    esp,4+4               ;pop edx, pop edx
  1279.    
  1280. ;add_app_parameters
  1281.     add    esp,12                ;now pointer to parameters is on the top of the stack
  1282.     call   new_start_application_fl.add_app_parameters ;start process
  1283.     mov    [esp+28],eax
  1284.     popad
  1285.     ret
  1286.    
  1287. .cleanfailed_mem:
  1288.     mov    esi,start_not_enough_memory
  1289.     call   sys_msg_board_str    
  1290. .cleanfailed:                    ;clean process name
  1291.     mov    edi,[new_process_place]
  1292.     shl    edi,8
  1293.     add    edi,0x80000
  1294.     mov    ecx,11
  1295.     mov    eax,' '
  1296.     cld
  1297.     rep    stosb    
  1298. .failed:
  1299.     add    esp,16
  1300.     popad  
  1301.     mov    eax,-1
  1302.     mov    [application_table_status],0
  1303.     sti
  1304.     ret
  1305. end if
  1306.