10 #define TIMER_QUANTUM 100
11 #define TIMER_FREQ 1024 //Hz
12 #define MS_PER_TICK_WHOLE (1000/(TIMER_FREQ))
13 #define MS_PER_TICK_FRACT ((Uint64)(1000*TIMER_FREQ-((Uint64)MS_PER_TICK_WHOLE)*0x80000000/TIMER_FREQ))
16 typedef struct sTimer {
18 void (*Callback)(void*);
23 void Time_Interrupt();
24 void Timer_CallTimers();
28 Sint64 giTimestamp = 0;
29 Uint64 giPartMiliseconds = 0;
30 tTimer gTimers[NUM_TIMERS];
34 * \fn int Time_Setup()
35 * \brief Sets the system time from the Realtime-Clock
41 outb(0x70, inb(0x70)&0x7F); // Disable NMIs
42 __asm__ __volatile__ ("cli"); // Disable normal interrupts
45 outb(0x70, 0x0B); // Set the index to register B
46 val = inb(0x71); // Read the current value of register B
47 outb(0x70, 0x0B); // Set the index again (a read will reset the index to register D)
48 outb(0x71, val | 0x40); // Write the previous value or'd with 0x40. This turns on bit 6 of register D
50 __asm__ __volatile__ ("sti"); // Disable normal interrupts
51 outb(0x70, inb(0x70)|0x80); // Disable NMIs
53 // Install IRQ Handler
54 IRQ_AddHandler(8, Time_Interrupt);
59 * \fn void Time_Interrupt()
60 * \brief Called on the timekeeping IRQ
65 giTimestamp += MS_PER_TICK_WHOLE;
66 giPartMiliseconds += MS_PER_TICK_FRACT;
67 if(giPartMiliseconds > 0x80000000) {
69 giPartMiliseconds -= 0x80000000;
76 * \fn void Time_TimerThread()
79 void Time_TimerThread()
82 Threads_SetName("TIMER");
84 next = giTimestamp + TIMER_QUANTUM;
87 while(giTimestamp < next) Threads_Yield();
88 next = giTimestamp + TIMER_QUANTUM;
96 * \brief Return the current timestamp
104 * \fn void Timer_CallTimers()
106 void Timer_CallTimers()
109 void (*callback)(void *);
115 if(gTimers[i].Callback == NULL) continue;
116 if(giTimestamp < gTimers[i].FiresAfter) continue;
117 callback = gTimers[i].Callback;
118 gTimers[i].Callback = NULL;
119 callback(gTimers[i].Argument);
124 * \fn int Time_CreateTimer(int Delta, void *Callback, void *Argument)
126 int Time_CreateTimer(int Delta, void *Callback, void *Argument)
133 if(gTimers[ret].Callback != NULL) continue;
134 gTimers[ret].Callback = Callback;
135 gTimers[ret].FiresAfter = giTimestamp + Delta;
136 gTimers[ret].Argument = Argument;
143 * \fn void Time_RemoveTimer(int ID)
145 void Time_RemoveTimer(int ID)
147 if(ID < 0 || ID >= NUM_TIMERS) return;
148 gTimers[ID].Callback = NULL;
152 * \fn void Time_Delay(int Delay)
153 * \brief Delay for a small ammount of time
155 void Time_Delay(int Delay)
157 Sint64 dest = giTimestamp + Delay;
158 while(dest < giTimestamp) Threads_Yield();