Subversion Repositories Kolibri OS

Rev

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