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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
.global asm_pit_tick
.global asm_pit_get_ticks
.global asm_pit_sleep_50ms
.global asm_pit_sleep_40ms
.global asm_pit_sleep_10ms
.global asm_pit_sleep_1ms
.global asm_pit_rate_50ms
.global asm_pit_rate_40ms
.global asm_pit_rate_10ms
.global asm_pit_rate_1ms
ticks:
.int 0
asm_pit_get_ticks:
mov (ticks),%eax
ret
asm_pit_tick:
push %eax // persist
// INC TICK COUNTER
mov $ticks, %eax
incl (%eax)
pop %eax // load original
ret
.macro asm_pit_rate val
mov $0b00110100, %al // chan 0 / mode 2
outb %al,$0x43
// LSB first
mov \val, %dx
out %al, $0x40
xchg %ah,%al
out %al, $0x40
ret
.endm
.macro asm_pit_sleep val
mov $0x00110000, %al // chan 0 / mode 0
outb %al,$0x43
// LSB first
mov \val, %ax
out %al, $0x40
xchg %ah,%al
out %al, $0x40
// check if finished
mov $0xE2, %al
outb %al,$0x43
//sleep until finished
//7th bit determines if finished
sleep\val:
inb $0x40, %al
or $0b1000000, %al
cmp $0b1000000, %al
jne sleep\val
ret
.endm
/* decrements at 1.193182Mhz
0xE90B // 50ms - 20 Hz
0xBA6F // 40ms - 25 Hz
0x2E9C // 10ms - 100 Hz
0x04A9 // 1ms - 1000 Hz
*/
asm_pit_sleep_50ms: asm_pit_sleep $0xE90B
asm_pit_sleep_40ms: asm_pit_sleep $0xBA6F
asm_pit_sleep_10ms: asm_pit_sleep $0x2E9C
asm_pit_sleep_1ms: asm_pit_sleep $0x04A9
asm_pit_rate_50ms: asm_pit_rate $0xE90B
asm_pit_rate_40ms: asm_pit_rate $0xBA6F
asm_pit_rate_10ms: asm_pit_rate $0x2E9C
asm_pit_rate_1ms: asm_pit_rate $0x04A9
|