diff --git a/dosclock.asm b/dosclock.asm index 1617f60..a78fad6 100644 --- a/dosclock.asm +++ b/dosclock.asm @@ -2,6 +2,15 @@ org 0x100 cpu 8086 bits 16 +midpoint_x equ 160 +midpoint_y equ 100 +hour_hand_len equ 50 +hour_hand_color equ 7 +minute_hand_len equ 80 +minute_hand_color equ 7 +second_hand_len equ 75 +second_hand_color equ 4 + section .code setup: @@ -51,33 +60,52 @@ mainloop: mov [minute], cl mov [second], dh - mov word [line_sx], 80 - mov word [line_sy], 0 - mov word [line_ex], 60 - mov ax, [second] - mov [line_ey], ax - call draw_line + mov ax, [hour] - mov word [line_sx], 80 - mov word [line_sy], 60 - mov word [line_ex], 60 - mov ax, [second] - mov [line_ey], ax - call draw_line + ; 12 hour clock face → map 12…23 to 0…11 + cmp ax, 12 + je .under_12 + sub ax, 12 + .under_12: - mov word [line_sx], 80 - mov word [line_sy], 0 - mov word [line_ex], 20 - mov ax, [second] - mov [line_ey], ax - call draw_line + ; 1 hour = 30° rotation of hour hand + mul word [thirty] + mov bx, ax - mov word [line_sx], 80 - mov word [line_sy], 60 - mov word [line_ex], 20 + ; 2 minutes = 1° rotation of hour hand + mov ax, [minute] + shr ax, 1 + add bx, ax + + ; Draw hour hand + mov ax, hour_hand_len + mov cl, hour_hand_color + call draw_hand + + ; 1 minute = 5° rotation of minute hand + mov ax, [minute] + mul word [six] + mov bx, ax + + ; 12 seconds = 1° rotation of minute hand mov ax, [second] - mov [line_ey], ax - call draw_line + div word [twelve] + add bx, ax + + ; Draw minute hand + mov ax, minute_hand_len + mov cl, minute_hand_color + call draw_hand + + ; 1 second = 5° rotation of second hand + mov ax, [second] + mul word [six] + mov bx, ax + + ; Draw second hand + mov ax, second_hand_len + mov cl, second_hand_color + call draw_hand .unchanged: hlt @@ -104,9 +132,40 @@ clear_screen: pop bp ret +; in: +; ax = hand length +; bx = hand angle +; cl = hand color +draw_hand: + push ax + push bx + push dx + + mov word [line_sx], midpoint_x + mov word [line_sy], midpoint_y + mov word [line_ex], midpoint_x + mov word [line_ey], midpoint_y + + mov dx, ax + call sinx + add [line_ex], ax + + mov ax, dx + call cosx + sub [line_ey], ax + + mov bl, cl + call draw_line + + pop dx + pop bx + pop ax + ret + ; in: ; [line_sx], [line_sy] = starting point ; [line_ex], [line_ey] = ending point +; bl = color ; clobbers: ; [line_sx], [line_sy], [line_ex], [line_ey] draw_line: @@ -165,7 +224,7 @@ draw_line_low: xor dx, dx sub dx, [width] - .y_adjust_done + .y_adjust_done: ; errorterm = 2·dy - dx mov ax, [line_dy] @@ -177,7 +236,7 @@ draw_line_low: jz draw_line_end .loop: - mov byte [es:bp], 7 + mov byte [es:bp], bl cmp ax, 0 jle .no_y_adjust @@ -219,7 +278,7 @@ draw_line_high: mov [line_dx], ax mov dx, -1 - .x_adjust_done + .x_adjust_done: ; errorterm = 2·dx - dy mov ax, [line_dx] @@ -231,7 +290,7 @@ draw_line_high: jz draw_line_end .loop: - mov byte [es:bp], 7 + mov byte [es:bp], bl cmp ax, 0 jle .no_x_adjust @@ -448,6 +507,8 @@ sin_table: dw 65526 ; sin(89°) six dw 6 +thirty dw 30 +twelve dw 12 section .data hour dw 0