summaryrefslogtreecommitdiff
path: root/asm/asm_pit.s
blob: 8be29cbe775e816712a1884990950b822e47c195 (plain)
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