Subversion Repositories Kolibri OS

Rev

Rev 133 | 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+TASKDATA.state],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+TASKDATA.state],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. ;  edx - flags
  64. ;result:
  65. ;  eax - pid of new process
  66. ;        or 0 if call fails.
  67.     mov    [appl_path],edi
  68.     pushad
  69.     mov    esi,new_process_loading
  70.     call   sys_msg_board_str     ;write to debug board
  71.    
  72. ;wait application_table_status mutex
  73. .table_status:    
  74.     cli
  75.     cmp    [application_table_status],0
  76.     jz     .stf
  77.     sti
  78.     call   change_task
  79.     jmp    .table_status
  80. .stf:
  81.     call   set_application_table_status
  82. ;we can change system tables now
  83.     push   edi
  84.     push   ebx
  85.     push   eax
  86.     call   find_new_process_place ;find empty process slot
  87.     sti
  88.     test   eax,eax
  89.         mov     ecx, -0x20      ; too many processes
  90.     jz     .failed
  91.  
  92.     mov    edi,eax
  93.     shl    edi,8
  94.     add    edi,0x80000
  95.     mov    ecx,256/4
  96.     xor    eax,eax
  97.     cld
  98.     rep    stosd                 ;clean extended information about process
  99.    
  100. ;set new process name
  101.     mov    [appl_path_size],eax
  102.     pop    eax
  103.     push   eax
  104. .find_last_byte:
  105.     cmp    byte [eax],0    
  106.     jz     .find_last_byte_end
  107.     inc    eax
  108.     inc    [appl_path_size]
  109.     jmp    .find_last_byte
  110. .find_last_byte_end:
  111.     add    [appl_path_size],24    
  112.     sub    eax,11                ;last 11 bytes = application name
  113. ;    mov    eax,[esp]             ;eax - pointer to file name
  114.     mov    ebx,[new_process_place]
  115.     shl    ebx,8
  116.     add    ebx,0x80000 + APPDATA.app_name
  117.     mov    ecx,11
  118.     call   memmove
  119.      
  120. ;read header of file
  121.     mov    eax,[esp]
  122.     mov    ebx,1                 ;index of first block
  123.     mov    ecx,2                 ;number of blocks
  124.     mov    edx,0x90000           ;temp area
  125.     mov    esi,12                ;file name length
  126.     mov    edi,[esp+8]
  127. ;    cli
  128.     call   floppy_fileread       ;read file from FD
  129. ;    sti
  130.         mov     ecx, eax
  131.         neg     ecx
  132.         jnz     .cleanfailed
  133. ;check MENUET signature
  134.         mov     ecx, -0x1F      ; not Menuet/Kolibri executable
  135.     cmp    [0x90000],dword 'MENU'
  136.     jnz    .cleanfailed
  137.     cmp    [0x90004],word 'ET'
  138.     jnz    .cleanfailed
  139.    
  140.     call   get_app_params        ;parse header fields
  141.     jc     .cleanfailed
  142.    
  143.     mov    eax,[new_process_place]
  144.         inc     ecx             ; -0x1E = no memory
  145.     call   create_app_cr3_table   ;create page directory for new process
  146.     test   eax,eax
  147.     jz     .cleanfailed_mem
  148.    
  149.     call   MEM_Get_Linear_Address ;calculate linear address of it
  150.    
  151.     mov    ebx,std_application_base_address
  152.     mov    ecx,[app_mem]
  153.     add    ecx,4095
  154.     shr    ecx,12
  155.     mov    edx,eax
  156.     call   mem_alloc_specified_region ;allocate memory for application
  157.     test   eax,eax
  158.         mov     ecx, -0x1E
  159.     jz     .cleanfailed_mem1
  160.    
  161.     mov    eax,[edx+(std_application_base_address shr 20)]
  162.     and    eax,not (4096-1)      ;eax - physical address of first (for application memory) page table
  163.     call   MEM_Get_Linear_Address
  164.     mov    edx,eax
  165.  
  166. ;read file
  167.     mov    ebx,1
  168.     mov    esi,12                ;length of file name
  169. .loop1:
  170. ;edx = linear address of current page table entry
  171. ;ebx = index of current block in file
  172.     push   edx
  173.     mov    eax,[edx]
  174.     and    eax,not (4096-1)
  175.     call   MEM_Get_Linear_Address
  176.     mov    edx,eax               ;read file block to current page
  177.     mov    eax,[esp+4]           ;restore pointer to file name
  178.     mov    ecx,8                 ;number of blocks read
  179.     mov    ebp,edx               ;save buffer address for .endofimage
  180.     push   ebx
  181.     mov    edi,[esp+16]    
  182. ;    cli
  183.     call   floppy_fileread
  184. ;ebx=file size    
  185. ;    sti
  186.     pop    ecx
  187.     add    ecx,8
  188.     test   eax,eax
  189.     jnz    .endloop1             ;check io errors
  190.     mov    eax,[app_i_end]
  191.     add    eax,511
  192.     shr    eax,9
  193.     cmp    ecx,eax
  194.     jg     .endofimage           ;we have loaded whole program
  195.     add    ebx,511
  196.     shr    ebx,9
  197.     cmp    ecx,ebx
  198.     jg     .endloop1             ;if end of file?
  199.     mov    ebx,ecx
  200.     pop    edx
  201.     add    edx,4
  202.     jmp    .loop1
  203.    
  204. .endofimage:                     ;set to zero memory at end of page
  205.     mov    ecx,[app_i_end]
  206.     and    ecx,4096-1
  207.     jz     .endloop1
  208.     lea    edi,[ebp+ecx]
  209.     neg    ecx
  210.     add    ecx,4096
  211.     xor    eax,eax
  212.     cld
  213.     rep    stosb
  214. .endloop1:
  215.     add    esp,8+4                 ;pop linear address of page table entry and pointer to file name
  216.     call   new_start_application_fl.add_app_parameters
  217.     mov    [esp+28],eax
  218.     popad
  219.     ret
  220.    
  221. .cleanfailed_mem1:
  222. ;there is mem for directory entry, but there is no mem for pages
  223. ;so free directory entry
  224.     mov    eax,[new_process_place]    
  225.     shl    eax,8
  226.     mov    eax,[0x80000+eax+APPDATA.dir_table]
  227.     call   MEM_Free_Page    
  228. .cleanfailed_mem:
  229. ;there is no mem for directory entry, display message.
  230.     mov    esi,start_not_enough_memory
  231.     call   sys_msg_board_str
  232. .cleanfailed:                    ;clean process name
  233.         push    ecx     ; save error code
  234. ;can't read file, clean process name.
  235. ;this avoid problems with panel application.
  236.     mov    edi,[new_process_place]
  237.     shl    edi,8
  238.     add    edi,0x80000 + APPDATA.app_name
  239.     mov    ecx,11
  240.     mov    eax,' '
  241.     cld
  242.     rep    stosb
  243.         pop     eax
  244. .failed:
  245. ;no more slots
  246.     add    esp,8+4
  247.     mov    [application_table_status],0
  248.     mov    [esp+1Ch], eax
  249.     popad
  250.     sti
  251.     ret  
  252.  
  253. ;-----------------------------------------------------------------------------    
  254. new_start_application_fl:
  255. ;input:
  256. ;  eax - pointer to filename
  257. ;  ebx - parameters to pass
  258. ;  edx - flags
  259. ;result:
  260. ;  eax - pid of new process
  261. ;        or 0 if call fails.
  262.     mov    [appl_path],edi
  263.     mov    [appl_path_size],36
  264.     pushad
  265.     mov    esi,new_process_loading
  266.     call   sys_msg_board_str     ;write to debug board
  267.    
  268. ;wait application_table_status mutex
  269. .table_status:    
  270.     cli
  271.     cmp    [application_table_status],0
  272.     jz     .stf
  273.     sti
  274.     call   change_task
  275.     jmp    .table_status
  276. .stf:
  277.     call   set_application_table_status
  278. ;we can change system tables now    
  279.     push   ebx
  280.     push   eax
  281.     call   find_new_process_place ;find empty process slot
  282.     call   safe_sti
  283.     test   eax,eax
  284.         mov     ecx, -0x20      ; too many processes
  285.     jz     .failed
  286.  
  287.     mov    edi,eax
  288.     shl    edi,8
  289.     add    edi,0x80000
  290.     mov    ecx,256/4
  291.     xor    eax,eax
  292.     cld
  293.     rep    stosd                 ;clean extended information about process
  294.    
  295. ;set new process name
  296.     mov    eax,[esp]             ;eax - pointer to file name
  297.     mov    ebx,[new_process_place]
  298.     shl    ebx,8
  299.     add    ebx,0x80000 + APPDATA.app_name
  300.     mov    ecx,11
  301.     call   memmove
  302.      
  303. ;read header of file
  304.     mov    ebx,1                 ;index of first block
  305.     mov    ecx,2                 ;number of blocks
  306.     mov    edx,0x90000           ;temp area
  307.     mov    esi,12                ;file name length
  308.     cli
  309.     call   fileread              ;read file from RD
  310.     call   safe_sti
  311.         mov     ecx, eax
  312.         neg     ecx
  313.         jnz     .cleanfailed
  314. ;check MENUET signature
  315.         mov     ecx, -0x1F      ; not Menuet/Kolibri executable
  316.     cmp    [0x90000],dword 'MENU'
  317.     jnz    .cleanfailed
  318.     cmp    [0x90004],word 'ET'
  319.     jnz    .cleanfailed
  320.    
  321.     call   get_app_params        ;parse header fields
  322.     jc     .cleanfailed
  323.    
  324.     mov    eax,[new_process_place]
  325.     inc    ecx          ; -0x1E = no memory
  326.     call   create_app_cr3_table   ;create page directory for new process
  327.     test   eax,eax
  328.     jz     .cleanfailed_mem
  329.    
  330.     call   MEM_Get_Linear_Address ;calculate linear address of it
  331.    
  332.     mov    ebx,std_application_base_address
  333.     mov    ecx,[app_mem]
  334.     add    ecx,4095
  335.     shr    ecx,12
  336.     mov    edx,eax
  337.     call   mem_alloc_specified_region ;allocate memory for application
  338.     test   eax,eax
  339.         mov     ecx, -0x1E
  340.     jz     .cleanfailed_mem1
  341.    
  342.     mov    eax,[edx+(std_application_base_address shr 20)]
  343.     and    eax,not (4096-1)      ;eax - physical address of first (for application memory) page table
  344.     call   MEM_Get_Linear_Address
  345.     mov    edx,eax
  346.  
  347. ;read file
  348.     mov    ebx,1
  349.     mov    esi,12                ;length of file name
  350. .loop1:
  351. ;edx = linear address of current page table entry
  352. ;ebx = index of current block in file
  353.     push   edx
  354.     mov    eax,[edx]
  355.     and    eax,not (4096-1)
  356.     call   MEM_Get_Linear_Address
  357.     mov    edx,eax               ;read file block to current page
  358.     mov    eax,[esp+4]           ;restore pointer to file name
  359.     mov    ecx,8                 ;number of blocks read
  360.     mov    ebp,edx               ;save buffer address for .endofimage
  361.     push   ebx
  362.     cli
  363.     call   fileread
  364. ;ebx=file size    
  365.     call   safe_sti
  366.     pop    ecx
  367.     add    ecx,8
  368.     test   eax,eax
  369.     jnz    .endloop1             ;check io errors
  370.     mov    eax,[app_i_end]
  371.     add    eax,511
  372.     shr    eax,9
  373.     cmp    ecx,eax
  374.     jg     .endofimage           ;we have loaded whole program
  375.     add    ebx,511
  376.     shr    ebx,9
  377.     cmp    ecx,ebx
  378.     jg     .endloop1             ;if end of file?
  379.     mov    ebx,ecx
  380.     pop    edx
  381.     add    edx,4
  382.     jmp    .loop1
  383.    
  384. .endofimage:                     ;set to zero memory at end of page
  385.     mov    ecx,[app_i_end]
  386.     and    ecx,4096-1
  387.     jz     .endloop1
  388.     lea    edi,[ebp+ecx]
  389.     neg    ecx
  390.     add    ecx,4096
  391.     xor    eax,eax
  392.     cld
  393.     rep    stosb
  394. .endloop1:
  395.     add    esp,8                 ;pop linear address of page table entry and pointer to file name
  396.     call   .add_app_parameters
  397.     mov    [esp+28],eax
  398.     popad
  399.     ret
  400.    
  401. .cleanfailed_mem1:
  402. ;there is mem for directory entry, but there is no mem for pages
  403. ;so free directory entry
  404.     mov    eax,[new_process_place]    
  405.     shl    eax,8
  406.     mov    eax,[0x80000+eax+APPDATA.dir_table]
  407.     call   MEM_Free_Page
  408. .cleanfailed_mem:
  409. ;there is no mem for directory entry, display message.
  410.     mov    esi,start_not_enough_memory
  411.     call   sys_msg_board_str
  412. .cleanfailed:                    ;clean process name
  413.         push    ecx     ; save error code
  414. ;can't read file, clean process name.
  415. ;this avoid problems with panel application.
  416.     mov    edi,[new_process_place]
  417.     shl    edi,8
  418.     add    edi,0x80000+APPDATA.app_name
  419.     mov    ecx,11
  420.     mov    eax,' '
  421.     cld
  422.     rep    stosb
  423.         pop     eax
  424. .failed:
  425. ;no more slots
  426.     add    esp,8
  427.     mov    [application_table_status],0
  428.     mov    [esp+1Ch], eax
  429.     popad
  430.     call   safe_sti
  431.     ret
  432.        
  433. .add_app_parameters:
  434. ;input:
  435. ;  [esp] - pointer to parameters
  436. ;  [esp+4]-[esp+36] pushad registers.
  437. ;result
  438. ;  eax - pid of new process
  439. ;        or zero if failed
  440.     cli
  441.     mov    ebx,[new_process_place]
  442.     cmp    ebx,[0x3004]
  443.     jle    .noinc
  444.     inc    dword [0x3004]        ;update number of processes
  445. .noinc:
  446.  
  447. ;   mov    ebx,[new_process_place]
  448. ;set 0x8c field of extended information about process
  449. ;(size of application memory)
  450.     shl    ebx,8
  451.     mov    eax,[app_mem]
  452.     mov    [second_base_address+0x80000+APPDATA.mem_size+ebx],eax            
  453. ;set 0x10 field of information about process
  454. ;(application base address)    
  455. ;    mov    ebx,[new_process_place]
  456. ;    shl    ebx,5
  457.     shr    ebx,3
  458.     mov    dword [second_base_address+0x3000+ebx+TASKDATA.mem_start],std_application_base_address
  459.  
  460. ;add command line parameters
  461. .add_command_line:
  462.     mov    edx,[app_i_param]
  463.     test   edx,edx
  464.     jz     .no_command_line      ;application don't need parameters
  465.     mov    eax,[esp+4]
  466.     test   eax,eax
  467.     jz     .no_command_line      ;no parameters specified
  468. ;calculate parameter length    
  469.     mov    esi,eax
  470.     xor    ecx,ecx
  471.     inc    ecx          ; include terminating null
  472. .command_line_len:
  473.     cmp    byte [esi],0
  474.     jz     .command_line_len_end
  475.     inc    esi
  476.     inc    ecx
  477.     cmp    ecx,256
  478.     jl     .command_line_len
  479.    
  480. .command_line_len_end:
  481. ;ecx - parameter length
  482. ;edx - address of parameters in new process address space
  483.     mov    ebx,eax               ;ebx - address of parameters in our address space
  484.     mov    eax,[new_process_place]
  485.     call   write_process_memory  ;copy parameters to new process address space
  486.    
  487. .no_command_line:
  488. ;******************************************************************
  489.     mov    edx,[app_i_icon]
  490.     test   edx,edx
  491.     jz     .no_command_line_1      ;application don't need path of file
  492.     mov    ebx,[appl_path]
  493.     mov    ecx,[appl_path_size]
  494.     mov    eax,[new_process_place]
  495.     call   write_process_memory  ;copy path of file to new process address space
  496. .no_command_line_1:
  497. ;******************************************************************
  498.     mov    ebx,[new_process_place]
  499.     mov    eax,ebx
  500.     shl    ebx,5
  501.     add    ebx,0x3000            ;ebx - pointer to information about process
  502.     mov    [ebx+TASKDATA.wnd_number],al  ;set window number on screen = process slot
  503.    
  504.     mov    [ebx+TASKDATA.event_mask],dword 1+2+4     ;set default event flags (see 40 function)
  505.    
  506.     inc    dword [process_number]
  507.     mov    eax,[process_number]
  508.     mov    [ebx+TASKDATA.pid],eax           ;set PID
  509.    
  510.     mov    ecx,ebx
  511.     add    ecx,draw_data-0x3000  ;ecx - pointer to draw data
  512. ;set draw data to full screen    
  513.     mov    [ecx+RECT.left],dword 0      
  514.     mov    [ecx+RECT.top],dword 0
  515.     mov    eax,[0xfe00]
  516.     mov    [ecx+RECT.right],eax
  517.     mov    eax,[0xfe04]
  518.     mov    [ecx+RECT.bottom],eax
  519. ;set window state to 'normal' (non-minimized/maximized/rolled-up) state
  520.     mov    [ecx+WDATA.fl_wstate],WSTATE_NORMAL
  521. ;set cr3 register in TSS of application    
  522.     mov    ecx,[new_process_place]    
  523.     shl    ecx,8
  524.     mov    eax,[0x80000+APPDATA.dir_table+ecx]
  525.     add    eax,8+16              ;add flags
  526.     mov    [l.cr3],eax
  527.    
  528.     mov    eax,[app_start]
  529.     mov    [l.eip],eax           ;set eip in TSS
  530.     mov    eax,[app_esp]
  531.     mov    [l.esp],eax           ;set stack in TSS
  532.    
  533. ;gdt
  534.     ;mov    ebx,[new_process_place]
  535.     ;shl    ebx,3
  536.     mov    ax,app_code           ;ax - selector of code segment
  537.     ;add    ax,bx
  538.     mov    [l.cs],ax
  539.     mov    ax,app_data
  540.     ;add    ax,bx                 ;ax - selector of data segment
  541.     mov    [l.ss],ax
  542.     mov    [l.ds],ax
  543.     mov    [l.es],ax
  544.     mov    [l.fs],ax
  545.     mov    ax,graph_data         ;ax - selector of graphic segment
  546.     mov    [l.gs],ax
  547.     mov    [l.io],word 128
  548.     mov    [l.eflags],dword 0x11202
  549.     mov    [l.ss0],os_data
  550.     mov    ebx,[new_process_place]
  551.     shl    ebx,12
  552.     add    ebx,sysint_stack_data+4096
  553.     mov    [l.esp0],ebx
  554.  
  555. ;copy tss to it place
  556.     mov    eax,tss_sceleton
  557.     mov    ebx,[new_process_place]
  558.     imul   ebx,tss_step
  559.     add    ebx,tss_data          ;ebx - address of application TSS
  560.     mov    ecx,120              
  561.     call   memmove
  562.    
  563. ;Add IO access table - bit array of permitted ports
  564.     or     eax,-1
  565.     mov    edi,[new_process_place]
  566.     imul   edi,tss_step
  567.     add    edi,tss_data+128
  568.     mov    ecx,2048
  569.     cld
  570.     rep    stosd                 ;full access to 2048*8=16384 ports
  571.    
  572.     mov    ecx,ebx               ;ecx - address of application TSS
  573.     mov    edi,[new_process_place]
  574.     shl    edi,3
  575. ;set TSS descriptor
  576.     mov    [edi+gdts+tss0+0],word tss_step ;limit (size)
  577.     mov    [edi+gdts+tss0+2],cx  ;part of offset
  578.     mov    eax,ecx
  579.     shr    eax,16
  580.     mov    [edi+gdts+tss0+4],al  ;part of offset
  581.     mov    [edi+gdts+tss0+7],ah  ;part of offset
  582.     mov    [edi+gdts+tss0+5],word 01010000b*256+11101001b ;system flags
  583.      
  584.  
  585. ;flush keyboard and buttons queue
  586.     mov    [0xf400],byte 0
  587.     mov    [0xf500],byte 0
  588.  
  589.     mov    edi,[new_process_place]
  590.     shl    edi,5
  591.     add    edi,window_data
  592.     mov    ebx,[new_process_place]
  593.     movzx  esi,word [0xC000+ebx*2]
  594.     lea    esi,[0xC400+esi*2]
  595.     call   windowactivate        ;gui initialization
  596.  
  597.     mov    ebx,[new_process_place]
  598.     shl    ebx,5
  599. ; set if debuggee
  600.         test    byte [esp+28], 1
  601.         jz      .no_debug
  602.         mov     [0x3000+ebx+TASKDATA.state], 1        ; set process state - suspended
  603.         mov     eax, [0x3000]
  604.         mov     [0x80000+ebx*8+APPDATA.debugger_slot], eax ;set debugger PID - current
  605.         jmp     .debug
  606. .no_debug:
  607.         mov     [0x3000+ebx+TASKDATA.state], 0        ; set process state - running
  608. .debug:
  609.    
  610.     mov    esi,new_process_running
  611.     call   sys_msg_board_str     ;output information about succefull startup
  612.    
  613. ;    add    esp,4                 ;pop pointer to parameters
  614. ;    popad
  615.     mov    eax,[process_number]  ;set result
  616.     mov    [application_table_status],0 ;unlock application_table_status mutex
  617.     call   safe_sti
  618.     ret    4
  619. ;-----------------------------------------------------------------------------    
  620. new_sys_threads:
  621. ;eax=1 - create thread
  622. ;   ebx=thread start
  623. ;   ecx=thread stack value
  624. ;result:
  625. ;   eax=pid
  626.     xor    edx,edx      ; flags=0
  627.     pushad
  628.    
  629.     cmp    eax,1
  630.     jnz    .ret                  ;other subfunctions
  631.     mov    esi,new_process_loading
  632.     call   sys_msg_board_str
  633. ;lock application_table_status mutex
  634. .table_status:    
  635.     cli
  636.     cmp    [application_table_status],0
  637.     je     .stf
  638.     sti
  639.     call   change_task
  640.     jmp    .table_status
  641. .stf:
  642.     call   set_application_table_status
  643. ;find free process slot
  644.  
  645.     call   find_new_process_place
  646.     test   eax,eax
  647.     jz     .failed
  648.    
  649. ;set parameters for thread
  650.     xor    eax,eax
  651.     mov    [app_i_param],eax
  652.     mov    [app_i_icon],eax
  653.     mov    [app_start],ebx
  654.     mov    [app_esp],ecx
  655.  
  656.     mov    esi,[0x3000]
  657.     shl    esi,8
  658.     add    esi,0x80000+APPDATA.app_name
  659.     mov    ebx,esi               ;ebx=esi - pointer to extended information about current thread
  660.    
  661.     mov    edi,[new_process_place]
  662.     shl    edi,8
  663.     add    edi,0x80000
  664.     lea    edx, [edi+APPDATA.app_name] ;edx=edi - pointer to extended infomation about new thread
  665.     mov    ecx,256/4
  666.     rep    stosd                 ;clean extended information about new thread
  667.     mov    edi,edx
  668.     mov    ecx,11
  669.     rep    movsb                 ;copy process name
  670.     mov    eax,[ebx+APPDATA.mem_size]
  671.     mov    [app_mem],eax         ;set memory size
  672.     mov    eax,[ebx+APPDATA.dir_table]
  673.     mov    dword [edx-APPDATA.app_name+APPDATA.dir_table],eax        ;copy page directory
  674. ;    mov    eax,[new_process_place]
  675. ;    mov    ebx,[0x3000]
  676. ;    call   addreference_app_cr3_table
  677.  
  678.     push   0                     ;no parameters
  679.     call    new_start_application_fl.add_app_parameters ;start thread
  680.     mov    [esp+28],eax
  681.     popad
  682.     ret
  683.    
  684. .failed:
  685.     sti
  686.     popad
  687.     mov    eax,-1
  688.     ret    
  689. .ret:
  690.     popad
  691.     ret
  692. ;-----------------------------------------------------------------------------    
  693. new_mem_resize:
  694. ;input:
  695. ;  ebx - new size
  696. ;result:
  697. ;  [esp+36]:=0 - normal
  698. ;  [esp+36]:=1 - error
  699. ;This function set new application memory size.
  700.     mov    esi,ebx               ;save new size
  701.     add    ebx,4095
  702.     and    ebx,not (4096-1)      ;round up size
  703.     mov    ecx,[0x3000]
  704.     shl    ecx,8
  705.     mov    edx,[0x80000 + APPDATA.mem_size +ecx]    
  706.     add    edx,4095
  707.     and    edx,not (4096-1)      ;old size
  708.     mov    eax,[0x80000 + APPDATA.dir_table+ecx]
  709.     call   MEM_Get_Linear_Address
  710. ;eax - linear address of page directory    
  711.     call   MEM_Heap_Lock         ;guarantee that two threads willn't
  712.                                  ;change memory size simultaneously
  713.     cmp    ebx,edx
  714. ;    mov    esi,ebx               ;save new size
  715.     jg     .expand
  716.    
  717. .free:
  718.     sub    edx,ebx
  719.     jz     .unlock               ;do nothing
  720.     mov    ecx,edx
  721.     shr    ecx,12
  722.     add    ebx,std_application_base_address
  723.     call   mem_free_specified_region  ;free unnecessary pages
  724.     jmp    .unlock
  725.  
  726. .expand:
  727.     sub    ebx,edx
  728.     mov    ecx,ebx
  729.     shr    ecx,12
  730.     mov    ebx,edx
  731.     add    ebx,std_application_base_address
  732.     call   mem_alloc_specified_region ;alloc necessary pages
  733.     test   eax,eax
  734.     jz     .failed               ;not enough memory
  735.    
  736. .unlock:
  737.     mov    ebx,esi
  738.     mov    eax,[0x3000]
  739.     shl    eax,8
  740.     mov    [eax+0x80000 + APPDATA.mem_size],ebx     ;write new memory size
  741. ;search threads and update
  742. ;application memory size infomation    
  743.     mov    ecx,[eax+0x80000 + APPDATA.dir_table]
  744.     mov    eax,2
  745.    
  746. .search_threads:
  747. ;eax = current slot
  748. ;ebx = new memory size
  749. ;ecx = page directory
  750.     cmp    eax,[0x3004]
  751.     jg     .search_threads_end
  752.     mov    edx,eax
  753.     shl    edx,5
  754.     cmp    word [0x3000+edx+TASKDATA.state],9 ;if slot empty?
  755.     jz     .search_threads_next
  756.     shl    edx,3
  757.     cmp    [edx+0x80000+APPDATA.dir_table],ecx     ;if it is our thread?
  758.     jnz    .search_threads_next
  759.     mov    [edx+0x80000+APPDATA.mem_size],ebx     ;update memory size
  760. .search_threads_next:
  761.     inc    eax
  762.     jmp    .search_threads
  763. .search_threads_end:
  764.  
  765.     call   MEM_Heap_UnLock
  766.     mov    dword [esp+36],0
  767.     ret
  768.    
  769. .failed:
  770.     call   MEM_Heap_UnLock
  771.     mov    dword [esp+36],1
  772.     ret    
  773. ;-----------------------------------------------------------------------------
  774. pid_to_slot:
  775. ;Input:
  776. ;  eax - pid of process
  777. ;Output:
  778. ;  eax - slot of process or 0 if process don't exists
  779. ;Search process by PID.
  780.     push   ebx
  781.     push   ecx
  782.     mov    ebx,[0x3004]
  783.     shl    ebx,5
  784.     mov    ecx,2*32
  785.    
  786. .loop:
  787. ;ecx=offset of current process info entry
  788. ;ebx=maximum permitted offset
  789.     cmp    byte [second_base_address+0x3000+ecx+TASKDATA.state],9
  790.     jz     .endloop              ;skip empty slots
  791.     cmp    [second_base_address+0x3000+ecx+TASKDATA.pid],eax ;check PID
  792.     jz     .pid_found
  793. .endloop:
  794.     add    ecx,32
  795.     cmp    ecx,ebx
  796.     jle    .loop
  797.    
  798.     pop    ecx
  799.     pop    ebx
  800.     xor    eax,eax
  801.     ret
  802.    
  803. .pid_found:
  804.     shr    ecx,5
  805.     mov    eax,ecx               ;convert offset to index of slot
  806.     pop    ecx
  807.     pop    ebx
  808.     ret
  809. ;-----------------------------------------------------------------------------    
  810. is_new_process:
  811. ;Input:
  812. ;  eax - process slot
  813. ;Output:
  814. ;  eax=1 - it is new process
  815. ;  eax=0 - it is old process
  816. ;    shl   eax,5
  817. ;    mov   eax,[second_base_address+0x3000+eax+0x10]
  818. ;    cmp   eax,std_application_base_address  ;check base address of application
  819. ;    jz    .new_process
  820. ;    xor   eax,eax
  821. ;    ret
  822.    
  823. ;.new_process:
  824.     mov   eax,1
  825.     ret
  826. ;-----------------------------------------------------------------------------    
  827. write_process_memory:
  828. ;Input:
  829. ;  eax - process slot
  830. ;  ebx - buffer address
  831. ;  ecx - buffer size
  832. ;  edx - start address in other process
  833. ;Output:
  834. ;  eax - number of bytes written
  835.     pushad
  836.     shl  eax,8
  837.     mov  eax,[0x80000+eax+APPDATA.dir_table]
  838.     call MEM_Get_Linear_Address
  839.     mov  ebp,eax
  840. ;ebp=linear address of page directory of other process.    
  841.     add  edx,std_application_base_address  ;convert to linear address
  842.     test ecx,ecx
  843.     jle  .ret
  844.    
  845. .write_loop:
  846. ;ebx = current buffer address
  847. ;ecx>0 = current size
  848. ;edx = current address in other process
  849. ;ebp = linear address of page directory
  850.  
  851.     call MEM_Heap_Lock           ;cli
  852.     mov  esi,edx
  853.     shr  esi,22
  854.     mov  eax,[ebp+4*esi]         ;find page directory entry
  855.     and  eax,not (4096-1)        ;clear flags
  856.     test eax,eax
  857.     jz   .page_not_found
  858.     call MEM_Get_Linear_Address  ;calculate linear address of page table
  859.     test eax,eax
  860.     jz   .page_not_found
  861.     mov  esi,edx
  862.     shr  esi,12
  863.     and  esi,1023                
  864.     mov  eax,[eax+4*esi]         ;find page table entry
  865.     and  eax,not (4096-1)
  866.     test eax,eax
  867.     jz   .page_not_found
  868.     call MEM_Get_Linear_Address  ;calculate linear address of page
  869.     test eax,eax
  870.     jz   .page_not_found
  871.     mov  edi,eax
  872.     call MEM_Add_Reference_Linear;guarantee that page willn't disappear
  873.     call MEM_Heap_UnLock         ;sti
  874.    
  875.     mov  esi,edx
  876.     and  esi,4095
  877.     add  edi,esi                 ;add offset in page
  878. ;edi = linear address corresponding edx in other process
  879.     sub  esi,4096
  880.     neg  esi                     ;esi - number of remaining bytes in page
  881.     cmp  esi,ecx
  882.     jl   .min_ecx
  883.     mov  esi,ecx
  884. .min_ecx:                        ;esi=min(ecx,esi) - number of bytes to write
  885.     sub  ecx,esi
  886.     push ecx
  887.     mov  ecx,esi                 ;ecx - number of bytes to write
  888.     mov  esi,ebx                 ;esi - source, edi - destination
  889.     add  edx,ecx                 ;move pointer in address space of other process
  890.     push edi
  891.    
  892. ;move ecx bytes    
  893.     test ecx,3
  894.     jnz  .not_aligned
  895.     shr  ecx,2
  896.     rep  movsd
  897.     jmp  .next_iter
  898. .not_aligned:
  899.     rep  movsb
  900. .next_iter:
  901.  
  902.     pop  eax                    
  903.     and  eax,not (4096-1)        ;eax - linear address of current page
  904.     call MEM_Free_Page_Linear    ;free reference
  905.     mov  ebx,esi                 ;new pointer to buffer - movsb automaticaly advance it.
  906.     pop  ecx                     ;restore number of remaining bytes
  907.     test ecx,ecx
  908.     jnz  .write_loop
  909. .ret:    
  910.     popad
  911.     mov  eax,ecx
  912.     ret
  913.    
  914. .page_not_found:
  915.     call MEM_Heap_UnLock         ;error has appeared in critical region
  916.     sub  ecx,[esp+24]            ;[esp+24]<-->ecx
  917.     neg  ecx                     ;ecx=number_of_written_bytes
  918.     mov  [esp+28],ecx            ;[esp+28]<-->eax
  919.     popad
  920.     ret    
  921. ;-----------------------------------------------------------------------------    
  922. syscall_test:
  923. ;for testing memory manager from applications.
  924.     mov  edx,ecx
  925.     mov  ecx,ebx
  926.     call trans_address
  927.     mov  ebx,eax
  928.     mov  eax,[0x3000]
  929.     call read_process_memory
  930.     ret
  931. ;-----------------------------------------------------------------------------    
  932. read_process_memory:
  933. ;Input:
  934. ;  eax - process slot
  935. ;  ebx - buffer address
  936. ;  ecx - buffer size
  937. ;  edx - start address in other process
  938. ;Output:
  939. ;  eax - number of bytes read.
  940.     pushad
  941.     shl  eax,8
  942.     mov  eax,[0x80000+eax+APPDATA.dir_table]
  943.     call MEM_Get_Linear_Address
  944.     mov  ebp,eax
  945.     add  edx,std_application_base_address
  946. .read_loop:
  947. ;ebx = current buffer address
  948. ;ecx>0 = current size
  949. ;edx = current address in other process
  950. ;ebp = linear address of page directory
  951.  
  952.     call MEM_Heap_Lock           ;cli
  953.     mov  esi,edx
  954.     shr  esi,22
  955.     mov  eax,[ebp+4*esi]         ;find page directory entry
  956.     and  eax,not (4096-1)
  957.     test eax,eax
  958.     jz   .page_not_found
  959.     call MEM_Get_Linear_Address
  960.     test eax,eax
  961.     jz   .page_not_found
  962.     mov  esi,edx
  963.     shr  esi,12
  964.     and  esi,1023
  965.     mov  eax,[eax+4*esi]         ;find page table entry
  966.     and  eax,not (4096-1)
  967.     test eax,eax
  968.     jz   .page_not_found
  969.     call MEM_Get_Linear_Address  ;calculate linear address of page
  970.     test eax,eax
  971.     jz   .page_not_found
  972.     mov  esi,eax
  973.     call MEM_Add_Reference_Linear;guarantee that page willn't disappear
  974.     call MEM_Heap_UnLock         ;sti
  975.    
  976.     mov  edi,edx
  977.     and  edi,4095                
  978.     add  esi,edi                 ;add offset in page
  979. ;esi = linear address corresponding edx in other process
  980.     sub  edi,4096
  981.     neg  edi
  982.    
  983. ;edi=min(edi,ecx) - number of bytes to copy  
  984.     cmp  edi,ecx
  985.     jl   .min_ecx
  986.     mov  edi,ecx
  987. .min_ecx:
  988.  
  989.     sub  ecx,edi                 ;update size of remaining bytes
  990.     add  edx,edi                 ;update current pointer in other address space.
  991.     push ecx
  992.     mov  ecx,edi                 ;ecx - number of bytes to read
  993.     mov  edi,ebx                 ;esi - source, edi - destination
  994.     push esi
  995. ;move ecx bytes    
  996.     test ecx,3
  997.     jnz  .not_aligned
  998.     shr  ecx,2
  999.     rep  movsd
  1000.     jmp  .next_iter
  1001. .not_aligned:
  1002.     rep  movsb
  1003. .next_iter:
  1004.     pop  eax
  1005.     and  eax,not (4096-1)        ;eax - linear address of current page
  1006.     call MEM_Free_Page_Linear    ;free reference
  1007.     mov  ebx,edi                 ;new pointer to buffer - movsb automaticaly advance it.
  1008.     pop  ecx                     ;restore number of remaining bytes
  1009.     test ecx,ecx
  1010.     jnz  .read_loop
  1011.    
  1012.     popad
  1013.     mov  eax,ecx
  1014.     ret
  1015.    
  1016. .page_not_found:
  1017.     call MEM_Heap_UnLock         ;error has appeared in critical region
  1018.     sub  ecx,[esp+24]            ;[esp+24]<-->ecx
  1019.     neg  ecx                     ;ecx=number_of_read_bytes
  1020.     mov  [esp+28],ecx            ;[esp+28]<-->eax
  1021.     popad
  1022.     ret
  1023. ;-----------------------------------------------------------------------------
  1024. check_region:
  1025. ;input:
  1026. ;  ebx - start of buffer
  1027. ;  ecx - size of buffer
  1028. ;result:
  1029. ;  eax = 1 region lays in app memory
  1030. ;  eax = 0 region don't lays in app memory
  1031.     mov  eax,[0x3000]
  1032.     jmp  check_process_region
  1033. ;-----------------------------------------------------------------------------    
  1034. check_process_region:
  1035. ;input:
  1036. ;  eax - slot
  1037. ;  ebx - start of buffer
  1038. ;  ecx - size of buffer
  1039. ;result:
  1040. ;  eax = 1 region lays in app memory
  1041. ;  eax = 0 region don't lays in app memory
  1042.     test ecx,ecx
  1043.     jle  .ok
  1044.     shl  eax,5
  1045.     cmp  word [0x3000+eax+TASKDATA.state],0
  1046.     jnz  .failed
  1047.     shl  eax,3
  1048.     mov  eax,[0x80000+eax+APPDATA.dir_table]
  1049.     test eax,eax
  1050.     jz   .failed
  1051.     call MEM_Get_Linear_Address
  1052.     push ebx
  1053.     push ecx
  1054.     push edx
  1055.     mov  edx,ebx
  1056.     and  edx,not (4096-1)
  1057.     sub  ebx,edx
  1058.     add  ecx,ebx
  1059.     mov  ebx,edx
  1060.     add  ecx,(4096-1)
  1061.     and  ecx,not (4096-1)
  1062. .loop:
  1063. ;eax - linear address of page directory    
  1064. ;ebx - current page
  1065. ;ecx - current size
  1066.     mov  edx,ebx
  1067.     shr  edx,22
  1068.     mov  edx,[eax+4*edx]
  1069.     and  edx,not (4096-1)
  1070.     test edx,edx
  1071.     jz   .failed1
  1072.     push eax
  1073.     mov  eax,edx
  1074.     call MEM_Get_Linear_Address
  1075.     mov  edx,ebx
  1076.     shr  edx,12
  1077.     and  edx,(1024-1)
  1078.     mov  eax,[eax+4*edx]
  1079.     and  eax,not (4096-1)
  1080.     test eax,eax
  1081.     pop  eax
  1082.     jz   .failed1
  1083.     add  ebx,4096
  1084.     sub  ecx,4096
  1085.     jg   .loop
  1086.     pop  edx
  1087.     pop  ecx
  1088.     pop  ebx
  1089. .ok:
  1090.     mov  eax,1
  1091.     ret
  1092.    
  1093. .failed1:
  1094.     pop  edx
  1095.     pop  ecx
  1096.     pop  ebx
  1097. .failed:
  1098.     xor  eax,eax
  1099.     ret
  1100. ;-----------------------------------------------------------------------------
  1101. new_sys_ipc:
  1102. ;input:
  1103. ;  eax=1 - set ipc buffer area
  1104. ;    ebx=address of buffer
  1105. ;    ecx=size of buffer
  1106. ;  eax=2 - send message
  1107. ;    ebx=PID
  1108. ;    ecx=address of message
  1109. ;    edx=size of message
  1110.     cmp  eax,1
  1111.     jnz  .no_ipc_def
  1112. ;set ipc buffer area    
  1113.     mov  edi,[0x3000]
  1114.     shl  edi,8
  1115.     add  edi,0x80000
  1116.     cli
  1117.     mov  [edi+APPDATA.ipc_start],ebx          ;set fields in extended information area
  1118.     mov  [edi+APPDATA.ipc_size],ecx
  1119.     sti
  1120.     mov  [esp+36],dword 0        ;success
  1121.     ret
  1122.        
  1123. .no_ipc_def:
  1124.     cmp  eax,2
  1125.     jnz  .no_ipc_send
  1126. ;send message    
  1127.     cli
  1128. ;obtain slot from PID    
  1129.     mov  eax,ebx
  1130.     call pid_to_slot
  1131.     test eax,eax
  1132.     jz   .no_pid
  1133.     mov  ebp,eax
  1134. ;ebp = slot of other process    
  1135.     shl  eax,8
  1136.     mov  edi,[eax+0x80000+APPDATA.ipc_start]  ;is ipc area defined?
  1137.     test edi,edi
  1138.     jz   .no_ipc_area
  1139.     mov  esi,[eax+0x80000+APPDATA.ipc_size]  ;esi - size of buffer
  1140.     push dword -1                ;temp variable for read_process_memory
  1141.     mov  ebx,esp
  1142.     push ecx
  1143.     push edx
  1144.     mov  ecx,4                   ;read 4 bytes
  1145.     mov  eax,ebp
  1146.     mov  edx,edi                 ;from beginning of buffer.
  1147.     call read_process_memory
  1148.     mov  eax,[esp+8]
  1149.     test eax,eax
  1150.     jnz  .ipc_blocked            ;if dword [buffer]<>0 - ipc blocked now
  1151.     add  edx,4                   ;move to next 4 bytes
  1152.     mov  eax,ebp
  1153.     call read_process_memory     ;read size of occupied space in buffer
  1154.     sub  esi,8
  1155.     sub  esi,[esp]
  1156.     sub  esi,[esp+8]             ;esi=(buffer size)-(occupied size)-(message size)-(header of message size)
  1157.     js   .buffer_overflow        ;esi<0 - not enough memory in buffer
  1158.     mov  esi,[esp+8]             ;previous offset
  1159.     add  dword [esp+8],8
  1160.     mov  edi,[esp]
  1161.     add  [esp+8],edi             ;add (size of message)+(size of header of message) to [buffer+4]
  1162.     mov  eax,ebp
  1163.     call write_process_memory
  1164.     add  edx,esi                
  1165.     sub  edx,4                   ;move to beginning of place for our message
  1166.     mov  eax,[second_base_address+0x3010]
  1167.     mov  eax,[eax+TASKDATA.pid]           ;eax - our PID
  1168.     mov  [esp+8],eax
  1169.     mov  eax,ebp
  1170.     call write_process_memory    ;write PID
  1171.     mov  ebx,esp                 ;address of size of message
  1172.     mov  eax,ebp
  1173.     add  edx,4
  1174.     call write_process_memory    ;write size of message
  1175.     add  edx,4
  1176.     pop  ecx                     ;ecx - size of message
  1177.     pop  eax
  1178.     call trans_address
  1179.     mov  ebx,eax                 ;ebx - linear address of message
  1180.     add  esp,4                   ;pop temporary variable
  1181.     mov  eax,ebp
  1182.     call write_process_memory    ;write message
  1183.     sti
  1184. ;awake other process    
  1185.     shl  ebp,8
  1186.     mov  eax,ebp
  1187.     or   [eax+0x80000+APPDATA.event_mask],dword 0x40
  1188.    
  1189.     cmp  dword [check_idle_semaphore],20
  1190.     jge  .ipc_no_cis
  1191.     mov  dword [check_idle_semaphore],5
  1192. .ipc_no_cis:
  1193.     mov  dword [esp+36],0
  1194.     ret
  1195. .no_ipc_send:
  1196.     mov  dword [esp+36],-1
  1197.     ret
  1198. .no_pid:
  1199.     sti
  1200.     mov  dword [esp+36],4
  1201.     ret
  1202. .no_ipc_area:
  1203.     sti
  1204.     mov  dword [esp+36],1
  1205.     ret
  1206. .ipc_blocked:
  1207.     sti
  1208.     add  esp,12
  1209.     mov  dword [esp+36],2
  1210.     ret
  1211. .buffer_overflow:
  1212.     sti
  1213.     add  esp,12
  1214.     mov  dword [esp+36],3
  1215.     ret
  1216. ;-----------------------------------------------------------------------------    
  1217. trans_address:
  1218. ;Input
  1219. ;  eax - application address
  1220. ;Output
  1221. ;  eax - linear address for kernel      
  1222.     add   eax,std_application_base_address
  1223.     ret
  1224. ;-----------------------------------------------------------------------------    
  1225. new_start_application_hd:
  1226. ;eax - file name (kernel address)
  1227. ;ebx - file name length
  1228. ;ecx - work area (kernel address)
  1229. ;edx - flags
  1230. ;ebp - parameters
  1231.     mov    [appl_path],edi
  1232.     pushad
  1233.    
  1234.     mov    esi,new_process_loading
  1235.     call   sys_msg_board_str     ;write message to message board
  1236.    
  1237. ;lock application_table_status mutex
  1238. .table_status:
  1239.     cli
  1240.     cmp    [application_table_status],0
  1241.     jz     .stf
  1242.     sti
  1243.     call   change_task
  1244.     jmp    .table_status
  1245. .stf:
  1246.     call   set_application_table_status
  1247.    
  1248.     push   ebp
  1249.     push   ebx
  1250.     push   eax
  1251.     push   ecx
  1252.     call   find_new_process_place ;find new process slot
  1253.     sti
  1254.     test   eax,eax
  1255.         mov     ecx, -0x20      ; too many processes
  1256.     jz     .failed
  1257.    
  1258. ;write application name
  1259.     xor    eax,eax
  1260.     mov    [appl_path_size],eax    
  1261.     mov    eax,[esp+4]
  1262. .find_last_byte:
  1263.     cmp    byte [eax],0    
  1264.     jz     .find_last_byte_end
  1265.     inc    eax
  1266.     inc    [appl_path_size]
  1267.     jmp    .find_last_byte
  1268. .find_last_byte_end:
  1269.     add    [appl_path_size],24    
  1270.     lea    esi,[eax-11]          ;last 11 bytes = application name
  1271.     mov    edi,[new_process_place]
  1272.     shl    edi,8
  1273.     add    edi,0x80000+APPDATA.app_name
  1274.     mov    ecx,11
  1275.     cld
  1276.     rep    movsb                 ;copy name to extended information about process
  1277.    
  1278. ;read header    
  1279.     mov    eax,[esp+4]           ;file name
  1280.     mov    esi,[esp]             ;work area
  1281.     mov    ecx,1                 ;read from first block
  1282.     mov    edx,1                 ;read 1 block
  1283.     call   read_hd_file
  1284.         mov     ecx, eax
  1285.         neg     ecx
  1286.         jnz     .cleanfailed
  1287.  
  1288.     pop    esi
  1289.     push   esi
  1290. ;check menuet signature
  1291.         mov     ecx, -0x1F      ; not Menuet/Kolibri executable
  1292.     cmp    [esi+1024+0],dword 'MENU'  ;read_hd_file function write file to +1024 offset
  1293.     jnz    .cleanfailed
  1294.     cmp    [esi+1024+4],word 'ET'
  1295.     jnz    .cleanfailed
  1296.     add    esi,1024
  1297.     mov    edi,0x90000
  1298.     mov    ecx,512/4
  1299.     cld
  1300.     rep    movsd                 ;copy first block to 0x90000 address for get_app_params function
  1301.     call   get_app_params
  1302.         mov     ecx, -0x1F      ; not Menuet/Kolibri executable
  1303.     jc     .cleanfailed
  1304.    
  1305.     mov    eax,[new_process_place]
  1306.         inc     ecx             ; -0x1E = no memory
  1307.     call   create_app_cr3_table  ;create page directory
  1308.     test   eax,eax
  1309.     jz     .cleanfailed_mem
  1310.    
  1311.     call   MEM_Get_Linear_Address
  1312.    
  1313.     mov    ebx,std_application_base_address
  1314.     mov    ecx,[app_mem]
  1315.     add    ecx,4096-1
  1316.     shr    ecx,12
  1317.     mov    edx,eax               ;edx - linear address of page directory
  1318.     call   mem_alloc_specified_region ;allocate memory for application
  1319.         mov     ecx, -0x1E      ; no memory
  1320.     test   eax,eax
  1321.     jz     .cleanfailed_mem1
  1322.    
  1323.     add    edx,(std_application_base_address shr 20)
  1324.     mov    eax,[edx]
  1325.     and    eax,not (4096-1)
  1326.     call   MEM_Get_Linear_Address
  1327.     push   edx                   ;save pointer to first page table
  1328.     mov    edx,eax
  1329. ;read file
  1330.     mov    ecx,1
  1331.     xor    ebp,ebp
  1332. .loop1:
  1333. ;[esp] - pointer to current page directory entry
  1334. ;edx - pointer to current page table
  1335. ;ebp - offset in page
  1336. ;ecx - current cluster
  1337.     push   edx
  1338.     mov    eax,[esp+12]          ;file name
  1339.     mov    ebx,[esp+16]          ;file name length
  1340.     mov    esi,[esp+8]           ;work area
  1341.     mov    edx,1                 ;number of blocks to read
  1342.     push   ecx
  1343.     push   ebp
  1344.     cli
  1345.     call   read_hd_file
  1346.     sti
  1347.     pop    ebp
  1348.     test   eax,eax
  1349.     jnz    .endloop1             ;check io errors
  1350.    
  1351.     mov    esi,[esp+8+4]         ;work area
  1352.     add    esi,1024
  1353.     mov    eax,[esp+4]           ;current page table
  1354.     mov    eax,[eax]
  1355.     and    eax,not (4096-1)        
  1356.     call   MEM_Get_Linear_Address;calculate linear page address
  1357.     lea    edi,[eax+ebp]         ;add page offset
  1358.     mov    ecx,512/4
  1359.     cld
  1360.     rep    movsd                 ;copy data
  1361.    
  1362.     pop    ecx
  1363.     inc    ecx                   ;next block
  1364.     mov    eax,[app_i_end] ;todo: precalculate ([app_i_end]+4095)/4096
  1365.     add    eax,512-1
  1366.     shr    eax,9                 ;calculate application image size
  1367.     cmp    ecx,eax
  1368.     jg     .endloop11
  1369.     pop    edx
  1370.     add    ebp,512               ;new offset
  1371.     test   ebp,4096
  1372.     jz     .loop1
  1373.     xor    ebp,ebp
  1374.     add    edx,4                 ;go to next page
  1375.     test   edx,(4096-1)
  1376.     jnz    .loop1
  1377.     add    dword [esp],4         ;go to next directory entry
  1378.     mov    eax,[esp]
  1379.     mov    eax,[eax]
  1380.     and    eax,not (4096-1)
  1381.     call   MEM_Get_Linear_Address
  1382.     mov    edx,eax
  1383.     jmp    .loop1
  1384. .endloop1:
  1385.     add    esp,4                 ;pop ecx
  1386. .endloop11:
  1387.     add    esp,4+4               ;pop edx, pop edx
  1388.    
  1389. ;add_app_parameters
  1390.     add    esp,12                ;now pointer to parameters is on the top of the stack
  1391.     call   new_start_application_fl.add_app_parameters ;start process
  1392.     mov    [esp+28],eax
  1393.     popad
  1394.     ret
  1395.    
  1396. .cleanfailed_mem1:
  1397. ;there is mem for directory entry, but there is no mem for pages
  1398. ;so free directory entry
  1399.     mov    eax,[new_process_place]
  1400.     shl    eax,8
  1401.     mov    eax,[0x80000+eax+APPDATA.dir_table]
  1402.     call   MEM_Free_Page
  1403. .cleanfailed_mem:
  1404. ;there is no mem for directory entry, display message.
  1405.     mov    esi,start_not_enough_memory
  1406.     call   sys_msg_board_str    
  1407. .cleanfailed:                    ;clean process name
  1408.         push    ecx
  1409. ;can't read file, clean process name.
  1410. ;this avoid problems with panel application.
  1411.     mov    edi,[new_process_place]
  1412.     shl    edi,8
  1413.     add    edi,0x80000+APPDATA.app_name
  1414.     mov    ecx,11
  1415.     mov    eax,' '
  1416.     cld
  1417.     rep    stosb
  1418.         pop     eax
  1419. .failed:
  1420. ;no more slots
  1421.     add    esp,16
  1422.     mov    [esp+1Ch], eax
  1423.     popad
  1424.     mov    [application_table_status],0
  1425.     sti
  1426.     ret
  1427. end if
  1428.  
  1429. ; \begin{diamond}
  1430.         include 'debug.inc'
  1431.  
  1432. fs_execute:
  1433. ; ebx - cmdline
  1434. ; edx - flags
  1435. ; ebp - full filename
  1436. ; [esp+4] = procedure DoRead, [esp+8] = filesize & [esp+12]... - arguments for it
  1437.         pushad
  1438. ; check filename length - with terminating NULL must be no more than 1024 symbols
  1439.         mov     edi, ebp
  1440.         mov     ecx, 1024
  1441.         xor     eax, eax
  1442.         repnz   scasb
  1443.         jz      @f
  1444.         popad
  1445.         mov     eax, -ERROR_FILE_NOT_FOUND
  1446.         ret
  1447. @@:
  1448.  
  1449.         mov     esi, new_process_loading
  1450.         call    sys_msg_board_str       ; write message to message board
  1451.  
  1452. ; lock application_table_status mutex
  1453. .table_status:
  1454.         cli
  1455.         cmp     [application_table_status], 0
  1456.         jz      .stf
  1457.         sti
  1458.         call    change_task
  1459.         jmp     .table_status
  1460. .stf:
  1461.         call    set_application_table_status
  1462.         push    ebx     ; save command line pointer for add_app_parameters
  1463.  
  1464.         call    find_new_process_place  ; find new process slot
  1465.         call    safe_sti
  1466.         test    eax, eax
  1467.         mov     ecx, -0x20      ; too many processes
  1468.         jz      .failed
  1469.  
  1470. ; write application name
  1471.         push    edi
  1472.         mov     ecx, edi
  1473.         sub     ecx, ebp
  1474.         mov     [appl_path], ebp
  1475.         mov     [appl_path_size], ecx
  1476.         dec     edi
  1477.         std
  1478.         mov     al, '/'
  1479.         repnz   scasb
  1480.         cld
  1481.         jnz     @f
  1482.         inc     edi
  1483. @@:
  1484.         inc     edi
  1485. ; now edi points to name without path
  1486.         mov     esi, edi
  1487.         mov     ecx, 8  ; 8 chars for name
  1488.         mov     edi, [new_process_place]
  1489.         shl     edi, cl
  1490.         add     edi, 0x80000+APPDATA.app_name
  1491. .copy_process_name_loop:
  1492.         lodsb
  1493.         cmp     al, '.'
  1494.         jz      .copy_process_name_done
  1495.         test    al, al
  1496.         jz      .copy_process_name_done
  1497.         stosb
  1498.         loop    .copy_process_name_loop
  1499. .copy_process_name_done:
  1500.         mov     al, ' '
  1501.         rep     stosb
  1502.         pop     eax
  1503.         mov     cl, 3   ; 3 chars for extension
  1504.         dec     esi
  1505. @@:
  1506.         dec     eax
  1507.         cmp     eax, esi
  1508.         jbe     .copy_process_ext_done
  1509.         cmp     byte [eax], '.'
  1510.         jnz     @b
  1511.         lea     esi, [eax+1]
  1512. .copy_process_ext_loop:
  1513.         lodsb
  1514.         test    al, al
  1515.         jz      .copy_process_ext_done
  1516.         stosb
  1517.         loop    .copy_process_ext_loop
  1518. .copy_process_ext_done:
  1519.         mov     al, ' '
  1520.         rep     stosb
  1521.  
  1522. ; read header
  1523.         lea     eax, [esp+8+36]
  1524.         mov     edi, 0x90000
  1525.         call    dword [eax-4]
  1526.         mov     ecx, eax
  1527.         neg     ecx
  1528.         jnz     .cleanfailed
  1529. ; check menuet signature
  1530.         mov     ecx, -0x1F
  1531.         cmp     dword [0x90000], 'MENU'
  1532.         jnz     .cleanfailed
  1533.         cmp     word [0x90004], 'ET'
  1534.         jnz     .cleanfailed
  1535.         call    get_app_params
  1536.         mov     ecx, -0x1F
  1537.         jc      .cleanfailed
  1538. ; sanity check - because we will load all file,
  1539. ; file size must be not greater than memory size
  1540.         mov     eax, [esp+8+36]
  1541.         cmp     [app_mem], eax
  1542.         jb      .cleanfailed
  1543.  
  1544.         mov     eax, [new_process_place]
  1545.         inc     ecx     ; -0x1E = no memory
  1546.         call    create_app_cr3_table
  1547.         test    eax, eax
  1548.         jz      .cleanfailed_mem
  1549.  
  1550.         call    MEM_Get_Linear_Address
  1551.  
  1552.         mov     ebx, std_application_base_address
  1553.         mov     ecx, [app_mem]
  1554.         add     ecx, 4095
  1555.         shr     ecx, 12
  1556.         mov     edx, eax        ; edx - linear address of page directory
  1557.         call    mem_alloc_specified_region
  1558.         mov     ecx, -0x1E      ; no memory
  1559.         test    eax, eax
  1560.         jz      .cleanfailed_mem1
  1561.  
  1562.         add     edx, std_application_base_address shr 20
  1563.         mov     eax, [edx]
  1564.         and     eax, not 4095
  1565.         call    MEM_Get_Linear_Address
  1566.         push    edx             ; save pointer to first page table
  1567.         mov     edx, eax
  1568. ; read file
  1569. ; first block is already read to 0x90000
  1570.         mov     eax, [edx]
  1571.         and     eax, not 0xFFF
  1572.         call    MEM_Get_Linear_Address
  1573.         mov     esi, 0x90000
  1574.         mov     edi, eax
  1575.         mov     ecx, 512/4
  1576.         rep     movsd
  1577.         sub     edi, eax
  1578. .loop1:
  1579. ; [esp] = pointer to current page directory entry
  1580. ; edx = pointer to current page table
  1581. ; edi = offset in page
  1582.         mov     eax, [edx]
  1583.         and     eax, not 0xFFF
  1584.         call    MEM_Get_Linear_Address
  1585.         push    edi
  1586.         add     edi, eax
  1587.         lea     eax, [esp+8+36+8]
  1588.         call    dword [eax-4]
  1589.         pop     edi
  1590.         test    eax, eax
  1591.         jnz     .endloop1
  1592.         add     edi, 512        ; new offset
  1593.         cmp     edi, 4096
  1594.         jb      .loop1
  1595.         xor     edi, edi
  1596.         add     edx, 4          ; go to next page
  1597.         test    edx, 4096-1
  1598.         jnz     .loop1
  1599.         pop     eax
  1600.         add     eax, 4          ; go to next directory entry
  1601.         push    eax
  1602.         mov     eax, [eax]
  1603.         and     eax, not 0xFFF
  1604.         call    MEM_Get_Linear_Address
  1605.         mov     edx, eax
  1606.         jmp     .loop1
  1607. .endloop1:
  1608.         pop     edx
  1609.         cmp     eax, 6
  1610.         jnz     .cleanfailed_mem2
  1611.         call    new_start_application_fl.add_app_parameters
  1612.         mov     [esp+28], eax
  1613.         popad
  1614.         ret
  1615.  
  1616. .cleanfailed_mem2:
  1617. ; file read error; free all allocated mem
  1618.         mov     ecx, eax
  1619.         neg     ecx
  1620.         mov     eax, [new_process_place]
  1621.         call    dispose_app_cr3_table
  1622.         jmp     .cleanfailed
  1623. .cleanfailed_mem1:
  1624. ; there is mem for directory entry, but there is no mem for pages
  1625. ; so free directory entry
  1626.         mov     eax, [new_process_place]
  1627.         shl     eax, 8
  1628.         mov     eax, [0x80000+eax+0xB8]
  1629.         call    MEM_Free_Page
  1630. .cleanfailed_mem:
  1631. ; there is no mem for directory entry, display message
  1632.         mov     esi, start_not_enough_memory
  1633.         call    sys_msg_board_str
  1634. .cleanfailed:
  1635.         push    ecx
  1636. ; clean process name, this avoid problems with @panel
  1637.         mov     edi, [new_process_place]
  1638.         shl     edi, 8
  1639.         add     edi, 0x80000+APPDATA.app_name
  1640.         mov     ecx, 11
  1641.         mov     al, ' '
  1642.         rep     stosb
  1643.         pop     eax
  1644. .failed:
  1645.         pop     ebx
  1646.         mov     [esp+28], eax
  1647.         popad
  1648.         mov     [application_table_status], 0
  1649.         call    safe_sti
  1650.         ret
  1651. ; \end{diamond}
  1652.