-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathUNIXts.asm
197 lines (159 loc) · 4.35 KB
/
UNIXts.asm
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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
.486
IDEAL
MODEL small
macro BCDtoHEX num ;8bit, puts in dl
push ax
push bx
push cx
mov bl, num
and bl, 0Fh
mov al, num
and al, 0F0h
mov cl, 4
ror al, cl
mov dl, 0Ah
mul dl
add al, bl
mov dl, al
pop cx
pop bx
pop ax
endm BCDtoHEX
macro AxDaysToSeconds ;ax * 86400 result --> dx:ax
local Loop1
local Loop2
local FinishM
push cx
push si
xor dx, dx
mov si, ax
xor ax, ax
mov cx, 2
Loop1:
push cx
mov cx, 43200
Loop2:
add ax, si
adc dx, 0
loop Loop2
pop cx
loop Loop1
FinishM:
pop si
pop cx
endm AxDaysToSeconds
DATASEG
UNIX_TO_2021 = 1609459200
BaseTime dd UNIX_TO_2021
TIME_ZONE = 2
SEC_TIME_ZONE = 3600*TIME_ZONE
DaysInMonthLookup dw 0 ;illegal
dw 0 ;Days between 1/1 and 1/1
dw 31 ;Days between 1/1 and 1/2
dw 59 ;Days between 1/1 and 1/3
dw 90 ;31+28+31 ;Days between 1/1 and 1/4
dw 120 ;31+28+31+30 ;Days between 1/1 and 1/5
dw 151 ;31+28+31+30+31 ;Days between 1/1 and 1/6
dw 181 ;31+28+31+30+31+30 ;Days between 1/1 and 1/7
dw 212 ;31+28+31+30+31+30+31 ;Days between 1/1 and 1/8
dw 243 ;31+28+31+30+31+30+31+31 ;Days between 1/1 and 1/9
dw 273 ;31+28+31+30+31+30+31+31+30 ;Days between 1/1 and 1/10
dw 304 ;31+28+31+30+31+30+31+31+30+31 ;Days between 1/1 and 1/11
dw 334 ;31+28+31+30+31+30+31+31+30+31+30 ;Days between 1/1 and 1/12
LeapYears dw 2020, 2024, 2028, 2032, 2036;, 2040, 2044, 2048, 2052, 2056, 2060 ;leap years lookup table.
CODESEG
public EpochTimeDiv30
proc EpochTimeDiv30
push cx
push bx
mov cx, [word ptr BaseTime+2]
mov bx, [word ptr BaseTime] ;cx:bx = UNIX_TO_2021
call SecThisYearUTC
add ax, bx
adc dx, cx
push ax
mov ax, dx
xor dx, dx
mov bx, 30
div bx ;dx = rem, ax = high order quotient
mov cx, ax ;store high order quotient
pop ax
div bx
mov dx, cx
;now dx:ax = quotient
pop bx
pop cx
ret
endp EpochTimeDiv30
;--------------------------------------------
;Calcultate the amout of seconds since January 1st of the current year
;OUTPUT: dx = days
;--------------------------------------------
proc SecThisYear
push cx
push bx
push si
mov ah, 4 ;get rtc date
int 1ah
push dx ;save month:day(DH:DL)
BCDtoHEX dh
mov al, dl ;save hex month
pop dx
BCDtoHEX dl ;now dl = day, al = month
shl al, 1 ;mul month by 2 because its in words(every word = 2bytes)
xor ah, ah
mov si, ax
mov ax, [DaysInMonthLookup+si]
xor dh, dh
dec dl ;if it's the 25th we add 24(current day isn't a full day)
add ax, dx ;ax = days this year
push ax ;save days
mov ah, 2
int 1ah
BCDtoHEX dh
mov dh, dl
BCDtoHEX ch
mov ch, dl
BCDtoHEX cl
mov cl, dl
mov bl, dh ;seconds - current day
xor bh, bh
mov si, bx ;save current day's seconds in si
mov bl, ch
mov ax, 3600
mul bx ;now dx:ax = current day's hours in seconds
push dx ;save hours in seconds high-order word
push ax ;low
mov bl, cl
mov al, 60
mul bl ;now ax = current day's minutes in seconds
add si, ax ;add minutes to seconds
pop ax
pop dx
add ax, si
adc dx, 0 ;add minutes and secondes to hours(all in seconds)
pop cx ;days current year that we pushed earlier
push dx
push ax
mov ax, cx
AxDaysToSeconds ;dx:ax = days current year in seconds
pop bx ;minutes secondes and hours - low order word
pop cx ;^^^^^^ - high-order word
add ax, bx
adc dx, 0
add dx, cx
pop si
pop bx
pop cx
ret
endp SecThisYear
;-----------------------------------------------------------
;Returns in dx:ax the seconds that have past since the beginnig of the current year in UTC
;-----------------------------------------------------------
proc SecThisYearUTC
call SecThisYear
sub ax, SEC_TIME_ZONE
sbb dx, 0 ;32 bit subtruction
ret
endp SecThisYearUTC
end