#include #include #include #include #include static inline void outb(UINT16 port, UINT8 val) { ASM("outb %0, %1" : : "a"(val), "Nd"(port)); } static volatile UINT64 g_ticks = 0; static timer_callback_t g_tick_handler = NULL; extern "C" void pit_irq_handler(void) { g_ticks++; if (g_tick_handler) { g_tick_handler(); } } void pit_init(void) { serial_write("PIT: initializing channel 0 at "); serial_write_hex(PIT_TICK_HZ); serial_write(" Hz\n"); UINT32 divisor = PIT_BASE_FREQ / PIT_TICK_HZ; // Command byte: channel 0, lobyte/hibyte, rate generator, binary outb(PIT_COMMAND_PORT, 0x36); // Send divisor (low byte first, then high byte) outb(PIT_CHANNEL0_DATA, (UINT8)(divisor & 0xFF)); outb(PIT_CHANNEL0_DATA, (UINT8)((divisor >> 8) & 0xFF)); // Unmask IRQ 0 (timer) pic_unmask_irq(0); serial_write("PIT: divisor = "); serial_write_hex(divisor); serial_write("\n"); } void pit_set_tick_handler(timer_callback_t handler) { g_tick_handler = handler; } UINT64 pit_get_ticks(void) { return g_ticks; }