Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 1054 → Rev 1055

/kernel/trunk/const.inc
468,9 → 468,10
.id dd ? ;event uid
.state dd ? ;internal flags
.code dd ?
rd 5
rd 6
.size = $ - .magic
.codesize = $ - .code
}
EVENT_SIZE equ 52
 
virtual at 0
EVENT EVENT
687,4 → 688,3
virtual at 0
CSYM COFF_SYM
end virtual
 
/kernel/trunk/core/exports.inc
126,11 → 126,11
dd szGetPid , get_pid
dd szCreateObject , create_kernel_object
dd szDestroyObject , destroy_kernel_object
dd szCreateEvent , create_event
dd szRaiseEvent , raise_event
dd szWaitEvent , wait_event
dd szDestroyEvent , destroy_event
dd szClearEvent , clear_event
dd szCreateEvent , create_event ;see EVENT.inc for specification
dd szRaiseEvent , raise_event ;see EVENT.inc for specification
dd szWaitEvent , wait_event ;see EVENT.inc for specification
dd szDestroyEvent , destroy_event ;see EVENT.inc for specification
dd szClearEvent , clear_event ;see EVENT.inc for specification
 
dd szLoadCursor , load_cursor ;stdcall
 
143,7 → 143,7
dd szSysMsgBoardChar , sys_msg_board
dd szGetCurrentTask , get_curr_task
dd szLoadFile , load_file ;retval eax, ebx
dd szSendEvent , send_event
dd szSendEvent , send_event ;see EVENT.inc for specification
dd szSetMouseData , set_mouse_data ;stdcall
dd szSleep , delay_ms
dd szGetTimerTicks , get_timer_ticks
160,4 → 160,3
dd 0 ;terminator, must be zero
 
endg
 
/kernel/trunk/core/memory.inc
1051,7 → 1051,8
.14:
cmp ebx, OS_BASE
jae .fail
stdcall get_event_ex, ebx, ecx
mov edi,ebx
call get_event_ex
mov [esp+36], eax
ret
.15:
/kernel/trunk/core/sched.inc
16,74 → 16,35
align 32
irq0:
pushad
mov ax, app_data ;
mov ds, ax
Mov ds, ax, app_data
mov es, ax
 
; cmp dword[CURRENT_TASK], 1
; jnz @f
; mov eax, [esp + 32]
; cmp eax, idle_loop + 1
; jz @f
; DEBUGF 1, "K : OOOPS! EAX = 0x%x\n", eax
; @@:
 
inc dword [timer_ticks]
 
inc [timer_ticks]
mov eax, [timer_ticks]
call playNote ; <<<--- Speaker driver
 
cmp eax,[next_usage_update]
sub eax,[next_usage_update]
cmp eax,100
jb .nocounter
add eax,100
mov [next_usage_update],eax
add [next_usage_update],100
call updatecputimes
.nocounter:
cmp [DONT_SWITCH], byte 1
jne .change_task
 
mov al,0x20 ; send End Of Interrupt signal
mov dx,0x20
out dx,al
 
mov [DONT_SWITCH], byte 0
 
popad
iretd
 
.change_task:
call update_counters
 
out 0x20,al
btr dword[DONT_SWITCH], 0
jc .return
call find_next_task
mov ecx, eax
 
mov al,0x20 ; send End Of Interrupt signal
mov dx,0x20
out dx,al
 
test ecx, ecx ; if there is only one running process
jnz .return
 
jz .return ; if there is only one running process
call do_change_task
 
.return:
popad
; popfd
iretd
 
 
align 4
change_task:
 
pushfd
cli
pushad
 
call update_counters
 
if 0
 
; \begin{Mario79}
; \begin{Mario79} ; <- must be refractoried, if used...
cmp [dma_task_switched], 1
jne .find_next_task
mov [dma_task_switched], 0
96,195 → 57,152
jmp @f
.find_next_task:
; \end{Mario79}
 
end if
 
call find_next_task
test eax, eax ; the same task -> skip switch
jnz .return
@@:
mov [DONT_SWITCH],byte 1
jz .return ; the same task -> skip switch
@@: mov byte[DONT_SWITCH], 1
call do_change_task
 
.return:
popad
popfd
ret
 
 
uglobal
align 4
far_jump:
.offs dd ?
.sel dw ?
context_counter dd ? ;noname & halyavin
next_usage_update dd ?
timer_ticks dd ?
prev_slot dd ?
event_sched dd ?
; far_jump:
; .offs dd ?
; .sel dw ?
context_counter dd 0 ;noname & halyavin
next_usage_update dd 0
timer_ticks dd 0
; prev_slot dd ?
; event_sched dd ?
endg
 
 
align 4
update_counters:
mov edi, [TASK_BASE]
mov ebx, [edi+TASKDATA.counter_add] ; time stamp counter add
rdtsc
sub eax, ebx
add eax, [edi+TASKDATA.counter_sum] ; counter sum
mov [edi+TASKDATA.counter_sum], eax
sub eax, [edi+TASKDATA.counter_add] ; time stamp counter add
add [edi+TASKDATA.counter_sum], eax ; counter sum
ret
align 4
updatecputimes:
xor eax,eax
xchg eax,[idleuse]
mov [idleusesec],eax
mov ecx, [TASK_COUNT]
mov edi, TASK_DATA
.newupdate:
xor eax,eax
xchg eax,[edi+TASKDATA.counter_sum]
mov [edi+TASKDATA.cpu_usage],eax
add edi,0x20
loop .newupdate
ret
 
 
align 4
find_next_task:
;info:
; Find next task to execute
; result: ebx = number of the selected task
; eax = 1 if the task is the same
; edi = address of the data for the task in ebx
; [0x3000] = ebx and [0x3010] = edi
; corrupts other regs
find_next_task:
mov ebx, [CURRENT_TASK]
mov edi, [TASK_BASE]
mov [prev_slot], ebx
 
.waiting_for_termination:
.waiting_for_reuse:
.waiting_for_event:
.suspended:
cmp ebx, [TASK_COUNT]
;retval:
; ebx = address of the APPDATA for the selected task (slot-base)
; esi = previous slot-base ([current_slot] at the begin)
; edi = address of the TASKDATA for the selected task
; ZF = 1 if the task is the same
;warning:
; [CURRENT_TASK] = bh , [TASK_BASE] = edi -- as result
; [current_slot] is not set to new value (ebx)!!!
;scratched: eax,ecx
call update_counters ; edi := [TASK_BASE]
Mov esi, ebx, [current_slot]
.loop:
cmp bh,[TASK_COUNT]
jb @f
xor bh, bh
mov edi, CURRENT_TASK
xor ebx, ebx
@@:
 
add edi,0x20
inc ebx
 
mov al, byte [edi+TASKDATA.state]
@@: inc bh ; ebx += APPDATA.size
add edi,0x20 ; edi += TASKDATA.size
mov al, [edi+TASKDATA.state]
test al, al
jz .found
cmp al, 1
jz .suspended
cmp al, 2
jz .suspended
cmp al, 3
je .waiting_for_termination
cmp al, 4
je .waiting_for_termination
cmp al, 9
je .waiting_for_reuse
 
mov [CURRENT_TASK],ebx
mov [TASK_BASE],edi
 
jz .found ; state == 0
cmp al, 5
jne .noevents
call get_event_for_app
test eax, eax
jne .loop ; state == 1,2,3,4,9
; state == 5
pushad ; more freedom for [APPDATA.wait_test]
call [ebx+APPDATA.wait_test]
mov [esp+28],eax
popad
or eax,eax
jnz @f
mov eax, ebx
shl eax, 8
mov eax, [SLOT_BASE + APPDATA.wait_timeout + eax]
cmp eax, [timer_ticks]
jae .waiting_for_event
xor eax, eax
@@:
mov [event_sched], eax
mov [edi+TASKDATA.state], byte 0
.noevents:
; testing for timeout
mov ecx, [timer_ticks]
sub ecx, [ebx+APPDATA.wait_begin]
cmp ecx, [ebx+APPDATA.wait_timeout]
jb .loop
@@: mov [ebx+APPDATA.wait_param], eax ; retval for wait
mov [edi+TASKDATA.state], 0
.found:
mov [CURRENT_TASK],ebx
mov [CURRENT_TASK],bh
mov [TASK_BASE],edi
rdtsc ;call _rdtsc
mov [edi+TASKDATA.counter_add],eax
 
mov esi, [prev_slot]
xor eax, eax
cmp ebx, esi
sete al
mov [edi+TASKDATA.counter_add],eax ; for next using update_counters
cmp ebx, esi ;esi - previous slot-base
ret
;TODO: Íàäî áû óáðàòü èñïîëüçîâàíèå do_change_task èç V86...
; è ïîñëå ýòîãî ïåðåíåñòè îáðàáîòêó TASKDATA.counter_add/sum â do_change_task
 
; param
; ebx = incoming task
; esi = outcomig task
 
align 4
do_change_task:
 
shl ebx, 8
add ebx, SLOT_BASE
mov [current_slot], ebx
 
shl esi, 8
add esi, SLOT_BASE
 
;param:
; ebx = address of the APPDATA for incoming task (new)
;warning:
; [CURRENT_TASK] and [TASK_BASE] must be changed before (e.g. in find_next_task)
; [current_slot] is the outcoming (old), and set here to a new value (ebx)
;scratched: eax,ecx,esi
mov esi,ebx
xchg esi,[current_slot]
; set new stack after saving old
mov [esi+APPDATA.saved_esp], esp
mov esp, [ebx+APPDATA.saved_esp]
 
; set thread io map
 
mov ecx, [ebx+APPDATA.io_map]
mov edx, [ebx+APPDATA.io_map+4]
mov dword [page_tabs+((tss._io_map_0 and -4096) shr 10)], ecx
mov dword [page_tabs+((tss._io_map_1 and -4096) shr 10)], edx
 
mov eax, [ebx+APPDATA.dir_table]
cmp eax, [esi+APPDATA.dir_table]
je @F
; set new thread io-map
Mov dword [page_tabs+((tss._io_map_0 and -4096) shr 10)],eax,[ebx+APPDATA.io_map]
Mov dword [page_tabs+((tss._io_map_1 and -4096) shr 10)],eax,[ebx+APPDATA.io_map+4]
; set new thread memory-map
mov ecx, APPDATA.dir_table
mov eax, [ebx+ecx] ;offset>0x7F
cmp eax, [esi+ecx] ;offset>0x7F
je @f
mov cr3, eax
@@:
mov eax, [ebx+APPDATA.saved_esp0]
mov [tss._esp0], eax
mov ax, graph_data
mov gs, ax
 
mov eax, [CURRENT_TASK]
cmp eax, [fpu_owner]
@@: ; set tss.esp0
Mov [tss._esp0],eax,[ebx+APPDATA.saved_esp0]
; set gs selector unconditionally
Mov gs,ax,graph_data
; set CR0.TS
cmp bh, byte[fpu_owner] ;bh == incoming task (new)
clts ;clear a task switch flag
je @F
;and set it again if the owner
mov ecx, cr0 ;of a fpu has changed
or ecx, CR0_TS
mov cr0, ecx
@@:
je @f
mov eax, cr0 ;and set it again if the owner
or eax, CR0_TS ;of a fpu has changed
mov cr0, eax
@@: ; set context_counter (only for user pleasure ???)
inc [context_counter] ;noname & halyavin
test [ebx+APPDATA.dbg_state], 1
jnz @F
ret
@@:
mov eax, [ebx+APPDATA.dbg_regs.dr0]
mov dr0, eax
mov eax, [ebx+APPDATA.dbg_regs.dr1]
mov dr1, eax
mov eax, [ebx+APPDATA.dbg_regs.dr2]
mov dr2, eax
mov eax, [ebx+APPDATA.dbg_regs.dr3]
mov dr3, eax
; set debug-registers, if it's necessary
test byte[ebx+APPDATA.dbg_state], 1
jz @f
xor eax, eax
mov dr6, eax
mov eax, [ebx+APPDATA.dbg_regs.dr7]
mov dr7, eax
ret
lea esi,[ebx+ecx+APPDATA.dbg_regs-APPDATA.dir_table] ;offset>0x7F
cld
macro lodsReg [reg] {
lodsd
mov reg,eax
} lodsReg dr0, dr1, dr2, dr3, dr7
purge lodsReg
@@: ret
;end.
 
align 4
updatecputimes:
 
mov eax,[idleuse]
mov [idleusesec],eax
mov [idleuse],dword 0
mov ecx, [TASK_COUNT]
mov edi, TASK_DATA
.newupdate:
mov ebx,[edi+TASKDATA.counter_sum]
mov [edi+TASKDATA.cpu_usage],ebx
mov [edi+TASKDATA.counter_sum],dword 0
add edi,0x20
dec ecx
jnz .newupdate
 
ret
 
if 0
 
 
struc TIMER
{
.next dd ?
293,14 → 211,6
.arg dd ?
}
 
 
 
 
 
 
 
 
 
MAX_PROIRITY 0 ; highest, used for kernel tasks
MAX_USER_PRIORITY 0 ; highest priority for user processes
USER_PRIORITY 7 ; default (should correspond to nice 0)
310,7 → 220,6
 
rdy_head rd 16
 
 
align 4
pick_task:
 
330,7 → 239,6
inc eax
jmp .pick
 
 
; param
; eax= task
;
338,7 → 246,6
; eax= task
; ebx= queue
; ecx= front if 1 or back if 0
 
align 4
shed:
cmp [eax+.tics_left], 0 ;signed compare
356,7 → 263,6
 
; param
; eax= task
 
align 4
enqueue:
call shed ;eax
385,4 → 291,3
ret
 
end if
 
/kernel/trunk/core/syscall.inc
16,8 → 16,7
mov ecx, edx
mov edx, esi
mov esi, edi
mov edi, [esp+28 + 4]
and edi,0xff
movzx edi, byte[esp+28 + 4]
call dword [servetable+edi*4]
ret
 
24,21 → 23,6
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; SYSTEM CALL ENTRY ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
align 16
i40:
pushad
cld
movzx eax, al
call dword [servetable2 + eax * 4]
popad
iretd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; SYSENTER ENTRY ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
70,6 → 54,21
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; SYSTEM CALL ENTRY ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 16
i40:
pushad
cld
movzx eax, al
call dword [servetable2 + eax * 4]
popad
iretd
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; SYSCALL ENTRY ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
95,6 → 94,7
mov ecx, [ss:esp+4]
pop esp
sysret
 
iglobal
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; SYSTEM FUNCTIONS TABLE ;;
175,7 → 175,6
dd sys_debug_services ; 69-Debug
dd file_system_lfn ; 70-Common file system interface, version 2
dd syscall_windowsettings ; 71-Window settings
dd sys_sendwindowmsg ; 72-Send window message
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; NEW SYSTEM FUNCTIONS TABLE ;;
255,7 → 254,7
dd cross_order ; 69-Debug
dd cross_order ; 70-Common file system interface, version 2
dd cross_order ; 71-Window settings
dd cross_order ; 72-Send window message
dd sys_sendwindowmsg ; 72-Send window message
times 255 - ( ($-servetable2) /4 ) dd undefined_syscall
dd sys_end ; -1-end application
 
/kernel/trunk/core/v86.inc
945,12 → 945,12
mov cx, [eax*4+2]
mov word [esi-v86_regs.size+v86_regs.cs], cx
and byte [esi-v86_regs.size+v86_regs.eflags+1], not 3
push ebx
; push ebx
call update_counters
pop ebx
sub ebx, SLOT_BASE
shr ebx, 8
mov esi, [CURRENT_TASK]
; pop ebx
; sub ebx, SLOT_BASE
; shr ebx, 8
; mov esi, [CURRENT_TASK]
call do_change_task
popad
iretd
/kernel/trunk/data32.inc
292,7 → 292,6
irq_tab rd 16
 
mem_block_map rb 512
event_map rb 64
mem_block_list rd 64
large_block_list rd 31
mem_block_mask rd 2
315,10 → 314,6
 
page_start rd 1
page_end rd 1
events rd 1
event_start rd 1
event_end rd 1
event_uid rd 1
sys_page_map rd 1
os_stack_seg rd 1
 
471,4 → 466,3
BiosDiskPartitions rd 80h
 
IncludeUGlobals
 
/kernel/trunk/gui/event.inc
7,695 → 7,478
 
$Revision$
 
 
uglobal
align 4
init_events:
stdcall kernel_alloc, 512*EVENT_SIZE
mov [events], eax
xor eax, eax
mov [event_uid], eax
not eax
mov edi, event_map
mov [event_start], edi
mov ecx, 64/4
cld
rep stosd
mov [event_end], edi
ret
 
event_start dd ?
event_end dd ?
event_uid dd 0
endg
EV_SPACE = 512
FreeEvents = event_start-EVENT.fd ; "âèðòóàëüíûé" event, èñïîëüçóþòñÿ òîëüêî ïîëÿ:
; FreeEvents.fd=event_start è FreeEvents.bk=event_end
align 4
proc alloc_event
init_events: ;; used from kernel.asm
stdcall kernel_alloc,EV_SPACE*EVENT.size
or eax,eax
jz .fail
; eax - current event, ebx - previos event below
mov ecx,EV_SPACE ; current - in allocated space
mov ebx,FreeEvents ; previos - íà÷àëî ñïèñêà
push ebx ; îíî æå è êîíåö ïîòîì áóäåò
@@: mov [ebx+EVENT.fd],eax
mov [eax+EVENT.bk],ebx
mov ebx,eax ; previos <- current
add eax,EVENT.size ; new current
loop @b
pop eax ; âîò îíî êîíöîì è ñòàëî
mov [ebx+EVENT.fd],eax
mov [eax+EVENT.bk],ebx
.fail: ret
 
pushfd
cli
mov ebx, [event_start]
mov ecx, [event_end]
.l1:
bsf eax,[ebx]
jnz .found
add ebx,4
cmp ebx, ecx
jb .l1
popfd
xor eax,eax
ret
.found:
btr [ebx], eax
mov [event_start],ebx
inc [event_uid]
EVENT_WATCHED equ 0x10000000 ;áèò 28
EVENT_SIGNALED equ 0x20000000 ;áèò 29
MANUAL_RESET equ 0x40000000 ;áèò 30
MANUAL_DESTROY equ 0x80000000 ;áèò 31
 
sub ebx, event_map
lea eax,[eax+ebx*8]
 
lea ebx, [eax+eax*4]
shl eax,5
lea eax,[eax+ebx*4] ;eax*=52 (EVENT_SIZE)
add eax, [events]
mov ebx, [event_uid]
popfd
ret
endp
 
align 4
free_event:
sub eax, [events]
mov ecx, EVENT_SIZE
mov ebx, event_map
cdq
div ecx
 
create_event: ;; EXPORT use
;info:
; Ïåðåíîñèì EVENT èç ñïèñêà FreeEvents â ñïèñîê ObjList òåêóùåãî ñëîòà
; EVENT.state óñòàíàâëèâàåì èç ecx, EVENT.code êîñâåííî èç esi (åñëè esi<>0)
;param:
; esi - event data
; ecx - flags
;retval:
; eax - event (=0 => fail)
; edx - uid
;scratched: ebx,ecx,esi,edi
mov ebx,[current_slot]
add ebx,APP_OBJ_OFFSET
mov edx,[TASK_BASE]
mov edx,[edx+TASKDATA.pid]
pushfd
cli
bts [ebx], eax
shr eax, 3
and eax, not 3
add eax, ebx
cmp [event_start], eax
ja @f
popfd
ret
@@:
mov [event_start], eax
popfd
ret
 
EVENT_WATCHED equ 0x10000000
EVENT_SIGNALED equ 0x20000000
MANUAL_RESET equ 0x40000000
MANUAL_DESTROY equ 0x80000000
 
 
; param
; eax= event data
; ebx= flags
;
; retval
; eax= event
; edx= id
 
create_event:
.flags equ esp+4
.data equ esp
 
push ebx
push eax
 
call alloc_event
test eax, eax
jz .fail
 
mov [eax+APPOBJ.magic], 'EVNT'
mov [eax+APPOBJ.destroy], destroy_event.internal
mov [eax+EVENT.id], ebx
 
mov ebx, [CURRENT_TASK]
shl ebx, 5
mov ebx, [CURRENT_TASK+ebx+4]
mov [eax+APPOBJ.pid], ebx
mov edx, [.flags]
mov [eax+EVENT.state], edx
 
mov esi, [.data]
test esi, esi
jz @F
set_event: ;; INTERNAL use !!! don't use for Call
;info:
; Áåðåì íîâûé event èç FreeEvents, çàïîëíÿåì åãî ïîëÿ, êàê óêàçàíî â ecx,edx,esi
; è óñòàíàâëèâàåì â ñïèñîê, óêàçàííûé â ebx.
; Âîçâðàùàåì ñàì event (â eax), è åãî uid (â edx)
;param:
; ebx - start-chain "virtual" event for entry new event Right of him
; ecx - flags (copied to EVENT.state)
; edx - pid (copied to EVENT.pid)
; esi - event data (copied to EVENT.code indirect, =0 => skip)
;retval:
; eax - event (=0 => fail)
; edx - uid
;scratched: ebx,ecx,esi,edi
mov eax,[event_start]
cmp eax,FreeEvents
jne @f ; not empty ???
pushad
call init_events
popad
jz RemoveEventTo.break ; POPF+RET
@@: mov [eax+EVENT.magic],'EVNT'
mov [eax+EVENT.destroy],destroy_event.internal
mov [eax+EVENT.state],ecx
mov [eax+EVENT.pid],edx
inc [event_uid]
Mov [eax+EVENT.id],edx,[event_uid]
or esi,esi
jz RemoveEventTo
lea edi, [eax+EVENT.code]
mov ecx, 6
mov ecx,EVENT.codesize/4
cld
rep movsd
@@:
mov ecx, [current_slot]
add ecx, APP_OBJ_OFFSET
 
pushfd
cli
mov edx, [ecx+APPOBJ.fd]
mov [eax+APPOBJ.fd], edx
mov [eax+APPOBJ.bk], ecx
mov [ecx+APPOBJ.fd], eax
mov [edx+APPOBJ.bk], eax
popfd
mov edx, [eax+EVENT.id]
.fail:
add esp, 8
RemoveEventTo: ;; INTERNAL use !!! don't use for Call
;param:
; eax - óêàçàòåëü íà event, ÊÎÒÎÐÛÉ âñòàâëÿåì
; ebx - óêàçàòåëü íà event, ÏÎÑËÅ êîòîðîãî âñòàâëÿåì
;scratched: ebx,ecx
mov ecx,eax ; ecx=eax=Self, ebx=NewLeft
xchg ecx,[ebx+EVENT.fd] ; NewLeft.fd=Self, ecx=NewRight
mov [ecx+EVENT.bk],eax ; NewRight.bk=Self
xchg ebx,[eax+EVENT.bk] ; Self.bk=NewLeft, ebx=OldLeft
xchg ecx,[eax+EVENT.fd] ; Self.fd=NewRight, ecx=OldRight
mov [ebx+EVENT.fd],ecx ; OldLeft.fd=OldRight
mov [ecx+EVENT.bk],ebx ; OldRight.bk=OldLeft
.break: popfd
ret
 
restore .flags
restore .data
 
; param
; eax= event
; ebx= id
 
destroy_event:
 
cmp [eax+APPOBJ.magic], 'EVNT'
jne .fail
cmp [eax+EVENT.id], ebx
jne .fail
.internal:
mov ebx, [eax+APPOBJ.fd]
mov ecx, [eax+APPOBJ.bk]
mov [ebx+APPOBJ.bk], ecx
mov [ecx+APPOBJ.fd], ebx
.force:
xor edx, edx ;clear common header
mov [eax], edx
mov [eax+4], edx
mov [eax+8], edx
mov [eax+12], edx
mov [eax+16], edx
 
call free_event ;release object memory
.fail:
ret
 
align 4
proc send_event stdcall pid:dword, event:dword
locals
slot dd ?
endl
 
mov eax, [pid]
call pid_to_slot
test eax, eax
jz .fail
 
NotDummyTest: ;; INTERNAL use (not returned for fail !!!)
pop edi
call DummyTest ; not returned for fail !!!
mov ebx,eax
mov eax,[ebx+EVENT.pid]
push edi
.small: ; êðèâî êàê-òî...
pop edi
pushfd
cli
call pid_to_slot ; seved all registers (eax - retval)
shl eax, 8
cmp [SLOT_BASE+eax+APPDATA.ev_count], 32
ja .fail
jz RemoveEventTo.break ; POPF+RET
jmp edi ; øòàòíûé âîçâðàò
 
mov [slot], eax
 
call alloc_event
test eax, eax
jz .fail
 
lea edi, [eax+EVENT.code]
mov ecx, 6
mov esi, [event]
align 4
raise_event: ;; EXPORT use
;info:
; Óñòàíàâëèâàåì äàííûå EVENT.code
; Åñëè òàì ôëàã EVENT_SIGNALED óæå àêòèâåí - áîëüøå íè÷åãî
; Èíà÷å: ýòîò ôëàã âçâîäèòñÿ, çà èñêëþ÷åíèåì ñëó÷àÿ íàëè÷èÿ ôëàãà EVENT_WATCHED â edx
;  ýòîì ñëó÷àå EVENT_SIGNALED âçâîäèòñÿ ëèøü ïðè íàëè÷èå EVENT_WATCHED â ñàìîì ñîáûòèè
;param:
; eax - event
; ebx - uid (for Dummy testing)
; edx - flags
; esi - event data (=0 => skip)
;scratched: ebx,ecx,esi,edi
call NotDummyTest ; not returned for fail !!!
or esi,esi
jz @f
lea edi,[ebx+EVENT.code]
mov ecx,EVENT.codesize/4
cld
rep movsd
@@:
test byte[ebx+EVENT.state+3], EVENT_SIGNALED shr 24
jnz RemoveEventTo.break ; POPF+RET
bt edx, 28 ;EVENT_WATCHED
jnc @f
test byte[ebx+EVENT.state+3], EVENT_WATCHED shr 24
jz RemoveEventTo.break ; POPF+RET
@@:
or byte[ebx+EVENT.state+3], EVENT_SIGNALED shr 24
add eax,SLOT_BASE+APP_EV_OFFSET
xchg eax,ebx
jmp RemoveEventTo
 
mov ecx, [slot]
add ecx, SLOT_BASE+APP_EV_OFFSET
 
mov [eax+APPOBJ.magic], 'EVNT'
mov [eax+APPOBJ.destroy], destroy_event
mov ebx, [pid]
mov [eax+APPOBJ.pid], ebx
mov [eax+EVENT.state], EVENT_SIGNALED
 
pushfd
cli ;insert event into
mov edx, [ecx+APPOBJ.fd] ;events list
mov [eax+APPOBJ.fd], edx ;and set events flag
mov [eax+APPOBJ.bk], ecx
mov [ecx+APPOBJ.fd], eax
mov [edx+APPOBJ.bk], eax
inc [ecx+APPDATA.ev_count-APP_EV_OFFSET]
or [ecx+APPDATA.event_mask-APP_EV_OFFSET], EVENT_EXTENDED
popfd
.fail:
ret
endp
 
; timeout ignored
 
align 4
proc get_event_ex stdcall, p_ev:dword, timeout:dword
 
.wait:
mov edx,[current_slot]
; cmp [SLOT_BASE+edx+APPDATA.ev_count], 0
; je .switch
 
add edx, APP_EV_OFFSET
 
mov eax, [edx+APPOBJ.fd]
cmp eax, edx
je .switch
 
lea esi, [eax+EVENT.code]
mov edi, [p_ev] ;copy event data
mov ecx, 6
cld
rep movsd
 
and dword [edi-24], 0xFF00FFFF ;clear priority field
clear_event: ;; EXPORT use
;info:
;
test [eax+EVENT.state], MANUAL_RESET
jnz .done
;param:
; eax - event
; ebx - uid (for Dummy testing)
;scratched: ebx,ecx
call NotDummyTest ; not returned for fail !!!
add eax,SLOT_BASE+APP_OBJ_OFFSET
and byte[ebx+EVENT.state+3], not((EVENT_SIGNALED+EVENT_WATCHED)shr 24)
xchg eax,ebx
jmp RemoveEventTo
 
pushfd
cli ;remove event from events
mov ebx, [eax+APPOBJ.fd] ;list (reset event)
mov ecx, [eax+APPOBJ.bk] ;and clear events flag
mov [ebx+APPOBJ.bk], ecx ;if no active events
mov [ecx+APPOBJ.fd], ebx
align 4
send_event: ;; EXPORT use
;info:
; Ñîçäàåò íîâûé EVENT (âûòàñêèâàåò èç ñïèñêà FreeEvents) â ñïèñêå EventList
; öåëåâîãî ñëîòà (eax=pid), ñ äàííûìè èç esi êîñâåííî, è state=EVENT_SIGNALED
;param:
; eax - slots pid, to sending new event
; esi - pointer to sending data (in code field of new event)
;retval:
; eax - event (=0 => fail)
; edx - uid
;warning:
; may be used as CDECL with such prefix...
; mov esi,[esp+8]
; mov eax,[esp+4]
; but not as STDCALL :(
;scratched: ebx,ecx,esi,edi
mov edx,eax
call NotDummyTest.small ; not returned for fail !!!
lea ebx,[eax+SLOT_BASE+APP_EV_OFFSET]
mov ecx,EVENT_SIGNALED
jmp set_event
 
and [eax+EVENT.state], not (EVENT_SIGNALED+EVENT_WATCHED)
 
dec [edx+APPDATA.ev_count-APP_EV_OFFSET]
jnz @F
and [edx+APPDATA.event_mask-APP_EV_OFFSET], not EVENT_EXTENDED
@@:
popfd
 
test [eax+EVENT.state], MANUAL_DESTROY
jz .destroy
 
add edx, (APP_OBJ_OFFSET-APP_EV_OFFSET)
 
pushfd
cli
mov ebx, [edx+APPOBJ.fd] ;insert event into
mov [eax+APPOBJ.fd], ebx ;objects list
mov [eax+APPOBJ.bk], edx
mov [edx+APPOBJ.fd], eax
mov [ebx+APPOBJ.bk], eax
popfd
.done:
ret
 
.destroy:
call destroy_event.force
ret
.switch:
mov eax, [TASK_BASE]
mov [eax+TASKDATA.state], byte 5
call change_task
jmp .wait
endp
 
; param
; eax= event
; ebx= id
 
align 4
wait_event:
.event equ esp
push eax
.wait:
cmp [eax+APPOBJ.magic], 'EVNT'
jne .done
DummyTest: ;; INTERNAL use (not returned for fail !!!)
;param:
; eax - event
; ebx - uid (for Dummy testing)
cmp [eax+EVENT.magic],'EVNT'
jne @f
cmp [eax+EVENT.id], ebx
jne .done
je .ret
@@: pop eax
xor eax,eax
.ret: ret
 
test [eax+EVENT.state], EVENT_SIGNALED
jz .switch
 
test [eax+EVENT.state], MANUAL_RESET
jnz .done
 
mov edx,[current_slot]
 
pushfd
cli ;remove event from events
mov ebx, [eax+APPOBJ.fd] ;list (reset event)
mov ecx, [eax+APPOBJ.bk] ;and clear events flag
mov [ebx+APPOBJ.bk], ecx ;if no active events
mov [ecx+APPOBJ.fd], ebx
dec [edx+APPDATA.ev_count]
jnz @F
and [edx+APPDATA.event_mask], not EVENT_EXTENDED
@@:
and [eax+EVENT.state], not (EVENT_SIGNALED+EVENT_WATCHED)
align 4
Wait_events:
or ebx,-1 ; infinite timeout
Wait_events_ex:
;info:
; Îæèäàíèå "àáñòðàêòíîãî" ñîáûòèÿ ÷åðåç ïåðåâîä ñëîòà â 5-þ ïîçèöèþ.
; Àáñòðàêòíîñòü çàêëþ÷åíà â òîì, ÷òî ôàêò ñîáûòèÿ îïðåäåëÿåòñÿ ôóíêöèåé APPDATA.wait_test,
; êîòîðàÿ çàäàåòñÿ êëèåíòîì è ìîæåò áûòü ôàêòè÷åñêè ëþáîé.
; Ýòî ïîçâîëÿåò shed-ó íàäåæíî îïðåäåëèòü ôàêò ñîáûòèÿ, è íå ñîâåðøàòü "õîëîñòûõ" ïåðåêëþ÷åíèé,
; ïðåäíàçíà÷åííûõ äëÿ ðàçáîðîê òèïà "ñâîé/÷óæîé" âíóòðè çàäà÷è.
;param:
; edx - wait_test, êëèåíòñêàÿ ô-ÿ òåñòèðîâàíèÿ (àäðåñ êîäà)
; ecx - wait_param, äîïîëíèòåëüíûé ïàðàìåòð, âîçìîæíî íåîáõîäèìûé äëÿ [wait_test]
; ebx - wait_timeout
;retval:
; eax - ðåçóëüòàò âûçîâà [wait_test] (=0 => timeout)
;scratched: esi
mov esi,[current_slot]
mov [esi+APPDATA.wait_param],ecx
pushad
mov ebx,esi;ïîêà ýòî âîïðîñ, ÷åãî êóäû ñóâàòü..........
pushfd ; ýòî ñëåäñòâèå îáùåé êîíöåïöèè: ïóñòü ô-ÿ òåñòèðîâàíèÿ èìååò
cli ; ïðàâî ðàññ÷èòûâàòü íà çàêðûòûå ïðåðûâàíèÿ, êàê ïðè âûçîâå èç shed
call edx
popfd
 
test [eax+EVENT.state], MANUAL_DESTROY
jz .destroy
 
add edx, APP_OBJ_OFFSET
 
pushfd
cli
mov ecx, [edx+APPOBJ.fd] ;insert event into
mov [eax+APPOBJ.fd], ecx ;objects list
mov [eax+APPOBJ.bk], edx
mov [edx+APPOBJ.fd], eax
mov [ecx+APPOBJ.bk], eax
popfd
.done:
add esp, 4
ret
.destroy:
call destroy_event.force
add esp, 4
ret
.switch:
or [eax+EVENT.state], EVENT_WATCHED
mov [esp+28],eax
popad
or eax,eax
jnz @f ;RET
mov [esi+APPDATA.wait_test],edx
mov [esi+APPDATA.wait_timeout],ebx
Mov [esi+APPDATA.wait_begin],eax,[timer_ticks]
mov eax, [TASK_BASE]
mov [eax+TASKDATA.state], byte 5
mov [eax+TASKDATA.state], 5
call change_task
mov eax, [.event]
jmp .wait
restore .event
mov eax,[esi+APPDATA.wait_param]
@@: ret
 
; param
; eax= event
; ebx= id
; ecx= flags
; edx= event data
align 4
wait_event: ;; EXPORT use
;info:
; Îæèäàíèå ôëàãà EVENT_SIGNALED â ñîâåðøåííî êîíêðåòíîì Event
; (óñòàíàâëèâàåìîãî, íàäî ïîëàãàòü, ÷åðåç raise_event)
; Ïðè àêòèâíîì ôëàãå MANUAL_RESET - áîëüøå íè÷åãî
; Èíà÷å: ôëàãè EVENT_SIGNALED è EVENT_WATCHED ó ïîëó÷åííîãî ñîáûòèÿ ñáðàñûâàþòñÿ,
; è, ïðè àêòèâíîì MANUAL_DESTROY - ïåðåìåùàåòñÿ â ñïèñîê ObjList òåêóùåãî ñëîòà,
; à ïðè íå àêòèâíîì - óíè÷òîæàåòñÿ øòàòíî (destroy_event.internal)
;param:
; eax - event
; ebx - uid (for Dummy testing)
;scratched: ecx,edx,esi
call DummyTest
mov ecx,eax ; wait_param
mov edx, get_event_alone
call Wait_events ; timeout ignored
jmp wait_finish
 
raise_event:
.event equ esp
push eax
 
cmp [eax+APPOBJ.magic], 'EVNT'
jne .fail
cmp [eax+EVENT.id], ebx
jne .fail
 
mov eax, [eax+APPOBJ.pid]
call pid_to_slot
test eax, eax
jz .fail
 
mov esi, edx
test esi, esi
mov edx, [.event]
jz @F
 
push ecx
lea edi, [edx+EVENT.code]
mov ecx, 6
align 4
get_event_ex: ;; f68:14
;info:
; Îæèäàíèå ëþáîãî ñîáûòèÿ â î÷åðåäè EventList òåêóùåãî ñëîòà
; Äàííûå ñîáûòèÿ code - êîïèðóþòñÿ â ïàìÿòü ïðèëîæåíèÿ (êîñâåííî ïî edi)
; Ïðè àêòèâíîì ôëàãå MANUAL_RESET - áîëüøå íè÷åãî
; Èíà÷å: ôëàãè EVENT_SIGNALED è EVENT_WATCHED ó ïîëó÷åííîãî ñîáûòèÿ ñáðàñûâàþòñÿ,
; è, ïðè àêòèâíîì MANUAL_DESTROY - ïåðåìåùàåòñÿ â ñïèñîê ObjList òåêóùåãî ñëîòà,
; à ïðè íå àêòèâíîì - óíè÷òîæàåòñÿ øòàòíî (destroy_event.internal)
;param:
; edi - àäðåñ â êîäå ïðèëîæåíèÿ äëÿ êîïèðîâàíèÿ äàííûõ èç EVENT.code
;retval:
; eax - ñîáñòâåííî EVENT (áóäåì íàçûâàòü ýòî åãî õýíäëîì)
;scratched: ebx,ecx,edx,esi,edi
mov edx, get_event_queue
call Wait_events ; timeout ignored
lea esi,[eax+EVENT.code]
mov ecx,EVENT.codesize/4
cld
rep movsd
pop ecx
@@:
test [edx+EVENT.state], EVENT_SIGNALED
jnz .done
mov [edi-EVENT.codesize+2],cl ;clear priority field
wait_finish:
test byte[eax+EVENT.state+3], MANUAL_RESET shr 24
jnz get_event_queue.ret ; RET
and byte[ebx+EVENT.state+3], not((EVENT_SIGNALED+EVENT_WATCHED)shr 24)
test byte[eax+EVENT.state+3], MANUAL_DESTROY shr 24
jz destroy_event.internal
mov ebx,[current_slot]
add ebx,APP_OBJ_OFFSET
pushfd
cli
jmp RemoveEventTo
 
test ecx, EVENT_WATCHED
jz @F
test [edx+EVENT.state], EVENT_WATCHED
jz .done
@@:
shl eax, 8
add eax, SLOT_BASE+APP_EV_OFFSET
 
align 4
destroy_event: ;; EXPORT use
;info:
; Ïåðåíîñèì EVENT â ñïèñîê FreeEvents, ÷èñòèì ïîëÿ magic,destroy,pid,id
;param:
; eax - event
; ebx - uid (for Dummy testing)
;retval:
; eax - àäðåñ îáúåêòà EVENT (=0 => fail)
;scratched: ebx,ecx
call DummyTest ; not returned for fail !!!
.internal:
xor ecx,ecx ; clear common header
pushfd
cli
mov ebx, [edx+APPOBJ.fd]
mov ecx, [edx+APPOBJ.bk]
mov [ebx+APPOBJ.bk], ecx
mov [ecx+APPOBJ.fd], ebx
mov [eax+EVENT.magic],ecx
mov [eax+EVENT.destroy],ecx
mov [eax+EVENT.pid],ecx
mov [eax+EVENT.id],ecx
mov ebx,FreeEvents
jmp RemoveEventTo
 
mov ecx, [eax+APPOBJ.fd]
mov [edx+APPOBJ.fd], ecx
mov [edx+APPOBJ.bk], eax
mov [eax+APPOBJ.fd], edx
mov [ecx+APPOBJ.bk], edx
or [edx+EVENT.state], EVENT_SIGNALED
align 4
get_event_queue:
;info:
; êëèåíòñêàÿ ô-ÿ òåñòèðîâàíèÿ äëÿ get_event_ex
;warning:
; -don't use [TASK_BASE],[current_slot],[CURRENT_TASK] - it is not for your slot
; -may be assumed, that interrupt are disabled
; -it is not restriction for scratched registers
;param:
; ebx - àäðåñ APPDATA ñëîòà òåñòèðîâàíèÿ
;retval:
; eax - àäðåñ îáúåêòà EVENT (=0 => fail)
add ebx,APP_EV_OFFSET
mov eax,[ebx+APPOBJ.bk] ; âûáèðàåì ñ êîíöà, ïî ïðèíöèïó FIFO
cmp eax,ebx ; empty ???
je get_event_alone.ret0
.ret: ret
 
inc [eax+APPDATA.ev_count-APP_EV_OFFSET]
or [eax+APPDATA.event_mask-APP_EV_OFFSET], EVENT_EXTENDED
popfd
.fail:
.done:
add esp, 4
ret
restore .event
align 4
get_event_alone:
;info:
; êëèåíòñêàÿ ô-ÿ òåñòèðîâàíèÿ äëÿ wait_event
;warning:
; -don't use [TASK_BASE],[current_slot],[CURRENT_TASK] - it is not for your slot
; -may be assumed, that interrupt are disabled
; -it is not restriction for scratched registers
;param:
; ebx - àäðåñ APPDATA ñëîòà òåñòèðîâàíèÿ
;retval:
; eax - àäðåñ îáúåêòà EVENT (=0 => fail)
mov eax,[ebx+APPDATA.wait_param]
test byte[eax+EVENT.state+3], EVENT_SIGNALED shr 24
jnz .ret
or byte[eax+EVENT.state+3], EVENT_WATCHED shr 24
.ret0: xor eax,eax ; NO event!!!
.ret: ret
 
; param
; eax= event
; ebx= id
align 4
clear_event:
.event equ esp
push eax
 
cmp [eax+APPOBJ.magic], 'EVNT'
jne .fail
cmp [eax+EVENT.id], ebx
jne .fail
 
mov eax, [eax+APPOBJ.pid]
call pid_to_slot
test eax, eax
jz .fail
 
shl eax, 8
add eax, SLOT_BASE+APP_EV_OFFSET
mov edx, [.event]
sys_sendwindowmsg: ;; f72
dec ebx
jnz .ret ;subfunction==1 ?
pushfd
cli ;remove event from events
mov ebx, [edx+APPOBJ.fd] ;list (reset event)
mov ecx, [edx+APPOBJ.bk] ;and clear events flag
mov [ebx+APPOBJ.bk], ecx ;if no active events
mov [ecx+APPOBJ.fd], ebx
cli
sub ecx,2
je .sendkey
loop .retf
.sendbtn:
cmp byte[BTN_COUNT],1
jae .result ;overflow
inc byte[BTN_COUNT]
mov [BTN_BUFF],edx
jmp .result
.sendkey:
movzx eax,byte[KEY_COUNT]
cmp al,120
jae .result ;overflow
inc byte[KEY_COUNT]
mov [KEY_COUNT+1+eax],dl
.result:
setae byte[esp+36] ;ñ÷èòàåì, ÷òî èñõîäíî: dword[esp+36]==72
.retf: popfd
.ret: ret
 
and [edx+EVENT.state], not (EVENT_SIGNALED+EVENT_WATCHED)
 
dec [eax+APPDATA.ev_count-APP_EV_OFFSET]
jnz @F
and [eax+APPDATA.event_mask-APP_EV_OFFSET], not EVENT_EXTENDED
@@:
add eax, (APP_OBJ_OFFSET-APP_EV_OFFSET)
 
mov ecx, [eax+APPOBJ.fd] ;insert event into
mov [edx+APPOBJ.fd], ecx ;objects list
mov [edx+APPOBJ.bk], eax
mov [eax+APPOBJ.fd], edx
mov [ecx+APPOBJ.bk], edx
align 4
sys_getevent: ;; f11
mov ebx,[current_slot] ;ïîêà ýòî âîïðîñ, ÷åãî êóäû ñóâàòü..........
pushfd ; ýòî ñëåäñòâèå îáùåé êîíöåïöèè: ïóñòü ô-ÿ òåñòèðîâàíèÿ èìååò
cli ; ïðàâî ðàññ÷èòûâàòü íà çàêðûòûå ïðåðûâàíèÿ, êàê ïðè âûçîâå èç shed
call get_event_for_app
popfd
.fail:
.done:
add esp, 4
mov [esp+32],eax
ret
restore .event
 
sys_getevent:
 
call get_event_for_app
align 4
sys_waitforevent: ;; f10
or ebx,-1 ; infinite timeout
sys_wait_event_timeout: ;; f23
mov edx,get_event_for_app
call Wait_events_ex
mov [esp + 32],eax
ret
 
sys_waitforevent:
or ebx, 0xFFFFFFFF ; infinite timeout
jmp @f
 
sys_wait_event_timeout:
add ebx, [timer_ticks]
@@:
mov eax, [current_slot]
mov [eax + APPDATA.wait_timeout], ebx
call get_event_for_app
test eax, eax
jnz eventoccur
 
mov eax, [TASK_BASE]
mov [eax+TASKDATA.state], byte 5
call change_task
 
mov eax, [event_sched]
eventoccur:
mov [esp+32], eax
align 4
get_event_for_app: ;; used from f10,f11,f23
;info:
; êëèåíòñêàÿ ô-ÿ òåñòèðîâàíèÿ äëÿ ïðèëîæåíèé (f10,f23)
;warning:
; -don't use [TASK_BASE],[current_slot],[CURRENT_TASK] - it is not for your slot
; -may be assumed, that interrupt are disabled
; -it is not restriction for scratched registers
;param:
; ebx - àäðåñ APPDATA ñëîòà òåñòèðîâàíèÿ
;retval:
; eax - íîìåð ñîáûòèÿ (=0 => no events)
movzx edi,bh ; bh is assumed as [CURRENT_TASK]
shl edi,5
add edi,CURRENT_TASK ; edi is assumed as [TASK_BASE]
mov ecx,[edi+TASKDATA.event_mask]
.loop: ; ïîêà íå èñ÷åðïàåì âñå áèòû ìàñêè
bsr eax,ecx ; íàõîäèì íåíóëåâîé áèò ìàñêè (31 -> 0)
jz .no_events ; èñ÷åðïàëè âñå áèòû ìàñêè, íî íè÷åãî íå íàøëè ???
btr ecx,eax ; ñáðàñûâàåì ïðîâåðÿåìûé áèò ìàñêè
; ïåðåõîäèì íà îáðàáîò÷èê ýòîãî (eax) áèòà
cmp eax,16
jae .IRQ ; eax=[16..31]=retvals, events irq0..irq15
cmp eax,9
jae .loop ; eax=[9..15], ignored
cmp eax,3
je .loop ; eax=3, ignored
ja .FlagAutoReset ; eax=[4..8], retvals=eax+1
cmp eax,1
jae .BtKy ; eax=[1,2], retvals=eax+1
.WndRedraw: ; eax=0, retval WndRedraw=1
cmp [edi-twdw+WDATA.fl_redraw],al ;al==0
jne .result
jmp .loop
.no_events:
xor eax,eax
ret
 
sys_sendwindowmsg:
dec eax
jnz .ret
cmp ebx, 3
jz .sendbtn
cmp ebx, 2
jnz .ret
.sendkey:
pushf
cli
movzx eax, byte [KEY_COUNT]
cmp al, 120
jae .overflow
.IRQ:
;TODO: ñäåëàòü òàê æå, êàê è äëÿ FlagAutoReset (BgrRedraw,Mouse,IPC,Stack,Debug)
mov edx,[irq_owner+eax*4-64] ; eax==16+irq
cmp edx,[edi+TASKDATA.pid]
jne .loop
mov edx,eax
shl edx,12
cmp dword[IRQ_SAVE+edx-0x10000],0 ; edx==(16+irq)*0x1000
je .loop ; empty ???
ret ; retval = eax
.FlagAutoReset: ; retvals: BgrRedraw=5, Mouse=6, IPC=7, Stack=8, Debug=9
btr [ebx+APPDATA.event_mask],eax
jnc .loop
.result: ; retval = eax+1
inc eax
mov [KEY_COUNT], al
mov [KEY_COUNT+eax], cl
jmp .ok
.overflow:
popf
mov dword [esp+36], 1
ret
.sendbtn:
pushf
cli
.BtKy:
movzx edx,bh
movzx edx, word[WIN_STACK+edx*2]
je .Keys ; eax=1, retval Keys=2
.Buttons: ; eax=2, retval Buttons=3
cmp byte [BTN_COUNT], 0
jnz .overflow
mov byte [BTN_COUNT], 1
mov [BTN_BUFF], ecx
.ok:
popf
and dword [esp+36], 0
.ret:
ret
 
get_event_for_app:
 
pushad
 
mov edi,[TASK_BASE] ; WINDOW REDRAW
test [edi+TASKDATA.event_mask], 1
jz no_eventoccur1
;mov edi,[TASK_BASE]
cmp [edi-twdw+WDATA.fl_redraw],byte 0
je no_eventoccur1
popad
mov eax,1
ret
no_eventoccur1:
 
;mov edi,[TASK_BASE] ; KEY IN BUFFER
test [edi+TASKDATA.event_mask],dword 2
jz no_eventoccur2
mov ecx, [CURRENT_TASK]
movzx edx,word [WIN_STACK+ecx*2]
mov eax, [TASK_COUNT]
cmp eax,edx
jne no_eventoccur2x
cmp [KEY_COUNT],byte 0
je no_eventoccur2x
eventoccur2:
popad
mov eax,2
ret
no_eventoccur2x:
mov eax, hotkey_buffer
@@:
cmp [eax], ecx
jz eventoccur2
add eax, 8
cmp eax, hotkey_buffer+120*8
je .loop ; empty ???
cmp edx,[TASK_COUNT]
jne .loop ; not Top ???
cmp dword[BTN_BUFF],0xFFFF ;-ID for Minimize-Button of Form
jne .result
mov [window_minimize],1
dec byte[BTN_COUNT]
jmp .loop
.Keys: ; eax==1
cmp edx,[TASK_COUNT]
jne @f ; not Top ???
cmp [KEY_COUNT],al ; al==1
jae .result ; not empty ???
@@: mov edx, hotkey_buffer
@@: cmp [edx],bh ; bh - slot for testing
je .result
add edx,8
cmp edx, hotkey_buffer+120*8
jb @b
no_eventoccur2:
 
;mov edi,[TASK_BASE] ; BUTTON IN BUFFER
test [edi+TASKDATA.event_mask],dword 4
jz no_eventoccur3
cmp [BTN_COUNT],byte 0
je no_eventoccur3
mov ecx, [CURRENT_TASK]
movzx edx, word [WIN_STACK+ecx*2]
mov eax, [TASK_COUNT]
cmp eax,edx
jnz no_eventoccur3
popad
mov eax,[BTN_BUFF]
cmp eax,65535
je no_event_1
mov eax,3
ret
 
no_event_1:
mov [window_minimize],1
mov [BTN_COUNT],byte 0
xor eax, eax
ret
 
no_eventoccur3:
 
;mov edi,[TASK_BASE] ; mouse event
mov eax, [CURRENT_TASK]
shl eax, 8
add eax, SLOT_BASE
test [edi+TASKDATA.event_mask],dword 00100000b
jz no_mouse_event
 
test [eax+APPDATA.event_mask],dword 00100000b
jz no_mouse_event
and [eax+APPDATA.event_mask],dword (not 00100000b)
popad
mov eax,6
ret
no_mouse_event:
 
;mov edi,[TASK_BASE] ; DESKTOP BACKGROUND REDRAW
test [edi+TASKDATA.event_mask], 16
jz no_eventoccur5
; cmp [REDRAW_BACKGROUND],byte 2
; jnz no_eventoccur5
test [eax+APPDATA.event_mask], 16
jz no_eventoccur5
and [eax+APPDATA.event_mask], not 16
popad
mov eax,5
ret
no_eventoccur5:
 
;mov edi,[TASK_BASE] ; IPC
test [edi+TASKDATA.event_mask],dword 01000000b
jz no_ipc
test [eax+APPDATA.event_mask],dword 01000000b
jz no_ipc
and [eax+APPDATA.event_mask],dword 0xffffffff-01000000b
popad
mov eax,7
ret
no_ipc:
 
;mov edi,[TASK_BASE] ; STACK
test [edi+TASKDATA.event_mask],dword 10000000b
jz no_stack_event
test [eax+APPDATA.event_mask],dword 10000000b
jz no_stack_event
and [eax+APPDATA.event_mask],dword 0xffffffff-10000000b
popad
mov eax,8
ret
no_stack_event:
 
test byte [edi+TASKDATA.event_mask+1], 1 ; DEBUG
jz .test_IRQ
test byte [eax+APPDATA.event_mask+1], byte 1
jz .test_IRQ
and byte [eax+APPDATA.event_mask+1], not 1
popad
mov eax, 9
ret
 
;.test_ext:
; mov eax, [CURRENT_TASK]
; shl eax, 8
; test dword [eax+SLOT_BASE+APPDATA.event_mask], EVENT_EXTENDED
; jz .test_IRQ
; popad
; mov eax, 10
; ret
 
.test_IRQ:
cmp dword [edi+TASKDATA.event_mask], 0xFFFF
jbe no_events
 
mov esi,IRQ_SAVE ; IRQ'S AND DATA
mov ebx,0x00010000
xor ecx, ecx
irq_event_test:
mov edi,[TASK_BASE]
test [edi+TASKDATA.event_mask],ebx
jz no_irq_event
mov edi,ecx
shl edi,2
add edi,irq_owner
mov edx,[edi]
mov eax,[TASK_BASE]
mov eax,[eax+TASKDATA.pid]
cmp edx,eax
jne no_irq_event
cmp [esi],dword 0
jz no_irq_event
mov eax,ecx
add eax,16
mov [esp+28],eax
popad
ret
no_irq_event:
add esi,0x1000
shl ebx,1
inc ecx
cmp ecx,16
jb irq_event_test
 
no_events:
popad
xor eax, eax
ret
 
 
 
jmp .loop
;end.
/kernel/trunk/kernel.asm
725,11 → 725,11
mov esi,boot_tsc
call boot_log
cli
call _rdtsc
rdtsc ;call _rdtsc
mov ecx,eax
mov esi,250 ; wait 1/4 a second
call delay_ms
call _rdtsc
rdtsc ;call _rdtsc
sti
sub eax,ecx
shl eax,2
1013,57 → 1013,27
 
checkidle:
pushad
 
cmp [check_idle_semaphore],0
jne no_idle_state
 
mov ebx,[timer_ticks]
call change_task
mov eax,[idlemem]
mov ebx,[timer_ticks] ;[0xfdf0]
cmp eax,ebx
jnz idle_exit
call _rdtsc
jmp idle_loop_entry
idle_loop:
cmp ebx,[timer_ticks]
jne idle_exit
rdtsc ;call _rdtsc
mov ecx,eax
idle_loop:
hlt
rdtsc ;call _rdtsc
sub eax,ecx
add [idleuse],eax
idle_loop_entry:
cmp [check_idle_semaphore],0
jne idle_loop_exit
mov eax,[timer_ticks] ;[0xfdf0]
cmp ebx,eax
jz idle_loop
idle_loop_exit:
mov [idlemem],eax
call _rdtsc
sub eax,ecx
mov ebx,[idleuse]
add ebx,eax
mov [idleuse],ebx
 
popad
ret
 
je idle_loop
dec [check_idle_semaphore]
idle_exit:
 
mov ebx,[timer_ticks] ;[0xfdf0]
mov [idlemem],ebx
call change_task
 
popad
ret
 
no_idle_state:
 
dec [check_idle_semaphore]
 
mov ebx,[timer_ticks] ;[0xfdf0]
mov [idlemem],ebx
call change_task
 
popad
ret
 
uglobal
idlemem dd 0x0
idleuse dd 0x0
idleusesec dd 0x0
check_idle_semaphore dd 0x0
1167,7 → 1137,6
mov [BTN_ADDR],dword BUTTON_INFO ; address of button list
 
;!! IP 04.02.2005:
mov [next_usage_update], 100
mov byte [DONT_SWITCH], 0 ; change task if possible
 
ret
4669,7 → 4638,7
 
ret
 
 
if used _rdtsc
_rdtsc:
bt [cpu_caps], CAPS_TSC
jnc ret_rdtsc
4679,6 → 4648,7
mov edx,0xffffffff
mov eax,0xffffffff
ret
end if
 
rerouteirqs:
 
5621,4 → 5591,3
 
uglobals_size = $ - endofcode
diff16 "end of kernel code",0,$
 
/kernel/trunk/kernel32.inc
121,7 → 121,7
db 5 dup(?)
 
.fpu_state dd ? ;+16
.ev_count dd ? ;+20
.ev_count_ dd ? ;unused ;+20
.fpu_handler dd ? ;+24
.sse_handler dd ? ;+28
.pl0_stack dd ? ;unused ;+32
138,9 → 138,11
.cur_dir dd ? ;+80
.wait_timeout dd ? ;+84
.saved_esp0 dd ? ;+88
.wait_begin dd ? ;+92 +++
.wait_test dd ? ;+96 +++
.wait_param dd ? ;+100 +++
db 24 dup(?) ;+104
 
db 36 dup(?) ;+92
 
.wnd_shape dd ? ;+128
.wnd_shape_scale dd ? ;+132
dd ? ;+136
/kernel/trunk/macros.inc
98,3 → 98,9
end if
}
; \end{diamond}[29.09.2006]
 
macro Mov op1,op2,op3 ; op1 = op2 = op3
{
mov op2,op3
mov op1,op2
}