From 5dcc4553ccc2f3fba6e9bde4acb1be0fa75763fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juhani=20Krekel=C3=A4?= Date: Fri, 11 Mar 2022 20:48:00 +0200 Subject: [PATCH] Add line drawing functions --- dosclock.asm | 214 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 204 insertions(+), 10 deletions(-) diff --git a/dosclock.asm b/dosclock.asm index 55b3255..1617f60 100644 --- a/dosclock.asm +++ b/dosclock.asm @@ -51,18 +51,33 @@ 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] - mul word [six] - mov bx, ax - mov ax, [width] - shr ax, 1 - shr ax, 1 - call sinx + mov [line_ey], ax + call draw_line - mov bp, [width] - shr bp, 1 - mov bp, ax - mov byte [es:bp], 7 + 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 + + 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 + + mov word [line_sx], 80 + mov word [line_sy], 60 + mov word [line_ex], 20 + mov ax, [second] + mov [line_ey], ax + call draw_line .unchanged: hlt @@ -89,6 +104,177 @@ clear_screen: pop bp ret +; in: +; [line_sx], [line_sy] = starting point +; [line_ex], [line_ey] = ending point +; clobbers: +; [line_sx], [line_sy], [line_ex], [line_ey] +draw_line: + ; Bresenham's line algorithm + push ax + push cx + push dx + push bp + + mov ax, [line_sy] + mul word [width] + mov bp, ax + add bp, [line_sx] + + ; dx = ex - sx + mov dx, [line_ex] + sub dx, [line_sx] + mov [line_dx], dx + + ; dy = ey - sy + mov ax, [line_ey] + sub ax, [line_sy] + mov [line_dy], ax + + .abs_dx: + cmp dx, 0 + jge .abs_dy + neg dx + + .abs_dy: + cmp ax, 0 + jge .abs_done + neg ax + + .abs_done: + + cmp ax, dx + ja draw_line_high ; dy > dx + +draw_line_low: + mov ax, [line_sx] + cmp ax, [line_ex] + ja draw_line_swap_start_end + + cmp word [line_dy], 0 + jl .negative_dy + + .positive_dy: + mov dx, [width] + jmp .y_adjust_done + + .negative_dy: + mov ax, [line_dy] + neg ax + mov [line_dy], ax + xor dx, dx + sub dx, [width] + + .y_adjust_done + + ; errorterm = 2·dy - dx + mov ax, [line_dy] + add ax, [line_dy] + sub ax, [line_dx] + + mov cx, [line_dx] + test cx, cx + jz draw_line_end + + .loop: + mov byte [es:bp], 7 + + cmp ax, 0 + jle .no_y_adjust + + ; errorterm -= 2·dx + sub ax, [line_dx] + sub ax, [line_dx] + + ; y += y_adjust + add bp, dx + + .no_y_adjust: + ; errorterm += 2·dy + add ax, [line_dy] + add ax, [line_dy] + + ; x += 1 + inc bp + + loop .loop + + jmp draw_line_end + +draw_line_high: + mov ax, [line_sy] + cmp ax, [line_ey] + ja draw_line_swap_start_end + + cmp word [line_dx], 0 + jl .negative_dx + + .positive_dx: + mov dx, 1 + jmp .x_adjust_done + + .negative_dx: + mov ax, [line_dx] + neg ax + mov [line_dx], ax + mov dx, -1 + + .x_adjust_done + + ; errorterm = 2·dx - dy + mov ax, [line_dx] + add ax, [line_dx] + sub ax, [line_dy] + + mov cx, [line_dy] + test cx, cx + jz draw_line_end + + .loop: + mov byte [es:bp], 7 + + cmp ax, 0 + jle .no_x_adjust + + ; errorterm -= 2·dy + sub ax, [line_dy] + sub ax, [line_dy] + + ; x += x_adjust + add bp, dx + + .no_x_adjust: + ; errorterm += 2·dx + add ax, [line_dx] + add ax, [line_dx] + + ; y += 1 + add bp, [width] + + loop .loop + +draw_line_end: + pop bp + pop dx + pop cx + pop ax + + ret + +draw_line_swap_start_end: + mov ax, [line_sx] + mov dx, [line_sy] + xchg ax, [line_ex] + xchg dx, [line_ey] + mov [line_sx], ax + mov [line_sy], dx + + pop bp + pop dx + pop cx + pop ax + jmp draw_line + ; in: ; ax = scale ; bx = angle @@ -268,4 +454,12 @@ hour dw 0 minute dw 0 second dw 0 +line_sx dw 0 +line_sy dw 0 +line_ex dw 0 +line_ey dw 0 + +line_dx dw 0 +line_dy dw 0 + original_video_mode db 0