From c7ab5c9d07bce82f9c60a9d9ce97dad43186f89e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juhani=20Krekel=C3=A4?= Date: Fri, 11 Mar 2022 19:42:50 +0200 Subject: [PATCH] Add trigonometric functions --- dosclock.asm | 190 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 180 insertions(+), 10 deletions(-) diff --git a/dosclock.asm b/dosclock.asm index 1d0d8cb..d4a73a3 100644 --- a/dosclock.asm +++ b/dosclock.asm @@ -51,18 +51,18 @@ mainloop: mov [minute], cl mov [second], dh - mov bp, 0 - add bp, [hour] - mov byte [es:bp], 1 + mov ax, [second] + mul word [six] + mov bx, ax + mov ax, [width] + shr ax, 1 + shr ax, 1 + call sinx mov bp, [width] - add bp, [minute] - mov byte [es:bp], 2 - - mov bp, [width] - add bp, [width] - add bp, [second] - mov byte [es:bp], 4 + shr bp, 1 + mov bp, ax + mov byte [es:bp], 7 .unchanged: hlt @@ -89,10 +89,180 @@ clear_screen: pop bp ret +; in: +; ax = scale +; bx = angle +; out: +; ax = scale·cos(angle) +cosx: + push bx + + ; cos(x) = sin(x + 90°) + add bx, 90 + call sinx + + pop bx + ret + +; in: +; ax = scale +; bx = angle +; out: +; ax = scale·sin(angle) +sinx: + push bx + push dx + + .get_in_range: + cmp bx, 360 + jb .in_range + + sub bx, 360 + jmp .get_in_range + + .in_range: + + ; sin(90°) = 1 + .angle_90: + cmp bx, 90 + je .end + + ; Main branch of function 0 ≤ bx < 90 + .q1: + cmp bx, 90 + ja .q2 + + ; Load sin(bx) * 2¹⁶ into bx + shl bx, 1 + mov bx, [sin_table + bx] + ; Compute ax·bx and take high 16 bits, which cancel out the + ; pre-multiplication of the sin_table + mul bx + mov ax, dx + + jmp .end + + ; sin(bx) = sin(180° - bx) for 90 < bx ≤ 180 + .q2: + cmp bx, 180 + ja .q3_q4 + + mov dx, 180 + sub dx, bx + mov bx, dx + call sinx + + jmp .end + + ; sin(bx) = -sin(bx - 180°) for 180 < bx < 360 + .q3_q4: + sub bx, 180 + call sinx + neg ax + + .end: + pop dx + pop bx + ret + section .rodata width dw 320 height dw 200 +sin_table: + dw 0 ; sin(0°) + dw 1143 ; sin(1°) + dw 2287 ; sin(2°) + dw 3429 ; sin(3°) + dw 4571 ; sin(4°) + dw 5711 ; sin(5°) + dw 6850 ; sin(6°) + dw 7986 ; sin(7°) + dw 9120 ; sin(8°) + dw 10252 ; sin(9°) + dw 11380 ; sin(10°) + dw 12504 ; sin(11°) + dw 13625 ; sin(12°) + dw 14742 ; sin(13°) + dw 15854 ; sin(14°) + dw 16961 ; sin(15°) + dw 18064 ; sin(16°) + dw 19160 ; sin(17°) + dw 20251 ; sin(18°) + dw 21336 ; sin(19°) + dw 22414 ; sin(20°) + dw 23486 ; sin(21°) + dw 24550 ; sin(22°) + dw 25606 ; sin(23°) + dw 26655 ; sin(24°) + dw 27696 ; sin(25°) + dw 28729 ; sin(26°) + dw 29752 ; sin(27°) + dw 30767 ; sin(28°) + dw 31772 ; sin(29°) + dw 32767 ; sin(30°) + dw 33753 ; sin(31°) + dw 34728 ; sin(32°) + dw 35693 ; sin(33°) + dw 36647 ; sin(34°) + dw 37589 ; sin(35°) + dw 38521 ; sin(36°) + dw 39440 ; sin(37°) + dw 40347 ; sin(38°) + dw 41243 ; sin(39°) + dw 42125 ; sin(40°) + dw 42995 ; sin(41°) + dw 43852 ; sin(42°) + dw 44695 ; sin(43°) + dw 45525 ; sin(44°) + dw 46340 ; sin(45°) + dw 47142 ; sin(46°) + dw 47929 ; sin(47°) + dw 48702 ; sin(48°) + dw 49460 ; sin(49°) + dw 50203 ; sin(50°) + dw 50931 ; sin(51°) + dw 51643 ; sin(52°) + dw 52339 ; sin(53°) + dw 53019 ; sin(54°) + dw 53683 ; sin(55°) + dw 54331 ; sin(56°) + dw 54963 ; sin(57°) + dw 55577 ; sin(58°) + dw 56175 ; sin(59°) + dw 56755 ; sin(60°) + dw 57319 ; sin(61°) + dw 57864 ; sin(62°) + dw 58393 ; sin(63°) + dw 58903 ; sin(64°) + dw 59395 ; sin(65°) + dw 59870 ; sin(66°) + dw 60326 ; sin(67°) + dw 60763 ; sin(68°) + dw 61183 ; sin(69°) + dw 61583 ; sin(70°) + dw 61965 ; sin(71°) + dw 62328 ; sin(72°) + dw 62672 ; sin(73°) + dw 62997 ; sin(74°) + dw 63302 ; sin(75°) + dw 63589 ; sin(76°) + dw 63856 ; sin(77°) + dw 64103 ; sin(78°) + dw 64331 ; sin(79°) + dw 64540 ; sin(80°) + dw 64729 ; sin(81°) + dw 64898 ; sin(82°) + dw 65047 ; sin(83°) + dw 65176 ; sin(84°) + dw 65286 ; sin(85°) + dw 65376 ; sin(86°) + dw 65446 ; sin(87°) + dw 65496 ; sin(88°) + dw 65526 ; sin(89°) + +six dw 6 + section .data hour dw 0 minute dw 0