diff --git a/src/kernel/main.c b/src/kernel/main.c index 70a8a90..6e40a0b 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -3,6 +3,7 @@ #include "isrs.h" #include "irq.h" #include "keyboard.h" +#include "timer.h" #include "system.h" void main() { @@ -13,6 +14,8 @@ void main() { sti(); setupKeyboard(); + setupTimer(); + timerPhase(100); // 1 tick per 10ms clear(0x0f); print("kern.\n\n", 0x0f); diff --git a/src/kernel/string.c b/src/kernel/string.c index 740dc2b..d0221aa 100644 --- a/src/kernel/string.c +++ b/src/kernel/string.c @@ -1,5 +1,6 @@ #include "string.h" +// Source: http://www.strudel.org.uk/itoa/ char* itoa(uint32_t val, uint8_t base) { static char buf[32] = { 0 }; diff --git a/src/kernel/timer.c b/src/kernel/timer.c new file mode 100644 index 0000000..12b9bd2 --- /dev/null +++ b/src/kernel/timer.c @@ -0,0 +1,31 @@ +#include "timer.h" +#include "stdint.h" +#include "idt.h" +#include "irq.h" +#include "system.h" + +uint32_t timerTicks = 0; + +void timerHandler() { + timerTicks++; +} + +void setupTimer() { + installIrqHandler(0, timerHandler); +} + +// Source: https://en.wikibooks.org/wiki/X86_Assembly/Programmable_Interval_Timer +void timerPhase(uint32_t hz) { + uint16_t div = INPUT_CLK / hz; + + outb(0x43, 0x36); // Tell PIT that we're setting channel 0 + outb(0x40, div & 0xff); // Low byte + outb(0X40, div >> 8); // High byte +} + +void sleep(uint32_t ticks) { + uint32_t eticks = ticks + timerTicks; + + while (timerTicks != eticks); // Should avoid overflows unlike '<' +} + diff --git a/src/kernel/timer.h b/src/kernel/timer.h new file mode 100644 index 0000000..42f8391 --- /dev/null +++ b/src/kernel/timer.h @@ -0,0 +1,12 @@ +#ifndef TIMER_H +#define TIMER_H + +#include "stdint.h" + +#define INPUT_CLK 1193180 + +void setupTimer(); +void sleep(uint32_t ticks); +void timerPhase(uint32_t hz); + +#endif