;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; IRQ0 HANDLER (TIMER INTERRUPT) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; align 32 irq0: pushfd pushad mov ax, app_data ; mov ds, ax mov es, ax inc dword [timer_ticks] mov eax, [timer_ticks] call playNote ; <<<--- Speaker driver cmp eax,[next_usage_update] jb .nocounter add eax,100 mov [next_usage_update],eax 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 popfd iretd .change_task: call update_counters 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 call do_change_task .return: popad popfd iretd align 4 change_task: pushfd cli pushad call update_counters ; \begin{Mario79} cmp [dma_task_switched], 1 jne .find_next_task mov [dma_task_switched], 0 mov ebx, [dma_process] cmp [CURRENT_TASK], ebx je .return mov edi, [dma_slot_ptr] mov [CURRENT_TASK], ebx mov [TASK_BASE], edi jmp @f .find_next_task: ; \end{Mario79} call find_next_task test eax, eax ; the same task -> skip switch jnz .return @@: mov [DONT_SWITCH],byte 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 ? endg 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 ret ; 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] jb @f mov edi, CURRENT_TASK xor ebx, ebx @@: add edi,0x20 inc ebx mov al, byte [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 cmp al, 5 jne .noevents call get_event_for_app test eax, eax jz .waiting_for_event mov [event_sched], eax mov [edi+TASKDATA.state], byte 0 .noevents: .found: mov [CURRENT_TASK],ebx 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 ret ; in: ebx = TSS selector index ; ; param ; ebx = incoming task ; esi = outcomig task do_change_task: shl ebx, 8 add ebx, SLOT_BASE mov [current_slot], ebx shl esi, 8 add esi, SLOT_BASE mov [esi+APPDATA.saved_esp], esp mov esp, [ebx+APPDATA.saved_esp] mov eax, [ebx+APPDATA.dir_table] mov cr3, eax mov ebx, [ebx+APPDATA.pl0_stack] add ebx, RING0_STACK_SIZE mov [tss_data+TSS._esp0], ebx mov ecx, cr0 or ecx, CR0_TS ;set task switch flag mov cr0, ecx inc [context_counter] ;noname & halyavin ret ; ; shl ebx, 3 ; xor eax, eax ; add ebx, tss0 ; mov [far_jump.sel], bx ; selector ; mov [far_jump.offs], eax ; offset ; jmp pword [far_jump] ; inc [context_counter] ;noname & halyavin ;ret 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