-
Notifications
You must be signed in to change notification settings - Fork 0
/
clock.c
69 lines (51 loc) · 1.41 KB
/
clock.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/*****************************************
Mroczna Harmonia
clock.c Facility to handle custom timer
(C) 2001, 2023 M. Feliks
*****************************************/
#include <dos.h>
#include <conio.h>
#define CLOCK_FREQUENCY 1193181
#define DOS_DIVISOR 65535
#define DOS_FREQUENCY CLOCK_FREQUENCY / DOS_DIVISOR // 18.206775005722132 ticks/s
#define MY_DIVISOR 8192
#define MY_FREQUENCY CLOCK_FREQUENCY / DOS_DIVISOR // 145.6519775390625 ticks/s
#define TIMER_FACTOR MY_FREQUENCY / DOS_FREQUENCY // call DOS interrupt every 8 ticks
void interrupt (*old_clock_interrupt)(void);
unsigned long timer = 0, timer_dos = 0, timer_stop;
void timer_start(unsigned long ticks)
{
timer_stop = timer + ticks;
}
void timer_wait()
{
while (timer < timer_stop) {
// Reduce CPU load in VirtualBox from 100% to 65%
_asm {
hlt
}
}
}
void interrupt clock_interrupt(void)
{
timer++;
if ((++timer_dos) > TIMER_FACTOR) {
timer_dos = 0;
old_clock_interrupt();
}
}
void clock_init(void)
{
old_clock_interrupt = _dos_getvect(0x1c);
_dos_setvect(0x1c, clock_interrupt);
outp(0x43, 0x34);
outp(0x40, (unsigned char)(MY_DIVISOR & 0xff));
outp(0x40, (unsigned char)((MY_DIVISOR >> 8) & 0xff));
}
void clock_shutdown(void)
{
_dos_setvect(0x1c, old_clock_interrupt);
outp(0x43, 0x34);
outp(0x40, -1);
outp(0x40, -1);
}