import platform.pch.pic as pic import platform.pch.pit as pit import sched.sched as sched import asm import t, c TIMER_FREQUENCY: t.CDefine = 1000 TICKS_PER_SECOND: t.CDefine = TIMER_FREQUENCY MILLISECONDS_PER_TICK: t.CDefine = (1000 / TIMER_FREQUENCY) ticks: t.CStatic | t.CVolatile | t.CUInt64T = 0 seconds: t.CStatic | t.CVolatile | t.CUInt32T = 0 milliseconds: t.CStatic | t.CVolatile | t.CUInt32T = 0 timer_running: t.CStatic | t.CVolatile | bool = False def timer_init(): global ticks, seconds, milliseconds, timer_running c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY]) ticks = 0 seconds = 0 milliseconds = 0 timer_running = True c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY]) pit.pit_init(TIMER_FREQUENCY) def timer_handler(): global ticks, seconds, milliseconds, timer_running if not timer_running: pic.eoi(0) return c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY]) ticks = ticks + 1 milliseconds = milliseconds + MILLISECONDS_PER_TICK if milliseconds >= 1000: seconds = seconds + 1 milliseconds = milliseconds - 1000 c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY]) sched.Scheduler.sched_tick() pic.eoi(0) def timer_start(): global timer_running c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY]) timer_running = True c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY]) def timer_stop(): global timer_running c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY]) timer_running = False c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY]) def timer_reset(): global ticks, seconds, milliseconds c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY]) ticks = 0 seconds = 0 milliseconds = 0 c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY]) def timer_get_ticks() -> t.CUInt64T: current_ticks: t.CUInt64T c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY]) current_ticks = ticks c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY]) return current_ticks def timer_get_seconds() -> t.CUInt32T: current_seconds: t.CUInt32T c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY]) current_seconds = seconds c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY]) return current_seconds def timer_get_milliseconds() -> t.CUInt32T: current_milliseconds: t.CUInt32T c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY]) current_milliseconds = milliseconds c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY]) return current_milliseconds def timer_get_time(out_seconds: t.CUInt32T | t.CPtr, out_milliseconds: t.CUInt32T | t.CPtr): c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY]) if out_seconds: c.Set(c.Deref(out_seconds), seconds) if out_milliseconds: c.Set(c.Deref(out_milliseconds), milliseconds) c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY]) def timer_msleep(ms: t.CUInt32T): target: t.CUInt64T = ticks + (ms + MILLISECONDS_PER_TICK - 1) / MILLISECONDS_PER_TICK while ticks < target: asm.sti() asm.hlt() sched.Scheduler._yield() def timer_sleep(sec: t.CUInt32T): target: t.CUInt64T = ticks + sec * TICKS_PER_SECOND while ticks < target: asm.sti() asm.hlt() sched.Scheduler._yield()