kolibrios/programs/demos/life2/include/kos_func.inc
IgorA 97d7b5c34a clean code
git-svn-id: svn://kolibrios.org@8170 a494cfbc-eb01-0410-851d-a64ba20cac60
2020-11-10 12:19:15 +00:00

1153 lines
24 KiB
C++

;const int
KOLIBRI_BORDER_SIZE = 4;
;const int
KOLIBRI_HEADER_SIZE = 20;
;const int
KOLIBRI_THREAD_DATA_USER = 0; // Thread data begin from the user dword
;const int
KOLIBRI_THREAD_DATA_ST_BEGIN = 1; // Stack beginning follows after the user dword
;const int
KOLIBRI_THREAD_DATA_NEXT = 2;
;const int
KOLIBRI_THREAD_DATA_PID = 3;
;const int
KOLIBRI_THREAD_DATA_FLAG = 4;
;const int
KOLIBRI_THREAD_DATA_X = 5;
;const int
KOLIBRI_THREAD_DATA_Y = 6;
;const int
KOLIBRI_THREAD_DATA_C_WINDOW = 7;
;const int
KOLIBRI_THREAD_DATA_C_HEADER = 8;
;const int
KOLIBRI_THREAD_DATA_C_BORDER = 9;
;const int
KOLIBRI_THREAD_DATA_C_TITLE = 10;
;const int
KOLIBRI_THREAD_DATA_TITLE = 11;
;const int
KOLIBRI_THREAD_DATA_PICTURE = 12;
;const int
KOLIBRI_THREAD_DATA_SZ_PICT = 13;
;const int
KOLIBRI_THREAD_DATA_LAST_SX = 14;
;const int
KOLIBRI_THREAD_DATA_LAST_SY = 15;
;const int
KOLIBRI_THREAD_DATA_LEN = 16;
;const int
KOLIBRI_MUTEX_MAX_TIME_WAIT = 20;
;const int
KOLIBRI_FILE_BLOCK_SIZE = 512;
;const int
KOLIBRI_FILE_MEMORY_OS_NEED = 4096;
;/***
macro segment name
{
segment name
if name eq _init_ | name eq _INIT_
Kolibri_SegmentInit:
else if name eq _exit_ | name eq _EXIT_
Kolibri_SegmentExit:
end if
}
macro endseg name
{
if name eq _init_ | name eq _INIT_
Kolibri_SegmentInitEnd:
else if name eq _exit_ | name eq _EXIT_
Kolibri_SegmentExitEnd:
end if
endseg name
}
macro Kolibri_Put_MovEaxVal_Ret address,val
{
mov byte [address],0xB8
mov dword [address+4],0xC089C300
mov dword [address+1],val
}
proc @Kolibri@Main$qv
and esp,not 3
sub esp,1024
mov eax,SF_THREAD_INFO
mov ebx,esp
mov ecx,-1
int 0x40
mov ebx,[esp+26]
mov edx,[esp+30]
lea eax,[ebx-0x20]
add esp,1024
cmp esp,eax
cmova esp,eax
and esp,not 3
if defined @Kolibri@CommandLine
mov byte [@Kolibri@CommandLine+256], 0
end if
xor eax,eax
cld
mov edi,@Kolibri@_ThreadTable
mov ecx,256
rep stosd
mov esi,@Kolibri@GetPid$qv
mov edi,@Kolibri@_ThreadSavedBegProc
movsd
movsd
mov esi,@Kolibri@GetThreadData$qv
movsd
movsd
Kolibri_Put_MovEaxVal_Ret @Kolibri@GetPid$qv,edx
if defined KolibriHeapInit
mov ecx,esp
push ebx
push ecx
push U_END
call KolibriHeapInit ; Initialize a dynamic heap and create new memory in its begin.
pop ecx ; Parameters: begin of a new heap, end of data to create in
mov [esp+4],eax ; the begin of a heap. Return address of the created data.
mov dword [esp],0
else
xor eax,eax
push eax
push eax
end if
call @Kolibri@ThreadMain$qpvt1
.ThreadFinish:
add esp,8
if defined KolibriHeapFreeAndThreadFinish
test eax,eax
jz .ThreadFinish_end
push dword @Kolibri@_ExitProcessNow
push eax
call KolibriHeapFreeAndThreadFinish ; Free the given memory and finish the thread,
end if ; should exit process if second argument points to not zero.
.ThreadFinish_end:
or eax,-1
int 0x40
endp
proc @Kolibri@ThreadMain$qpvt1
xchg ebx,[esp+4]
xchg ebp,[esp+8]
push esi edi
sub esp,KOLIBRI_THREAD_DATA_LEN*4
mov [esp],ebx
mov [esp+4],ebp
mov eax,SF_SET_EVENTS_MASK
mov ebx,0x27
int 0x40
mov ebx,esp
cmp byte [@Kolibri@_ThreadSavedBegProc],0x90
jz .main_else_first_check
Kolibri_Put_MovEaxVal_Ret @Kolibri@GetThreadData$qv,esp
if defined Kolibri_SegmentInit & defined Kolibri_SegmentInitEnd
push Kolibri_SegmentInitEnd
push Kolibri_SegmentInit
jmp .main_after_first_check
end if
.main_else_first_check:
xor eax,eax
push eax eax
.main_after_first_check:
push ebx
call @@Kolibri@_CallStart$qppvpvt2
add esp,12
test al,al
jnz .main_test_close_first
jmp .main_end
.main_close_first:
btr dword [esp+KOLIBRI_THREAD_DATA_FLAG*4],31
if defined @@KolibriOnClose$qppv
push esp
call @@KolibriOnClose$qppv
pop ecx
test al,al
jnz .main_end
end if
.main_test_close_first:
cmp dword [esp+KOLIBRI_THREAD_DATA_FLAG*4],0
jl .main_close_first
push esp
push dword 1
call @Kolibri@Redraw$qippv
add esp,8
.main_paint_msg:
or dword [esp+KOLIBRI_THREAD_DATA_FLAG*4],3
sub esp,1024
mov eax,SF_THREAD_INFO
mov ebx,esp
mov ecx,-1
int 0x40
mov eax,[esp+34]
mov ebx,[esp+38]
mov ecx,[esp+42]
mov edx,[esp+46]
add esp,1024
cmp ecx,[esp+KOLIBRI_THREAD_DATA_LAST_SX*4]
jnz .main_size
cmp edx,[esp+KOLIBRI_THREAD_DATA_LAST_SY*4]
jz .main_paint
.main_size:
mov [esp+KOLIBRI_THREAD_DATA_LAST_SX*4],ecx
mov [esp+KOLIBRI_THREAD_DATA_LAST_SY*4],edx
if defined @@KolibriOnSize$qpippv
push edx
push ecx
push ebx
push eax
lea ecx,[esp+16]
mov edx,esp
push ecx
push edx
call @@KolibriOnSize$qpippv
add esp,24
end if
test dword [esp+KOLIBRI_THREAD_DATA_FLAG*4],3
jz .main_cycle
.main_paint:
cmp dword [esp+KOLIBRI_THREAD_DATA_FLAG*4],0
jl .main_close
push esp
push dword 0
call @Kolibri@Redraw$qippv
add esp,8
.main_cycle:
mov eax,SF_CHECK_EVENT
.main_message:
cmp dword [esp+KOLIBRI_THREAD_DATA_FLAG*4],0
jl .main_close
int 0x40
test eax,eax
jnz .main_on_message
cmp dword [esp+KOLIBRI_THREAD_DATA_FLAG*4],0
jne .main_paint
if defined @@KolibriOnIdle$qppv
push esp
call @@KolibriOnIdle$qppv
pop ecx
else
or eax,-1
end if
test eax,eax
jz .main_cycle
jl .main_wait_message
mov ebx,eax
mov eax,SF_WAIT_EVENT_TIMEOUT
jmp .main_message
.main_wait_message:
mov eax,SF_WAIT_EVENT
jmp .main_message
if defined @@KolibriOnKeyPress$qppv
.main_key_press:
push esp
call @@KolibriOnKeyPress$qppv
pop ecx
jmp .main_cycle
end if
if defined @@KolibriOnMouse$qppv
.main_mouse:
push esp
call @@KolibriOnMouse$qppv
pop ecx
jmp .main_cycle
end if
align 4
.main_on_message:
dec eax
jz .main_paint_msg
dec eax
if defined @@KolibriOnKeyPress$qppv
jz .main_key_press
else
jz .main_cycle
end if
cmp eax,4
if defined @@KolibriOnMouse$qppv
jz .main_mouse
else
jz .main_cycle
end if
dec eax
jnz .main_cycle
align 4
.main_button:
mov eax,SF_GET_BUTTON
int 0x40
shr eax,8
cmp eax,1
je .main_close
if defined @@KolibriOnButton$qlppv
push esp
push eax
call @@KolibriOnButton$qlppv
add esp,8
end if
jmp .main_cycle
.main_close:
btr dword [esp+KOLIBRI_THREAD_DATA_FLAG*4],31
if defined @@KolibriOnClose$qppv
push esp
call @@KolibriOnClose$qppv
pop ecx
test al,al
jz .main_button
end if
.main_end:
mov ebx,esp
lock dec dword [@Kolibri@_ThreadNumber]
if defined Kolibri_SegmentExit & defined Kolibri_SegmentExitEnd
jnz .main_else_last_check
push Kolibri_SegmentExitEnd
push Kolibri_SegmentExit
jmp .main_after_last_check
end if
.main_else_last_check:
xor eax,eax
push eax
push eax
.main_after_last_check:
push ebx
call @@Kolibri@_RemoveThreadData$qppvpvt2
add esp,12
lock inc dword [@Kolibri@_ThreadScanCount+4]
mov ebx,1
jmp .main_end_wait
.main_end_wait_loop:
mov eax,SF_SLEEP
int 0x40
shl ebx,1
cmp ebx,KOLIBRI_MUTEX_MAX_TIME_WAIT
jna .main_end_wait
mov ebx,KOLIBRI_MUTEX_MAX_TIME_WAIT
.main_end_wait:
cmp dword [@Kolibri@_ExitProcessNow],0
jnz @Kolibri@ExitProcess$qv
cmp dword [@Kolibri@_ThreadScanCount],0
jnz .main_end_wait_loop
lock dec dword [@Kolibri@_ThreadScanCount+4]
mov ebp,[esp+4]
mov ebx,[esp]
add esp,KOLIBRI_THREAD_DATA_LEN*4
mov eax,ebp
pop edi esi
xchg ebp,[esp+8]
xchg ebx,[esp+4]
ret
endp
macro call func
{
if func eq __chkstk
sub esp,eax
else
call func
end if
}
proc @Kolibri@Redraw$qippv
push ebp
mov ebp,[esp+12]
mov edx,[ebp+KOLIBRI_THREAD_DATA_FLAG*4]
cmp dword [esp+8],0
jl .redraw_only_inv
jz .redraw_no_frame
or dl,2
.redraw_no_frame:
bt edx,30
jnc .redraw_begin
or dl,1
mov [ebp+KOLIBRI_THREAD_DATA_FLAG*4],edx
jmp .redraw_end
.redraw_only_inv:
test dl,3
jnz .redraw_no_frame
.redraw_end:
pop ebp
ret
.redraw_begin:
push ebx esi edi
and dword [ebp+KOLIBRI_THREAD_DATA_FLAG*4],0xFFFFFFFC
test dl,2
jz .redraw_picture
mov eax,SF_REDRAW
mov ebx,SSF_BEGIN_DRAW
int 0x40
xor eax,eax
mov ebx,[ebp+KOLIBRI_THREAD_DATA_X*4]
mov ecx,[ebp+KOLIBRI_THREAD_DATA_Y*4]
mov edx,[ebp+KOLIBRI_THREAD_DATA_C_WINDOW*4]
mov esi,[ebp+KOLIBRI_THREAD_DATA_C_HEADER*4]
mov edi,[ebp+KOLIBRI_THREAD_DATA_C_BORDER*4]
int 0x40
mov edx,[ebp+KOLIBRI_THREAD_DATA_TITLE*4]
test edx,edx
jz .window_defined
mov edi,edx
mov ecx,0xFFFFFFFF
xor al,al
cld
repnz scas byte [edi]
not ecx
mov esi,ecx
dec esi
jz .window_defined
mov eax,SF_DRAW_TEXT
mov ebx,0x00070007
mov ecx,[ebp+KOLIBRI_THREAD_DATA_C_TITLE*4]
int 0x40
.window_defined:
.redraw_picture:
mov eax,SF_REDRAW
mov ebx,SSF_END_DRAW
int 0x40
mov esi,[ebp+KOLIBRI_THREAD_DATA_PICTURE*4]
test esi,esi
jz .redraw_end_draw
mov ecx,[ebp+KOLIBRI_THREAD_DATA_SZ_PICT*4]
jecxz .redraw_end_draw
mov al,byte [ebp+KOLIBRI_THREAD_DATA_C_WINDOW*4+3]
and al,15
mov edx,KOLIBRI_BORDER_SIZE*65536+KOLIBRI_HEADER_SIZE
cmp al,3
jnz .redraw_no_skin
mov eax,SF_STYLE_SETTINGS
mov ebx,SSF_GET_SKIN_HEIGHT
int 0x40
mov dx,ax
.redraw_no_skin:
mov eax,SF_PUT_IMAGE
mov ebx,esi
int 0x40
.redraw_end_draw:
pop edi esi ebx ebp
ret
endp
proc @Kolibri@MoveWindow$qxpxi uses ebx esi
mov eax,[esp+12]
mov ebx,[eax]
mov ecx,[eax+4]
mov edx,[eax+8]
mov esi,[eax+12]
mov eax,SF_CHANGE_WINDOW
int 0x40
ret
endp
proc @Kolibri@ExitDebug$qv
push dword [@Kolibri@DebugPrefix]
call @Kolibri@DebugPutString$qpxc
mov dword [esp],Kolibri_debug_string
call @Kolibri@DebugPutString$qpxc
pop ecx
jmp @Kolibri@ExitProcess$qv
endp
proc @Kolibri@ExitProcess$qv
lock bts dword [@Kolibri@_ExitProcessNow],0
jc .exit_process_wait
sub esp,1024
mov eax,SF_THREAD_INFO
mov ebx,esp
mov ecx,-1
int 0x40
mov esi,eax
mov edi,[esp+30]
.exit_process_loop:
mov eax,SF_THREAD_INFO
mov ebx,esp
mov ecx,esi
int 0x40
mov eax,[esp+30]
cmp eax,edi
jz .exit_process_continue
mov ebx,eax
or bl,15
inc ebx
jz .exit_process_continue
mov ebx,eax
call Kolibri_HashInt
movzx eax,al
mov eax,dword [@Kolibri@_ThreadTable+eax*4]
jmp .exit_process_test
.exit_process_next:
mov eax,dword [eax+KOLIBRI_THREAD_DATA_NEXT*4]
.exit_process_test:
test eax,eax
jz .exit_process_continue
cmp ebx,[eax+KOLIBRI_THREAD_DATA_PID*4]
jnz .exit_process_next
mov eax,SF_SYSTEM
mov ebx,SSF_TERMINATE_THREAD
mov ecx,esi
int 0x40
.exit_process_continue:
dec esi
jnl .exit_process_loop
add esp,1024
mov dword [@Kolibri@_ExitProcessNow],-1
if defined EMULATOR
int3
call 0x76543210
end if
.exit_process_end:
mov dword [@Kolibri@_ThreadMutex],0
or eax,-1
int 0x40
.exit_process_wait:
mov eax,SF_SLEEP
mov ebx,1
.exit_process_wait_loop:
cmp dword [@Kolibri@_ExitProcessNow],0
jl .exit_process_end
int 0x40
shl ebx,1
cmp ebx,KOLIBRI_MUTEX_MAX_TIME_WAIT
jna .exit_process_wait_loop
mov ebx,KOLIBRI_MUTEX_MAX_TIME_WAIT
jmp .exit_process_wait_loop
endp
proc @Kolibri@ExitThread$qppv,@Kolibri@ThreadMain$qpvt1
mov esp,[esp+4]
jmp Kolibri_main_end
endp
proc @Kolibri@ReturnMessageLoop$qppv,@Kolibri@ThreadMain$qpvt1
mov esp,[esp+4]
bt dword [esp+KOLIBRI_THREAD_DATA_FLAG*4],30
jc Kolibri_main_end
jmp Kolibri_main_cycle
endp
proc @Kolibri@Delay$qui uses ebx
mov eax,SF_SLEEP
mov ebx,[esp+8]
int 0x40
ret
endp
proc @Kolibri@Clock$qv uses ebx
mov eax,SF_SYSTEM_GET
mov ebx,SSF_TIME_COUNT
int 0x40
ret
endp
proc @Kolibri@DrawButton$qllllll uses ebx esi
mov eax,SF_DEFINE_BUTTON
mov ebx,[esp+12-2+8]
mov bx,[esp+20+8]
mov ecx,[esp+16-2+8]
mov cx,[esp+24+8]
mov edx,[esp+4+8]
mov esi,[esp+8+8]
int 0x40
ret
endp
proc @Kolibri@GetPackedTime$qv
mov eax,SF_GET_SYS_TIME
int 0x40
ret
endp
proc @Kolibri@GetTime$qpi
mov eax,SF_GET_SYS_TIME
int 0x40
mov edx,[esp+4]
movzx ecx,al
shr ecx,4
and al,0x0F
imul ecx,10
add cl,al
mov dword [edx+8],ecx
mov cl,ah
shr ecx,4
and ah,0x0F
imul ecx,10
add cl,ah
mov dword [edx+4],ecx
bswap eax
mov cl,ah
shr ecx,4
and ah,0x0F
imul ecx,10
add cl,ah
mov dword [edx],ecx
ret
endp
proc @Kolibri@GetPackedDate$qv
mov eax,SF_GET_SYS_DATE
int 0x40
ret
endp
proc @Kolibri@GetDate$qpi
mov eax,SF_GET_SYS_DATE
int 0x40
mov edx,[esp+4]
movzx ecx,al
shr ecx,4
and al,0x0F
imul ecx,10
add cl,al
mov dword [edx+4],ecx
mov cl,ah
shr ecx,4
and ah,0x0F
imul ecx,10
add cl,ah
mov dword [edx],ecx
bswap eax
mov cl,ah
shr ecx,4
and ah,0x0F
imul ecx,10
add cl,ah
mov dword [edx+8],ecx
ret
endp
proc @Kolibri@ReadCommonColors$qpui uses ebx
mov eax,SF_STYLE_SETTINGS
mov ebx,SSF_GET_COLORS
mov ecx,[esp+8]
mov edx,40
int 0x40
ret
endp
proc @Kolibri@DrawText$qssipxc uses ebx
mov eax,SF_DRAW_TEXT
mov ebx,[esp+8-2]
mov bx,[esp+12]
mov ecx,[esp+16]
or ecx,0x80000000
mov edx,[esp+20]
int 0x40
ret
endp
proc @Kolibri@SetWindowCaption$qpxc uses ebx
mov eax,SF_SET_CAPTION
mov ebx,2
mov ecx,[esp+8]
int 0x40
ret
endp
proc @Kolibri@GetProcessInfo$qpuipct1t1piui uses ebx esi edi
sub esp,1024
mov eax,SF_THREAD_INFO
mov ebx,esp
mov ecx,[1024+12+24+esp]
int 0x40
xor edi,edi
or edi,[1024+12+4+esp]
jz .get_proc_info_no_usecpu
mov ecx,[esp]
mov [edi],ecx
xor edi,edi
.get_proc_info_no_usecpu:
or edi,[1024+12+8+esp]
jz .get_proc_info_no_name
lea esi,[esp+10]
cld
movsd
movsd
movsd
mov byte [edi],0
xor edi,edi
.get_proc_info_no_name:
or edi,[1024+12+12+esp]
jz .get_proc_info_no_mem
mov ecx,[esp+26]
mov [edi],ecx
xor edi,edi
.get_proc_info_no_mem:
or edi,[1024+12+16+esp]
jz .get_proc_info_no_pid
mov ecx,[esp+30]
mov [edi],ecx
xor edi,edi
.get_proc_info_no_pid:
or edi,[1024+12+20+esp]
jz .get_proc_info_no_rect
lea esi,[esp+34]
cld
movsd
movsd
movsd
movsd
xor edi,edi
.get_proc_info_no_rect:
add esp,1024
ret
endp
proc @Kolibri@GetPid$qv uses ebx
sub esp,1024
mov eax,SF_THREAD_INFO
mov ebx,esp
mov ecx,-1
int 0x40
mov eax,[esp+30]
add esp,1024
ret
endp
proc @Kolibri@GetPid$qppv
mov ecx,[esp+4]
mov eax,[ecx+KOLIBRI_THREAD_DATA_PID*4]
ret
endp
proc @Kolibri@_HashByte$qui
@Kolibri@_HashWord$qui:
@Kolibri@_HashDword$qui:
mov eax,[esp+4]
Kolibri_HashInt:
mul dword [Kolibri_hash_int_val0]
xor eax,edx
bswap eax
mul dword [Kolibri_hash_int_val1]
shrd eax,edx,14
bswap eax
lea eax,[eax+4*eax]
ror eax,9
ret
endp
if defined @Kolibri@_HashByte$qui | defined @Kolibri@_HashWord$qui | defined @Kolibri@_HashDword$qui
Kolibri_hash_int_val0:
dd 0xA82F94C5
Kolibri_hash_int_val1:
dd 0x9193780B
end if
proc @Kolibri@GetThreadData$qv
call @Kolibri@GetPid$qv
push eax
call @Kolibri@GetThreadData$qui
pop ecx
ret
endp
proc @Kolibri@GetThreadData$qui
mov eax,[esp+4]
call Kolibri_HashInt
movzx eax,al
cmp dword [@Kolibri@_ThreadScanCount+4],0
jnz .get_thread_data_wait
.get_thread_data_nowait:
lock inc dword [@Kolibri@_ThreadScanCount]
mov eax,dword [@Kolibri@_ThreadTable+eax*4]
mov ecx,[esp+4]
jmp .get_thread_data_test
.get_thread_data_loop:
mov eax,dword [eax+KOLIBRI_THREAD_DATA_NEXT*4]
.get_thread_data_test:
test eax,eax
jz .get_thread_data_end
cmp ecx,[eax+KOLIBRI_THREAD_DATA_PID*4]
jnz .get_thread_data_loop
.get_thread_data_end:
lock dec dword [@Kolibri@_ThreadScanCount]
ret
.get_thread_data_wait:
push eax ebx
mov eax,SF_SLEEP
mov ebx,1
.get_thread_data_wait_loop:
int 0x40
cmp dword [@Kolibri@_ThreadScanCount+4],0
jz .get_thread_data_wait_end
shl ebx,1
cmp ebx,KOLIBRI_MUTEX_MAX_TIME_WAIT
jna .get_thread_data_wait_loop
mov ebx,KOLIBRI_MUTEX_MAX_TIME_WAIT
jmp .get_thread_data_wait_loop
.get_thread_data_wait_end:
pop ebx eax
jmp .get_thread_data_nowait
endp
proc @Kolibri@_GetSkinHeader$qv uses ebx
mov eax,SF_STYLE_SETTINGS
mov ebx,SSF_GET_SKIN_HEIGHT
int 0x40
ret
endp
proc @Kolibri@GetScreenSize$qrust1
mov eax,SF_GET_SCREEN_SIZE
int 0x40
mov ecx,[esp+8]
mov word [ecx],ax
mov ecx,[esp+4]
shr eax,16
mov word [ecx],ax
ret
endp
proc Kolibri_MutexLockNoWait
pop eax
xor al,al
ret
endp
proc Kolibri_MutexLockWait uses ebx
mov eax,SF_SLEEP
xor ebx,ebx
.lock_wait_cycle:
int 0x40
shl byte [ecx],1
jz .lock_wait_cycle
mov al,1
ret
endp
proc Kolibri_MutexLockWaitTime
cmp dword [esp+12],0
jng .MutexLockWait
push ebx edx
mov edx,[esp+20]
mov eax,SF_SYSTEM_GET
mov ebx,SSF_TIME_COUNT
int 0x40
add edx,eax
.lock_wait_time_cycle:
mov eax,SF_SLEEP
xor ebx,ebx
int 0x40
shl byte [ecx],1
jnz .lock_wait_time_ret_true
mov eax,SF_SYSTEM_GET
mov ebx,SSF_TIME_COUNT
int 0x40
cmp eax,edx
js .lock_wait_time_cycle
pop edx ebx eax
xor al,al
ret
.lock_wait_time_ret_true:
pop edx ebx
mov al,1
ret
endp
proc Kolibri_MutexLock
shl byte [ecx],1
jnz .lock_first
call eax
.lock_first:
mov al,1
ret
endp
proc @Kolibri@TryLock$qp14Kolibri@TMutex
mov eax,Kolibri_MutexLockNoWait
mov ecx,[esp+4]
jmp Kolibri_MutexLock
endp
proc @Kolibri@Lock$qp14Kolibri@TMutex
mov eax,Kolibri_MutexLockWait
mov ecx,[esp+4]
jmp Kolibri_MutexLock
endp
proc @Kolibri@LockTime$qp14Kolibri@TMutexi
mov eax,Kolibri_MutexLockWaitTime
mov ecx,[esp+4]
jmp Kolibri_MutexLock
endp
proc @Kolibri@UnLock$qp14Kolibri@TMutex
mov ecx,[esp+4]
shr byte [ecx],1
jz .unlock_pause
ret
.unlock_pause:
mov byte [ecx],0x40
push ebx
mov eax,SF_SLEEP
xor ebx,ebx
int 0x40
pop ebx
ret
endp
proc Kolibri_MutexLockRec
shl byte [ecx],1
jng .lock_first
cmp dword [ecx+4],edx
jz .lock_rec_self
call eax
.lock_rec_first:
mov al,1
mov dword [ecx+4],edx
ret
.lock_rec_self:
mov al,1
add dword [ecx],0x100
jc .lock_rec_overflow
ret
.lock_rec_overflow:
push dword [@Kolibri@DebugPrefix]
call @Kolibri@DebugPutString$qpxc
mov dword [esp],Kolibri_try_lock_rec_overflow_string
call @Kolibri@DebugPutString$qpxc
pop ecx
jmp @Kolibri@ExitDebug$qv
endp
proc @Kolibri@TryLock$qp16Kolibri@TRecMutexui
mov eax,Kolibri_MutexLockNoWait
mov ecx,[esp+4]
mov edx,[esp+8]
jmp Kolibri_MutexLockRec
endp
proc @Kolibri@Lock$qp16Kolibri@TRecMutexui
mov eax,Kolibri_MutexLockWait
mov ecx,[esp+4]
mov edx,[esp+8]
jmp Kolibri_MutexLockRec
endp
proc @Kolibri@LockTime$qp16Kolibri@TRecMutexiui
mov eax,Kolibri_MutexLockWaitTime
mov ecx,[esp+4]
mov edx,[esp+12]
jmp Kolibri_MutexLockRec
endp
proc @Kolibri@UnLock$qp16Kolibri@TRecMutexui
mov ecx,[esp+4]
mov edx,[esp+8]
cmp dword [ecx+4],edx
jnz .unlock_rec_notlocked
sub dword [ecx],0x100
jnc .unlock_rec_end
add dword [ecx],0x100
shl byte [ecx],1
shr byte [ecx],2
jng .unlock_rec_pause
.unlock_rec_end:
ret
.unlock_rec_pause:
mov byte [ecx],0x20
push ebx
mov eax,SF_SLEEP
xor ebx,ebx
int 0x40
pop ebx
ret
.unlock_rec_notlocked:
push dword [@Kolibri@DebugPrefix]
call @Kolibri@DebugPutString$qpxc
mov dword [esp],Kolibri_unlock_rec_notlocked_string
call @Kolibri@DebugPutString$qpxc
pop ecx
jmp @Kolibri@ExitDebug$qv
endp
proc @Kolibri@DebugPutChar$qc
mov cl,byte [esp+4]
cmp cl,13
jz .debug_put_char_ret
push ebx
cmp cl,10
jz .debug_put_char_enter
.debug_put_char_after_cmp:
mov eax,SF_BOARD
mov ebx,SSF_DEBUG_WRITE
int 0x40
pop ebx
.debug_put_char_ret:
ret
.debug_put_char_enter:
mov cl,13
mov eax,SF_BOARD
mov ebx,SSF_DEBUG_WRITE
int 0x40
mov cl,10
jmp .debug_put_char_after_cmp
endp
proc @Kolibri@DebugPutString$qpxc uses esi
push dword 0
mov esi,dword [esp+12]
jmp .debug_put_string_test
.debug_put_string_loop:
mov dword [esp],eax
call @Kolibri@DebugPutChar$qc
inc esi
.debug_put_string_test:
xor eax,eax
or al,[esi]
test al,al
jnz .debug_put_string_loop
pop ecx
ret
endp
proc @Kolibri@GetKey$qv
mov eax,SF_GET_KEY
int 0x40
test al,al
jnz .get_key_eof
movzx eax,ah
ret
.get_key_eof:
mov eax,SF_TERMINATE_PROCESS
ret
endp
proc @Kolibri@GetMouseButton$qv uses ebx
mov eax,SF_MOUSE_GET
mov ebx,SSF_BUTTON
int 0x40
ret
endp
proc @Kolibri@GetMousePosition$qrst1o uses ebx
mov eax,SF_MOUSE_GET
xor ebx,ebx ;SSF_SCREEN_POSITION
cmp byte [esp+16],0
jnz .get_mouse_pos_absolute
inc ebx
.get_mouse_pos_absolute:
int 0x40
mov ecx,[esp+12]
mov word [ecx],ax
mov ecx,[esp+8]
shr eax,16
mov word [ecx],ax
ret
endp
proc @Kolibri@WasThreadCreated$qv
cmp byte [@Kolibri@_ThreadSavedBegProc],0x90
setz al
ret
endp
proc @Kolibri@CreateThread$qpvuit1
push ebx
mov edx,[esp+16]
mov ebx,[esp+12]
test edx,edx
jnz .create_thread_after_new
if defined KolibriHeapAlloc
cmp ebx,4096
jnb .create_thread_alloc
mov ebx,STACKSIZE
.create_thread_alloc:
push ebx
call KolibriHeapAlloc ; Create new dynamic memory of the given size
pop ecx
test eax,eax
jnz .create_thread_mem_created
end if
or eax,-1
jmp .create_thread_end
.create_thread_mem_created:
lea edx,[eax+ebx]
.create_thread_after_new:
neg ebx
jz .create_thread_test_first
add ebx,edx
.create_thread_test_first:
cmp byte [@Kolibri@_ThreadSavedBegProc],0x90
jnz .create_thread_init
.create_thread_fill_stack:
lock inc dword [@Kolibri@_ThreadNumber]
and edx,not 3
sub edx,12
mov ecx,[esp+8]
mov dword [edx+8],ebx
mov dword [edx+4],ecx
mov dword [edx],Kolibri_ThreadFinish
mov eax,SF_CREATE_THREAD
mov ebx,1
mov ecx,@Kolibri@ThreadMain$qpvt1
int 0x40
mov ebx,eax
or bl,15
inc ebx
jnz .create_thread_end
lock dec dword [@Kolibri@_ThreadNumber]
if defined KolibriHeapFree
or ebx,[edx+8]
jz .create_thread_end
push ebx
call KolibriHeapFree ; Delete the given dynamic memory
pop ecx
end if
.create_thread_end:
pop ebx
ret
.create_thread_init:
push esi edi
cld
mov esi,@Kolibri@_ThreadSavedBegProc
mov edi,@Kolibri@GetPid$qv
movsd
movsd
mov edi,@Kolibri@GetThreadData$qv
movsd
movsd
mov eax,0x90909090
mov edi,@Kolibri@_ThreadSavedBegProc
stosd
stosd
stosd
stosd
pop edi esi
jmp .create_thread_fill_stack
endp
proc @Kolibri@_FileAccess$qpv uses ebx
mov eax,SF_FILE
mov ebx,[esp+8]
int 0x40
mov ecx,[esp+8]
mov [ecx],ebx
ret
endp
if defined Kolibri_debug_string
Kolibri_debug_string:
db 'Abnormal program termination.',10,0
end if
if defined Kolibri_MutexLockRec
Kolibri_try_lock_rec_overflow_string:
db 'Recursive mutex lock count overflow.',10,0
end if
if defined @Kolibri@UnLock$qp16Kolibri@TRecMutexui
Kolibri_unlock_rec_notlocked_string:
db 'Recursive mutex unlock error.',10,0
end if
include "kos_lib.inc"
;/**/