[feat] add option -u print next in timestamp
[azan.git] / azan-nasm.s
blobd2ee02e7d75bca850a4f4f7b15a5030796468578
1 ; See LICENSE file for copyright and license details.
2 ; azan-nasm is simple muslim prayers calculator.
3 ; print next prayer left duration or today's all prayers.
5 BITS 64
6 %include "syscalls.s"
7 %include "macros.s"
8 %include "config.s"
9 CHECK_OPENBSD
11 section .rodata
12 sec_inday: dq 0x40f5180000000000 ;double 86400.0
13 jul1970: dq 0x41429ec5c0000000 ;double 2440587.5
14 offset: dq 0xc142b42c80000000 ;double -2451545
15 to_rad: dq 0x3f91df46a2529d39 ;double pi / 180
16 to_deg: dq 0x404ca5dc1a63c1f8 ;double 180 / pi
17 g_1: dq 0x3fef8a099930e901 ;double 0.98560027999999999
18 g_2: dq 0x40765876c8b43958 ;double 357.529
19 e_3: dq 0xbe9828c0be769dc1 ;double -3.5999999999999999E-7
20 e_4: dq 0x403770624dd2f1aa ;double 23.439
21 q_5: dq 0x3fef8a6c5512d6f2 ;double 0.98564735999999997
22 q_6: dq 0x4071875810624dd3 ;double 280.459
23 sing_1: dq 0x3FFEA3D70A3D70A4 ;double 1.915
24 sing_2: dq 0x3F947AE147AE147B ;double 0.020
25 RA_1: dq 0x402E000000000000 ;double 15.0
26 eqt_1: dq 0x4076800000000000 ;double 360.0
27 duhr_1: dq 0x4028000000000000 ;double 12.0
28 pray_1: dq 0x4038000000000000 ;double 24.0
29 neg1: dq 0xBFF0000000000000 ;double -1.0
30 p1: dq 0X3fb1111111111111 ;double 0.066666666666666666
31 sec_inhour: dq 0x40ac200000000000 ;double 3600
32 sec_inmin: dq 0x404e000000000000 ;double 60
33 maghrib_1: dq 0x3fa1c432ca57a787 ;double 0.0347
34 maghrib_2: dq 0x3feaaaaaaaaaaaab ;double 0.833333333333333333
35 isha_nor: dq 0x40b5180000000000 ;double 5400.0 90 min
36 isha_ram: dq 0x40bc200000000000 ;double 7200.0 120 min
38 section .bss
39 tmp0: resq 1
40 tmp1: resq 1
42 section .text
43 global _start
45 _start:
46 pop rcx
47 cmp rcx, MAX_ARGC
48 jl get_timestamp
49 je check_argv
51 die_usage:
52 DIE usage_msg, usage_len
54 check_argv:
55 mov r11, [rsp+8] ;argv
56 cmp [r11], byte 0x2d ;-
57 jne die_usage
58 cmp [r11+2], byte 0x00
59 jne die_usage
60 mov r12b, [r11+1]
61 cmp r12b, 0x75 ;u
62 je get_timestamp
63 cmp r12b, 0x76 ;v
64 jne die_usage
65 DIE version_msg, version_len
67 get_timestamp:
68 mov rax, SYS_gettimeofday ;sys_gettimeofday(
69 mov rdi, tmp0 ;struct timeval *tv,
70 mov rsi, rsi ;struct timezone* tz
71 syscall
73 ;start_of_day = tstamp - (tstamp % 86400);
74 mov edi, [tmp0]
75 movsx rax, edi
76 mov edx, edi
77 imul rax, rax, -1037155065
78 sar edx, 31
79 shr rax, 32
80 add eax, edi
81 sar eax, 16
82 sub eax, edx
83 imul edx, eax, 86400
84 mov eax, edi
85 sub eax, edx
86 cvtsi2sd xmm15, rdx
87 movsd xmm14, [time_zone]
88 mulsd xmm14, [sec_inhour]
89 subsd xmm15, xmm14
91 ;tstamp = xmm6 convert tstamp to double
92 cvtsi2sd xmm6, [tmp0]
94 ;julian = tstamp / sec_inday) + jul1970 = xmm0
95 movsd xmm0, xmm6 ;copy tstamp to xmm0
96 divsd xmm0, [sec_inday] ;tstamp / sec_inday
97 addsd xmm0, [jul1970] ;div result + jul1970
99 calc_equation_of_time:
100 ;d = julian - offset = xmm0
101 addsd xmm0, [offset]
103 ;g = to_rad * ((d * 0.98560028) + 357.529) = xmm1
104 movsd xmm1, [g_1]
105 mulsd xmm1, xmm0
106 addsd xmm1, [g_2]
107 mulsd xmm1, [to_rad]
109 ;e = to_rad * (23.439 - (d * 0.00000036)) = xmm3
110 movsd xmm3, [e_3]
111 mulsd xmm3, xmm0
112 addsd xmm3, [e_4]
113 mulsd xmm3, [to_rad]
115 ;q = (d * 0.98564736) + 280.459 = xmm4
116 movsd xmm4, [q_5]
117 mulsd xmm4, xmm0
118 addsd xmm4, [q_6]
120 ;sing = 1.915 * sin(g) = xmm5
121 movsd xmm5, xmm1
122 SIN xmm5
123 mulsd xmm5, [sing_1]
125 ;sin2g = 0.020 * sin(2.0*g) = xmm1
126 addsd xmm1, xmm1
127 SIN xmm1
128 mulsd xmm1, [sing_2]
130 ;sin(e) = xmm8
131 movsd xmm8 , xmm3
132 SIN xmm8
134 ;cos(e) = xmm7
135 movsd xmm7, xmm3
136 COS xmm7
138 ;L = to_rad(q + sing + sin2g) = xmm5
139 addsd xmm5, xmm1
140 addsd xmm5, xmm4
141 mulsd xmm5, [to_rad]
143 ;sin(L) = xmm2
144 movsd xmm2, xmm5
145 SIN xmm2
147 ;cos(L) = xmm5
148 COS xmm5
150 ;RA = to_deg(atan2(cose * sinL, cosL) / 15.0) = xmm7
151 mulsd xmm7, xmm2 ;cose * sinL
152 ATAN2 xmm7, xmm5 ;result in xmm7
153 divsd xmm7, [RA_1] ;atan2 result /15.0
154 mulsd xmm7, [to_deg] ;* to_deg
156 ;D = to_deg(asin(sine * sinL)) = xmm8
157 mulsd xmm8, xmm2
158 ASIN xmm8
159 mulsd xmm8, [to_deg]
161 ;EqT = q / 15.0 - RA = xmm9
162 movsd xmm9, xmm4 ;move q to xmm9
163 divsd xmm9, [RA_1] ;q / 15.0
164 subsd xmm9, xmm7 ;- RA
165 subsd xmm9, [eqt_1] ;EqT = EqT - 360.0
167 get_duhr: ;duhr = 12.0+time_zone-EqT-(longitude/15.0)=xmm0
168 movsd xmm1, [longitude]
169 divsd xmm1, [RA_1]
170 movsd xmm0, [duhr_1]
171 addsd xmm0, [time_zone]
172 subsd xmm0, xmm9
173 subsd xmm0, xmm1
174 NORM xmm0, [pray_1]
176 calc_p2p3:
177 CALC_P2 ;xmm1
178 CALC_P3 ;xmm2
180 get_fajr: ;fajr = duhr - T(fajr_angle, D) = xmm3
182 movsd xmm3, [fajr_angle]
183 CALC_T xmm3
185 ;fajr = duhr - T = xmm3
186 movsd xmm4, xmm3
187 movsd xmm3, xmm0
188 subsd xmm3, xmm4
190 test_fajr:
191 mulsd xmm3, [sec_inhour] ;convert to seconds
192 roundsd xmm3, xmm3, ROUND_DOWN
193 addsd xmm3, xmm15 ;fajr seconds + start_of_day
194 ucomisd xmm3, xmm6 ;if fajr > tstamp
195 jae print_fajr
197 test_duhr:
198 movsd xmm13, xmm0 ;save duhr to xmm13
199 mulsd xmm0, [sec_inhour] ;convert to seconds
200 roundsd xmm0, xmm0, ROUND_DOWN
201 addsd xmm0, xmm15 ;duhr seconds + start_of_day
202 ucomisd xmm0, xmm6 ;if duhr > tstamp
203 jae print_duhr
205 get_asr: ;asr = duhr + A(1.0, D);
206 ;A = p1 * p7 = xmm4
207 ;p4 = tan(convert_degrees_to_radians((latitude - D)))
208 ;p5 = atan2(1.0, (t + p4));
209 ;p6 = sin(p5) = xmm4
210 movsd xmm4, [latitude]
211 subsd xmm4, xmm8
212 mulsd xmm4, [to_rad]
213 movsd [tmp0], xmm4
214 fld1
215 fld qword [tmp0]
216 fptan
217 fadd
218 fpatan
219 fsin
220 fstp qword [tmp0]
221 movsd xmm4, [tmp0]
223 ;p7 = convert_radians_to_degrees(acos((p6 - p3) / p2));
224 subsd xmm4, xmm2
225 divsd xmm4, xmm1
226 ACOS xmm4
227 mulsd xmm4, [to_deg]
229 ;A = p1 * p7 = xmm4
230 mulsd xmm4, [p1]
231 addsd xmm4, xmm13
232 NORM xmm4, [pray_1]
234 test_asr:
235 mulsd xmm4, [sec_inhour] ;convert to seconds
236 roundsd xmm4, xmm4, ROUND_DOWN
237 addsd xmm4, xmm15 ;asr seconds + start_of_day
238 ucomisd xmm4, xmm6 ;if asr > tstamp
239 jae print_asr
241 get_maghrib: ;duhr + T(0.8333 + 0.0347 * sqrt(altitude), D) = xmm5
242 sqrtsd xmm5, [altitude]
243 mulsd xmm5, [maghrib_1]
244 addsd xmm5, [maghrib_2]
245 CALC_T xmm5
246 addsd xmm5, xmm13
248 test_maghrib:
249 mulsd xmm5, [sec_inhour] ;convert to seconds
250 roundsd xmm5, xmm5, ROUND_DOWN
251 addsd xmm5, xmm15 ;maghrib seconds + start_of_day
252 ucomisd xmm5, xmm6 ;if maghrib > tstamp
253 jae print_maghrib
255 get_isha:
256 mov rcx, 1
257 cmp rcx, use_umm_al_qura
258 jne um_nor
259 cmp rcx, ramadan
260 je um_ram
262 um_nor: ;maghrib + 90.0 min;
263 movsd xmm7, [isha_nor]
264 addsd xmm7, xmm5
265 jmp test_isha
267 um_ram: ;maghrib + 120.0 min;
268 movsd xmm7, [isha_ram]
269 addsd xmm7, xmm5
270 jmp test_isha
272 calc_isha_nor: ;duhr + T(isha_angle, D);
273 movsd xmm7, [isha_angle]
274 CALC_T xmm7
275 addsd xmm7, xmm13
276 NORM xmm7, [pray_1]
278 test_isha:
279 ucomisd xmm7, xmm6 ;if isha > tstamp
280 jae print_isha
282 get_nfajr: ;fajr + sec_inday
283 movsd xmm12, [sec_inday]
284 addsd xmm12, xmm3
286 print_nfajr:
287 mov [res_msg], byte 'F'
288 movsd xmm14, xmm12
289 cmp r12b, byte 'u'
290 je print_unix
291 CALC_DIFF xmm12
292 PRINT_EXIT
294 print_fajr:
295 mov [res_msg], byte 'F'
296 movsd xmm14, xmm3
297 cmp r12b, byte 'u'
298 je print_unix
299 CALC_DIFF xmm3
300 PRINT_EXIT
302 print_duhr:
303 mov [res_msg], byte 'D'
304 movsd xmm14, xmm0
305 cmp r12b, byte 'u'
306 je print_unix
307 CALC_DIFF xmm0
308 PRINT_EXIT
310 print_asr:
311 mov [res_msg], byte 'A'
312 movsd xmm14, xmm4
313 cmp r12b, byte 'u'
314 je print_unix
315 CALC_DIFF xmm4
316 PRINT_EXIT
318 print_maghrib:
319 mov [res_msg], byte 'M'
320 movsd xmm14, xmm5
321 cmp r12b, byte 'u'
322 je print_unix
323 CALC_DIFF xmm5
324 PRINT_EXIT
326 print_isha:
327 mov [res_msg], byte 'I'
328 movsd xmm14, xmm7
329 cmp r12b, byte 'u'
330 je print_unix
331 CALC_DIFF xmm7
332 PRINT_EXIT
334 print_unix:
335 PRINT_INT ;from xmm14
337 ; result_hour ;r8
338 ; result_min ;r9
339 ; duhr_ts: ;xmm0
340 ; p2: ;xmm1
341 ; p3: ;xmm2
342 ; fajr_ts: ;xmm3
343 ; asr_ts ;xmm4
344 ; maghrib_ts: ;xmm5
345 ; tstamp: ;xmm6
346 ; isha_ts: ;xmm7
347 ; D: ;xmm8
348 ; EqT: ;xmm9
349 ; next_fajr ;xmm12
350 ; duhr: ;xmm13
351 ; macros: ;xmm14
352 ; start_of_day: ;xmm15
354 EEXIT EXIT_SUCCESS