mirror of
https://github.com/Tom-on64/kern.git
synced 2026-11-04 02:23:10 +00:00
Reimplemented PIT Timer. Sleep is now a syscall. Also made docs/ that contains some info so i don't forget.
This commit is contained in:
+22
-21
@@ -4,43 +4,44 @@
|
||||
#include <stdint.h>
|
||||
#include <idt.h>
|
||||
#include <pic.h>
|
||||
#include <system.h>
|
||||
#include <screen.h>
|
||||
|
||||
#define INPUT_CLK 1193180
|
||||
#define CHANNEL_0 0x40 // Offset it by 1 or 2 for ch1 and ch2
|
||||
#define COMMAND 0x43
|
||||
#define INPUT_CLK 1193182
|
||||
|
||||
uint32_t timerTicks = 0;
|
||||
static uint32_t* timerTicks = (uint32_t*)0x1000;
|
||||
|
||||
__attribute__ ((interrupt))
|
||||
void timerHandler(intFrame_t* iframe) {
|
||||
timerTicks++;
|
||||
*timerTicks += 1;
|
||||
|
||||
// TODO: Improve the cursor rendering
|
||||
if (timerTicks % 500 == 0) putcAt(127, cursor.x, cursor.y);
|
||||
else if (timerTicks % 250 == 0) putcAt(' ', cursor.x, cursor.y);
|
||||
if (*timerTicks % 500 == 0) putcAt(' ', cursor.x, cursor.y);
|
||||
else if (*timerTicks % 250 == 0) putcAt(127, cursor.x, cursor.y);
|
||||
|
||||
sendPicEOI(0);
|
||||
}
|
||||
|
||||
void setupTimer() {
|
||||
idtSetGate(32, timerHandler, INT_GATE_FLAGS);
|
||||
unsetIrqMask(0);
|
||||
}
|
||||
void setPitPhase(uint8_t channel, uint8_t opMode, uint16_t hz) {
|
||||
if (channel > 2 || opMode > 7) { return; }
|
||||
__asm__ volatile ("cli");
|
||||
|
||||
// Source: https://en.wikibooks.org/wiki/X86_Assembly/Programmable_Interval_Timer
|
||||
void timerPhase(uint32_t hz) {
|
||||
uint16_t div = INPUT_CLK / hz;
|
||||
// Send command - bits 7-6 channel, 5-4 Access mode, 3-1 operating mode, 0 - Should be zero in x86
|
||||
outb(COMMAND, ((channel << 6) | (3 << 4) | (opMode << 1)));
|
||||
|
||||
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;
|
||||
// Send frequency
|
||||
uint16_t freq = INPUT_CLK / hz; // I solved an equation to figure this out
|
||||
outb(CHANNEL_0 + channel, (uint8_t)freq);
|
||||
outb(CHANNEL_0 + channel, (uint8_t)(freq >> 8));
|
||||
|
||||
while (timerTicks != eticks); // Should ignore overflows unlike '<'
|
||||
__asm__ volatile ("sti");
|
||||
}
|
||||
|
||||
void setupTimer() { // Sets up IRQ 0 - PIT
|
||||
idtSetGate(0x20, timerHandler, INT_GATE_FLAGS);
|
||||
unsetIrqMask(0);
|
||||
setPitPhase(0, 2, 1000); // Default setup: 1000Hz - 1 tick per 1ms
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user