2019-02-09 16:48:40 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <dos.h>
|
|
|
|
#include "timer.h"
|
|
|
|
|
|
|
|
#define TIMER_INTERRUPT 0x1c
|
|
|
|
#define REG_8253_CTL 0x43
|
|
|
|
#define REG_COUNTER0 0x40
|
|
|
|
|
|
|
|
volatile unsigned int timer_counter = 0;
|
|
|
|
|
|
|
|
static void interrupt (*oldTimerISR)() = NULL;
|
2019-03-31 23:29:16 +00:00
|
|
|
static void (*callback)() = NULL;
|
2019-02-09 16:48:40 +00:00
|
|
|
|
|
|
|
static void interrupt timer_isr() {
|
2019-04-05 23:35:43 +00:00
|
|
|
disable();
|
2019-02-09 16:48:40 +00:00
|
|
|
timer_counter ++;
|
2019-03-31 23:29:16 +00:00
|
|
|
if (callback) callback();
|
2019-04-05 23:35:43 +00:00
|
|
|
enable();
|
2019-02-09 16:48:40 +00:00
|
|
|
oldTimerISR();
|
|
|
|
}
|
|
|
|
|
2019-03-31 23:29:16 +00:00
|
|
|
void timer_setcallback(void (*cb)()) {
|
|
|
|
callback = cb;
|
|
|
|
}
|
|
|
|
|
2019-02-09 16:48:40 +00:00
|
|
|
void timer_setrate(unsigned int rate) {
|
|
|
|
outp(REG_8253_CTL, 0x3c);
|
|
|
|
outp(REG_COUNTER0, rate & 0xff);
|
|
|
|
outp(REG_COUNTER0, (rate >> 8) & 0xff);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void timer_cleanup() {
|
|
|
|
if (oldTimerISR != NULL) {
|
|
|
|
setvect(TIMER_INTERRUPT, oldTimerISR);
|
|
|
|
timer_setrate(TIMER_18HZ);
|
|
|
|
oldTimerISR = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void timer_init(unsigned int rate) {
|
|
|
|
timer_setrate(rate);
|
|
|
|
oldTimerISR = getvect(TIMER_INTERRUPT);
|
|
|
|
setvect(TIMER_INTERRUPT, timer_isr);
|
|
|
|
atexit(timer_cleanup);
|
|
|
|
}
|