Subversion Repositories Kolibri OS

Rev

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