kolibrios-gitea/kernel/trunk/core/taskman.inc
Alexey Teplov ( 5c55e63fc6 small optimization
git-svn-id: svn://kolibrios.org@1260 a494cfbc-eb01-0410-851d-a64ba20cac60
2009-11-09 19:30:40 +00:00

1151 lines
26 KiB
PHP

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision$
GREEDY_KERNEL equ 0
struc APP_HEADER_00
{ .banner dq ?
.version dd ? ;+8
.start dd ? ;+12
.i_end dd ? ;+16
.mem_size dd ? ;+20
.i_param dd ? ;+24
}
struc APP_HEADER_01
{ .banner dq ?
.version dd ? ;+8
.start dd ? ;+12
.i_end dd ? ;+16
.mem_size dd ? ;+20
.stack_top dd ? ;+24
.i_param dd ? ;+28
.i_icon dd ? ;+32
}
struc APP_PARAMS
{ .app_cmdline ;0x00
.app_path ;0x04
.app_eip ;0x08
.app_esp ;0x0C
.app_mem ;0x10
}
macro _clear_ op
{ mov ecx, op/4
xor eax, eax
cld
rep stosd
}
fs_execute_from_sysdir:
xor ebx, ebx
xor edx, edx
mov esi, sysdir_path
align 4
proc fs_execute
;fn_read:dword, file_size:dword, cluster:dword
; ebx - cmdline
; edx - flags
; ebp - full filename
; [esp+4] = procedure DoRead, [esp+8] = filesize & [esp+12]... - arguments for it
locals
cmdline rd 64 ;256/4
filename rd 256 ;1024/4
flags dd ?
save_cr3 dd ?
slot dd ?
slot_base dd ?
file_base dd ?
file_size dd ?
;app header data
hdr_cmdline dd ? ;0x00
hdr_path dd ? ;0x04
hdr_eip dd ? ;0x08
hdr_esp dd ? ;0x0C
hdr_mem dd ? ;0x10
hdr_i_end dd ? ;0x14
endl
pushad
mov [flags], edx
; [ebp] pointer to filename
lea edi, [filename]
lea ecx, [edi+1024]
mov al, '/'
stosb
@@:
cmp edi, ecx
jae .bigfilename
lodsb
stosb
test al, al
jnz @b
mov esi, [ebp]
test esi, esi
jz .namecopied
mov byte [edi-1], '/'
@@:
cmp edi, ecx
jae .bigfilename
lodsb
stosb
test al, al
jnz @b
jmp .namecopied
.bigfilename:
popad
mov eax, -ERROR_FILE_NOT_FOUND
ret
.namecopied:
mov [cmdline], ebx
test ebx, ebx
jz @F
lea eax, [cmdline]
mov dword [eax+252], 0
stdcall strncpy, eax, ebx, 255
@@:
lea eax, [filename]
stdcall load_file, eax
mov ecx, -ERROR_FILE_NOT_FOUND
test eax, eax
jz .err_file
mov [file_base], eax
mov [file_size], ebx
lea ebx, [hdr_cmdline]
call test_app_header
mov ecx, -0x1F
test eax, eax
jz .err_hdr
;mov esi, new_process_loading
;call sys_msg_board_str ; write message to message board
.wait_lock:
cmp [application_table_status],0
je .get_lock
call change_task
jmp .wait_lock
.get_lock:
mov eax, 1
xchg eax, [application_table_status]
test eax, eax
jnz .wait_lock
call set_application_table_status
call get_new_process_place
test eax, eax
mov ecx, -0x20 ; too many processes
jz .err
mov [slot], eax
shl eax, 8
add eax, SLOT_BASE
mov [slot_base], eax
mov edi, eax
_clear_ 256 ;clean extended information about process
; write application name
lea eax, [filename]
stdcall strrchr, eax, '/' ; now eax points to name without path
lea esi, [eax+1]
test eax, eax
jnz @F
lea esi, [filename]
@@:
mov ecx, 8 ; 8 chars for name
mov edi, [slot_base]
.copy_process_name_loop:
lodsb
cmp al, '.'
jz .copy_process_name_done
test al, al
jz .copy_process_name_done
stosb
loop .copy_process_name_loop
.copy_process_name_done:
mov ebx, cr3
mov [save_cr3], ebx
stdcall create_app_space,[hdr_mem],[file_base],[file_size]
mov ecx, -30 ; no memory
test eax, eax
jz .failed
mov ebx,[slot_base]
mov [ebx+APPDATA.dir_table],eax
mov eax,[hdr_mem]
mov [ebx+APPDATA.mem_size],eax
xor edx, edx
cmp word [6], '02'
jne @f
not edx
@@:
mov [ebx+APPDATA.tls_base],edx
if GREEDY_KERNEL
else
mov ecx, [hdr_mem]
mov edi, [file_size]
add edi, 4095
and edi, not 4095
sub ecx, edi
jna @F
xor eax, eax
cld
rep stosb
@@:
end if
; release only virtual space, not phisical memory
stdcall free_kernel_space, [file_base]
lea eax, [hdr_cmdline]
lea ebx, [cmdline]
lea ecx, [filename]
stdcall set_app_params ,[slot],eax,ebx,ecx,[flags]
mov eax, [save_cr3]
call set_cr3
xor ebx, ebx
mov [application_table_status],ebx ;unlock application_table_status mutex
mov eax,[process_number] ;set result
ret
.failed:
mov eax, [save_cr3]
call set_cr3
.err:
.err_hdr:
stdcall kernel_free,[file_base]
.err_file:
xor eax, eax
mov [application_table_status],eax
mov eax, ecx
ret
endp
align 4
test_app_header:
virtual at eax
APP_HEADER_00 APP_HEADER_00
end virtual
virtual at eax
APP_HEADER_01 APP_HEADER_01
end virtual
cmp dword [eax], 'MENU'
jne .fail
cmp word [eax+4],'ET'
jne .fail
cmp [eax+6], word '00'
jne .check_01_header
mov ecx,[APP_HEADER_00.start]
mov [ebx+0x08], ecx ;app_eip
mov edx,[APP_HEADER_00.mem_size]
mov [ebx+0x10], edx ;app_mem
shr edx,1
sub edx,0x10
mov [ebx+0x0C], edx ;app_esp
mov ecx,[APP_HEADER_00.i_param]
mov [ebx], ecx ;app_cmdline
mov [ebx+4], dword 0 ;app_path
mov edx, [APP_HEADER_00.i_end]
mov [ebx+0x14], edx
ret
.check_01_header:
cmp [eax+6], word '01'
je @f
cmp [eax+6], word '02'
jne .fail
@@:
mov ecx,[APP_HEADER_01.start]
mov [ebx+0x08], ecx ;app_eip
mov edx,[APP_HEADER_01.mem_size]
; \begin{diamond}[20.08.2006]
; sanity check (functions 19,58 load app_i_end bytes and that must
; fit in allocated memory to prevent kernel faults)
cmp edx,[APP_HEADER_01.i_end]
jb .fail
; \end{diamond}[20.08.2006]
mov [ebx+0x10], edx ;app_mem
mov ecx,[APP_HEADER_01.stack_top]
mov [ebx+0x0C], ecx ;app_esp
mov edx,[APP_HEADER_01.i_param]
mov [ebx], edx ;app_cmdline
mov ecx,[APP_HEADER_01.i_icon]
mov [ebx+4], ecx ;app_path
mov edx, [APP_HEADER_01.i_end]
mov [ebx+0x14], edx
ret
.fail:
xor eax, eax
ret
align 4
proc get_new_process_place
;input:
; none
;result:
; eax=[new_process_place]<>0 - ok
; 0 - failed.
;This function find least empty slot.
;It doesn't increase [TASK_COUNT]!
mov eax,CURRENT_TASK
mov ebx,[TASK_COUNT]
inc ebx
shl ebx,5
add ebx,eax ;ebx - address of process information for (last+1) slot
.newprocessplace:
;eax = address of process information for current slot
cmp eax,ebx
jz .endnewprocessplace ;empty slot after high boundary
add eax,0x20
cmp word [eax+0xa],9 ;check process state, 9 means that process slot is empty
jnz .newprocessplace
.endnewprocessplace:
mov ebx,eax
sub eax,CURRENT_TASK
shr eax,5 ;calculate slot index
cmp eax,256
jge .failed ;it should be <256
mov word [ebx+0xa],9 ;set process state to 9 (for slot after hight boundary)
ret
.failed:
xor eax,eax
ret
endp
align 4
proc create_app_space stdcall, app_size:dword,img_base:dword,img_size:dword
locals
app_pages dd ?
img_pages dd ?
dir_addr dd ?
app_tabs dd ?
endl
mov ebx, pg_data.pg_mutex
call wait_mutex ;ebx
xor eax, eax
mov [dir_addr], eax
mov eax, [app_size]
add eax, 4095
and eax, NOT(4095)
mov [app_size], eax
mov ebx, eax
shr eax, 12
mov [app_pages], eax
add ebx, 0x3FFFFF
and ebx, NOT(0x3FFFFF)
shr ebx, 22
mov [app_tabs], ebx
mov ecx, [img_size]
add ecx, 4095
and ecx, NOT(4095)
mov [img_size], ecx
shr ecx, 12
mov [img_pages], ecx
if GREEDY_KERNEL
lea eax, [ecx+ebx+2] ;only image size
else
lea eax, [eax+ebx+2] ;all requested memory
end if
cmp eax, [pg_data.pages_free]
ja .fail
call alloc_page
test eax, eax
jz .fail
mov [dir_addr], eax
stdcall map_page,[tmp_task_pdir],eax,dword PG_SW
mov edi, [tmp_task_pdir]
mov ecx, (OS_BASE shr 20)/4
xor eax, eax
cld
rep stosd
mov ecx, (OS_BASE shr 20)/4
mov esi, sys_pgdir+(OS_BASE shr 20)
rep movsd
mov eax, [dir_addr]
or eax, PG_SW
mov [edi-4096+(page_tabs shr 20)], eax
and eax, -4096
call set_cr3
mov edx, [app_tabs]
mov edi, new_app_base
@@:
call alloc_page
test eax, eax
jz .fail
stdcall map_page_table, edi, eax
add edi, 0x00400000
dec edx
jnz @B
mov edi, new_app_base
shr edi, 10
add edi, page_tabs
mov ecx, [app_tabs]
shl ecx, 10
xor eax, eax
rep stosd
mov ecx, [img_pages]
mov ebx, PG_UW
mov edx, new_app_base
mov esi, [img_base]
mov edi, new_app_base
shr esi, 10
shr edi, 10
add esi, page_tabs
add edi, page_tabs
.remap:
lodsd
or eax, ebx ; force user level r/w access
stosd
add edx, 0x1000
dec [app_pages]
dec ecx
jnz .remap
mov ecx, [app_pages]
test ecx, ecx
jz .done
if GREEDY_KERNEL
mov eax, 0x02
rep stosd
else
.alloc:
call alloc_page
test eax, eax
jz .fail
stdcall map_page,edx,eax,dword PG_UW
add edx, 0x1000
dec [app_pages]
jnz .alloc
end if
.done:
stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP
dec [pg_data.pg_mutex]
mov eax, [dir_addr]
ret
.fail:
dec [pg_data.pg_mutex]
cmp [dir_addr], 0
je @f
stdcall destroy_app_space, [dir_addr]
@@:
xor eax, eax
ret
endp
align 4
set_cr3:
mov ebx, [current_slot]
mov [ebx+APPDATA.dir_table], eax
mov cr3, eax
ret
align 4
proc destroy_page_table stdcall, pg_tab:dword
push esi
mov esi, [pg_tab]
mov ecx, 1024
.free:
mov eax, [esi]
test eax, 1
jz .next
test eax, 1 shl 9
jnz .next ;skip shared pages
call free_page
.next:
add esi, 4
dec ecx
jnz .free
pop esi
ret
endp
align 4
proc destroy_app_space stdcall, pg_dir:dword
mov ebx, pg_data.pg_mutex
call wait_mutex ;ebx
xor edx,edx
mov eax,0x2
mov ebx, [pg_dir]
.loop:
;eax = current slot of process
mov ecx,eax
shl ecx,5
cmp byte [CURRENT_TASK+ecx+0xa],9 ;if process running?
jz @f ;skip empty slots
shl ecx,3
cmp [SLOT_BASE+ecx+0xB8],ebx ;compare page directory addresses
jnz @f
inc edx ;thread found
@@:
inc eax
cmp eax,[TASK_COUNT] ;exit loop if we look through all processes
jle .loop
;edx = number of threads
;our process is zombi so it isn't counted
cmp edx,1
jg .exit
;if there isn't threads then clear memory.
mov eax, [pg_dir]
and eax, not 0xFFF
stdcall map_page,[tmp_task_pdir],eax,dword PG_SW
mov esi, [tmp_task_pdir]
mov edi, (OS_BASE shr 20)/4
.destroy:
mov eax, [esi]
test eax, 1
jz .next
and eax, not 0xFFF
stdcall map_page,[tmp_task_ptab],eax,dword PG_SW
stdcall destroy_page_table, [tmp_task_ptab]
mov eax, [esi]
call free_page
.next:
add esi, 4
dec edi
jnz .destroy
mov eax, [pg_dir]
call free_page
.exit:
stdcall map_page,[tmp_task_ptab],dword 0,dword PG_UNMAP
stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP
dec [pg_data.pg_mutex]
ret
endp
align 4
get_pid:
mov eax, [TASK_BASE]
mov eax, [eax+TASKDATA.pid]
ret
pid_to_slot:
;Input:
; eax - pid of process
;Output:
; eax - slot of process or 0 if process don't exists
;Search process by PID.
push ebx
push ecx
mov ebx,[TASK_COUNT]
shl ebx,5
mov ecx,2*32
.loop:
;ecx=offset of current process info entry
;ebx=maximum permitted offset
cmp byte [CURRENT_TASK+ecx+0xa],9
jz .endloop ;skip empty slots
cmp [CURRENT_TASK+ecx+0x4],eax ;check PID
jz .pid_found
.endloop:
add ecx,32
cmp ecx,ebx
jle .loop
pop ecx
pop ebx
xor eax,eax
ret
.pid_found:
shr ecx,5
mov eax,ecx ;convert offset to index of slot
pop ecx
pop ebx
ret
check_region:
;input:
; ebx - start of buffer
; ecx - size of buffer
;result:
; eax = 1 region lays in app memory
; eax = 0 region don't lays in app memory
mov eax,[CURRENT_TASK]
jmp check_process_region
;-----------------------------------------------------------------------------
check_process_region:
;input:
; eax - slot
; ebx - start of buffer
; ecx - size of buffer
;result:
; eax = 1 region lays in app memory
; eax = 0 region don't lays in app memory
test ecx,ecx
jle .ok
shl eax,5
cmp word [CURRENT_TASK+eax+0xa],0
jnz .failed
shl eax,3
mov eax,[SLOT_BASE+eax+0xb8]
test eax,eax
jz .failed
mov eax,1
ret
; call MEM_Get_Linear_Address
; push ebx
; push ecx
; push edx
; mov edx,ebx
; and edx,not (4096-1)
; sub ebx,edx
; add ecx,ebx
; mov ebx,edx
; add ecx,(4096-1)
; and ecx,not (4096-1)
;.loop:
;;eax - linear address of page directory
;;ebx - current page
;;ecx - current size
; mov edx,ebx
; shr edx,22
; mov edx,[eax+4*edx]
; and edx,not (4096-1)
; test edx,edx
; jz .failed1
; push eax
; mov eax,edx
; call MEM_Get_Linear_Address
; mov edx,ebx
; shr edx,12
; and edx,(1024-1)
; mov eax,[eax+4*edx]
; and eax,not (4096-1)
; test eax,eax
; pop eax
; jz .failed1
; add ebx,4096
; sub ecx,4096
; jg .loop
; pop edx
; pop ecx
; pop ebx
.ok:
mov eax,1
ret
;
;.failed1:
; pop edx
; pop ecx
; pop ebx
.failed:
xor eax,eax
ret
align 4
proc read_process_memory
;Input:
; eax - process slot
; ebx - buffer address
; ecx - buffer size
; edx - start address in other process
;Output:
; eax - number of bytes read.
locals
slot dd ?
buff dd ?
r_count dd ?
offset dd ?
tmp_r_cnt dd ?
endl
mov [slot], eax
mov [buff], ebx
and [r_count], 0
mov [tmp_r_cnt], ecx
mov [offset], edx
pushad
.read_mem:
mov edx, [offset]
mov ebx, [tmp_r_cnt]
mov ecx, 0x400000
and edx, 0x3FFFFF
sub ecx, edx
cmp ecx, ebx
jbe @f
mov ecx, ebx
@@:
cmp ecx, 0x8000
jna @F
mov ecx, 0x8000
@@:
mov eax, [slot]
shl eax,8
mov ebx, [offset]
push ecx
stdcall map_memEx, [proc_mem_map],\
[SLOT_BASE+eax+0xB8],\
ebx, ecx
pop ecx
mov esi, [offset]
and esi, 0xfff
add esi, [proc_mem_map]
mov edi, [buff]
mov edx, ecx
rep movsb
add [r_count], edx
add [offset], edx
sub [tmp_r_cnt], edx
jnz .read_mem
popad
mov eax, [r_count]
ret
endp
align 4
proc write_process_memory
;Input:
; eax - process slot
; ebx - buffer address
; ecx - buffer size
; edx - start address in other process
;Output:
; eax - number of bytes written
locals
slot dd ?
buff dd ?
w_count dd ?
offset dd ?
tmp_w_cnt dd ?
endl
mov [slot], eax
mov [buff], ebx
and [w_count], 0
mov [tmp_w_cnt], ecx
mov [offset], edx
pushad
.read_mem:
mov edx, [offset]
mov ebx, [tmp_w_cnt]
mov ecx, 0x400000
and edx, 0x3FFFFF
sub ecx, edx
cmp ecx, ebx
jbe @f
mov ecx, ebx
@@:
cmp ecx, 0x8000
jna @F
mov ecx, 0x8000
@@:
mov eax, [slot]
shl eax,8
mov ebx, [offset]
; add ebx, new_app_base
push ecx
stdcall map_memEx, [proc_mem_map],\
[SLOT_BASE+eax+0xB8],\
ebx, ecx
pop ecx
mov edi, [offset]
and edi, 0xfff
add edi, [proc_mem_map]
mov esi, [buff]
mov edx, ecx
rep movsb
add [w_count], edx
add [offset], edx
sub [tmp_w_cnt], edx
jnz .read_mem
popad
mov eax, [w_count]
ret
endp
align 4
proc new_sys_threads
locals
slot dd ?
app_cmdline dd ? ;0x00
app_path dd ? ;0x04
app_eip dd ? ;0x08
app_esp dd ? ;0x0C
app_mem dd ? ;0x10
endl
cmp eax,1
jne .failed ;other subfunctions
xor eax,eax
mov [app_cmdline], eax
mov [app_path], eax
mov [app_eip], ebx
mov [app_esp], ecx
;mov esi,new_process_loading
;call sys_msg_board_str
.wait_lock:
cmp [application_table_status],0
je .get_lock
call change_task
jmp .wait_lock
.get_lock:
mov eax, 1
xchg eax, [application_table_status]
cmp eax, 0
jne .wait_lock
call set_application_table_status
call get_new_process_place
test eax, eax
jz .failed
mov [slot], eax
mov esi,[current_slot]
mov ebx,esi ;ebx=esi - pointer to extended information about current thread
mov edi, eax
shl edi,8
add edi,SLOT_BASE
mov edx,edi ;edx=edi - pointer to extended infomation about new thread
mov ecx,256/4
xor eax, eax
cld
rep stosd ;clean extended information about new thread
mov esi,ebx
mov edi,edx
mov ecx,11
rep movsb ;copy process name
mov eax,[ebx+APPDATA.heap_base]
mov [edx+APPDATA.heap_base], eax
mov ecx,[ebx+APPDATA.heap_top]
mov [edx+APPDATA.heap_top], ecx
mov eax,[ebx+APPDATA.mem_size]
mov [edx+APPDATA.mem_size], eax
mov ecx,[ebx+APPDATA.dir_table]
mov [edx+APPDATA.dir_table],ecx ;copy page directory
mov eax, [ebx+APPDATA.tls_base]
test eax, eax
jz @F
push edx
stdcall user_alloc, 4096
pop edx
test eax, eax
jz .failed
@@:
mov [edx+APPDATA.tls_base], eax
lea eax, [app_cmdline]
stdcall set_app_params ,[slot],eax,dword 0,\
dword 0,dword 0
;mov esi,new_process_running
;call sys_msg_board_str ;output information about succefull startup
mov [application_table_status],0 ;unlock application_table_status mutex
mov eax,[process_number] ;set result
ret
.failed:
mov [application_table_status],0
mov eax,-1
ret
endp
; param
; ebx=mutex
align 4
wait_mutex:
;;Maxis use atomic bts for mutex 4.4.2009
push eax
push ebx
.do_wait:
bts dword [ebx],0
jnc .locked
call change_task
jmp .do_wait
.locked:
pop ebx
pop eax
ret
align 4
tls_app_entry:
call init_heap
stdcall user_alloc, 4096
mov edx, [current_slot]
mov [edx+APPDATA.tls_base], eax
mov [tls_data_l+2],ax
shr eax,16
mov [tls_data_l+4],al
mov [tls_data_l+7],ah
mov dx, app_tls
mov fs, dx
popad
iretd
EFL_IF equ 0x0200
EFL_IOPL1 equ 0x1000
EFL_IOPL2 equ 0x2000
EFL_IOPL3 equ 0x3000
align 4
proc set_app_params stdcall,slot:dword, params:dword,\
cmd_line:dword, app_path:dword, flags:dword
locals
pl0_stack dd ?
endl
stdcall kernel_alloc, RING0_STACK_SIZE+512
mov [pl0_stack], eax
lea edi, [eax+RING0_STACK_SIZE]
mov eax, [slot]
mov ebx, eax
shl eax, 8
mov [eax+SLOT_BASE+APPDATA.fpu_state], edi
mov [eax+SLOT_BASE+APPDATA.exc_handler], 0
mov [eax+SLOT_BASE+APPDATA.except_mask], 0
;set default io permission map
mov [eax+SLOT_BASE+APPDATA.io_map],\
(tss._io_map_0-OS_BASE+PG_MAP)
mov [eax+SLOT_BASE+APPDATA.io_map+4],\
(tss._io_map_1-OS_BASE+PG_MAP)
mov esi, fpu_data
mov ecx, 512/4
rep movsd
cmp ebx,[TASK_COUNT]
jle .noinc
inc dword [TASK_COUNT] ;update number of processes
.noinc:
shl ebx,8
lea edx, [ebx+SLOT_BASE+APP_EV_OFFSET]
mov [SLOT_BASE+APPDATA.fd_ev+ebx],edx
mov [SLOT_BASE+APPDATA.bk_ev+ebx],edx
add edx, APP_OBJ_OFFSET-APP_EV_OFFSET
mov [SLOT_BASE+APPDATA.fd_obj+ebx],edx
mov [SLOT_BASE+APPDATA.bk_obj+ebx],edx
mov ecx, [def_cursor]
mov [SLOT_BASE+APPDATA.cursor+ebx],ecx
mov eax, [pl0_stack]
mov [SLOT_BASE+APPDATA.pl0_stack+ebx],eax
add eax, RING0_STACK_SIZE
mov [SLOT_BASE+APPDATA.saved_esp0+ebx], eax
push ebx
stdcall kernel_alloc, 0x1000
pop ebx
mov esi,[current_slot]
mov esi,[esi+APPDATA.cur_dir]
mov ecx,0x1000/4
mov edi,eax
mov [ebx+SLOT_BASE+APPDATA.cur_dir],eax
rep movsd
shr ebx,3
mov eax, new_app_base
mov dword [CURRENT_TASK+ebx+0x10],eax
.add_command_line:
mov edx,[params]
mov edx,[edx] ;app_cmdline
test edx,edx
jz @f ;application doesn't need parameters
mov eax, edx
add eax, 256
jc @f
cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8]
ja @f
mov byte [edx], 0 ;force empty string if no cmdline given
mov eax, [cmd_line]
test eax, eax
jz @f
stdcall strncpy, edx, eax, 256
@@:
mov edx,[params]
mov edx, [edx+4] ;app_path
test edx,edx
jz @F ;application don't need path of file
mov eax, edx
add eax, 1024
jc @f
cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8]
ja @f
stdcall strncpy, edx, [app_path], 1024
@@:
mov ebx,[slot]
mov eax,ebx
shl ebx,5
lea ecx,[draw_data+ebx] ;ecx - pointer to draw data
mov edx, irq0.return
cmp [ebx*8+SLOT_BASE+APPDATA.tls_base], -1
jne @F
mov edx, tls_app_entry
@@:
; set window state to 'normal' (non-minimized/maximized/rolled-up) state
mov [ebx+window_data+WDATA.fl_wstate], WSTATE_NORMAL
mov [ebx+window_data+WDATA.fl_redraw], 1
add ebx,CURRENT_TASK ;ebx - pointer to information about process
mov [ebx+TASKDATA.wnd_number],al;set window number on screen = process slot
mov [ebx+TASKDATA.event_mask],dword 1+2+4 ;set default event flags (see 40 function)
inc dword [process_number]
mov eax,[process_number]
mov [ebx+4],eax ;set PID
;set draw data to full screen
mov [ecx+0],dword 0
mov [ecx+4],dword 0
mov eax,[Screen_Max_X]
mov [ecx+8],eax
mov eax,[Screen_Max_Y]
mov [ecx+12],eax
mov ebx, [pl0_stack]
mov esi,[params]
lea ecx, [ebx+REG_EIP]
xor eax, eax
mov [ebx+REG_RET], edx
mov [ebx+REG_EDI], eax
mov [ebx+REG_ESI], eax
mov [ebx+REG_EBP], eax
mov [ebx+REG_ESP], ecx ;ebx+REG_EIP
mov [ebx+REG_EBX], eax
mov [ebx+REG_EDX], eax
mov [ebx+REG_ECX], eax
mov [ebx+REG_EAX], eax
mov eax, [esi+0x08] ;app_eip
mov [ebx+REG_EIP], eax ;app_entry
mov [ebx+REG_CS], dword app_code
mov [ebx+REG_EFLAGS], dword EFL_IOPL1+EFL_IF
mov eax, [esi+0x0C] ;app_esp
mov [ebx+REG_APP_ESP], eax ;app_stack
mov [ebx+REG_SS], dword app_data
lea ecx, [ebx+REG_RET]
mov ebx, [slot]
shl ebx, 5
mov [ebx*8+SLOT_BASE+APPDATA.saved_esp], ecx
xor ecx, ecx ; process state - running
; set if debuggee
test byte [flags], 1
jz .no_debug
inc ecx ; process state - suspended
mov eax,[CURRENT_TASK]
mov [SLOT_BASE+ebx*8+APPDATA.debugger_slot],eax
.no_debug:
mov [CURRENT_TASK+ebx+TASKDATA.state], cl
;mov esi,new_process_running
;call sys_msg_board_str ;output information about succefull startup
ret
endp
include "debug.inc"