Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 1 → Rev 2

/kernel/trunk/core/fpu.inc
0,0 → 1,62
iglobal
prev_user_of_fpu dd 0x1 ; set to OS
endg
 
label fpu_tss at 0xB080
label fpu_stack dword at 0xB060
 
 
align 4
fpu_handler:
 
; clear TS flag in CR0 -> for task switching
clts
 
; save FPU context of the previous task
mov eax,[prev_user_of_fpu]
shl eax,8
add eax,0x80000+0x10
fsave [eax]
 
; next task switch save our FPU context
; now restore context of current task (if exists)
mov eax,[0x3000]
mov [prev_user_of_fpu],eax
shl eax,8
add eax,0x80000
cmp [eax+0x7f],byte 0
je bs7_first_fpu
frstor [eax+0x10]
bs7_first_fpu:
mov [eax+0x7f],byte 1
 
; prepare structure in stack for proper IRET
movzx eax,word [fpu_tss+l.ss-tss_sceleton] ; push ss
push eax
mov eax,[fpu_tss+l.esp-tss_sceleton] ; push esp
push eax
mov eax,[fpu_tss+l.eflags-tss_sceleton] ; push eflags
push eax
 
movzx eax,word [fpu_tss+l.cs-tss_sceleton] ; push cs
push eax
mov eax,[fpu_tss+l.eip-tss_sceleton] ; push eip
push eax
 
; save eax
push dword [fpu_tss+l.eax-tss_sceleton]
 
; restore all segment registers
mov ax,[fpu_tss+l.es-tss_sceleton]
mov es,ax
mov ax,[fpu_tss+l.fs-tss_sceleton]
mov fs,ax
mov ax,[fpu_tss+l.gs-tss_sceleton]
mov gs,ax
mov ax,[fpu_tss+l.ds-tss_sceleton]
mov ds,ax
 
; restore eax
pop eax
 
iret
/kernel/trunk/core/mem.inc
0,0 → 1,473
if ~defined mem_inc
mem_inc_fix:
mem_inc fix mem_inc_fix
;include "memmanag.inc"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;High-level memory management in MenuetOS.
;;It uses memory manager in memmanager.inc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
second_base_address=0xC0000000
std_application_base_address=0x10000000
general_page_table_ dd 0
general_page_table=general_page_table_+second_base_address
;-----------------------------------------------------------------------------
create_general_page_table:
;input
; none
;output
; none
;Procedure create general page directory and write
;it address to [general_page_table].
pushad
mov eax,1 ;alloc 1 page
mov ebx,general_page_table ;write address to [general_page_table]
call MEM_Alloc_Pages ;allocate page directory
mov eax,[general_page_table]
call MEM_Get_Linear_Address ;eax - linear address of page directory
mov edi,eax
mov ebx,eax
xor eax,eax
mov ecx,4096/4
cld
rep stosd ;clear page directory
mov eax,4
mov edx,eax
call MEM_Alloc_Pages ;alloc page tables for 0x0-0x1000000 region
cmp eax,edx
jnz $ ;hang if not enough memory
;fill page tables
xor esi,esi
mov ebp,7
.loop:
;esi - number of page in page directory
;ebp - current page address
;ebx - linear address of page directory
mov eax,[ebx+4*esi]
add dword [ebx+4*esi],7 ;add flags to address of page table
call MEM_Get_Linear_Address
;eax - linear address of page table
mov ecx,4096/4
;ecx (counter) - number of pages in page table
;current address=4Mb*esi
cmp esi,2
jz .start_lfb_map ;lfb map begin at 0x800000
cmp esi,3
jz .end_lfb_map ;lfb map end at 0xC00000
jmp .loop1
.start_lfb_map:
;current address=lfb address
mov ebp,[0x2f0000+0x9018]
add ebp,7 ;add flags
jmp .loop1
.end_lfb_map:
;current address=linear address
mov ebp,12*0x100000+7
.loop1:
mov [eax],ebp ;write page address (with flags) in page table
add eax,4
add ebp,4096 ;size of page=4096 bytes
loop .loop1
inc esi ;next page directory entry
cmp esi,edx
jnz .loop
;map region 0x80000000-0x803fffff to 0x800000-0xcfffff
mov eax,1 ;size of the region is 4Mb so only 1 page table needed
mov edx,ebx ;ebx still contains linear address of the page directory
add ebx,0x800
call MEM_Alloc_Pages ;alloc page table for the region
mov eax,[ebx]
add dword [ebx],7 ;add flags
call MEM_Get_Linear_Address ;get linear address of the page table
mov ebx,eax
mov ecx,4096/4 ;number of pages in page table
mov eax,8*0x100000+7
.loop3:
;ebx - linear address of page table
;eax - current linear address with flags
mov [ebx],eax
add ebx,4
add eax,4096
loop .loop3
;map region 0xC0000000-* to 0x0-*
mov esi,edx ;esi=linear address of the page directory
lea edi,[esi+(second_base_address shr 20)];add offset of entry (0xC00)
mov ecx,4
rep movsd ;first 16Mb of the region mapped as 0x0-0x1000000 block
mov eax,[0xfe8c] ;eax=memory size
add eax,0x3fffff
shr eax,22
mov esi,eax ;calculate number of entries in page directory
sub esi,4 ;subtract entries for first 16Mb.
mov ebp,0x1000000+7 ;start physical address with flags
;mapping memory higher than 16Mb
.loop4:
;esi (counter) - number of entries in page directory
;edi - address of entry
test esi,esi
jle .loop4end
call MEM_Alloc_Page ;alloc page table for entry in page directory
mov [edi],eax
add dword [edi],7 ;write physical address of page table in page directory
add edi,4 ;move entry pointer
call MEM_Get_Linear_Address
mov ecx,eax
xor edx,edx
.loop5:
;ecx - linear address of page table
;edx - index of page in page table
;ebp - current mapped physical address with flags
mov [ecx+4*edx],ebp ;write address of page in page table
add ebp,0x1000 ;move to next page
inc edx
cmp edx,4096/4
jl .loop5
dec esi
jmp .loop4
.loop4end:
.set_cr3:
;set value of cr3 register to the address of page directory
mov eax,[general_page_table]
add eax,8+16 ;add flags
mov cr3,eax ;now we have full access paging
popad
ret
;-----------------------------------------------------------------------------
simple_clone_cr3_table:
;Parameters:
; eax - physical address of cr3 table (page directory)
;result:
; eax - physical address of clone of cr3 table.
;Function copy only page directory.
push ecx
push edx
push esi
push edi
call MEM_Get_Linear_Address
;eax - linear address of cr3 table
mov esi,eax
call MEM_Alloc_Page
test eax,eax
jz .failed
;eax - physical address of new page diretory
mov edx,eax
call MEM_Get_Linear_Address
mov edi,eax
mov ecx,4096/4
cld
;esi - address of old page directory
;edi - address of new page directory
rep movsd ;copy page directory
mov eax,edx
.failed:
pop edi
pop esi
pop edx
pop ecx
ret
;-----------------------------------------------------------------------------
create_app_cr3_table:
;Parameters:
; eax - slot of process (index in 0x3000 table)
;result:
; eax - physical address of table.
;This function create page directory for new process and
;write it physical address to offset 0xB8 of extended
;process information.
push ebx
 
mov ebx,eax
mov eax,[general_page_table]
call simple_clone_cr3_table ;clone general page table
shl ebx,8
mov [second_base_address+0x80000+ebx+0xB8],eax ;save address of page directory
pop ebx
ret
;-----------------------------------------------------------------------------
get_cr3_table:
;Input:
; eax - slot of process
;result:
; eax - physical address of page directory
shl eax,8 ;size of process extended information=256 bytes
mov eax,[second_base_address+0x80000+eax+0xB8]
ret
;-----------------------------------------------------------------------------
dispose_app_cr3_table:
;Input:
; eax - slot of process
;result:
; none
;This procedure frees page directory,
;page tables and all memory of process.
pushad
mov ebp,eax
;ebp = process slot in the procedure.
shl eax,8
mov eax,[second_base_address+0x80000+eax+0xB8]
mov ebx,eax
;ebx = physical address of page directory
call MEM_Get_Linear_Address
mov edi,eax
;edi = linear address of page directory
mov eax,[edi+(std_application_base_address shr 20)]
and eax,not (4096-1)
call MEM_Get_Linear_Address
mov esi,eax
;esi = linear address of first page table
 
;search threads
; mov ecx,0x200
xor edx,edx
mov eax,0x2
.loop:
;eax = current slot of process
mov ecx,eax
shl ecx,5
cmp byte [second_base_address+0x3000+ecx+0xa],0 ;if process running?
jnz .next ;slot empty or process is terminating - go to next slot
shl ecx,3
cmp [second_base_address+0x80000+ecx+0xB8],ebx ;compare page directory addresses
jnz .next
inc edx ;thread found
.next:
inc eax
cmp eax,[0x3004] ;exit loop if we look through all processes
jle .loop
;edx = number of threads
;our process is zombi so it isn't counted
test edx,edx
jnz .threadsexists
;if there isn't threads then clear memory.
add edi,std_application_base_address shr 20
.loop1:
;edi = linear address of current directory entry
;esi = linear address of current page table
test esi,esi
jz .loop1end
xor ecx,ecx
.loop2:
;ecx = index of page
mov eax,[esi+4*ecx]
test eax,eax
jz .loopend ;skip empty entries
and eax,not (4096-1) ;clear flags
push ecx
call MEM_Free_Page ;free page
pop ecx
.loopend:
inc ecx
cmp ecx,1024 ;there are 1024 pages in page table
jl .loop2
mov eax,esi
call MEM_Free_Page_Linear ;free page table
.loop1end:
add edi,4 ;move to next directory entry
mov eax,[edi]
and eax,not (4096-1)
call MEM_Get_Linear_Address
mov esi,eax ;calculate linear address of new page table
test edi,0x800
jz .loop1 ;test if we at 0x80000000 address?
and edi,not (4096-1) ;clear offset of page directory entry
mov eax,edi
call MEM_Free_Page_Linear ;free page directory
popad
ret
.threadsexists: ;do nothing
popad ;last thread will free memory
ret
;-----------------------------------------------------------------------------
mem_alloc_specified_region:
;eax - linear directory address
;ebx - start address (aligned to 4096 bytes)
;ecx - size in pages
;result:
; eax=1 - ok
; eax=0 - failed
;Try to alloc and map ecx pages to [ebx;ebx+4096*ecx) interval.
pushad
mov ebp,ebx ;save start address for recoil
mov esi,eax
.gen_loop:
;esi = linear directory address
;ebx = current address
;ecx = remaining size in pages
mov edx,ebx
shr edx,22
mov edi,[esi+4*edx] ;find directory entry for current address
test edi,edi
jnz .table_exists ;check if page table allocated
call MEM_Alloc_Page ;alloc page table
test eax,eax
jz .failed
mov [esi+4*edx],eax
add dword [esi+4*edx],7 ;write it address with flags
call MEM_Get_Linear_Address
call mem_fill_page ;clear page table
jmp .table_linear
.table_exists:
;calculate linear address of page table
mov eax,edi
and eax,not (4096-1) ;clear flags
call MEM_Get_Linear_Address
.table_linear:
;eax = linear address of page table
mov edx,ebx
shr edx,12
and edx,(1024-1) ;calculate index in page table
mov edi,eax
.loop:
;edi = linear address of page table
;edx = current page table index
;ecx = remaining size in pages
;ebx = current address
test ecx,ecx
jle .endloop1 ;all requested pages allocated
call MEM_Alloc_Page ;alloc new page
test eax,eax
jz .failed
mov [edi+4*edx],eax
add dword [edi+4*edx],7 ;write it address with flags
call MEM_Get_Linear_Address
call mem_fill_page ;clear new page
;go to next page table entry
dec ecx
add ebx,4096
inc edx
test edx,(1024-1)
jnz .loop
jmp .gen_loop
.endloop1:
popad
mov eax,1 ;ok
ret
.failed:
;calculate data for recoil
sub ebx,ebp
shr ebx,12
mov ecx,ebx ;calculate number of allocated pages
mov eax,esi ;restore linear address of page directory
mov ebx,ebp ;restore initial address
call mem_free_specified_region ;free all allocated pages
popad
xor eax,eax ;fail
ret
;-----------------------------------------------------------------------------
mem_fill_page:
;Input:
; eax - address
;result:
; none
;set to zero 4096 bytes at eax address.
push ecx
push edi
mov edi,eax
mov ecx,4096/4
xor eax,eax
rep stosd
lea eax,[edi-4096]
pop edi
pop ecx
ret
;-----------------------------------------------------------------------------
mem_free_specified_region:
;eax - linear page directory address
;ebx - start address (aligned to 4096 bytes)
;ecx - size in pages
;result - none
;Free pages in [ebx;ebx+4096*ecx) region.
pushad
mov esi,eax
xor ebp,ebp
.gen_loop:
;esi = linear page directory address
;ebx = current address
;ecx = remaining pages
;ebp = 0 for first page table
; 1 otherwise
mov edx,ebx
shr edx,22
mov eax,[esi+4*edx] ;find directory entry for current address
and eax,not (4096-1)
test eax,eax
jnz .table_exists
;skip absent page tables
mov edx,ebx
shr edx,12
and edx,(1024-1) ;edx - index of current page
add ebx,1 shl 22
add ecx,edx
and ebx,not ((1 shl 22)-1)
mov ebp,1 ;set flag
sub ecx,1024 ;ecx=ecx-(1024-edx)
jg .gen_loop
popad
ret
.table_exists:
call MEM_Get_Linear_Address
;eax - linear address of table
mov edx,ebx
shr edx,12
and edx,(1024-1) ;edx - index of current page
mov edi,eax
.loop:
;edi = linear address of page table entry
;edx = index of page table entry
;ecx = remaining pages
test ecx,ecx
jle .endloop1
mov eax,[edi+4*edx]
and eax,not (4096-1)
call MEM_Free_Page ;free page
mov dword [edi+4*edx],0 ;and clear page table entry
dec ecx
inc edx
cmp edx,1024
jl .loop
test ebp,ebp
jz .first_page
mov eax,edi
call MEM_Free_Page_Linear ;free page table
mov edx,ebx
shr edx,22
mov dword [esi+4*edx],0 ;and clear page directory entry
.first_page:
add ebx,1 shl 22
and ebx,not ((1 shl 22)-1) ;calculate new current address
mov ebp,1 ;set flag
jmp .gen_loop
.endloop1:
popad
ret
end if
/kernel/trunk/core/memmanag.inc
0,0 → 1,977
if ~defined memmanager_inc
memmanager_inc_fix:
memmanager_inc fix memmanager_inc_fix
;for testing in applications
if defined B32
iskernel=1
else
iskernel=0
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Memory allocator for MenuetOS kernel
;; Andrey Halyavin, halyavin@land.ru 2005
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; heap block structure -
;; you can handle several ranges of
;; pages simultaneosly.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.heap_linear_address equ 0
.heap_block_size equ 4
.heap_physical_address equ 8
.heap_reserved equ 12
.heap_block_info equ 16
max_heaps equ 8
.range_info equ 36
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; memory manager data
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MEM_heap_block_ rd .heap_block_info*max_heaps/4
MEM_heap_block=MEM_heap_block_+second_base_address
MEM_heap_count_ rd 1
MEM_heap_count=MEM_heap_count_+second_base_address
if iskernel = 0
MEM_general_mutex rd 1
MEM_call_count rd 1
MEM_mutex_pid rd 1
MEM_mutex_count rd 1
else
MEM_cli_count_ rd 1
MEM_cli_count=MEM_cli_count_+second_base_address
MEM_cli_prev_ rd 1
MEM_cli_prev=MEM_cli_prev_+second_base_address
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Init
;;Initialize memory manager structures.
;;Must be called first.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MEM_Init:
push eax
xor eax,eax
if iskernel = 0
mov [MEM_heap_count],eax
mov [MEM_general_mutex],eax
mov [MEM_call_count],eax
mov [MEM_mutex_pid],eax
mov [MEM_mutex_count],eax
else
mov [MEM_cli_prev],eax ;init value = 0
dec eax
mov [MEM_cli_count],eax ;init value = -1
end if
pop eax
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;change_task
;;procedure for changing tasks.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if iskernel = 0
change_task:
push eax
push ebx
mov eax,5
xor ebx,ebx
inc ebx
int 0x40
pop ebx
pop eax
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_get_pid
;;determine current pid
;;result:
;; eax - pid
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if iskernel = 0
MEM_get_pid:
push ebx
push ecx
sub esp,1024
mov eax,9
mov ebx,esp
mov ecx,-1
int 0x40
mov eax,[esp+30]
add esp,1024
pop ecx
pop ebx
ret
else
; pid_address dd 0x3000
;MEM_get_pid:
; mov eax,[pid_address]
; mov eax,[eax]
; ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Heap_Lock
;;Wait until all operations with heap will be finished.
;;Between MEM_Heap_Lock and MEM_Heap_UnLock operations
;;with heap are forbidden.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MEM_Heap_Lock:
if iskernel = 0
push eax
inc dword [MEM_call_count]
MEM_Heap_Lock_wait:
mov eax,1
xchg [MEM_general_mutex],eax
test eax,eax
jz MEM_Heap_Lock_end
call MEM_get_pid
cmp [MEM_mutex_pid],eax
jz MEM_Heap_Lock_end1
call change_task
jmp MEM_Heap_Lock_wait
MEM_Heap_Lock_end1:
inc dword [MEM_mutex_count]
pop eax
ret
MEM_Heap_Lock_end:
call MEM_get_pid
mov [MEM_mutex_pid],eax
mov dword [MEM_mutex_count],1
pop eax
ret
else
pushfd
cli
inc dword [MEM_cli_count]
jz MEM_Heap_First_Lock
add esp,4
ret
MEM_Heap_First_Lock: ;save interrupt flag
shr dword [esp],9
and dword [esp],1
pop dword [MEM_cli_prev]
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Heap_UnLock
;;After this routine operations with heap are allowed.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MEM_Heap_UnLock:
if iskernel = 0
push eax
xor eax,eax
dec dword [MEM_mutex_count]
jnz MEM_Heap_UnLock_No_Wait1
dec dword [MEM_call_count]
mov [MEM_mutex_pid],eax
mov [MEM_general_mutex],eax;release mutex BEFORE task switching
jz MEM_Heap_UnLock_No_Wait
call change_task ;someone want to use heap - switch tasks
MEM_Heap_UnLock_No_Wait:
pop eax
ret
MEM_Heap_UnLock_No_Wait1:
dec dword [MEM_call_count]
jz MEM_Heap_UnLock_No_Wait2
call change_task
MEM_Heap_UnLock_No_Wait2:
pop eax
ret
else
dec dword [MEM_cli_count]
js MEM_Heap_UnLock_last
ret
MEM_Heap_UnLock_last:
cmp dword [MEM_cli_prev],0 ;restore saved interrupt flag
jz MEM_Heap_UnLock_No_sti
sti
MEM_Heap_UnLock_No_sti:
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Add_Heap
;;Add new range to memory manager.
;;eax - linear address
;;ebx - size in pages
;;ecx - physical address
;;Result:
;; eax=1 - success
;; eax=0 - failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MEM_Add_Heap:
push edx
call MEM_Heap_Lock
mov edx,[MEM_heap_count]
cmp edx,max_heaps
jz MEM_Add_Heap_Error
inc dword [MEM_heap_count]
shl edx,4
mov [MEM_heap_block+edx+.heap_linear_address],eax
mov [MEM_heap_block+edx+.heap_block_size],ebx
shl dword [MEM_heap_block+edx+.heap_block_size],12
mov [MEM_heap_block+edx+.heap_physical_address],ecx
lea edx,[4*ebx+.range_info+4095] ;calculate space for page info table
and edx,0xFFFFF000
mov [eax],eax
add [eax],edx ;first 4 bytes - pointer to first free page
;clean page info area
push edi
lea edi,[eax+4]
mov ecx,edx
shr ecx,2
push eax
xor eax,eax
rep stosd
pop eax
pop edi
;create free pages list.
mov ecx,[eax]
shl ebx,12
add eax,ebx ;eax - address after block
MEM_Add_Heap_loop:
add ecx,4096
mov [ecx-4096],ecx ;set forward pointer
cmp ecx,eax
jnz MEM_Add_Heap_loop
mov dword [ecx-4096],0 ;set end of list
MEM_Add_Heap_ret:
call MEM_Heap_UnLock
pop edx
ret
MEM_Add_Heap_Error:
xor eax,eax
jmp MEM_Add_Heap_ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Get_Physical_Address
;;Translate linear address to physical address
;;Parameters:
;; eax - linear address
;;Result:
;; eax - physical address
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Get_Physical_Address
MEM_Get_Physical_Address:
push ecx
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Get_Physical_Address_loop:
sub eax,[MEM_heap_block+ecx+.heap_linear_address]
jl MEM_Get_Physical_Address_next
cmp eax,[MEM_heap_block+ecx+.heap_block_size]
jge MEM_Get_Physical_Address_next
add eax,[MEM_heap_block+ecx+.heap_physical_address]
jmp MEM_Get_Physical_Address_loopend
MEM_Get_Physical_Address_next:
add eax,[MEM_heap_block+ecx+.heap_linear_address]
sub ecx,16
jns MEM_Get_Physical_Address_loop
xor eax,eax ;address not found
MEM_Get_Physical_Address_loopend:
call MEM_Heap_UnLock
pop ecx
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Get_Linear_Address
;;Translate physical address to linear address.
;;Parameters:
;; eax - physical address
;;Result:
;; eax - linear address
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Get_Linear_Address
MEM_Get_Linear_Address:
push ecx
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Get_Linear_Address_loop:
sub eax,[MEM_heap_block+ecx+.heap_physical_address]
jl MEM_Get_Linear_Address_Next
cmp eax,[MEM_heap_block+ecx+.heap_block_size]
jge MEM_Get_Linear_Address_Next
add eax,[MEM_heap_block+ecx+.heap_linear_address]
call MEM_Heap_UnLock
pop ecx
ret
MEM_Get_Linear_Address_Next:
add eax,[MEM_heap_block+ecx+.heap_physical_address]
sub ecx,16
jns MEM_Get_Linear_Address_loop
call MEM_Heap_UnLock
pop ecx
xor eax,eax ;address not found
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Alloc_Page
;;Allocate and add reference to page
;;Result:
;; eax<>0 - physical address of page
;; eax=0 - not enough memory
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Alloc_Page
MEM_Alloc_Page:
push ecx
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Alloc_Page_loop:
push ecx
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
cmp dword [ecx],0
jz MEM_Alloc_Page_loopend
mov eax,[ecx]
push dword [eax]
pop dword [ecx]
sub eax,ecx
push eax
shr eax,10
mov word [ecx+.range_info+eax],1
pop eax
pop ecx
add eax,[MEM_heap_block+ecx+.heap_physical_address]
jmp MEM_Alloc_Page_ret
MEM_Alloc_Page_loopend:
pop ecx
sub ecx,16
jns MEM_Alloc_Page_loop
xor eax,eax
MEM_Alloc_Page_ret:
call MEM_Heap_UnLock
pop ecx
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Alloc_Page_Linear
;;Allocate and add reference to page
;;Result:
;; eax<>0 - linear address of page
;; eax=0 - not enough memory
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Alloc_Page_Linear
MEM_Alloc_Page_Linear:
push ecx
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Alloc_Page_Linear_loop:
push ecx
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
cmp dword [ecx],0
jz MEM_Alloc_Page_Linear_loopend
mov eax,[ecx]
push dword [eax]
pop dword [ecx]
push eax
sub eax,ecx
shr eax,10
mov word [ecx+.range_info+eax],1
pop eax
pop ecx
jmp MEM_Alloc_Page_Linear_ret
MEM_Alloc_Page_Linear_loopend:
pop ecx
sub ecx,16
jns MEM_Alloc_Page_Linear_loop
xor eax,eax
MEM_Alloc_Page_Linear_ret:
call MEM_Heap_UnLock
pop ecx
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Free_Page
;;Remove reference and free page if number of
;;references is equal to 0
;;Parameters:
;; eax - physical address of page
;;Result:
;; eax - 1 success
;; eax - 0 failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Free_Page
MEM_Free_Page:
test eax,eax
jz MEM_Free_Page_Zero
test eax,0xFFF
jnz MEM_Free_Page_Not_Aligned
push ebx
push ecx
push edx
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Free_Page_Heap_loop:
sub eax,[MEM_heap_block+ecx+.heap_physical_address]
js MEM_Free_Page_Heap_loopnext
cmp eax,[MEM_heap_block+ecx+.heap_block_size]
jl MEM_Free_Page_Heap_loopend
MEM_Free_Page_Heap_loopnext:
add eax,[MEM_heap_block+ecx+.heap_physical_address]
sub ecx,16
jns MEM_Free_Page_Heap_loop
xor eax,eax
inc eax
jmp MEM_Free_Page_ret
MEM_Free_Page_Heap_loopend:
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
mov ebx,eax
add eax,ecx
shr ebx,10
mov edx,[ecx+.range_info+ebx]
test edx,0x80000000
jnz MEM_Free_Page_Bucket
test dx,dx
jz MEM_Free_Page_Error
dec word [ecx+.range_info+ebx]
jnz MEM_Free_Page_OK
MEM_Free_Page_Bucket:
push dword [ecx]
mov [ecx],eax
pop dword [eax]
mov dword [ecx+.range_info+ebx],0
MEM_Free_Page_OK:
mov eax,1
MEM_Free_Page_ret:
call MEM_Heap_UnLock
pop edx
pop ecx
pop ebx
ret
MEM_Free_Page_Error:
xor eax,eax
jmp MEM_Free_Page_ret
MEM_Free_Page_Zero:
inc eax
ret
MEM_Free_Page_Not_Aligned:
xor eax,eax
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Free_Page_Linear
;;Remove reference and free page if number of
;;references is equal to 0
;;Parameters:
;; eax - linear address of page
;;Result:
;; eax - 1 success
;; eax - 0 failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Free_Page_Linear
MEM_Free_Page_Linear:
test eax,eax
jz MEM_Free_Page_Linear_Zero
test eax,0xFFF
jnz MEM_Free_Page_Linear_Not_Aligned
push ebx
push ecx
push edx
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Free_Page_Linear_Heap_loop:
sub eax,[MEM_heap_block+ecx+.heap_linear_address]
js MEM_Free_Page_Linear_Heap_loopnext
cmp eax,[MEM_heap_block+ecx+.heap_block_size]
jl MEM_Free_Page_Linear_Heap_loopend
MEM_Free_Page_Linear_Heap_loopnext:
add eax,[MEM_heap_block+ecx+.heap_linear_address]
sub ecx,16
jns MEM_Free_Page_Linear_Heap_loop
xor eax,eax
inc eax
jmp MEM_Free_Page_Linear_ret
MEM_Free_Page_Linear_Heap_loopend:
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
mov ebx,eax
add eax,ecx
shr ebx,10
mov edx,[ecx+.range_info+ebx]
test edx,0x80000000
jnz MEM_Free_Page_Linear_Bucket
test dx,dx
jz MEM_Free_Page_Linear_Error
dec word [ecx+.range_info+ebx]
jnz MEM_Free_Page_Linear_OK
MEM_Free_Page_Linear_Bucket:
mov edx,[ecx]
mov [eax],edx
mov dword [eax+4],0
mov [ecx],eax
test edx,edx
jz MEM_Free_Page_No_Next
mov [edx+4],eax
MEM_Free_Page_No_Next:
mov dword [ecx+.range_info+ebx],0
MEM_Free_Page_Linear_OK:
xor eax, eax
inc eax
MEM_Free_Page_Linear_ret:
call MEM_Heap_UnLock
pop edx
pop ecx
pop ebx
ret
MEM_Free_Page_Linear_Error:
xor eax,eax
jmp MEM_Free_Page_Linear_ret
MEM_Free_Page_Linear_Zero:
inc eax
ret
MEM_Free_Page_Linear_Not_Aligned:
xor eax,eax
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Alloc_Pages
;;Allocates set of pages.
;;Parameters:
;; eax - number of pages
;; ebx - buffer for physical addresses
;;Result:
;; eax - number of allocated pages
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Alloc_Pages
MEM_Alloc_Pages:
push eax
push ebx
push ecx
mov ecx,eax
test ecx,ecx
jz MEM_Alloc_Pages_ret
MEM_Alloc_Pages_loop:
call MEM_Alloc_Page
test eax,eax
jz MEM_Alloc_Pages_ret
mov [ebx],eax
add ebx,4
dec ecx
jnz MEM_Alloc_Pages_loop
MEM_Alloc_Pages_ret:
sub [esp+8],ecx
pop ecx
pop ebx
pop eax
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Alloc_Pages_Linear
;;Allocates set of pages.
;;Parameters:
;; eax - number of pages
;; ebx - buffer for linear addresses
;;Result:
;; eax - number of allocated pages
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Alloc_Pages_Linear
MEM_Alloc_Pages_Linear:
push eax
push ebx
push ecx
mov ecx,eax
test ecx,ecx
jz MEM_Alloc_Pages_Linear_ret
MEM_Alloc_Pages_Linear_loop:
call MEM_Alloc_Page_Linear
test eax,eax
jz MEM_Alloc_Pages_Linear_ret
mov [ebx],eax
add ebx,4
dec ecx
jnz MEM_Alloc_Pages_Linear_loop
MEM_Alloc_Pages_Linear_ret:
sub [esp+8],ecx
pop ecx
pop ebx
pop eax
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Free_Pages
;;Parameters:
;; eax - number of pages
;; ebx - array of addresses
;;Result:
;; eax=1 - succcess
;; eax=0 - failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Free_Pages
MEM_Free_Pages:
push ebx
push ecx
mov ecx,eax
test ecx,ecx
jz MEM_Free_Pages_ret
MEM_Free_Pages_loop:
mov eax,[ebx]
call MEM_Free_Page
add ebx,4
test eax,eax
jz MEM_Free_Pages_ret
dec ecx
jnz MEM_Free_Pages_loop
MEM_Free_Pages_ret:
pop ecx
pop ebx
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Free_Pages_Linear
;;Parameters:
;; eax - number of pages
;; ebx - array of addresses
;;Result:
;; eax=1 - succcess
;; eax=0 - failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Free_Pages_Linear
MEM_Free_Pages_Linear:
push ebx
push ecx
mov ecx,eax
test ecx,ecx
jz MEM_Free_Pages_Linear_ret
MEM_Free_Pages_Linear_loop:
mov eax,[ebx]
call MEM_Free_Page_Linear
add ebx,4
test eax,eax
jz MEM_Free_Pages_Linear_ret
dec ecx
jnz MEM_Free_Pages_Linear_loop
MEM_Free_Pages_Linear_ret:
pop ecx
pop ebx
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Get_Heap_Number
;;Calculate number of heap which pointer belongs to.
;;Parameter:
;; eax - address
;;Result:
;; ecx - number of heap*16.
;; eax=0 if address not found.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Get_Heap_Number
MEM_Get_Heap_Number:
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Get_Heap_loop:
sub eax,[MEM_heap_block+ecx+.heap_physical_address]
jl MEM_Get_Heap_loopnext
cmp eax,[MEM_heap_block+ecx+.heap_block_size]
jl MEM_Get_Heap_loopend
MEM_Get_Heap_loopnext:
add eax,[MEM_heap_block+ecx+.heap_physical_address]
sub ecx,16
jns MEM_Get_Heap_loop
call MEM_Heap_UnLock
xor eax,eax
ret
MEM_Get_Heap_loopend:
add eax,[MEM_heap_block+ecx+.heap_physical_address]
call MEM_Heap_UnLock
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Get_Heap_Number_Linear
;;Calculate number of heap which pointer belongs to.
;;Parameter:
;; eax - address
;;Result:
;; ecx - number of heap*16.
;; eax=0 if address not found.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Get_Heap_Number_Linear
MEM_Get_Heap_Number_Linear:
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Get_Heap_Linear_loop:
sub eax,[MEM_heap_block+ecx+.heap_linear_address]
jl MEM_Get_Heap_Linear_loopnext
cmp eax,[MEM_heap_block+ecx+.heap_block_size]
jl MEM_Get_Heap_Linear_loopend
MEM_Get_Heap_Linear_loopnext:
add eax,[MEM_heap_block+ecx+.heap_linear_address]
sub ecx,16
jns MEM_Get_Heap_Linear_loop
call MEM_Heap_UnLock
xor eax,eax
ret
MEM_Get_Heap_Linear_loopend:
add eax,[MEM_heap_block+ecx+.heap_linear_address]
call MEM_Heap_UnLock
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Alloc
;;Allocate small region.
;;Parameters:
;; eax - size (0<eax<=4096)
;;Result:
;; eax - linear address
;; eax=0 - not enough memory
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Alloc
MEM_Alloc:
;find chain
test eax,eax
jng MEM_Alloc_Wrong_Size
cmp eax,4096
jg MEM_Alloc_Wrong_Size
push ebx
push ecx
push edx
push esi
dec eax
shr eax,4
xor edx,edx
MEM_Alloc_Find_Size:
add edx,4
shr eax,1
jnz MEM_Alloc_Find_Size
MEM_Alloc_Size_Found:
mov ecx,edx
shr ecx,2
add ecx,4
mov eax,1
shl eax,cl
mov esi,eax
;esi - block size
;edx - offset
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Alloc_Find_Heap:
mov eax,[MEM_heap_block+ecx+.heap_linear_address]
cmp dword [eax+edx],0
jnz MEM_Alloc_Use_Existing
sub ecx,16
jns MEM_Alloc_Find_Heap
;create new bucket page
call MEM_Alloc_Page_Linear
call MEM_Get_Heap_Number_Linear
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
mov [ecx+edx],eax
lea ebx,[eax+4096]
MEM_Alloc_List_loop:
mov [eax],eax
mov [eax+4],eax
add [eax],esi
sub [eax+4],esi
add eax,esi
cmp eax,ebx
jnz MEM_Alloc_List_loop
sub ebx,esi
mov dword [ebx],0
sub eax,4096
mov dword [eax+4],0
mov eax,ecx
MEM_Alloc_Use_Existing:
mov ebx,eax
mov eax,[eax+edx]
mov ecx,[eax]
mov [ebx+edx],ecx
test ecx,ecx
jz MEM_Alloc_Became_Empty
mov dword [ecx+4],0
MEM_Alloc_Became_Empty:
mov ecx,eax
sub ecx,ebx
shr ecx,10
and ecx,0xFFFFFFFC
inc byte [ebx+.range_info+ecx+2]
shr edx,2
add edx,128
dec edx
mov [ebx+.range_info+ecx+3],dl
MEM_Alloc_ret:
call MEM_Heap_UnLock
pop esi
pop edx
pop ecx
pop ebx
ret
MEM_Alloc_Wrong_Size:
xor eax,eax
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Free
;;Parameters:
;; eax - linear address
;;Result:
;; eax=1 - success
;; eax=0 - failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Free
MEM_Free:
test eax,eax
jz MEM_Free_Zero
push ebx
push ecx
push edx
push esi
push edi
push ebp
call MEM_Heap_Lock
call MEM_Get_Heap_Number_Linear
test eax,eax
jz MEM_Free_ret
mov edx,eax
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
sub edx,ecx
shr edx,10
and edx,0xFFFFFFFC
mov ebx,[ecx+.range_info+edx]
mov esi,ebx
shr esi,24
sub esi,128
mov edi,[ecx+4+4*esi]
mov [eax],edi
mov dword [eax+4],0
test edi,edi
jz MEM_Free_Empty_List
mov [edi+4],eax
MEM_Free_Empty_List:
mov [ecx+4+4*esi],eax
sub ebx,0x10000
mov [ecx+.range_info+edx],ebx
test ebx,0xFF0000
jnz MEM_Free_ret
;delete empty blocks on the page
lea edx,[esi+5]
and eax,0xFFFFF000
mov edi,eax
mov eax,1
xchg ecx,edx
shl eax,cl
mov ecx,edx
mov edx,eax
;edx - size of block
;edi - start of page
mov eax,edi
lea ebx,[eax+4096]
MEM_Free_Block_loop:
cmp dword [eax+4],0
jnz MEM_Free_Block_Not_First
mov ebp,dword [eax]
mov [ecx+4+4*esi],ebp
test ebp,ebp
jz MEM_Free_Block_Last
mov dword [ebp+4],0
MEM_Free_Block_Last:
jmp MEM_Free_Block_loop_end
MEM_Free_Block_Not_First:
mov ebp,dword [eax]
push ebp
mov ebp,dword [eax+4]
pop dword [ebp]
mov ebp,dword [eax]
test ebp,ebp
jz MEM_Free_Block_loop_end
push dword [eax+4]
pop dword [ebp+4]
; jmp MEM_Free_Block_loop_end
MEM_Free_Block_loop_end:
add eax,edx
cmp eax,ebx
jnz MEM_Free_Block_loop
mov eax,edi
call MEM_Free_Page_Linear
MEM_Free_ret:
call MEM_Heap_UnLock
pop ebp
pop edi
pop esi
pop edx
pop ecx
pop ebx
ret
MEM_Free_Zero:
inc eax
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Add_Reference
;; eax - physical address of page
;;Result:
;; eax=1 - success
;; eax=0 - failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Add_Reference
MEM_Add_Reference:
push ebx
push ecx
call MEM_Heap_Lock
call MEM_Get_Heap_Number
test eax,eax
jz MEM_Add_Reference_ret
sub eax,[MEM_heap_block+ecx+.heap_physical_address]
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
shr eax,10
and eax,0xFFFFFFFC
test dword [ecx+eax+.range_info],0x80000000
jnz MEM_Add_Reference_failed
inc dword [ecx+eax+.range_info]
MEM_Add_Reference_ret:
call MEM_Heap_UnLock
pop ecx
pop ebx
ret
MEM_Add_Reference_failed:
xor eax,eax
jmp MEM_Add_Reference_ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Add_Reference_Linear
;; eax - linear address of page
;;Result:
;; eax=1 - success
;; eax=0 - failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Add_Reference_Linear
MEM_Add_Reference_Linear:
push ebx
push ecx
call MEM_Heap_Lock
call MEM_Get_Heap_Number_Linear
test eax,eax
jz MEM_Add_Reference_Linear_ret
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
sub eax,ecx
shr eax,10
and eax,0xFFFFFFFC
test dword [ecx+eax+.range_info],0x80000000
jnz MEM_Add_Reference_Linear_failed
inc dword [ecx+eax+.range_info]
mov eax,1
MEM_Add_Reference_Linear_ret:
call MEM_Heap_UnLock
pop ecx
pop ebx
ret
MEM_Add_Reference_Linear_failed:
xor eax,eax
jmp MEM_Add_Reference_Linear_ret
end if
end if ;memmanager.inc
/kernel/trunk/core/newproce.inc
0,0 → 1,1321
if ~defined newprocess_inc
newprocess_inc_fix:
newprocess_inc fix newprocess_inc_fix
include "mem.inc"
include "memmanag.inc"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Working with new types of processes.
;;Author: Khalyavin Andrey halyavin@land.ru
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
iglobal
new_process_loading db 'K : New Process - loading',13,10,0
new_process_running db 'K : New Process - done',13,10,0
start_not_enough_memory db 'K : New Process - not enough memory',13,10,0
endg
;-----------------------------------------------------------------------------
find_new_process_place:
;input:
; none
;result:
; eax=[new_process_place]<>0 - ok
; 0 - failed.
;This function find least empty slot.
;It doesn't increase [0x3004]!
mov eax,0x3000+second_base_address
push ebx
mov ebx,[0x3004]
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,0x3000+second_base_address
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)
mov [new_process_place],eax ;save process slot
pop ebx
ret
.failed:
xor eax,eax
pop ebx
ret
;-----------------------------------------------------------------------------
 
new_start_application_floppy:
;input:
; eax - pointer to filename
; ebx - parameters to pass
;result:
; eax - pid of new process
; or 0 if call fails.
pushad
mov esi,new_process_loading
call sys_msg_board_str ;write to debug board
;wait application_table_status mutex
.table_status:
cli
cmp [application_table_status],0
jz .stf
sti
call change_task
jmp .table_status
.stf:
call set_application_table_status
;we can change system tables now
push edi
push ebx
push eax
call find_new_process_place ;find empty process slot
sti
test eax,eax
jz .failed
 
mov edi,eax
shl edi,8
add edi,0x80000
mov ecx,256/4
xor eax,eax
cld
rep stosd ;clean extended information about process
;set new process name
mov eax,[esp+8]
.find_last_byte:
cmp byte [eax],0
jz .find_last_byte_end
inc eax
jmp .find_last_byte
.find_last_byte_end:
sub eax,11 ;last 11 bytes = application name
; mov eax,[esp] ;eax - pointer to file name
mov ebx,[new_process_place]
shl ebx,8
add ebx,0x80000
mov ecx,11
call memmove
;read header of file
mov eax,[esp]
mov ebx,1 ;index of first block
mov ecx,2 ;number of blocks
mov edx,0x90000 ;temp area
mov esi,12 ;file name length
mov edi,[esp+8]
; cli
call floppy_fileread ;read file from FD
; sti
cmp eax,0
jne .cleanfailed
;check MENUET signature
cmp [0x90000],dword 'MENU'
jnz .cleanfailed
cmp [0x90004],word 'ET'
jnz .cleanfailed
call get_app_params ;parse header fields
cmp esi,0
jz .cleanfailed
mov eax,[new_process_place]
call create_app_cr3_table ;create page directory for new process
test eax,eax
jz .cleanfailed_mem
call MEM_Get_Linear_Address ;calculate linear address of it
mov ebx,std_application_base_address
mov ecx,[app_mem]
add ecx,4095
shr ecx,12
mov edx,eax
call mem_alloc_specified_region ;allocate memory for application
test eax,eax
jz .cleanfailed_mem
mov eax,[edx+(std_application_base_address shr 20)]
and eax,not (4096-1) ;eax - physical address of first (for application memory) page table
call MEM_Get_Linear_Address
mov edx,eax
;read file
mov ebx,1
mov esi,12 ;length of file name
.loop1:
;edx = linear address of current page table entry
;ebx = index of current block in file
push edx
mov eax,[edx]
and eax,not (4096-1)
call MEM_Get_Linear_Address
mov edx,eax ;read file block to current page
mov eax,[esp+4] ;restore pointer to file name
mov ecx,8 ;number of blocks read
push ebx
mov edi,[esp+16]
; cli
call floppy_fileread
;ebx=file size
; sti
pop ecx
shr ebx,9
cmp ecx,ebx
jg .endloop1 ;if end of file?
mov ebx,ecx
test eax,eax
jnz .endloop1 ;check io errors
pop edx
add ebx,8 ;go to next page
add edx,4
jmp .loop1
.endloop1:
add esp,8+4 ;pop linear address of page table entry and pointer to file name
call new_start_application_fl.add_app_parameters
mov [esp+28],eax
popad
ret
.cleanfailed_mem:
mov esi,start_not_enough_memory
call sys_msg_board_str
.cleanfailed: ;clean process name
mov edi,[new_process_place]
shl edi,8
add edi,0x80000
mov ecx,11
mov eax,' '
cld
rep stosb
.failed:
add esp,8+4
mov [application_table_status],0
popad
sti
mov eax,-1
ret
 
;-----------------------------------------------------------------------------
new_start_application_fl:
;input:
; eax - pointer to filename
; ebx - parameters to pass
;result:
; eax - pid of new process
; or 0 if call fails.
pushad
mov esi,new_process_loading
call sys_msg_board_str ;write to debug board
;wait application_table_status mutex
.table_status:
cli
cmp [application_table_status],0
jz .stf
sti
call change_task
jmp .table_status
.stf:
call set_application_table_status
;we can change system tables now
push ebx
push eax
call find_new_process_place ;find empty process slot
sti
test eax,eax
jz .failed
 
mov edi,eax
shl edi,8
add edi,0x80000
mov ecx,256/4
xor eax,eax
cld
rep stosd ;clean extended information about process
;set new process name
mov eax,[esp] ;eax - pointer to file name
mov ebx,[new_process_place]
shl ebx,8
add ebx,0x80000
mov ecx,11
call memmove
;read header of file
mov ebx,1 ;index of first block
mov ecx,2 ;number of blocks
mov edx,0x90000 ;temp area
mov esi,12 ;file name length
cli
call fileread ;read file from RD
sti
cmp eax,0
jne .cleanfailed
;check MENUET signature
cmp [0x90000],dword 'MENU'
jnz .cleanfailed
cmp [0x90004],word 'ET'
jnz .cleanfailed
call get_app_params ;parse header fields
cmp esi,0
jz .failed
mov eax,[new_process_place]
call create_app_cr3_table ;create page directory for new process
test eax,eax
jz .cleanfailed_mem
call MEM_Get_Linear_Address ;calculate linear address of it
mov ebx,std_application_base_address
mov ecx,[app_mem]
add ecx,4095
shr ecx,12
mov edx,eax
call mem_alloc_specified_region ;allocate memory for application
test eax,eax
jz .cleanfailed_mem
mov eax,[edx+(std_application_base_address shr 20)]
and eax,not (4096-1) ;eax - physical address of first (for application memory) page table
call MEM_Get_Linear_Address
mov edx,eax
;read file
mov ebx,1
mov esi,12 ;length of file name
.loop1:
;edx = linear address of current page table entry
;ebx = index of current block in file
push edx
mov eax,[edx]
and eax,not (4096-1)
call MEM_Get_Linear_Address
mov edx,eax ;read file block to current page
mov eax,[esp+4] ;restore pointer to file name
mov ecx,8 ;number of blocks read
push ebx
cli
call fileread
;ebx=file size
sti
pop ecx
shr ebx,9
cmp ecx,ebx
jg .endloop1 ;if end of file?
mov ebx,ecx
test eax,eax
jnz .endloop1 ;check io errors
pop edx
add ebx,8 ;go to next page
add edx,4
jmp .loop1
.endloop1:
add esp,8 ;pop linear address of page table entry and pointer to file name
call .add_app_parameters
mov [esp+28],eax
popad
ret
.cleanfailed_mem:
mov esi,start_not_enough_memory
call sys_msg_board_str
.cleanfailed: ;clean process name
mov edi,[new_process_place]
shl edi,8
add edi,0x80000
mov ecx,11
mov eax,' '
cld
rep stosb
.failed:
add esp,8
mov [application_table_status],0
popad
sti
mov eax,-1
ret
.add_app_parameters:
;input:
; [esp] - pointer to parameters
; [esp+4]-[esp+36] pushad registers.
;result
; eax - pid of new process
; or zero if failed
cli
mov ebx,[new_process_place]
cmp ebx,[0x3004]
jle .noinc
inc dword [0x3004] ;update number of processes
.noinc:
 
; mov ebx,[new_process_place]
;set 0x8c field of extended information about process
;(size of application memory)
shl ebx,8
mov eax,[app_mem]
mov [second_base_address+0x80000+0x8c+ebx],eax
;set 0x10 field of information about process
;(application base address)
; mov ebx,[new_process_place]
; shl ebx,5
shr ebx,3
mov dword [second_base_address+0x3000+ebx+0x10],std_application_base_address
 
;add command line parameters
.add_command_line:
mov edx,[app_i_param]
test edx,edx
jz .no_command_line ;application don't need parameters
mov eax,[esp+4]
test eax,eax
jz .no_command_line ;no parameters specified
;calculate parameter length
mov esi,eax
xor ecx,ecx
.command_line_len:
cmp byte [esi],0
jz .command_line_len_end
inc esi
inc ecx
cmp ecx,256
jl .command_line_len
.command_line_len_end:
;ecx - parameter length
;edx - address of parameters in new process address space
mov ebx,eax ;ebx - address of parameters in our address space
mov eax,[new_process_place]
call write_process_memory ;copy parameters to new process address space
.no_command_line:
mov ebx,[new_process_place]
mov eax,ebx
shl ebx,5
add ebx,0x3000 ;ebx - pointer to information about process
mov [ebx+0xe],al ;set window number on screen = process slot
mov [ebx],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
mov ecx,ebx
add ecx,draw_data-0x3000 ;ecx - pointer to draw data
;set draw data to full screen
mov [ecx+0],dword 0
mov [ecx+4],dword 0
mov eax,[0xfe00]
mov [ecx+8],eax
mov eax,[0xfe04]
mov [ecx+12],eax
;set cr3 register in TSS of application
mov ecx,[new_process_place]
shl ecx,8
mov eax,[0x800B8+ecx]
add eax,8+16 ;add flags
mov [l.cr3],eax
;write cr3 in TSS of System Call Handler
mov ecx,[new_process_place]
shl ecx,7
mov [0x298000+ecx+l.cr3-tss_sceleton],eax ;write directy to TSS
mov eax,[app_start]
mov [l.eip],eax ;set eip in TSS
mov eax,[app_esp]
mov [l.esp],eax ;set stack in TSS
;gdt
mov ebx,[new_process_place]
shl ebx,3
mov ax,app_code ;ax - selector of code segment
add ax,bx
mov [l.cs],ax
mov ax,app_data
add ax,bx ;ax - selector of data segment
mov [l.ss],ax
mov [l.ds],ax
mov [l.es],ax
mov [l.fs],ax
mov ax,graph_data ;ax - selector of graphic segment
mov [l.gs],ax
mov [l.io],word 128
mov [l.eflags],dword 0x11202
mov [l.ss0],os_data
mov [l.esp0],0x55000
; mov [l.esp1],0x56000
; mov [l.esp2],0x57000
 
;copy tss to it place
mov eax,tss_sceleton
mov ebx,[new_process_place]
imul ebx,tss_step
add ebx,tss_data ;ebx - address of application TSS
mov ecx,120
call memmove
;Add IO access table - bit array of permitted ports
or eax,-1
mov edi,[new_process_place]
imul edi,tss_step
add edi,tss_data+128
mov ecx,2048
cld
rep stosd ;full access to 2048*8=16384 ports
mov ecx,ebx ;ecx - address of application TSS
mov edi,[new_process_place]
shl edi,3
;set TSS descriptor
mov [edi+gdts+tss0+0],word tss_step ;limit (size)
mov [edi+gdts+tss0+2],cx ;part of offset
mov eax,ecx
shr eax,16
mov [edi+gdts+tss0+4],al ;part of offset
mov [edi+gdts+tss0+7],ah ;part of offset
mov [edi+gdts+tss0+5],word 01010000b*256+11101001b ;system flags
;set code and data segments
mov eax,[new_process_place]
shl eax,3
;set base address of code segment
mov word [eax+gdts+app_code-3+2],0
mov byte [eax+gdts+app_code-3+4],0
mov byte [eax+gdts+app_code-3+7],std_application_base_address shr 24
;set limit of code segment
; mov ebx,[app_mem]
; add ebx,4095
; shr ebx,12
mov ebx,(0x80000000-std_application_base_address) shr 12
mov [eax+gdts+app_code-3+0],bx
mov [eax+gdts+app_code-3+5],word 11010000b*256+11111010b+256*((0x80000000-std_application_base_address) shr 28)
;set base address of data segment
mov word [eax+gdts+app_data-3+2],0
mov byte [eax+gdts+app_data-3+4],0
mov byte [eax+gdts+app_data-3+7],std_application_base_address shr 24
;set limit of data segment
mov [eax+gdts+app_data-3+0],bx
mov [eax+gdts+app_data-3+5],word 11010000b*256+11110010b+256*((0x80000000-std_application_base_address) shr 28)
 
;flush keyboard and buttons queue
mov [0xf400],byte 0
mov [0xf500],byte 0
 
mov edi,[new_process_place]
shl edi,5
add edi,window_data
mov ebx,[new_process_place]
movzx esi,word [0xC000+ebx*2]
lea esi,[0xC400+esi*2]
call windowactivate ;gui initialization
 
mov ebx,[new_process_place]
shl ebx,5
mov [0x3000+ebx+0xa],byte 0 ;set process state - running
mov esi,new_process_running
call sys_msg_board_str ;output information about succefull startup
; add esp,4 ;pop pointer to parameters
; popad
mov eax,[process_number] ;set result
mov [application_table_status],0 ;unlock application_table_status mutex
sti
ret 4
;-----------------------------------------------------------------------------
new_sys_threads:
;eax=1 - create thread
; ebx=thread start
; ecx=thread stack value
;result:
; eax=pid
pushad
cmp eax,1
jnz .ret ;other subfunctions
mov esi,new_process_loading
call sys_msg_board_str
;lock application_table_status mutex
.table_status:
cli
cmp [application_table_status],0
je .stf
sti
call change_task
jmp .table_status
.stf:
call set_application_table_status
;find free process slot
 
call find_new_process_place
test eax,eax
jz .failed
;set parameters for thread
xor eax,eax
mov [app_i_param],eax
mov [app_i_icon],eax
mov [app_start],ebx
mov [app_esp],ecx
 
mov esi,[0x3000]
shl esi,8
add esi,0x80000
mov ebx,esi ;ebx=esi - pointer to extended information about current thread
mov edi,[new_process_place]
shl edi,8
add edi,0x80000
mov edx,edi ;edx=edi - pointer to extended infomation about new thread
mov ecx,256/4
rep stosd ;clean extended information about new thread
mov edi,edx
mov ecx,11
rep movsb ;copy process name
mov eax,[ebx+0x8c]
mov [app_mem],eax ;set memory size
mov eax,[ebx+0xb8]
mov [edx+0xb8],eax ;copy page directory
; mov eax,[new_process_place]
; mov ebx,[0x3000]
; call addreference_app_cr3_table
 
push 0 ;no parameters
call new_start_application_fl.add_app_parameters ;start thread
mov [esp+28],eax
popad
ret
.failed:
sti
popad
mov eax,-1
ret
.ret:
popad
ret
;-----------------------------------------------------------------------------
new_mem_resize:
;input:
; ebx - new size
;result:
; [esp+36]:=0 - normal
; [esp+36]:=1 - error
;This function set new application memory size.
mov esi,ebx ;save new size
add ebx,4095
and ebx,not (4096-1) ;round up size
mov ecx,[0x3000]
shl ecx,8
mov edx,[0x8008C+ecx]
add edx,4095
and edx,not (4096-1) ;old size
mov eax,[0x800B8+ecx]
call MEM_Get_Linear_Address
;eax - linear address of page directory
call MEM_Heap_Lock ;guarantee that two threads willn't
;change memory size simultaneously
cmp ebx,edx
; mov esi,ebx ;save new size
jg .expand
.free:
sub edx,ebx
jz .unlock ;do nothing
mov ecx,edx
shr ecx,12
add ebx,std_application_base_address
call mem_free_specified_region ;free unnecessary pages
jmp .unlock
 
.expand:
sub ebx,edx
mov ecx,ebx
shr ecx,12
mov ebx,edx
add ebx,std_application_base_address
call mem_alloc_specified_region ;alloc necessary pages
test eax,eax
jz .failed ;not enough memory
.unlock:
mov ebx,esi
mov eax,[0x3000]
shl eax,8
mov [eax+0x8008c],ebx ;write new memory size
;search threads and update
;application memory size infomation
mov ecx,[eax+0x800b8]
mov eax,2
.search_threads:
;eax = current slot
;ebx = new memory size
;ecx = page directory
cmp eax,[0x3004]
jg .search_threads_end
mov edx,eax
shl edx,5
cmp word [0x3000+edx+0xa],9 ;if slot empty?
jz .search_threads_next
shl edx,3
cmp [edx+0x800b8],ecx ;if it is our thread?
jnz .search_threads_next
mov [edx+0x8008c],ebx ;update memory size
.search_threads_next:
inc eax
jmp .search_threads
.search_threads_end:
 
call MEM_Heap_UnLock
mov dword [esp+36],0
ret
.failed:
call MEM_Heap_UnLock
mov dword [esp+36],1
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,[0x3004]
shl ebx,5
mov ecx,2*32
.loop:
;ecx=offset of current process info entry
;ebx=maximum permitted offset
cmp byte [second_base_address+0x3000+ecx+0xa],9
jz .endloop ;skip empty slots
cmp [second_base_address+0x3000+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
;-----------------------------------------------------------------------------
is_new_process:
;Input:
; eax - process slot
;Output:
; eax=1 - it is new process
; eax=0 - it is old process
; shl eax,5
; mov eax,[second_base_address+0x3000+eax+0x10]
; cmp eax,std_application_base_address ;check base address of application
; jz .new_process
; xor eax,eax
; ret
;.new_process:
mov eax,1
ret
;-----------------------------------------------------------------------------
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
pushad
shl eax,8
mov eax,[0x80000+eax+0xB8]
call MEM_Get_Linear_Address
mov ebp,eax
;ebp=linear address of page directory of other process.
add edx,std_application_base_address ;convert to linear address
test ecx,ecx
jle .ret
.write_loop:
;ebx = current buffer address
;ecx>0 = current size
;edx = current address in other process
;ebp = linear address of page directory
 
call MEM_Heap_Lock ;cli
mov esi,edx
shr esi,22
mov eax,[ebp+4*esi] ;find page directory entry
and eax,not (4096-1) ;clear flags
test eax,eax
jz .page_not_found
call MEM_Get_Linear_Address ;calculate linear address of page table
test eax,eax
jz .page_not_found
mov esi,edx
shr esi,12
and esi,1023
mov eax,[eax+4*esi] ;find page table entry
and eax,not (4096-1)
test eax,eax
jz .page_not_found
call MEM_Get_Linear_Address ;calculate linear address of page
test eax,eax
jz .page_not_found
mov edi,eax
call MEM_Add_Reference_Linear;guarantee that page willn't disappear
call MEM_Heap_UnLock ;sti
mov esi,edx
and esi,4095
add edi,esi ;add offset in page
;edi = linear address corresponding edx in other process
sub esi,4096
neg esi ;esi - number of remaining bytes in page
cmp esi,ecx
jl .min_ecx
mov esi,ecx
.min_ecx: ;esi=min(ecx,esi) - number of bytes to write
sub ecx,esi
push ecx
mov ecx,esi ;ecx - number of bytes to write
mov esi,ebx ;esi - source, edi - destination
add edx,ecx ;move pointer in address space of other process
push edi
;move ecx bytes
test ecx,3
jnz .not_aligned
shr ecx,2
rep movsd
jmp .next_iter
.not_aligned:
rep movsb
.next_iter:
 
pop eax
and eax,not (4096-1) ;eax - linear address of current page
call MEM_Free_Page_Linear ;free reference
mov ebx,esi ;new pointer to buffer - movsb automaticaly advance it.
pop ecx ;restore number of remaining bytes
test ecx,ecx
jnz .write_loop
.ret:
popad
mov eax,ecx
ret
.page_not_found:
call MEM_Heap_UnLock ;error has appeared in critical region
sub ecx,[esp+24] ;[esp+24]<-->ecx
neg ecx ;ecx=number_of_written_bytes
mov [esp+28],ecx ;[esp+28]<-->eax
popad
ret
;-----------------------------------------------------------------------------
syscall_test:
;for testing memory manager from applications.
mov edx,ecx
mov ecx,ebx
call trans_address
mov ebx,eax
mov eax,[0x3000]
call read_process_memory
ret
;-----------------------------------------------------------------------------
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.
pushad
shl eax,8
mov eax,[0x80000+eax+0xB8]
call MEM_Get_Linear_Address
mov ebp,eax
add edx,std_application_base_address
.read_loop:
;ebx = current buffer address
;ecx>0 = current size
;edx = current address in other process
;ebp = linear address of page directory
 
call MEM_Heap_Lock ;cli
mov esi,edx
shr esi,22
mov eax,[ebp+4*esi] ;find page directory entry
and eax,not (4096-1)
test eax,eax
jz .page_not_found
call MEM_Get_Linear_Address
test eax,eax
jz .page_not_found
mov esi,edx
shr esi,12
and esi,1023
mov eax,[eax+4*esi] ;find page table entry
and eax,not (4096-1)
test eax,eax
jz .page_not_found
call MEM_Get_Linear_Address ;calculate linear address of page
test eax,eax
jz .page_not_found
mov esi,eax
call MEM_Add_Reference_Linear;guarantee that page willn't disappear
call MEM_Heap_UnLock ;sti
mov edi,edx
and edi,4095
add esi,edi ;add offset in page
;esi = linear address corresponding edx in other process
sub edi,4096
neg edi
;edi=min(edi,ecx) - number of bytes to copy
cmp edi,ecx
jl .min_ecx
mov edi,ecx
.min_ecx:
 
sub ecx,edi ;update size of remaining bytes
add edx,edi ;update current pointer in other address space.
push ecx
mov ecx,edi ;ecx - number of bytes to read
mov edi,ebx ;esi - source, edi - destination
push esi
;move ecx bytes
test ecx,3
jnz .not_aligned
shr ecx,2
rep movsd
jmp .next_iter
.not_aligned:
rep movsb
.next_iter:
pop eax
and eax,not (4096-1) ;eax - linear address of current page
call MEM_Free_Page_Linear ;free reference
mov ebx,edi ;new pointer to buffer - movsb automaticaly advance it.
pop ecx ;restore number of remaining bytes
test ecx,ecx
jnz .read_loop
popad
mov eax,ecx
ret
.page_not_found:
call MEM_Heap_UnLock ;error has appeared in critical region
sub ecx,[esp+24] ;[esp+24]<-->ecx
neg ecx ;ecx=number_of_read_bytes
mov [esp+28],ecx ;[esp+28]<-->eax
popad
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,[0x3000]
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 [0x3000+eax+0xa],0
jnz .failed
shl eax,3
mov eax,[0x80000+eax+0xb8]
test eax,eax
jz .failed
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
;-----------------------------------------------------------------------------
new_sys_ipc:
;input:
; eax=1 - set ipc buffer area
; ebx=address of buffer
; ecx=size of buffer
; eax=2 - send message
; ebx=PID
; ecx=address of message
; edx=size of message
cmp eax,1
jnz .no_ipc_def
;set ipc buffer area
mov edi,[0x3000]
shl edi,8
add edi,0x80000
cli
mov [edi+0xA0],ebx ;set fields in extended information area
mov [edi+0xA4],ecx
sti
mov [esp+36],dword 0 ;success
ret
.no_ipc_def:
cmp eax,2
jnz .no_ipc_send
;send message
cli
;obtain slot from PID
mov eax,ebx
call pid_to_slot
test eax,eax
jz .no_pid
mov ebp,eax
;ebp = slot of other process
shl eax,8
mov edi,[eax+0x80000+0xa0] ;is ipc area defined?
test edi,edi
jz .no_ipc_area
mov esi,[eax+0x80000+0xa4] ;esi - size of buffer
push dword -1 ;temp variable for read_process_memory
mov ebx,esp
push ecx
push edx
mov ecx,4 ;read 4 bytes
mov eax,ebp
mov edx,edi ;from beginning of buffer.
call read_process_memory
mov eax,[esp+8]
test eax,eax
jnz .ipc_blocked ;if dword [buffer]<>0 - ipc blocked now
add edx,4 ;move to next 4 bytes
mov eax,ebp
call read_process_memory ;read size of occupied space in buffer
sub esi,8
sub esi,[esp]
sub esi,[esp+8] ;esi=(buffer size)-(occupied size)-(message size)-(header of message size)
js .buffer_overflow ;esi<0 - not enough memory in buffer
mov esi,[esp+8] ;previous offset
add dword [esp+8],8
mov edi,[esp]
add [esp+8],edi ;add (size of message)+(size of header of message) to [buffer+4]
mov eax,ebp
call write_process_memory
add edx,esi
sub edx,4 ;move to beginning of place for our message
mov eax,[second_base_address+0x3010]
mov eax,[eax+0x4] ;eax - our PID
mov [esp+8],eax
mov eax,ebp
call write_process_memory ;write PID
mov ebx,esp ;address of size of message
mov eax,ebp
add edx,4
call write_process_memory ;write size of message
add edx,4
pop ecx ;ecx - size of message
pop eax
call trans_address
mov ebx,eax ;ebx - linear address of message
add esp,4 ;pop temporary variable
mov eax,ebp
call write_process_memory ;write message
sti
;awake other process
shl ebp,8
mov eax,ebp
or [eax+0x800A8],dword 0x40
cmp dword [check_idle_semaphore],20
jge .ipc_no_cis
mov dword [check_idle_semaphore],5
.ipc_no_cis:
mov dword [esp+36],0
ret
.no_ipc_send:
mov dword [esp+36],-1
ret
.no_pid:
sti
mov dword [esp+36],4
ret
.no_ipc_area:
sti
mov dword [esp+36],1
ret
.ipc_blocked:
sti
add esp,12
mov dword [esp+36],2
ret
.buffer_overflow:
sti
add esp,12
mov dword [esp+36],3
ret
;-----------------------------------------------------------------------------
trans_address:
;Input
; eax - application address
;Output
; eax - linear address for kernel
add eax,std_application_base_address
ret
;-----------------------------------------------------------------------------
new_start_application_hd:
;eax - file name (kernel address)
;ebx - file name length
;ecx - work area (kernel address)
;ebp - parameters
pushad
mov esi,new_process_loading
call sys_msg_board_str ;write message to message board
;lock application_table_status mutex
.table_status:
cli
cmp [application_table_status],0
jz .stf
sti
call change_task
jmp .table_status
.stf:
call set_application_table_status
push ebp
push ebx
push eax
push ecx
call find_new_process_place ;find new process slot
sti
test eax,eax
jz .failed
;write application name
mov eax,[esp+4]
.find_last_byte:
cmp byte [eax],0
jz .find_last_byte_end
inc eax
jmp .find_last_byte
.find_last_byte_end:
lea esi,[eax-11] ;last 11 bytes = application name
mov edi,[new_process_place]
shl edi,8
add edi,0x80000
mov ecx,11
cld
rep movsb ;copy name to extended information about process
;read header
mov eax,[esp+4] ;file name
mov esi,[esp] ;work area
mov ecx,1 ;read from first block
mov edx,1 ;read 1 block
call read_hd_file
test eax,eax
jnz .cleanfailed
 
mov esi,[esp]
;check menuet signature
cmp [esi+1024+0],dword 'MENU' ;read_hd_file function write file to +1024 offset
jnz .cleanfailed
cmp [esi+1024+4],word 'ET'
jnz .cleanfailed
add esi,1024
mov edi,0x90000
mov ecx,512/4
cld
rep movsd ;copy first block to 0x90000 address for get_app_params function
call get_app_params
test esi,esi
jz .cleanfailed
mov eax,[new_process_place]
call create_app_cr3_table ;create page directory
test eax,eax
jz .cleanfailed_mem
call MEM_Get_Linear_Address
mov ebx,std_application_base_address
mov ecx,[app_mem]
add ecx,4096-1
shr ecx,12
mov edx,eax ;edx - linear address of page directory
call mem_alloc_specified_region ;allocate memory for application
test eax,eax
jz .cleanfailed_mem
add edx,(std_application_base_address shr 20)
mov eax,[edx]
and eax,not (4096-1)
call MEM_Get_Linear_Address
push edx ;save pointer to first page table
mov edx,eax
;read file
mov ecx,1
xor ebp,ebp
.loop1:
;[esp] - pointer to current page directory entry
;edx - pointer to current page table
;ebp - offset in page
;ecx - current cluster
push edx
mov eax,[esp+12] ;file name
mov ebx,[esp+16] ;file name length
mov esi,[esp+8] ;work area
mov edx,1 ;number of blocks to read
push ecx
push ebp
cli
call read_hd_file
sti
pop ebp
test eax,eax
jnz .endloop1 ;check io errors
mov esi,[esp+8+4] ;work area
add esi,1024
mov eax,[esp+4] ;current page table
mov eax,[eax]
and eax,not (4096-1)
call MEM_Get_Linear_Address;calculate linear page address
lea edi,[eax+ebp] ;add page offset
mov ecx,512/4
cld
rep movsd ;copy data
pop ecx
inc ecx ;next block
mov eax,[app_i_end] ;todo: precalculate ([app_i_end]+4095)/4096
add eax,512-1
shr eax,9 ;calculate application image size
cmp ecx,eax
jg .endloop11
pop edx
add ebp,512 ;new offset
test ebp,4096
jz .loop1
xor ebp,ebp
add edx,4 ;go to next page
test edx,(4096-1)
jnz .loop1
add dword [esp],4 ;go to next directory entry
mov eax,[esp]
mov eax,[eax]
and eax,not (4096-1)
call MEM_Get_Linear_Address
mov edx,eax
jmp .loop1
.endloop1:
add esp,4 ;pop ecx
.endloop11:
add esp,4+4 ;pop edx, pop edx
;add_app_parameters
add esp,12 ;now pointer to parameters is on the top of the stack
call new_start_application_fl.add_app_parameters ;start process
mov [esp+28],eax
popad
ret
.cleanfailed_mem:
mov esi,start_not_enough_memory
call sys_msg_board_str
.cleanfailed: ;clean process name
mov edi,[new_process_place]
shl edi,8
add edi,0x80000
mov ecx,11
mov eax,' '
cld
rep stosb
.failed:
add esp,16
popad
mov eax,-1
mov [application_table_status],0
sti
ret
end if
/kernel/trunk/core/physmem.inc
0,0 → 1,218
virtual at 0
physical_mem_block:
.start rd 1
.size rd 1
.flags rd 1 ;0-free, pid-used.
.sizeof:
end virtual
max_physical_mem_blocks = 24
uglobal
num_physical_mem_blocks rd 1
physical_mem_blocks rd 3*max_physical_mem_blocks
endg
Init_Physical_Memory_Manager:
pushad
mov edi,physical_mem_blocks
mov ecx,3*max_physical_mem_blocks
xor eax,eax
cld
rep stosd
mov dword [num_physical_mem_blocks],2
mov [physical_mem_blocks+physical_mem_block.start],0x60000
mov [physical_mem_blocks+physical_mem_block.size],0x20000 ;128Kb
mov [physical_mem_blocks+physical_mem_block.sizeof+physical_mem_block.start],0x780000
mov [physical_mem_blocks+physical_mem_block.sizeof+physical_mem_block.size],0x80000 ;512Kb
popad
ret
Insert_Block:
;input:
; eax - handle
;output:
; none
push eax ecx esi edi
sub eax,[num_physical_mem_blocks]
neg eax
mov edi,physical_mem_block.sizeof
imul eax,edi
shr eax,2
mov ecx,eax
mov esi,[num_physical_mem_blocks]
imul esi,edi
add esi,physical_mem_blocks
lea edi,[esi+physical_mem_block.sizeof]
std
rep movsd
pop edi esi ecx eax
ret
Delete_Block:
;input:
; eax - handle
;output:
; none
pushad
mov edi,eax
sub eax,[num_physical_mem_blocks]
neg eax
dec eax
mov esi,physical_mem_block.sizeof
imul eax,esi
imul edi,esi
add edi,physical_mem_blocks
lea esi,[edi+physical_mem_block.sizeof]
mov ecx,eax
shr ecx,2
cld
rep movsd
popad
ret
Allocate_Physical_Block:
;input:
; eax - size
;output:
; eax - address or 0 if not enough memory.
pushad
cmp [num_physical_mem_blocks],max_physical_mem_blocks
jge .error
mov ebx,eax
xor eax,eax
mov esi,physical_mem_blocks
.loop:
cmp dword [esi+physical_mem_block.flags],0
jnz .next
cmp [esi+physical_mem_block.size],ebx
jg .addblock
jz .noaddblock
.next:
inc eax
add esi,physical_mem_block.sizeof
cmp eax,[num_physical_mem_blocks]
jl .loop
.error:
popad
xor eax,eax
ret
.noaddblock:
mov eax,[esi+physical_mem_block.start]
mov [esp+28],eax
mov eax,[0x3010]
mov eax,[eax+0x4]
mov [esi+physical_mem_block.flags],eax
popad
ret
.addblock:
call Insert_Block
inc dword [num_physical_mem_blocks]
mov eax,[esi+physical_mem_block.start]
mov [esp+28],eax
mov ecx,[0x3010]
mov ecx,[ecx+0x4]
mov [esi+physical_mem_block.flags],ecx
mov ecx,[esi+physical_mem_block.size]
mov [esi+physical_mem_block.size],ebx
sub ecx,ebx
mov [esi+physical_mem_block.sizeof+physical_mem_block.size],ecx
add ebx,[esi+physical_mem_block.start]
mov [esi+physical_mem_block.sizeof+physical_mem_block.start],ebx
mov dword [esi+physical_mem_block.sizeof+physical_mem_block.flags],0
popad
ret
Free_Physical_Block:
;input:
; eax - address
;output:
; none
pushad
test eax,eax
jz .ret
mov ebx,eax
xor eax,eax
mov esi,physical_mem_blocks
.loop:
cmp ebx,[esi+physical_mem_block.start]
jz .endloop
inc eax
add esi,physical_mem_block.sizeof
cmp eax,[num_physical_mem_blocks]
jl .loop
jmp .ret
.endloop:
mov dword [esi+physical_mem_block.flags],0
test eax,eax
jz .no_union_previous
cmp dword [esi-physical_mem_block.sizeof+physical_mem_block.flags],0
jnz .no_union_previous
mov ebx,[esi-physical_mem_block.sizeof+physical_mem_block.start]
add ebx,[esi-physical_mem_block.sizeof+physical_mem_block.size]
cmp ebx,[esi+physical_mem_block.start]
jnz .no_union_previous
mov ebx,[esi+physical_mem_block.size]
add [esi-physical_mem_block.sizeof+physical_mem_block.size],ebx
call Delete_Block
dec eax
dec [num_physical_mem_blocks]
.no_union_previous:
inc eax
cmp eax,[num_physical_mem_blocks]
jge .no_union_next
cmp dword [esi+physical_mem_block.sizeof+physical_mem_block.flags],0
jnz .no_union_next
mov ebx,[esi+physical_mem_block.start]
add ebx,[esi+physical_mem_block.size]
cmp ebx,[esi+physical_mem_block.sizeof+physical_mem_block.start]
jnz .no_union_next
mov ebx,[esi+physical_mem_block.sizeof+physical_mem_block.size]
add [esi+physical_mem_block.size],ebx
call Delete_Block
dec [num_physical_mem_blocks]
.no_union_next:
.ret:
popad
ret
sys_allocate_physical_block:
;eax - subfunction number
mov eax,ebx
call Allocate_Physical_Block
mov [esp+36],eax
ret
sys_free_physical_block:
;eax - subfunction number
mov eax,ebx
call Free_Physical_Block
ret
sys_set_buffer:
add ecx,std_application_base_address
isys_set_buffer: ;for using in kernel
;eax - subfunction number
;ebx - physical address
;ecx - buffer start
;edx - buffer size
lea edi,[ebx+second_base_address]
mov esi,ecx
mov ecx,edx
rep movsb
ret
sys_get_buffer:
add ecx,std_application_base_address
isys_get_buffer: ;for using in kernel
;eax - subfunction number
;ebx - physical address
;ecx - buffer start
;edx - buffer size
mov edi,ecx
lea esi,[ebx+second_base_address]
mov ecx,edx
rep movsb
ret
sys_internal_services:
cmp eax,4
jle sys_sheduler
cmp eax,5
jz sys_allocate_physical_block
cmp eax,6
jz sys_free_physical_block
cmp eax,7
jz sys_set_buffer
cmp eax,8
jz sys_get_buffer
ret
/kernel/trunk/core/sched.inc
0,0 → 1,286
label next_usage_update dword at 0xB008
label timer_ticks dword at 0xFDF0
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; IRQ0 HANDLER (TIMER INTERRUPT) ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 32
irq0:
 
cmp [error_interrupt],-1
je no_error_in_previous_process
 
mov edi,[error_interrupt]
shl edi, 3
mov [edi+tss0i_l +5], word 01010000b *256 +11101001b
 
mov edi,[error_interrupt]
shl edi,7
add edi,0x290000
mov esi,[error_interrupt_entry]
mov [edi+l.eip-tss_sceleton],esi
mov [edi+l.eflags-tss_sceleton],dword 0x11002
 
mov [0xffff],byte 0
 
mov [error_interrupt],-1
 
no_error_in_previous_process:
 
mov edi,[0x3000]
shl edi, 3
; fields of TSS descriptor:
mov [edi+gdts+ tss0 +5], word 01010000b *256 +11101001b
 
inc dword [timer_ticks]
 
mov eax, [timer_ticks]
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
call playNote ; <<<--- INSERT THIS LINE !!!!!!!!!!
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
cmp eax,[next_usage_update]
jb .nocounter
add eax,100
mov [next_usage_update],eax
call updatecputimes
.nocounter:
 
mov edi, [0x3010]
 
mov ebx, [edi+0x18] ; time stamp counter add
call _rdtsc
sub eax, ebx
add eax, [edi+0x14] ; counter sum
mov [edi+0x14], eax
 
mov ebx,[0x3000]
 
cmp [0xffff], byte 1 ;1
je do_not_change_task ;je
 
.waiting_for_termination:
.waiting_for_reuse:
.waiting_on_queue:
add edi,0x20
inc ebx
 
mov al, byte [edi+0xA]
cmp al, 3
je .waiting_for_termination
cmp al, 4
je .waiting_for_termination
cmp al, 9
je .waiting_for_reuse
cmp al, 16
je .waiting_on_queue
cmp al, 17
je .waiting_on_queue
 
cmp ebx,[0x3004]
jbe nsched0
mov ebx,1
mov edi,0x3020
 
nsched0:
 
mov [0x3000],ebx
mov [0x3010],edi
 
do_not_change_task:
 
mov edx,[0x3000]
lea edx,[tss0sys+8*edx]
;mov [8*0x40+idts+8+0], word 0
mov [8*0x40+idts+8+2],dx
;mov [8*0x40+idts+8+4],word 11100101b*256
;mov [8*0x40+idts+8+6], word 0
 
call _rdtsc
mov [edi+0x18],eax
 
cmp [0xffff],byte 0
je nodecffff
dec byte [0xffff]
nodecffff:
 
 
shl ebx, 3
xor eax, eax
add ebx, tss0
mov word [0xB004], bx ; selector ;mov [tss_s],bx
mov dword [0xB000], eax ; offset
 
mov al,0x20 ; send End Of Interrupt signal
mov dx,0x20
out dx,al
.switch:
jmp pword [0xB000]
inc [context_counter] ;noname & halyavin
jmp irq0
 
iglobal
context_counter dd 0 ;noname & halyavin
endg
 
 
align 4
change_task:
 
mov [0xffff],byte 2
 
dec dword [timer_ticks] ; because irq0 will increase it
 
int 0x20 ; irq0 handler
 
ret
 
 
 
align 4
updatecputimes:
 
mov eax,[idleuse]
mov [idleusesec],eax
mov [idleuse],dword 0
mov ecx, [0x3004]
mov edi, 0x3020
.newupdate:
mov ebx,[edi+0x14]
mov [edi+0x1c],ebx
mov [edi+0x14],dword 0
add edi,0x20
dec ecx
jnz .newupdate
 
ret
 
 
 
;
; Wait queue is 16 bytes
; dd return code +12
; dd pointer to process +8
; dd prev +4
; dd next +0
;
; eax - pointer to pointer to the wait queue
; return:
; ecx - return code
sleep_on_queue:
sub esp,16 ; reserve space for wait node
mov ecx,esp ; ecx=this_node, [eax]=queue
 
pusha
 
mov ebx,[0x3010] ; get pointer to the current process
mov [ecx+8],ebx
 
pushf
cli ; adding element to the wait queue must be atomic
 
mov edi,[eax] ; edi=queue
and edi,edi ; check if queue is empty
jz .is_empty
 
; add element at the end of wait queue
 
mov edx,[edi+4] ; get pointer to prev edx=queue->prev
mov [ecx+4],edx ; this_node->prev=queue->prev
mov [ecx+0],edi ; this_node->next=queue
mov [edx+0],ecx ; this_node->prev->next=this_node
mov [edi+4],ecx ; queue->prev=this_node
jmp .added_ok
.is_empty:
; set this element as first in the queue
mov [ecx+0],ecx ; this_node->next=this_node
mov [ecx+4],ecx ; this_node->prev=this_node
mov [eax],ecx ; [queue]=this_node
.added_ok:
 
popf ; we can safely restore interrupts
 
mov [ebx+0xa],byte 17 ; set current task state as sleeping
call change_task ; schedule new thread
 
; someone has called wake_up_queue
 
pushf ; disable interrupts
cli
 
mov edx,[ecx+0] ; edx=this_node->next
mov esi,[ecx+4] ; esi=this_node->prev
 
; check if we need to remove this node from head
cmp [eax],ecx
jne .no_head
 
cmp [ecx+0],ecx ; check if queue is empty
jne .not_empty
 
mov [eax],dword 0
jmp .no_head
 
.not_empty:
mov [eax],edx
 
; remove our node from the queue (this must be atomic)
.no_head:
mov [edx+4],esi ; this_node->next->prev=this_node->prev
mov [esi+0],edx ; this_node->prev->next=this_node->next
 
popf
popa
add esp,12
pop ecx
ret
 
; eax - pointer to the wait queue
; ebx - wake up all (1=yes, 0=no)
; ecx - return code
; return:
; ebx - number of processes woken
wake_up_queue:
and eax,eax
jnz .nz
ret
.nz:
push eax
push ebx
push ecx
push edx
push esi
 
pushf
cli
 
xor ebx,ebx
mov edx,eax
.wake_loop:
 
mov [edx+12],ecx
mov esi,[edx+8]
mov byte [esi+0xa],0
inc ebx
 
mov edx,[edx+0]
cmp edx,eax
jne .wake_loop
 
and ebx,ebx
jz .wake_up_1
 
.return_it:
popf
pop esi
pop edx
pop ecx
add esp,4
pop eax
ret
.wake_up_1:
mov [eax+12],ecx
mov ecx,[eax+8]
mov byte [ecx+0xa],0
jmp .return_it
/kernel/trunk/core/sync.inc
0,0 → 1,111
if ~defined sync_inc
sync_inc_fix:
sync_inc fix sync_inc_fix
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Synhronization for MenuetOS. ;;
;;Author: Halyavin Andrey, halyavin@land.ru ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;simplest mutex.
macro SimpleMutex name
{
; iglobal
name dd 0
name#.type = 1
; endg
}
macro WaitSimpleMutex name
{
local start_wait,ok
start_wait=$
cli
cmp [name],dword 0
jz ok
sti
call change_task
jmp start_wait
ok=$
push eax
mov eax,dword [0x3010+second_base_address]
mov eax,[eax+0x4]
mov [name],eax
pop eax
sti
}
macro ReleaseSimpleMutex name
{
mov [name],dword 0
}
macro TryWaitSimpleMutex name ;result in eax and in flags
{
local ok,try_end
cmp [name],dword 0
jz ok
xor eax,eax
jmp try_end
ok=$
xor eax,eax
inc eax
try_end=$
}
macro SimpleCriticalSection name
{
; iglobal
name dd 0
dd 0
name#.type=2
; endg
}
macro WaitSimpleCriticalSection name
{
local start_wait,first_wait,inc_counter,end_wait
push eax
mov eax,[0x3010+second_base_address]
mov eax,[eax+0x4]
start_wait=$
cli
cmp [name],dword 0
jz first_wait
cmp [name],eax
jz inc_counter
sti
call change_task
jmp start_wait
first_wait=$
mov [name],eax
mov [name+4],dword 1
jmp end_wait
inc_counter=$
inc dword [name+4]
end_wait=$
sti
pop eax
}
macro ReleaseSimpleCriticalSection name
{
local release_end
dec dword [name+4]
jnz release_end
mov [name],dword 0
release_end=$
}
macro TryWaitSimpleCriticalSection name ;result in eax and in flags
{
local ok,try_end
mov eax,[0x3000+second_base_address]
mov eax,[eax+0x4]
cmp [name],eax
jz ok
cmp [name],0
jz ok
xor eax,eax
jmp try_end
ok=$
xor eax,eax
inc eax
try_end=$
}
_cli equ call MEM_HeapLock
_sti equ call MEM_HeapUnLock
end if
 
/kernel/trunk/core/sys32.inc
0,0 → 1,2301
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; MenuetOS process management, protected ring3 ;;
;; ;;
;; Distributed under GPL. See file COPYING for details. ;;
;; Copyright 2003 Ville Turjanmaa ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 32
 
; GDT TABLE
 
gdts:
 
dw gdte-$-1
dd gdts
dw 0
 
int_code_l:
os_code_l:
 
dw 0xffff
dw 0x0000
db 0x00
dw 11011111b *256 +10011010b
db 0x00
 
int_data_l:
os_data_l:
 
dw 0xffff
dw 0x0000
db 0x00
dw 11011111b *256 +10010010b
db 0x00
 
graph_data_l:
 
dw 0x3ff
dw 0x0000
db 0x00
dw 11010000b *256 +11110010b
db 0x00
 
tss0_l:
times (max_processes+10) dd 0,0
 
tss0i_l:
times 0x41 dq 0 ;(256+10) dd 0,0
 
app_code_l:
times (max_processes+10) dd 0,0
 
app_data_l:
times (max_processes+10) dd 0,0
 
tss0sys_l:
times (max_processes+10) dd 0,0
 
gdte:
 
 
 
; <IP 05.02.2005>
idtreg:
dw 8*0x41-1
dd idts+8
 
label idts at 0xB100-8
;idte = idts + 8 + 0x60
 
; </IP> ; old code below:
 
 
;align 32
 
;idts:
; dw idte-$-1
; dd idts+8
; dw 0
 
; times 0x62 dd 0,0
 
;idte:
 
build_process_gdt_tss_pointer:
 
mov ecx,tss_data
mov edi,0
setgdtl2:
mov [edi+gdts+ tss0 +0], word tss_step
mov [edi+gdts+ tss0 +2], cx
mov eax,ecx
shr eax,16
mov [edi+gdts+ tss0 +4], al
mov [edi+gdts+ tss0 +7], ah
mov [edi+gdts+ tss0 +5], word 01010000b *256 +11101001b
add ecx,tss_step
add edi,8
cmp edi,8*(max_processes+5)
jbe setgdtl2
 
ret
 
;build_process_gdt_gate_pointer:
 
; mov edi,0
; mov dx,tss0
; setidtl1:
; mov ecx,[esi]
; mov [edi+gdts+ tss0t +0], word 0
; mov [edi+gdts+ tss0t +2], dx
; mov [edi+gdts+ tss0t +4], word 11100101b*256
; mov [edi+gdts+ tss0t +6], word 0
; add dx,8
; add edi,8
; cmp edi,8*(max_processes+5)
; jb setidtl1
 
; ret
 
build_interrupt_table:
 
mov [l.eflags],dword 0x11002
mov [l.ss0], int_data
;mov [l.ss1], ring1_data
;mov [l.ss2], ring2_data
mov [l.esp0], 0x52000
mov [l.esp1], 0x53000
mov [l.esp2], 0x54000
 
mov eax,cr3
mov [l.cr3],eax
mov [l.cs],int_code
mov [l.ss],int_data
mov [l.ds],int_data
mov [l.es],int_data
mov [l.fs],int_data
mov [l.gs],int_data
 
mov eax,sys_int
mov [l.esp],0x720000
mov edi,0x290000
 
newint:
push edi
mov ebx,[eax]
mov [l.eip],ebx
mov esi,tss_sceleton
mov ecx,120/4
cld
rep movsd
pop edi
 
add edi,128
add [l.esp],1024
add eax,4
 
cmp eax,sys_int+4*0x40 ;0x60
jbe newint ;jb
 
;;
 
mov esi,boot_sched_3_2
call boot_log
 
mov ecx,0x290000
mov edi,0
setgdtl2i:
mov [edi+gdts+ tss0i +0], word 128
mov [edi+gdts+ tss0i +2], cx
mov eax,ecx
shr eax,16
mov [edi+gdts+ tss0i +4], al
mov [edi+gdts+ tss0i +7], ah
mov [edi+gdts+ tss0i +5], word 01010000b *256 +11101001b
add ecx,128
add edi,8
cmp edi,8*0x40 ;0x60
jbe setgdtl2i
 
;;
 
mov esi,boot_sched_3_3
call boot_log
 
mov edi,0
mov edx,tss0i
setidtl2:
mov [edi+idts+ 8 +0], word 0
mov [edi+idts+ 8 +2], dx
mov [edi+idts+ 8 +4], word 10000101b*256 ; task gate DPL=0
; cmp edi,0x40*8
; jne no_sw_int
; mov [edi+idts+ 8 +4], word 11100101b*256 ; task gate DPL=3
; no_sw_int:
mov [edi+idts+ 8 +6], word 0
add edx,8
add edi,8
 
cmp edi,8*0x40 ;0x60
jbe setidtl2 ;jb
 
; <Ivan Poddubny 06.02.2005>
; THIS CODE WON'T WORK ;-(
; because each process's 0-level stack points to the same area
; and if task switch occurs and another process is being interrupted
; a stack overflow happens
; The only way to solve that problem is to disable interrupts
; while 0x40-handler is working
; Then we have to make all entries in the IDT INTERRUPT gates, not TASK
; mov edi, idts+8
; mov esi, sys_int
; mov ecx, 32
; @@:
; mov eax, [esi]
; mov [edi], ax ; lower part of offset
; mov [edi+2], word os_code ; segment selector
; shr eax, 16
; mov [edi+4], word 10001110b shl 8 ; interrupt descriptor
; mov [edi+6], ax
; add esi, 4
; add edi, 8
; dec ecx
; jnz @b
; </Ivan Poddubny>
 
ret
 
build_syscall_interrupt_table:
 
mov [l.eflags],dword 0x11002
mov [l.ss0], int_data ;code
;mov [l.ss1], ring1_data ;code
;mov [l.ss2], ring2_data ;code
mov [l.esp0], 0x52000
mov [l.esp1], 0x53000
mov [l.esp2], 0x54000
 
mov eax,cr3
mov [l.cr3],eax
mov [l.cs],int_code
mov [l.ss],int_data
mov [l.ds],int_data
mov [l.es],int_data
mov [l.fs],int_data
mov [l.gs],int_data
 
mov [l.esp],sysint_stack_data
mov edi,0x298000
 
newint2:
push edi
mov ebx,i40
mov [l.eip],ebx
mov esi,tss_sceleton
mov ecx,120/4
cld
rep movsd
pop edi
 
add [l.esp],4096
add edi,128
;add eax,4
 
cmp edi,0x298000+128*(max_processes+5)
jb newint2
 
;;
 
mov ecx,0x298000
mov edi,0
setgdtl2i2:
mov [edi+gdts+ tss0sys +0], word 128
mov [edi+gdts+ tss0sys +2], cx
mov eax,ecx
shr eax,16
mov [edi+gdts+ tss0sys +4], al
mov [edi+gdts+ tss0sys +7], ah
mov [edi+gdts+ tss0sys +5], word 01010000b *256 +11101001b
add ecx,128
add edi,8
cmp edi,8*(max_processes+5)
jbe setgdtl2i2
 
;;
 
;mov dx,tss0sys
mov edi,8*0x40+idts+8
mov [edi + 0], word 0
mov [edi + 2], word tss0sys ;dx
mov [edi + 4], word 11100101b*256
mov [edi + 6], word 0
 
mov edi,8*0x38+idts+8
mov eax, i38
mov [edi], ax ; lower part of offset
mov [edi+2], word os_code ; segment selector
shr eax, 16
mov [edi+4], word 11101110b shl 8 ; 32-bit interrupt gate, DPL 3
mov [edi+6], ax
 
ret
 
 
align 4
i38:
; load data selectors
pushfd
push ds es
push eax
mov ax, os_data
mov ds, ax
mov es, ax
pop eax
 
pushad
push edi
mov edi, eax
mov eax, ebx
mov ebx, ecx
mov ecx, edx
mov esi, [esp]
and edi, 0xFF
call dword [servetable+edi*4]
add esp, 4
popad
pop es ds
popfd
iret
 
 
iglobal
sys_int:
dd s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,sa,sb,sc,sd,se,sf
 
dd s10 ,s11 ; ,i_unknown12,i_unknown13
; dd i_unknown14,i_unknown15,i_unknown16,i_unknown17
; dd i_unknown18,i_unknown19,i_unknown1a,i_unknown1b
; dd i_unknown1c,i_unknown1d,i_unknown1e,i_unknown1f
times 14 dd unknown_interrupt
 
dd irq0 ,irq1 ,p_irq2 ,p_irq3 ,p_irq4 ,p_irq5,p_irq6 ,p_irq7
dd p_irq8,p_irq9,p_irq10,p_irq11,p_irq12,irqD ,p_irq14,p_irq15
 
;dd i_unknown30,i_unknown31,i_unknown32,i_unknown33
;dd i_unknown34,i_unknown35,i_unknown36,i_unknown37
;dd i_unknown38,i_unknown39,i_unknown3a,i_unknown3b
;dd i_unknown3c,i_unknown3d,i_unknown3e,i_unknown3f
times 16 dd unknown_interrupt
 
dd i40
endg
 
uglobal
tss_sceleton:
l.back dw 0,0
l.esp0 dd 0
l.ss0 dw 0,0
l.esp1 dd 0
l.ss1 dw 0,0
l.esp2 dd 0
l.ss2 dw 0,0
l.cr3 dd 0
l.eip dd 0
l.eflags dd 0
l.eax dd 0
l.ecx dd 0
l.edx dd 0
l.ebx dd 0
l.esp dd 0
l.ebp dd 0
l.esi dd 0
l.edi dd 0
l.es dw 0,0
l.cs dw 0,0
l.ss dw 0,0
l.ds dw 0,0
l.fs dw 0,0
l.gs dw 0,0
l.ldt dw 0,0
l.trap dw 0
l.io dw 0
endg
 
s0:
cli
 
mov [error_interrupt],0x0
mov [error_interrupt_entry],dword s0
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
 
s1:
cli
 
mov [error_interrupt],0x1
mov [error_interrupt_entry],dword s1
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
s2:
cli
 
mov [error_interrupt],0x2
mov [error_interrupt_entry],dword s2
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
s3:
cli
 
mov [error_interrupt],0x3
mov [error_interrupt_entry],dword s3
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
s4:
cli
 
mov [error_interrupt],0x4
mov [error_interrupt_entry],dword s4
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
s5:
cli
 
mov [error_interrupt],0x5
mov [error_interrupt_entry],dword s5
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
s6:
cli
 
mov [error_interrupt],0x6
mov [error_interrupt_entry],dword s6
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
 
;;;;;;;;;;;;;;;;;;;;;;;
;; FPU ERROR HANDLER ;;
;;;;;;;;;;;;;;;;;;;;;;;
 
align 4
s7:
; <IP 05.02.2004>
cli
; </IP>
mov edi, 7*8
mov [edi+gdts+ tss0i +5], word 01010000b *256 +11101001b
 
mov edi,[0x3000]
shl edi, 3
mov [edi+gdts+ tss0 +5], word 01010000b *256 +11101001b
 
 
; save a copy of current task's TSS to fpu_tss
mov esi,[0x3000]
imul esi,tss_step
add esi,tss_data
mov edi,fpu_tss
mov ecx,120/4
cld
rep movsd
 
; get base address of our TSS and...
mov esi,[0x3000]
imul esi,tss_step
add esi,tss_data
 
; ...init segments, stack, eip, flags
mov word [esi+l.cs-tss_sceleton],int_code
mov word [esi+l.ss-tss_sceleton],int_data
mov word [esi+l.ds-tss_sceleton],int_data
mov word [esi+l.es-tss_sceleton],int_data
mov word [esi+l.fs-tss_sceleton],int_data
mov word [esi+l.gs-tss_sceleton],int_data
mov dword [esi+l.esp-tss_sceleton],fpu_stack+4*8
mov dword [esi+l.eip-tss_sceleton],fpu_handler
mov dword [esi+l.eflags-tss_sceleton],0x11002
 
; then execute this task
mov ebx, [0x3000]
shl ebx,3
add ebx, tss0 ;t
mov [0xB004], bx
 
jmp pword [0xB000]
 
jmp s7
 
s8:
cli
 
mov [error_interrupt],0x8
mov [error_interrupt_entry],dword s8
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
s9:
cli
 
mov [error_interrupt],0x9
mov [error_interrupt_entry],dword s9
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
sa:
cli
 
mov [error_interrupt],0xa
mov [error_interrupt_entry],dword sa
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
sb:
cli
 
mov [error_interrupt],0xb
mov [error_interrupt_entry],dword sb
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
sc:
cli
 
mov [error_interrupt],0xc
mov [error_interrupt_entry],dword sc
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
sd:
cli
 
mov [error_interrupt],0xd
mov [error_interrupt_entry],dword sd
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
se:
cli
 
mov [error_interrupt],0xe
mov [error_interrupt_entry],dword se
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
sf:
cli
 
mov [error_interrupt],0xf
mov [error_interrupt_entry],dword sf
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
s10:
cli
 
mov [error_interrupt],0x10
mov [error_interrupt_entry],dword s10
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
s11:
cli
 
mov [error_interrupt],0x11
mov [error_interrupt_entry],dword s11
 
call show_error_parameters
 
mov edx,[0x3010]
mov [edx+0xa],byte 4
 
jmp change_task
 
writehex:
 
pusha
 
mov ecx,eax
mov ax,word [printerrorat]
shl eax,16
mov ax,[esp+32+4]
sub ax,60
mov edx,1
mov esi,8
mov ebx,0xffffff
whl1:
push ecx
and ecx,0xf
add ecx,hexletters
mov edi,1
 
mov cl,[ecx]
mov edi,[write_error_to]
mov [edi],cl
dec [write_error_to]
 
pop ecx
shr ecx,4
sub eax,6*65536
dec esi
jnz whl1
 
popa
ret
 
iglobal
hexletters db '0123456789ABCDEF'
 
error_interrupt dd -1
error_interrupt_entry dd -1
 
printerrorat dd 300
 
process_error db 'K : Process - forced terminate INT: 00000000',13,10,0
process_pid db 'K : Process - forced terminate PID: 00000000',13,10,0
process_eip db 'K : Process - forced terminate EIP: 00000000',13,10,0
system_error db 'K : Kernel error',13,10,0
endg
 
uglobal
write_error_to dd 0x0
endg
 
show_error_parameters:
mov [write_error_to],process_pid+43
mov eax,[0x3000]
shl eax, 5
mov eax,[0x3000+4+eax]
call writehex
mov [write_error_to],process_error+43
mov eax,[error_interrupt]
call writehex
mov eax,[0x3000]
shl eax,8
cmp [0x80000+eax+0xB0],dword 0
jnz .system_error
 
mov eax,[0x3000]
imul eax,tss_step
mov eax,[eax+tss_data+l.eip-tss_sceleton]
.out_eip:
mov [write_error_to],process_eip+43
call writehex
 
mov esi,process_error
call sys_msg_board_str
 
mov esi,process_pid
call sys_msg_board_str
 
mov esi,process_eip
call sys_msg_board_str
 
ret
.system_error:
mov esi,system_error
call sys_msg_board_str
mov eax,[0x3000]
shl eax,7
mov eax,[eax+0x298000+l.eip-tss_sceleton]
jmp .out_eip
 
 
irq5:
 
call restore_caller
 
mov dx,word [sb16]
add dx,0xe
in al,dx
 
; mov byte [SB16_Status],0
 
mov [check_idle_semaphore],5
 
mov al,0x20
out 0x20,al
 
call return_to_caller
 
jmp irq5
 
irqD:
 
call restore_caller
 
mov dx,0xf0
mov al,0
out dx,al
 
mov dx,0xa0
mov al,0x20
out dx,al
mov dx,0x20
out dx,al
 
mov ds,cx
mov es,cx
mov fs,cx
 
call return_to_caller
 
jmp irqD
 
p_irq2:
 
call restore_caller
 
mov edi,2 ; 1
call irqhandler ; 2/5
 
call return_to_caller
 
jmp p_irq2
 
p_irq3:
 
call restore_caller
 
mov edi,3
call irqhandler
 
call return_to_caller
 
jmp p_irq3
 
p_irq4:
 
call restore_caller
 
mov edi,4
call irqhandler
 
call return_to_caller
 
jmp p_irq4
 
p_irq5:
 
call restore_caller
 
mov edi,5
call irqhandler
 
call return_to_caller
 
jmp p_irq5
 
p_irq6:
 
call restore_caller
 
call fdc_irq
 
mov edi,6
call irqhandler
 
call return_to_caller
 
jmp p_irq6
 
p_irq7:
 
call restore_caller
 
mov edi,7
call irqhandler
 
call return_to_caller
 
jmp p_irq7
 
p_irq8:
 
call restore_caller
 
mov edi,8
call irqhandler
 
call return_to_caller
 
jmp p_irq8
 
p_irq9:
 
call restore_caller
 
mov edi,9
call irqhandler
 
call return_to_caller
 
jmp p_irq9
 
p_irq10:
 
call restore_caller
 
mov edi,10
call irqhandler
 
call return_to_caller
 
jmp p_irq10
 
p_irq11:
 
call restore_caller
 
mov edi,11
call irqhandler
 
call return_to_caller
 
jmp p_irq11
 
p_irq12:
 
call restore_caller
 
mov edi,12
call irqhandler
 
call return_to_caller
 
jmp p_irq12
 
p_irq13:
 
call restore_caller
 
mov edi,13
call irqhandler
 
call return_to_caller
 
jmp p_irq13
 
p_irq14:
 
call restore_caller
mov edi,14
call irqhandler
 
call return_to_caller
 
jmp p_irq14
 
p_irq15:
 
call restore_caller
 
mov edi,15
call irqhandler
 
call return_to_caller
 
jmp p_irq15
 
 
 
align 4
restore_caller:
 
mov edi,[0x3000]
shl edi, 3
mov [edi+gdts+ tss0 +5], word 01010000b *256 +11101001b
 
ret
 
align 4
return_to_caller:
 
mov ebx,[0x3000]
shl bx,3
add bx,tss0;t
mov [tss_irq12],bx
 
db 0xea
dd 0
tss_irq12 dw tss0;t
 
ret
 
uglobal
irqh dd 0x0
endg
 
irqhandler:
 
push edi
 
mov esi,edi ; 1
shl esi,6 ; 1
add esi,irq00read ; 1
shl edi,12 ; 1
add edi,0x2E0000
 
mov [check_idle_semaphore],5
 
irqnewread:
 
mov dx,[esi] ; 2+
 
cmp dx,0 ; 1
jz irqover
cmp [esi+3],byte 1 ; 2 ; byte read
jne noirqbyte ; 4-11
 
in al,dx
 
mov edx,[edi]
cmp edx,4000
je irqfull
mov ebx,edi
add ebx,0x10
add ebx,edx
mov [ebx],al
inc edx
mov [edi],edx
 
add esi,4
jmp irqnewread
 
noirqbyte:
 
 
cmp [esi+3],byte 2 ; word read
jne noirqword
 
in ax,dx
 
mov edx,[edi]
cmp edx,4000
je irqfull
mov ebx,edi
add ebx,0x10
add ebx,edx
mov [ebx],ax
add edx,2
mov [edi],edx
add esi,4
jmp irqnewread
 
noirqword:
irqfull:
irqover:
 
mov al,0x20 ; ready for next irq
out 0x20,al
 
pop ebx
cmp ebx,7
jbe noa0
out 0xa0,al
noa0:
 
ret
 
 
; this code should never get control!
; applications can use only 0x40 interrupt
unknown_interrupt:
@@: call change_task
jmp @b
 
 
 
compare_to_thread:
 
push ebx
 
mov eax,edx
shl eax, 3
add eax,gdts+ app_code-3
mov ebx,[eax]
cmp ebx,[old_code_0]
jne ctt0
mov ebx,[eax+4]
cmp ebx,[old_code_1]
jne ctt0
 
pop ebx
mov eax,1
ret
 
ctt0:
 
pop ebx
mov eax,0
ret
 
 
 
check_for_thread_mem:
 
pusha
 
mov ecx,[0x3004]
cftm0:
mov eax,ecx
shl eax, 8
add eax,gdts+ app_code-3
mov ebx,[eax]
cmp ebx,[old_code_0]
jne cftm1
mov ebx,[eax+4]
cmp ebx,[old_code_1]
jne cftm1
 
mov eax,ecx ; new code segments
shl eax, 3 ;imul eax,8
add eax,gdts+ app_code-3
 
mov ebx,[new_code_0]
mov [eax],ebx
mov ebx,[new_code_1]
mov [eax+4],ebx
 
mov eax,ecx ; new data segments
shl eax, 3
 
add eax,gdts+ app_data-3
 
mov ebx,[new_data_0]
mov [eax],ebx
mov ebx,[new_data_1]
mov [eax+4],ebx
 
cmp [new_pos],0 ; new memory position segments
je no_new_postition_for_thread
mov eax,ecx
shl eax, 5
add eax,0x3000
mov ebx,[new_pos]
mov [eax+0x10],ebx
no_new_postition_for_thread:
 
mov eax,ecx ; new amount of memory
shl eax, 8
add eax,0x80000
mov ebx,[new_amount]
mov [eax+0x8C],ebx
 
cftm1:
 
dec ecx
jnz cftm0
 
popa
 
ret
 
 
save_for_thread_check:
 
; save for thread check
 
pusha
mov esi,[0x3000]
;imul esi,8
shl esi, 3
add esi,gdts+ app_code-3 +0
mov edi,old_code_0
mov ecx,8
cld
rep movsb
popa
 
ret
 
 
save_new_position_for_threads:
 
; new code segment for thread check
pusha
mov esi,[0x3000]
;imul esi,8
shl esi, 3
add esi,gdts+ app_code-3 +0
mov edi,new_code_0
mov ecx,8
cld
rep movsb
popa
 
; new data segment for thread check
pusha
mov esi,[0x3000]
;imul esi,8
shl esi, 3
add esi,gdts+ app_data-3 +0
mov edi,new_data_0
mov ecx,8
cld
rep movsb
popa
 
ret
 
set_application_table_status:
push eax
 
mov eax,[0x3000]
;imul eax,32
shl eax, 5
add eax,0x3000+4
mov eax,[eax]
 
mov [application_table_status],eax
 
pop eax
 
ret
 
 
clear_application_table_status:
push eax
 
mov eax,[0x3000]
;imul eax,32
shl eax, 5
add eax,0x3000+4
mov eax,[eax]
 
cmp eax,[application_table_status]
jne apptsl1
mov [application_table_status],0
apptsl1:
 
pop eax
 
ret
 
uglobal
old_code_0 dd 0x0
old_code_1 dd 0x0
 
;
 
new_code_0 dd 0x0
new_code_1 dd 0x0
 
new_data_0 dd 0x0
new_data_1 dd 0x0
 
new_pos dd 0x0
new_amount dd 0x0
endg
 
 
sys_resize_app_memory:
; eax = 1 - resize
; ebx = new amount of memory
 
cmp eax,1
jne no_application_mem_resize
mov eax,[0x3010]
cmp dword [eax+0x10],std_application_base_address
jz new_mem_resize ;resize for new type of processes
 
add ebx,4095
shr ebx,12
shl ebx,12
mov ebp,ebx
 
; wait for process table to be free
 
rsm0:
 
cli
cmp [application_table_status],0
je rsm1
sti
call change_task
jmp rsm0
 
rsm1:
 
call set_application_table_status
sti
 
cmp ebx,0 ; other than zero
je mem_resize_unsuccess
 
call save_for_thread_check
 
; find a free place
 
mov esi,[0xfe84] ; application memory start
mov edi,ebp
add edi,esi
dec edi
 
rfgdt:
 
mov edx,2
 
rfindgdtl1:
 
call compare_to_thread
cmp eax,1
je rfindfl3
 
mov ecx,edx
shl ecx,3
 
; eax run base -> ebx limit
 
mov al,[ecx+gdts+ app_code-3 +4]
mov ah,[ecx+gdts+ app_code-3 +7]
shl eax,16
mov ax,[ecx+gdts+ app_code-3 +2]
;!!mem
cmp eax,std_application_base_address
jz rfindfl3
;!!mem
 
movzx ebx,word [ecx+gdts+ app_code-3 +0]
shl ebx,12
add ebx,eax
 
cmp eax,edi
jg rfindfl3
cmp ebx,esi
jb rfindfl3
 
add esi,4096
add edi,4096
 
cmp edi,[0xfe8c] ; < c_memory
jbe rfgdt
 
jmp rfind_free_ret_2 ;; not enough memory
 
rfindfl3:
 
inc edx
cmp edx,[0x3004]
jbe rfindgdtl1
 
rfindfl1:
rthread_c:
 
mov ecx,[0x3000]
shl ecx,3
 
inc edi
sub edi,esi
add edi,4095
shr edi,12
dec edi
 
; code
 
mov eax,esi
mov ebx,edi
 
mov [ecx+gdts+ app_code-3 +2], ax ; base 0:15
shr eax,16
mov [ecx+gdts+ app_code-3 +4], al ; base 23:16
mov [ecx+gdts+ app_code-3 +7], ah ; base 31:24
mov [ecx+gdts+ app_code-3 +0], bx ; limit
 
; data
 
mov eax,esi
mov [ecx+gdts+ app_data-3 +2], ax ; base 0:15
shr eax,16
mov [ecx+gdts+ app_data-3 +4], al ; base 23:16
mov [ecx+gdts+ app_data-3 +7], ah ; base 31:24
 
movzx edx,word [ecx+gdts+ app_code-3 +0] ; save limit
 
mov [ecx+gdts+ app_data-3 +0], bx ; limit
 
and ebx,0xffff
 
cmp ebx,edx ; copy smaller from memory sizes
jge noedxebxxchg
mov edx,ebx
noedxebxxchg:
 
movzx ecx,dx
shl ecx,12
add ecx,4096
 
mov edi,esi
 
mov eax,[0x3010]
mov esi,[eax+0x10]
 
mov [eax+0x10],edi ; new memory position
 
mov eax,[0x3000] ; new memory size
shl eax,8
add eax,0x80000
mov [eax+0x8c],ebp
 
mov [new_pos],edi ; new position for threads
mov [new_amount],ebp ; new amount of mem for threads
 
cmp esi,edi
je no_app_move
 
cld
rep movsb ; move the app image to the new position
 
no_app_move:
 
call save_new_position_for_threads
call check_for_thread_mem
 
mov [application_table_status],0
 
mov [esp+36],dword 0 ; eax <- 0 ; successfull
 
ret
 
rfind_free_ret_2:
 
mem_resize_unsuccess:
 
mov [application_table_status],0
 
mov [esp+36],dword 1 ; eax <- 1 ; unsuccessfull
 
ret
 
no_application_mem_resize:
 
 
ret
 
 
align 4
find_free_mem:
 
push eax
push ebx
push ecx
push edx
push edi
 
call find_free_process_slot
mov eax,[new_process_place]
 
cmp eax,max_processes
jg find_free_ret_2
 
cmp [thread_create],1
je thread_c
 
mov esi,[0xfe84]
add edi,esi
dec edi
 
mov eax,2
cmp dword [0x3004],1
je findf4
 
fgdt:
 
mov edx,2
 
findgdtl1:
 
mov ecx,edx
shl ecx,3
 
; eax run base -> ebx limit
 
mov al,[ecx+gdts+ app_code-3 +4]
mov ah,[ecx+gdts+ app_code-3 +7]
shl eax,16
mov ax,[ecx+gdts+ app_code-3 +2]
;!!mem
cmp eax,std_application_base_address
jz findfl3
;!!mem
 
movzx ebx,word [ecx+gdts+ app_code-3 +0]
shl ebx,12
add ebx,eax
 
cmp eax,edi
jg findfl3
cmp ebx,esi
jb findfl3
 
add esi,4096
add edi,4096
 
cmp edi,[0xfe8c] ; < c_memory
jbe fgdt
 
jmp find_free_ret_2
 
findfl3:
 
inc edx
cmp edx,[check_processes]
jbe findgdtl1
 
findfl1:
thread_c:
 
mov eax,[new_process_place]
 
findf4:
 
mov [first_gdt_search],eax
mov [gdt_place],eax
 
mov ecx,eax
shl ecx,3
 
inc edi
sub edi,esi
add edi,4095
shr edi,12
dec edi
 
; code
 
mov eax,esi
mov ebx,edi
 
mov [ecx+gdts+ app_code-3 +2], ax ; base 0:15
shr eax,16
mov [ecx+gdts+ app_code-3 +4], al ; base 23:16
mov [ecx+gdts+ app_code-3 +7], ah ; base 31:24
mov [ecx+gdts+ app_code-3 +0], bx ; limit
mov [ecx+gdts+ app_code-3 +5], word 11010000b *256 +11111010b
 
; data
 
mov eax,esi
mov [ecx+gdts+ app_data-3 +2], ax ; base 0:15
shr eax,16
mov [ecx+gdts+ app_data-3 +4], al ; base 23:16
mov [ecx+gdts+ app_data-3 +7], ah ; base 31:24
mov [ecx+gdts+ app_data-3 +0], bx ; limit
mov [ecx+gdts+ app_data-3 +5], word 11010000b *256 +11110010b
 
push esi
mov esi,process_loading
call sys_msg_board_str
pop esi
 
find_free_ret:
 
pop edi
pop edx
pop ecx
pop ebx
pop eax
ret
 
find_free_ret_2:
 
cmp [dec3004],0
je no3004inc
dec dword [0x3004]
no3004inc:
 
pop edi
pop edx
pop ecx
pop ebx
pop eax
mov esi,0
ret
 
 
get_app_params:
 
push eax
 
cmp [0x90000+6],word '00'
jne no_00_header
 
mov eax,[0x90000+12]
mov [app_start],eax
mov eax,[0x90000+16]
mov [app_i_end],eax
mov eax,[0x90000+20]
mov [app_mem],eax
shr eax,1
sub eax,0x10
mov [app_esp],eax
mov eax,[0x90000+24]
mov [app_i_param],eax
mov [app_i_icon],dword 0
 
pop eax
mov esi,1
ret
 
no_00_header:
 
 
cmp [0x90000+6],word '01'
jne no_01_header
 
mov eax,[0x90000+12]
mov [app_start],eax
mov eax,[0x90000+16]
mov [app_i_end],eax
mov eax,[0x90000+20]
mov [app_mem],eax
mov eax,[0x90000+24]
mov [app_esp],eax
mov eax,[0x90000+28]
mov [app_i_param],eax
mov eax,[0x90000+32]
mov [app_i_icon],eax
 
pop eax
mov esi,1
ret
 
no_01_header:
 
pop eax
mov esi,0
ret
 
 
start_application_fl:
jmp new_start_application_fl
 
;************************************************************************
 
start_application_floppy:
jmp new_start_application_floppy
 
;********************************************************************
 
start_application_hd:
jmp new_start_application_hd
 
uglobal
threadstring dd 0x0
new_process_place dd 0x0
check_processes dd 0x0
dec3004 db 0x0
app_start dd 0x0
app_i_end dd 0x0
app_mem dd 0x0
app_esp dd 0x0
app_i_param dd 0x0
app_i_icon dd 0x0
app_mem_pos dd 0x0
thread_create dd 0x0
gdt_place dd 0x0
endg
 
iglobal
hd_app_string db 'HDAPP '
process_loading db 'K : Process - loading ',13,10,0
process_running db 'K : Process - done',13,10,0
first_gdt_search dd 0x2
endg
 
 
sys_threads:
 
; eax=1 create thread
;
; ebx=thread start
; ecx=thread stack value
;
; on return : eax = pid
jmp new_sys_threads
cli
cmp [application_table_status],0
je stth9
sti
call change_task
jmp sys_threads
stth9:
 
call set_application_table_status
 
sti
 
cmp eax,1
jne no_sys_thread_create
cli
 
mov eax,[0x3010]
mov eax,[eax+0x10]
mov [app_mem_pos],eax
 
mov [app_i_param],0
mov [app_i_icon],0
 
mov [app_start],ebx
mov [app_esp],ecx
 
mov ebx,[0x3000]
shl ebx,8
add ebx,0x80000
mov [threadstring],ebx
mov ebx,[ebx+0x8c]
mov [app_mem],ebx
 
mov esi,[app_mem_pos]
mov edi,[app_mem]
add edi,esi
dec edi
mov [thread_create],1
call find_free_mem
cmp esi,0
jne th_cr1
mov [application_table_status],0
mov eax,1 ; no free memory
sti
ret
th_cr1:
push dword 0
push dword [threadstring]
jmp add_app_parameters
no_sys_thread_create:
 
mov eax,-1
mov [application_table_status],0
ret
 
 
find_free_process_slot:
 
pusha
 
mov ebx,[0x3004]
mov [check_processes],ebx
inc ebx
mov [new_process_place],ebx
 
mov ebx,2
 
newfps:
 
mov eax,ebx
;imul eax,0x20
shl eax, 5
add eax,0x3000+0xa
cmp [eax],byte 9
je ffpl
 
inc ebx
cmp ebx,[0x3004]
jbe newfps
 
;mov [dec3004],0
mov [dec3004],1
shl ebx,5
mov [0x3000+0xa+ebx],byte 9
inc dword [0x3004]
 
popa
ret
 
ffpl:
 
;mov [dec3004],1
;dec dword [0x3004]
mov [dec3004],0
mov [new_process_place],ebx
 
popa
ret
 
 
add_app_parameters:
; returns: eax = pid or -1 if unsuccesfull
cmp [app_i_param],dword 0 ; parameter
jz no_app_params
xor eax, eax
mov edi,[app_i_param]
add edi,[app_mem_pos]
mov ecx,256/4
cld
rep stosd
mov esi,[esp+4]
test esi, esi
jz no_app_params
mov eax,[app_i_param]
add eax,[app_mem_pos]
mov edi,eax
mov ecx,256
cld
app_new_param:
cmp [esi],byte 0
jz no_app_params
movsb
loop app_new_param
no_app_params:
 
;inc dword [0x3004] ; increase number of processes
mov ebx,[new_process_place]
 
mov edi,ebx ; clear 0x80000 (256 bytes)
shl edi,8
add edi,0x80000
mov ecx,256 / 4
mov eax,0
cld
rep stosd
 
shl ebx,5 ; * 32 +0x3000
add ebx,0x3000
 
mov al,byte [new_process_place] ; screen id ?
mov [ebx+0xe],al
 
mov [ebx],dword 1+2+4 ; report events: windowdraw, key, button
 
inc dword [process_number] ; process id number
mov eax,[process_number]
mov [ebx+4],eax
 
mov ecx,ebx ; set draw limits
add ecx,draw_data-0x3000
mov [ecx+0],dword 0
mov [ecx+4],dword 0
mov eax,[0xfe00]
mov [ecx+8],eax
mov eax,[0xfe04]
mov [ecx+12],eax
 
mov eax,[app_mem_pos] ; position in memory
mov [ebx+0x10],eax
 
; TSS
xor ebx,ebx
cmp [thread_create],ebx
jnz clone_cr3_table
mov eax,[new_process_place]
call create_app_cr3_table
jmp set_cr3
clone_cr3_table:
; mov eax,[new_process_place]
; mov ebx,[0x3000]
; call addreference_app_cr3_table
mov eax,[0x3000]
call get_cr3_table
set_cr3:
add eax,8+16
mov [l.cr3],eax
mov eax,[app_start]
mov [l.eip],eax
mov eax,[app_esp]
mov [l.esp],eax
 
mov ebx,[new_process_place] ; gdt's
shl ebx,3
 
mov ax,app_code
add ax,bx
mov [l.cs],ax
mov ax,app_data
add ax,bx
mov [l.ss],ax
mov [l.ds],ax
mov [l.es],ax
mov [l.fs],ax
mov ax,graph_data
mov [l.gs],ax
mov [l.io],word 128
mov [l.eflags],dword 0x11202
mov [l.ss0], os_data
;mov [l.ss1], ring1_data
;mov [l.ss2], ring2_data
; [Ivan 07.03.2005]
mov [l.esp0], 0x8000 ;0x55000 ; used by i38 handler
; [/Ivan 07.03.2005]
mov [l.esp1], 0x56000
mov [l.esp2], 0x57000
 
mov eax,tss_sceleton ; move tss to tss_data+
mov ebx,[new_process_place]
imul ebx,tss_step
add ebx,tss_data
mov ecx,120
call memmove
 
 
; Add IO access table
 
or eax, -1
mov edi, [new_process_place]
imul edi, tss_step
add edi, tss_data + 128
mov ecx, 2048 ; for 2048 * 4 * 8 bits = 65536 ports
cld
rep stosd
 
; make sure gdt is pointing to the process
; and not to i40 handler
 
mov ecx,ebx
mov edi,[new_process_place]
; imul edi,8
shl edi, 3
 
mov [edi+gdts+ tss0 +0], word tss_step ; limit 0:15
mov [edi+gdts+ tss0 +2], cx ; base 0:15
mov eax,ecx
shr eax,16
mov [edi+gdts+ tss0 +4], al ; base 23:16
mov [edi+gdts+ tss0 +7], ah ; base 31:24
mov [edi+gdts+ tss0 +5], word 01010000b *256 +11101001b
 
pop eax
pop ebx
 
mov ebx,[new_process_place] ; save name of the process
shl ebx,8
add ebx,0x80000
mov ecx,11
call memmove
 
mov ebx,[new_process_place] ; save image size
shl ebx,8
add ebx,0x80000+0x8C
mov eax,[app_mem]
mov [ebx],eax
 
mov [0xf400],byte 0 ; empty keyboard buffer
mov [0xf500],byte 0 ; empty button buffer
 
mov [application_table_status],0
mov eax,[process_number]
 
mov ebx,[new_process_place]
shl ebx, 5 ;imul ebx,0x20
mov [0x3000+ebx+0xa],byte 0
 
mov edi,[new_process_place]
shl edi,5
add edi,window_data
 
mov ebx,[new_process_place]
movzx esi, word [0xC000 + ebx*2]
lea esi, [0xC400 + esi*2]
call windowactivate
 
sti
 
push esi
mov esi,process_running
call sys_msg_board_str
pop esi
 
ret
 
iglobal
process_terminating db 'K : Process - terminating',13,10,0
process_terminated db 'K : Process - done',13,10,0
endg
 
 
terminate: ; terminate application
push esi
mov esi,process_terminating
call sys_msg_board_str
pop esi
;start memory manager code
; mov eax,esi
; call MEM_Heap_Clean
;end memory manager code
 
cli
cmp [application_table_status],0
je term9
sti
call change_task
jmp terminate
term9:
 
call set_application_table_status
mov eax,esi
call dispose_app_cr3_table
 
mov [first_gdt_search],0x2 ; start gdt search from beginning
 
cmp [prev_user_of_fpu],esi ; if user fpu last -> fpu user = 1
jne fpu_ok_1
mov [prev_user_of_fpu],1
fpu_ok_1:
 
mov [0xf400],byte 0 ; empty keyboard buffer
mov [0xf500],byte 0 ; empty button buffer
 
mov ecx,esi ; clear memory reserv.
shl ecx,3
mov [ecx+gdts+ app_code-3 +0],dword 0
mov [ecx+gdts+ app_code-3 +4],dword 0
mov [ecx+gdts+ app_data-3 +0],dword 0
mov [ecx+gdts+ app_data-3 +4],dword 0
 
mov edi, esi
; shl edi, 5
; add edi, 0x3000
; cmp [edi+0xa],byte 3 ; if normal terminate then clear int40 handler
; jne nocl40
 
; mov edi,esi ; free the used interrupt 0x40 handler
; shl edi, 8 ;imul edi,256
; mov eax,[edi+0x80000+0xb0]
 
; cmp eax,0 ; is application using a systemcall interrupt ?
; je nocl40
 
mov [usedi40+eax],byte 0
 
; mov edi,8
; imul edi,eax
mov edi, eax
shl edi, 3
mov [edi+tss0sys_l +5], word 01010000b *256 +11101001b
 
; mov edi,128
; imul edi,eax
mov edi, eax
shl edi, 7
mov [edi+0x298000+l.eip-tss_sceleton],dword i40
mov [edi+0x298000+l.eflags-tss_sceleton],dword 0x11002
 
mov ebx,eax
shl ebx, 12 ;imul ebx,4096
add ebx,sysint_stack_data
mov [edi+0x298000+l.esp-tss_sceleton],ebx
 
nocl40:
 
mov ecx,esi ; remove buttons
bnewba2:
mov edi,[0xfe88]
mov eax,edi
cld
movzx ebx,word [edi]
inc bx
bnewba:
dec bx
jz bnmba
add eax,0x10
cmp cx,[eax]
jnz bnewba
pusha
mov ecx,ebx
inc ecx
shl ecx,4
mov ebx,eax
add eax,0x10
call memmove
dec dword [edi]
popa
jmp bnewba2
bnmba:
 
pusha ; save window coordinates for window restoring
cld
shl esi,5
add esi,window_data
mov ax,[esi+0]
mov word [dlx],ax
mov bx,[esi+8]
add ax,bx
mov word [dlxe],ax
mov ax,[esi+4]
mov word [dly],ax
mov bx,[esi+12]
add ax,bx
mov word [dlye],ax
mov [esi+0],word 0
mov [esi+8],word 5
mov ax,[0xFE04]
mov [esi+4],ax
mov [esi+12],word 5
xor eax, eax
mov [esi+16],eax;dword 0
mov [esi+20],eax;dword 0
mov [esi+24],eax;dword 0
mov [esi+28],eax;dword 0
popa
 
pusha
mov edi,esi
shl edi,5
add edi,window_data
mov ecx,32/4
xor eax, eax
; cld
rep stosd
 
mov eax,[0xFE04] ; set window to start from maxy+1
add eax,2
 
mov edi,esi
shl edi,5
add edi,window_data
mov [edi+4],eax
 
popa
 
pusha
mov edi,esi
shl edi,5
add edi,draw_data
mov ecx,32/4
xor eax, eax
; cld
rep stosd
popa
 
pusha ; at 0x80000+
mov edi,esi
shl edi,8
add edi,0x80000
mov ecx,256/4
xor eax, eax
; cld
rep stosd
popa
 
pusha ; name to spaces
mov edi,esi
shl edi,8
add edi,0x80000
mov ecx,11
mov eax,' '
; cld
rep stosb
popa
 
pusha ; C000 --> C400
mov eax, 0xc000
mov esi, 0
nlc40:
add eax, 2
inc esi
cmp esi, [0x3004]
jae nlc41
movzx ecx, word [eax]
mov [0xC400 + ecx*2], si
jmp nlc40
nlc41:
; ivan 08.12.2004 begin
;mov ebx, [0x3004]
;dec ebx
;lea esi, [0xC400 + ebx*2]
;call windowactivate
; ivan 08.12.2004 end
popa
 
pusha ; remove hd1 reservation
mov edx,esi
shl edx, 5 ;imul edx,0x20
add edx,0x3000
mov edx,[edx+4]
cmp [hd1_status],edx
jne no_hd1_s_remove
mov [hd1_status],0
no_hd1_s_remove:
popa
 
pusha ; remove all irq reservations
mov edx,esi
shl edx, 5 ;imul edx,0x20
add edx,0x3000
mov edx,[edx+4]
mov edi,irq_owner
mov ecx,16
newirqfree:
cmp [edi],edx
jne nofreeirq
mov [edi],dword 0
nofreeirq:
add edi,4
loop newirqfree
popa
 
 
pusha ; remove all port reservations
 
mov edx,esi
shl edx, 5 ;imul edx,0x20
add edx,0x3000
mov edx,[edx+4]
 
rmpr0:
 
mov esi,[0x2d0000]
 
cmp esi,0
je rmpr9
 
rmpr3:
 
mov edi,esi
shl edi,4
add edi,0x2d0000
 
cmp edx,[edi]
je rmpr4
 
dec esi
jnz rmpr3
 
jmp rmpr9
 
rmpr4:
 
mov ecx,256
sub ecx,esi
shl ecx,4
 
mov esi,edi
add esi,16
cld
rep movsb
 
dec dword [0x2d0000]
 
jmp rmpr0
 
rmpr9:
 
popa
mov edi,esi ; do not run this process slot
shl edi, 5 ;imul edi,0x20
; add edi,0x3000
mov [edi+0x300A],byte 9
; call systest
sti ; .. and life goes on
 
; movzx eax,word [dlx]
; movzx ebx,word [dly]
; movzx ecx,word [dlxe]
; movzx edx,word [dlye]
call calculatescreen
 
xor eax, eax
xor esi, esi
call redrawscreen
 
mov [0xfff4],byte 0 ; no mouse background
mov [0xfff5],byte 0 ; draw mouse
 
mov [application_table_status],0
 
mov esi,process_terminated
call sys_msg_board_str
 
;* start code - fix error redraw for terminate (2) - Mario79
; cmp [draw_present],1
; je no_draw_background_temp
; mov [0xfff0],byte 1
;no_draw_background_temp:
; mov [draw_present],0
ret
;draw_present db 0
;* end code - fix error redraw for terminate (2) - Mario79
 
iglobal
boot_sched_1 db 'Building gdt tss pointer',0
;boot_sched_2 db 'Building gdt gate pointer',0
boot_sched_3 db 'Building interrupt table - TSS',0
boot_sched_3_2 db 'Building interrupt table - GDT',0
boot_sched_3_3 db 'Building interrupt table - IDT',0
boot_sched_4 db 'Building syscall interrupt table',0
endg
 
 
build_scheduler:
; { Ivan 06.03.2005
mov edi, usedi40
mov ecx, 256/4
xor eax, eax
rep stosd
; } Ivan 06.03.2005
 
mov esi,boot_sched_1
call boot_log
call build_process_gdt_tss_pointer
 
; mov esi,boot_sched_2
; call boot_log
; call build_process_gdt_gate_pointer
 
mov esi,boot_sched_3
call boot_log
call build_interrupt_table
 
mov esi,boot_sched_4
call boot_log
call build_syscall_interrupt_table
 
ret
 
/kernel/trunk/core/syscall.inc
0,0 → 1,238
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; SYSTEM CALL ENTRY ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 32
i40:
cli
 
mov edi,[0x3000]
mov eax,edi
shl edi, 3
;clear busy flag in application's TSS
mov [edi+gdts+ tss0 +5], word 01010000b *256 +11101001b
;save GDT TSS entry
mov edx,[edi+tss0_l]
mov [reg1+eax*4],edx
mov edx,[edi+tss0_l+4]
mov [reg2+eax*4],edx
;and then write there i40's descriptor
mov edx,[tss0sys_l+edi]
mov [edi+tss0_l],edx
mov edx,[tss0sys_l+edi+4]
mov [edi+tss0_l+4],edx
 
 
shl edi,5
mov [edi+0x80000+0xB0],eax ; used i40 handler
 
; for syscall trace function
call save_registers
 
mov esi, [0x3000]
imul esi, tss_step
add esi, tss_data
; esi holds address of TSS of interupted program
; load first 3 registers
mov eax,[esi+l.eax-tss_sceleton]
mov ebx,[esi+l.ebx-tss_sceleton]
mov ecx,[esi+l.ecx-tss_sceleton]
 
; save current registers
; stack may be modified by a system function to return some value to caller!
pushad
 
; load all registers from TSS of the application, in crossed order (why?)
mov edi,[esi+l.eax-tss_sceleton]
mov eax,[esi+l.ebx-tss_sceleton]
mov ebx,[esi+l.ecx-tss_sceleton]
mov ecx,[esi+l.edx-tss_sceleton]
mov edx,[esi+l.esi-tss_sceleton]
mov esi,[esi+l.edi-tss_sceleton]
 
; enable interupts - a task switch or an IRQ _CAN_ interrupt i40 handler
sti
; eax doesn't need to be saved, but...
push eax
and edi,0xff
call dword [servetable+edi*4]
pop eax
cli
; return saved and probably even changed regs
popad
 
; <Ivan 05.03.2005> esi already loaded - look above "pusha"
;mov esi,[0x3000]
;imul esi,tss_step
;add esi,tss_data
; </Ivan 05.03.2005>
 
; modify 3 program's registers (in its TSS)
mov [esi+l.eax-tss_sceleton], eax
mov [esi+l.ebx-tss_sceleton], ebx
mov [esi+l.ecx-tss_sceleton], ecx
 
; calculate app's TSS address
mov ebx, [0x3000]
shl ebx, 3
add ebx, tss0_l
 
mov ecx, [0x3000]
 
; restore saved TSS descriptor
mov eax, [reg1+ecx*4]
mov [ebx], eax
mov eax, [reg2+ecx*4]
mov [ebx+4], eax
 
xor eax, eax
mov edi, [0x3000] ; no syscall interrupt in use anymore
shl edi, 8
mov [edi+0x80000+0xB0],eax
 
; clear busy flag in TSS of this handler
mov edi, [0x3000]
shl edi, 3
mov [edi+tss0sys_l +5], word 01010000b *256 +11101001b
 
add edi,tss0
mov [0xB004], di
 
jmp pword [0xB000]
 
jmp i40
 
label reg1 dword at 0x6000
label reg2 dword at 0x6400
label usedi40 byte at 0x6800
 
uglobal
schd dd 0x0
endg
 
align 4
save_registers:
 
mov esi,[0x3000]
imul esi,tss_step
add esi,tss_data
 
mov eax,[esi+l.eax-tss_sceleton]
mov ebx,[esi+l.ebx-tss_sceleton]
mov ecx,[esi+l.ecx-tss_sceleton]
mov edx,[esi+l.edx-tss_sceleton]
mov edi,[esi+l.edi-tss_sceleton]
mov ebp,[esi+l.ebp-tss_sceleton]
 
mov esi,[esi+l.esi-tss_sceleton]
 
push eax ecx esi edi
mov esi,[0x3010]
mov eax,[esi+0x4]
mov esi,esp
inc [save_syscall_count]
mov edi,[save_syscall_count]
and edi,0xF
shl edi,6
add edi,save_syscall_data+32
mov [edi-32],eax
mov ecx,32 / 4
cld
rep movsd
pop edi esi ecx eax
ret
 
uglobal
save_syscall_count dd 0x0
endg
 
label save_syscall_data dword at 0x5000
 
 
iglobal
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; SYSTEM FUNCTIONS TABLE ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 4
servetable:
 
dd sys_drawwindow ; 0-DrawWindow
dd syscall_setpixel ; 1-SetPixel
dd sys_getkey ; 2-GetKey
dd sys_clock ; 3-GetTime
dd syscall_writetext ; 4-WriteText
dd delay_hs ; 5-DelayHs
dd syscall_openramdiskfile ; 6-OpenRamdiskFile
dd syscall_putimage ; 7-PutImage
dd sys_button ; 8-DefineButton
dd sys_cpuusage ; 9-GetProcessInfo
dd sys_waitforevent ; 10-WaitForEvent
dd sys_getevent ; 11-CheckForEvent
dd sys_redrawstat ; 12-BeginDraw and EndDraw
dd syscall_drawrect ; 13-DrawRect
dd syscall_getscreensize ; 14-GetScreenSize
dd sys_background ; 15-bgr
dd sys_cachetodiskette ; 16-FlushFloppyCache
dd sys_getbutton ; 17-GetButton
dd syscall_system ; 18-Shutdown,KillApp,WindowActivate
dd syscall_startapp ; 19-StartApp
dd sys_midi ; 20-ResetMidi and OutputMidi
dd sys_setup ; 21-SetMidiBase,SetKeymap,SetShiftKeymap,.
dd sys_settime ; 22-setting date,time,clock and alarm-clock
dd sys_wait_event_timeout ; 23-TimeOutWaitForEvent
dd syscall_cdaudio ; 24-PlayCdTrack,StopCd and GetCdPlaylist
dd sys_sb16 ; 25-SetSb16
dd sys_getsetup ; 26-GetMidiBase,GetKeymap,GetShiftKeymap,.
dd sys_wss ; 27-SetWssMainVol and SetWssCdVol
dd sys_sb16II ; 28-SetSb16
dd sys_date ; 29-GetDate
dd syscall_readhd ; 30-ReadHd
dd syscall_starthdapp ; 31-StartHdApp
dd syscall_delramdiskfile ; 32-DelRamdiskFile
dd syscall_writeramdiskfile; 33-WriteRamdiskFile
dd read_floppy_file ; 34-ReadFloppyDrive
dd syscall_getpixel ; 35-GetPixel
dd syscall_readstring ; 36-ReadString (not yet ready)
dd readmousepos ; 37-GetMousePosition_ScreenRelative,.
dd syscall_drawline ; 38-DrawLine
dd sys_getbackground ; 39-GetBackgroundSize,ReadBgrData,.
dd set_app_param ; 40-WantEvents
dd syscall_getirqowner ; 41-GetIrqOwner
dd get_irq_data ; 42-ReadIrqData
dd sys_outport ; 43-SendDeviceData
dd sys_programirq ; 44-ProgramIrqs
dd reserve_free_irq ; 45-ReserveIrq and FreeIrq
dd syscall_reserveportarea ; 46-ReservePortArea and FreePortArea
dd display_number ; 47-WriteNum
dd display_settings ; 48-SetRedrawType and SetButtonType
dd syscall_appints ; 49-AppInts
dd random_shaped_window ; 50-Window shape & scale
dd syscall_threads ; 51-Threads
dd stack_driver_stat ; 52-Stack driver status
dd socket ; 53-Socket interface
dd user_events ; 54-User events
dd sound_interface ; 55-Sound interface
dd write_to_hd ; 56-Write a file to hd
dd delete_from_hd ; 57-Delete a file from hd
dd file_system ; 58-Common file system interface
dd sys_trace ; 59-System call trace
dd new_sys_ipc ; 60-Inter Process Communication
dd sys_gs ; 61-Direct graphics access
dd sys_pci ; 62-PCI functions
dd sys_msg_board ; 63-System message board
dd sys_resize_app_memory ; 64-Resize application memory usage
dd undefined_syscall ; 65-UTF
dd sys_process_def ; 66-Process definitions - keyboard
dd sys_window_move ; 67-Window move or resize
dd sys_internal_services ; 68-Some internal services
 
times 255 - ( ($-servetable) /4 ) dd undefined_syscall
 
dd sys_end ; -1-end application
endg