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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
bits 64
section .rodata
section .text
read_cmos_byte:
;dil in = register number
;al out = value
;rdx and rcx are not touched
mov al, dil
out 0x70, al
in al, 0x71
ret
global enable_rtc_interrupts
enable_rtc_interrupts:
;secondary status register
mov dil, 11
call read_cmos_byte
;enable interrupts
or al, 0x40
mov cl, al
;do cmos write
mov al, 11
out 0x70, al
mov al, cl
out 0x71, al
ret
global acknowledge_rtc_interrupt
acknowledge_rtc_interrupt:
mov dil, 12
jmp read_cmos_byte
convert_bcd:
;al in = byte (possibly bcd)
;al out = byte (not bcd)
;sil 0x02 = bcd
;does not touch rdx, rcx, sil
test sil, 0x02
jz .no_convert
mov dil, al
and dil, 0xf0
and al, 0x0f
shr dil, 3
add al, dil
shl dil, 2
add al, dil
.no_convert:
ret
convert_hours:
;al in = byte (possibly bcd and 12 hour)
;al out = byte (not bcd or 12 hour)
;sil 0x02 = bcd, sil 0x01 = 12 hour
;does not touch rdx, rcx, sil
test sil, 0x01
jz convert_bcd
test al, 0x80
jz .am
and al, 0x7f
call convert_bcd
cmp al, 12
je .noon
add al, 12
ret
.noon:
ret
.am:
call convert_bcd
cmp al, 12
je .midnight
ret
.midnight:
xor al, al
ret
global get_time_from_rtc
get_time_from_rtc:
;rax out = time (see timer.cpp for encoding)
;we assume the year is 20xx (sorry)
mov dil, 11
call read_cmos_byte
shr al, 1
not al
and al, 3
mov sil, al
xor rdx, rdx
.outer_loop:
mov rcx, rdx
.wait_for_update_loop:
;status register - 0x80 is update in progress
mov dil, 10
call read_cmos_byte
test al, 0x80
jnz .wait_for_update_loop
;years
mov dil, 9
call read_cmos_byte
call convert_bcd
mov dh, al
;months
mov dil, 8
call read_cmos_byte
call convert_bcd
mov dl, al
shl edx, 16
;days
mov dil, 7
call read_cmos_byte
call convert_bcd
mov dh, al
;hours
mov dil, 4
call read_cmos_byte
call convert_hours
mov dl, al
shl rdx, 16
;minutes
mov dil, 2
call read_cmos_byte
call convert_bcd
mov dh, al
;seconds
xor dil, dil
call read_cmos_byte
call convert_bcd
mov dl, al
cmp rdx, rcx
jne .outer_loop
mov rax, rdx
ret
|