#include <alloc.h> #include <interrupts.h> #include <irqs.h> #include <ports.h> #include <stdint.h> #include <stdio.h> #include <task.h> #define PIT_A 0x40 #define PIT_CONTROL 0x43 #define PIT_MASK 0xFF #define PIT_SCALE 1193180 #define PIT_SET 0x36 #define CMD_BINARY 0x00 #define CMD_MODE0 0x00 #define CMD_MODE1 0x02 #define CMD_MODE2 0x04 #define CMD_MODE3 0x06 #define CMD_MODE4 0x08 #define CMD_MODE5 0x0a #define CMD_RW_BOTH 0x30 #define CMD_COUNTER0 0x00 #define CMD_COUNTER2 0x80 void sleep(uint16_t millis) { int32_t ticksLeft = getCurrentTask()->ticksLeft - millis; getCurrentTask()->ticksLeft = millis; yield(); if (ticksLeft > 0) { getCurrentTask()->ticksLeft = ticksLeft; } } void setTimerFrequency(uint32_t hz) { int divisor = PIT_SCALE / hz; outb(PIT_CONTROL, CMD_BINARY | CMD_MODE3 | CMD_RW_BOTH | CMD_COUNTER0); outb(PIT_A, (uint8_t)divisor); outb(PIT_A, (uint8_t)(divisor >> 8)); } uintptr_t timerMillis = 0; void timerHandler() { timerMillis++; for (ListElement *current = getAllTasks(); current; current = current->next) { Task *task = current->data; if (task->ticksLeft == -1) { continue; } if (task->ticksLeft == 0) { task->ticksLeft = task->timerTicks; Message *message = malloc(sizeof(Message)); message->size = 0; message->data = (void *)timerMillis; message->type = TIMER_UPDATE; listAdd(&task->messages, message); schedule(task); } else { task->ticksLeft--; } } } void setupTimer() { setTimerFrequency(1000); setIRQHandler(0, &timerHandler); }