[fix] use config.def.s as default configuration
[azan.git] / azan-nasm.s
blobbbfa25e66105ec14ec0d6277fd1ad7a49fbf472f
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 86400.0
13 jul1970: dq 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 asin_1: dq 0x3FF0000000000000 ;double 1
27 eqt_1: dq 0x4076800000000000 ;double 360.0
28 duhr_1: dq 0x4028000000000000 ;double 12.0
29 pray_1: dq 0x4038000000000000 ;double 24.0
30 neg1: dq 0xBFF0000000000000 ;double -1.0
31 one: dq 0x3FF0000000000000 ;double 1
32 p1: dq 0X3fb1111111111111 ;double 0.066666666666666666
33 hours_to_sec: dq 0x40ac200000000000 ;double 3600
35 section .bss
37 tstamp: resb 12
38 julian: resq 1
39 g: resq 1
40 g2: resq 1
41 sing: resq 1
42 sin2g: resq 1
43 sine: resq 1
44 cose: resq 1
45 sinL: resq 1
46 cosL: resq 1
47 RA_2: resq 1
48 asin_x: resq 1
49 x: resq 1
51 section .text
52 global _start
54 _start:
55 get_timestamp:
56 mov rax, SYS_gettimeofday ;sys_gettimeofday(
57 mov rdi, tstamp ;struct timeval *tv,
58 mov rsi, rsi ;struct timezone* tz
59 syscall
61 ; start_of_day: ; = tstamp - (tstamp % 86400);
62 mov edi, [tstamp]
63 movsx rax, edi
64 mov edx, edi
65 imul rax, rax, -1037155065
66 sar edx, 31
67 shr rax, 32
68 add eax, edi
69 sar eax, 16
70 sub eax, edx
71 imul edx, eax, 86400
72 mov eax, edi
73 sub eax, edx
74 cvtsi2sd xmm15, rdx
75 movsd xmm14, [time_zone]
76 mulsd xmm14, [hours_to_sec]
77 subsd xmm15, xmm14
79 ; calc_julian:;(tstamp / sec_inday) + jul1970
80 cvtsi2sd xmm0, [tstamp] ;convert tstamp to double
81 divsd xmm0, [sec_inday] ;tstamp / sec_inday
82 addsd xmm0, [jul1970] ;div result + jul1970
83 ; xmm0 = julian
85 ; calc_equation_of_time:
86 addsd xmm0, [offset] ;d = julian - offset
87 ; xmm0 = d
89 movsd xmm2, [to_rad]
90 movsd xmm1, [g_1] ;g = to_rad * ((d * 0.98560028) + 357.529)
91 mulsd xmm1, xmm0
92 addsd xmm1, [g_2]
93 mulsd xmm1, xmm2
94 ; xmm1 = g
95 ; xmm2 = to_rad
97 movsd xmm3, [e_3] ;e = to_rad * (23.439 - (d * 0.00000036))
98 mulsd xmm3, xmm0
99 addsd xmm3, [e_4]
100 mulsd xmm3, xmm2
101 ; xmm3 = e
103 movsd xmm4, [q_5] ;q = (d * 0.98564736) + 280.459
104 mulsd xmm4, xmm0
105 addsd xmm4, [q_6]
106 ; xmm4 = q
108 ; sing: ;sing = 1.915 * sin(g);
109 movsd xmm5, [sing_1]
110 finit
111 movsd [g], xmm1
112 fld qword [g]
113 fsin
114 fstp qword [sing]
115 mulsd xmm5, [sing]
116 ; xmm5 = sing
118 ; sin2g: ;sin2g = 0.020 * sin(2.0*g)
119 movsd xmm6, [sing_2]
120 addsd xmm1, xmm1
121 movsd [g2], xmm1
122 fld qword [g2]
123 fsin
124 fstp qword [sin2g]
125 mulsd xmm6, [sin2g]
126 ; xmm1 = 2 * g
127 ; xmm6 = sin2g
129 ; sine: ;sin(e)
130 movsd [sine], xmm3
131 fld qword [sine]
132 fsin
133 fstp qword [sine]
135 ; cose: ;cos(e)
136 movsd [cose], xmm3
137 fld qword [cose]
138 fcos
139 fstp qword [cose]
141 ; L: ;L = to_rad(q + sing + sin2g);
142 addsd xmm5, xmm6 ;sing + sin2g
143 addsd xmm5, xmm4 ;+ q
144 mulsd xmm5, xmm2 ;* to_rad
145 ; xmm5 = L
147 ; sinL: ;sin(L)
148 movsd [sinL], xmm5
149 fld qword [sinL]
150 fsin
151 fstp qword [sinL]
153 ; cosL: ;cos(L)
154 movsd [cosL], xmm5
155 fld qword [cosL]
156 fcos
157 fstp qword [cosL]
159 ; RA: ;RA = to_deg(atan2(cose * sinL, cosL) / 15.0);
160 movsd xmm7, [cose]
161 mulsd xmm7, [sinL]
162 movsd [cose], xmm7
163 fld qword [cose] ;load cose
164 fld qword [cosL] ;load cosL
165 fpatan ;calc atan2 (cose / cosL)
166 fstp qword [RA_2] ;save angle
167 movsd xmm7, [RA_2]
168 divsd xmm7, [RA_1] ;atan2 result /15.0
169 mulsd xmm7, [to_deg] ;* to_deg
170 ; xmm7 = RA
172 ; D: ;D = to_deg(asin(sine * sinL));
173 ; asin = arctan(x / sqrt(1 - x * x))
174 movsd xmm8, [sine]
175 mulsd xmm8, [sinL]
176 movsd [asin_x], xmm8
177 ; xmm8 = x
179 movsd xmm9, xmm8 ; xmm8 = x
180 mulsd xmm9, xmm8 ; xmm9 = x * x
181 movsd xmm10, [asin_1] ; xmm10 = 1
182 subsd xmm10, xmm9 ; 1 - xmm9
183 movsd [asin_1], xmm10 ; asin_1 = (1-x*x)
184 movsd [asin_x], xmm8 ; asin_1 = (1-x*x)
185 ; xmm9 = x * x
186 ; xmm10 = 1 - xmm9
188 fld qword [asin_x]
189 fld qword [asin_1]
190 fsqrt
191 fpatan
192 fstp qword [asin_1]
193 movsd xmm8, [asin_1]
194 mulsd xmm8, [to_deg]
195 ; xmm8 = D
197 ; Eqt ;EqT = q / 15.0 - RA;
198 movsd xmm9, xmm4 ; move q to xmm9
199 divsd xmm9, [RA_1] ; q / 15.0
200 subsd xmm9, xmm7 ; - RA
201 ; xmm9 = EqT
202 ; EqT = EqT - 360.0
203 subsd xmm9, [eqt_1]
204 ;xmm8 = D
205 ;xmm9 = EqT
207 ; get_duhr: duhr = 12.0 + time_zone - EqT - (longitude / 15.0);
208 ; xmm0 - (pray_1 * floor(xmm1 / pray_1));
209 movsd xmm1, [longitude]
210 divsd xmm1, [RA_1]
211 movsd xmm0, [duhr_1]
212 addsd xmm0, [time_zone]
213 subsd xmm0, xmm9
214 subsd xmm0, xmm1
216 ; normalize duhr
217 movsd xmm1, xmm0
218 divsd xmm1, [pray_1]
219 roundsd xmm1, xmm1, ROUND_DOWN ;floor(xmm1)
220 mulsd xmm1, [pray_1]
221 subsd xmm0, xmm1
222 ;xmm0 = duhr
224 ; get_fajr:; fajr = duhr - T(fajr_angle, D);
226 ; p2 = cos(convert_degrees_to_radians(latitude)) *
227 ; cos(convert_degrees_to_radians(D));
228 movsd xmm1, [latitude]
229 mulsd xmm1, [to_rad]
230 movsd [x], xmm1
231 fld qword [x]
232 fcos
233 fstp qword [x]
234 movsd xmm1, [x]
236 movsd xmm2, xmm8,
237 mulsd xmm2, [to_rad]
238 movsd [x], xmm2
239 fld qword [x]
240 fcos
241 fstp qword [x]
242 movsd xmm2, [x]
243 mulsd xmm1, xmm2
244 ;xmm1 = p2
246 ; p3 = sin(convert_degrees_to_radians(latitude)) *
247 ; sin(convert_degrees_to_radians(D));
248 movsd xmm2, [latitude]
249 mulsd xmm2, [to_rad]
250 movsd [sine], xmm2
251 fld qword [sine]
252 fsin
253 fstp qword [sine]
254 movsd xmm2, [sine]
256 movsd xmm3, xmm8, ; xmm8 = D
257 mulsd xmm3, [to_rad]
258 movsd [sine], xmm3
259 fld qword [sine]
260 fsin
261 fstp qword [sine]
262 movsd xmm3, [sine]
263 mulsd xmm2, xmm3
264 ;xmm2 = p3
266 ; p4 = -1.0 * sin(convert_degrees_to_radians(alpha));
267 movsd xmm3, [fajr_angle]
268 mulsd xmm3, [to_rad]
269 movsd [sine], xmm3
270 fld qword [sine]
271 fsin
272 fstp qword [sine]
273 movsd xmm3, [sine]
274 mulsd xmm3, [neg1]
276 ; p5 = convert_radians_to_degrees(acos((p4 - p3) / p2));
277 subsd xmm3, xmm2 ; p4 - p3
278 divsd xmm3, xmm1 ; / p2
279 movsd [x], xmm3
280 ACOS [x]
281 movsd xmm3, [x]
282 mulsd xmm3, [to_deg] ; xmm3 = p5
283 mulsd xmm3, [p1] ; xmm3 = T
285 movsd xmm4, xmm3
286 movsd xmm3, xmm0 ; xmm3 = duhr
287 subsd xmm3, xmm4 ; xmm3 = duhr - T
289 ; convert_fajr_to_sec:
290 mulsd xmm3, [hours_to_sec] ; convert to seconds
291 roundsd xmm3, xmm3, ROUND_DOWN ;floor(xmm1)
292 addsd xmm3, xmm15
294 ; duhr: ; xmm0
295 ; p2: ; xmm1
296 ; p3: ; xmm2
297 ; fajr: ; xmm3
298 ; EqT: ; xmm9
299 ; D: ; xmm8
300 ; start_of_day: ; xmm15
302 EEXIT EXIT_SUCCESS