[feat] print left duration, fajr & duhr
[azan.git] / azan-nasm.s
blob0b93a86a938c056f98a209a9d55afc3e09cd71d4
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
34 section .bss
35 tmp0: resq 1
36 tmp1: resq 1
38 section .text
39 global _start
41 _start:
42 pop rcx
43 cmp rcx, MAX_ARGC
44 jl get_timestamp
45 je die_version
47 die_usage:
48 DIE usage_msg, usage_len
50 die_version:
51 mov rcx, [rsp+8] ; argv
52 cmp [rcx], byte '-'
53 jne die_usage
54 cmp [rcx+1], byte 'v'
55 jne die_usage
56 cmp [rcx+2], byte 0
57 jne die_usage
58 DIE version_msg, version_len
60 get_timestamp:
61 mov rax, SYS_gettimeofday ;sys_gettimeofday(
62 mov rdi, tmp0 ;struct timeval *tv,
63 mov rsi, rsi ;struct timezone* tz
64 syscall
66 ; start_of_day = tstamp - (tstamp % 86400);
67 mov edi, [tmp0]
68 movsx rax, edi
69 mov edx, edi
70 imul rax, rax, -1037155065
71 sar edx, 31
72 shr rax, 32
73 add eax, edi
74 sar eax, 16
75 sub eax, edx
76 imul edx, eax, 86400
77 mov eax, edi
78 sub eax, edx
79 cvtsi2sd xmm15, rdx
80 movsd xmm14, [time_zone]
81 mulsd xmm14, [sec_inhour]
82 subsd xmm15, xmm14
84 ;tstamp = xmm6 convert tstamp to double
85 cvtsi2sd xmm6, [tmp0]
87 ;julian = tstamp / sec_inday) + jul1970 = xmm0
88 movsd xmm0, xmm6 ;copy tstamp to xmm0
89 divsd xmm0, [sec_inday] ;tstamp / sec_inday
90 addsd xmm0, [jul1970] ;div result + jul1970
92 calc_equation_of_time:
93 ;d = julian - offset = xmm0
94 addsd xmm0, [offset]
96 ;g = to_rad * ((d * 0.98560028) + 357.529) = xmm1
97 movsd xmm1, [g_1]
98 mulsd xmm1, xmm0
99 addsd xmm1, [g_2]
100 mulsd xmm1, [to_rad]
102 ;e = to_rad * (23.439 - (d * 0.00000036)) = xmm3
103 movsd xmm3, [e_3]
104 mulsd xmm3, xmm0
105 addsd xmm3, [e_4]
106 mulsd xmm3, [to_rad]
108 ;q = (d * 0.98564736) + 280.459 = xmm4
109 movsd xmm4, [q_5]
110 mulsd xmm4, xmm0
111 addsd xmm4, [q_6]
113 ;sing = 1.915 * sin(g) = xmm5
114 movsd xmm5, xmm1
115 SIN xmm5
116 mulsd xmm5, [sing_1]
118 ;sin2g = 0.020 * sin(2.0*g) = xmm1
119 addsd xmm1, xmm1
120 SIN xmm1
121 mulsd xmm1, [sing_2]
123 ;sin(e) = xmm8
124 movsd xmm8 , xmm3
125 SIN xmm8
127 ;cos(e) = xmm7
128 movsd xmm7, xmm3
129 COS xmm7
131 ;L = to_rad(q + sing + sin2g) = xmm5
132 addsd xmm5, xmm1
133 addsd xmm5, xmm4
134 mulsd xmm5, [to_rad]
136 ;sin(L) = xmm2
137 movsd xmm2, xmm5
138 SIN xmm2
140 ;cos(L) = xmm5
141 COS xmm5
143 ;RA = to_deg(atan2(cose * sinL, cosL) / 15.0) = xmm7
144 mulsd xmm7, xmm2 ;cose * sinL
145 ATAN2 xmm7, xmm5 ;result in xmm7
146 divsd xmm7, [RA_1] ;atan2 result /15.0
147 mulsd xmm7, [to_deg] ;* to_deg
149 ;D = to_deg(asin(sine * sinL)) = xmm8
150 mulsd xmm8, xmm2
151 ASIN xmm8
152 mulsd xmm8, [to_deg]
154 ;EqT = q / 15.0 - RA = xmm9
155 movsd xmm9, xmm4 ;move q to xmm9
156 divsd xmm9, [RA_1] ;q / 15.0
157 subsd xmm9, xmm7 ;- RA
158 subsd xmm9, [eqt_1] ;EqT = EqT - 360.0
160 get_duhr: ;duhr = 12.0+time_zone-EqT-(longitude/15.0);
161 movsd xmm1, [longitude]
162 divsd xmm1, [RA_1]
163 movsd xmm0, [duhr_1]
164 addsd xmm0, [time_zone]
165 subsd xmm0, xmm9
166 subsd xmm0, xmm1
168 ;normalize duhr
169 ;xmm0 - (pray_1 * floor(xmm1 / pray_1));
170 movsd xmm1, xmm0
171 divsd xmm1, [pray_1]
172 roundsd xmm1, xmm1, ROUND_DOWN ;floor(xmm1)
173 mulsd xmm1, [pray_1]
174 subsd xmm0, xmm1
175 ;xmm0 = duhr
177 get_fajr: ;fajr = duhr - T(fajr_angle, D);
178 ;calculate T = p1 * p5
179 ;p2 = cos(convert_degrees_to_radians(latitude)) *
180 ; cos(convert_degrees_to_radians(D)) = xmm1
181 movsd xmm1, [latitude]
182 mulsd xmm1, [to_rad]
183 COS xmm1
184 movsd xmm2, xmm8,
185 mulsd xmm2, [to_rad]
186 COS xmm2
187 mulsd xmm1, xmm2
189 ;p3 = sin(convert_degrees_to_radians(latitude)) *
190 ; sin(convert_degrees_to_radians(D)) = xmm2
191 movsd xmm2, [latitude]
192 mulsd xmm2, [to_rad]
193 SIN xmm2
194 movsd xmm3, xmm8, ; xmm8 = D
195 mulsd xmm3, [to_rad]
196 SIN xmm3
197 mulsd xmm2, xmm3
199 ;p4 = -1.0 * sin(convert_degrees_to_radians(alpha)) = xmm3
200 movsd xmm3, [fajr_angle]
201 mulsd xmm3, [to_rad]
202 SIN xmm3
203 mulsd xmm3, [neg1]
205 ;p5 = convert_radians_to_degrees(acos((p4 - p3) / p2)) = xmm3
206 subsd xmm3, xmm2 ; p4 - p3
207 divsd xmm3, xmm1 ; / p2
208 ACOS xmm3
209 mulsd xmm3, [to_deg] ; xmm3 = p5
211 ;T = p1 * p5 = xmm3
212 mulsd xmm3, [p1]
214 ;fajr = duhr - T = xmm3
215 movsd xmm4, xmm3
216 movsd xmm3, xmm0
217 subsd xmm3, xmm4
219 test_fajr:
220 mulsd xmm3, [sec_inhour] ;convert to seconds
221 roundsd xmm3, xmm3, ROUND_DOWN
222 addsd xmm3, xmm15 ;fajr seconds + start_of_day
223 ucomisd xmm3, xmm6 ;if fajr > tstamp
224 jae print_fajr
225 jmp test_duhr
227 test_duhr:
228 mulsd xmm0, [sec_inhour] ;convert to seconds
229 roundsd xmm0, xmm0, ROUND_DOWN
230 addsd xmm0, xmm15 ;duhr seconds + start_of_day
231 ucomisd xmm0, xmm6 ;if duhr > tstamp
232 jae print_duhr
233 jmp get_asr
235 print_fajr:
236 mov [res_msg], byte 'F'
237 CALC_DIFF xmm3
238 PRINT_EXIT
240 print_duhr:
241 mov [res_msg], byte 'D'
242 CALC_DIFF xmm0
243 PRINT_EXIT
245 get_asr:
246 PRINT_EXIT
248 ; duhr: ; xmm0
249 ; p2: ; xmm1
250 ; p3: ; xmm2
251 ; fajr: ; xmm3
252 ; tstamp: ; xmm6
253 ; EqT: ; xmm9
254 ; D: ; xmm8
255 ; result_hour ; r8
256 ; result_min ; r9
257 ; start_of_day: ; xmm15
259 EEXIT EXIT_SUCCESS