/* *----------------------------------------------------------------------------- * * timer.c -- * * Handle the timer interrupt. * *----------------------------------------------------------------------------- */ #include #define TIMER_INTERRUPT 0x20 #define TICK_HZ 64 /* spin at ~8Hz */ #define TICK_MASK 0xf #define INPUT_TICKS 1193181 void tick (void) { static unsigned long ticks = 0; static unsigned long v = 0; char spinner[] = { '|', '/', '-', '\\' }; char *vgabuf = (char *)0xb8000; acknowledge_irq (); ticks++; if (ticks & TICK_MASK) { return; } vgabuf[0] = spinner[v & 0x3]; vgabuf[1] = 0x7; v++; } extern void tick_stub (void); asm (" .global tick_stub\n" "tick_stub:\n\t" " call tick\n\t" " iret\n"); void enable_timer (void) { install_iv (TIMER_INTERRUPT, &tick_stub, INTERRUPT); outb (inb (0x21) & 0xfe, 0x21); } void disable_timer (void) { outb (inb (0x21) & 0x01, 0x21); } void set_timer_interval (unsigned long interval) { unsigned long counter; if (interval < 19) { /* 18.2Hz is as low as this goes */ interval = 19; } counter = INPUT_TICKS / interval; outb (0x36, 0x43); outb ((char)(counter & 0xff), 0x40); outb ((char)((counter >> 8) & 0xff), 0x40); } void timer_init (void) { set_timer_interval (TICK_HZ); enable_timer (); }