From 65eb2edc121a198ac6f02fc691152e4e46b19a08 Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Sat, 3 Apr 2021 21:00:48 +0200 Subject: [PATCH] Added better rounding after division. --- src/main/kc/include/mega65-math.h | 3 +++ src/test/kc/examples/mega65/linedrawing.c | 21 +++++++++++---------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/main/kc/include/mega65-math.h b/src/main/kc/include/mega65-math.h index 5abfad3e3..e2e16d78f 100644 --- a/src/main/kc/include/mega65-math.h +++ b/src/main/kc/include/mega65-math.h @@ -18,6 +18,9 @@ char * const MATH_BUSY = 0xd70f; // $D768-$D76F DIVOUT 64-bit output of MULTINA ÷ MULTINB // $D768-$D76B DIVOUT FRAC 32-bit output of MULTINA ÷ MULTINB signed char volatile * const MATH_DIVOUT_FRAC_CHAR0 = 0xd768; +signed char volatile * const MATH_DIVOUT_FRAC_CHAR1 = 0xd769; +signed char volatile * const MATH_DIVOUT_FRAC_CHAR2 = 0xd76a; +signed char volatile * const MATH_DIVOUT_FRAC_CHAR3 = 0xd76b; signed int volatile * const MATH_DIVOUT_FRAC_INT0 = 0xd768; signed int volatile * const MATH_DIVOUT_FRAC_INT1 = 0xd76a; signed long volatile * const MATH_DIVOUT_FRAC_LONG0 = 0xd768; diff --git a/src/test/kc/examples/mega65/linedrawing.c b/src/test/kc/examples/mega65/linedrawing.c index 3c4a13e36..d70d6c2e3 100644 --- a/src/test/kc/examples/mega65/linedrawing.c +++ b/src/test/kc/examples/mega65/linedrawing.c @@ -216,9 +216,9 @@ void draw_line(int x1, int y1, int x2, int y2, unsigned char colour) { y2 = temp; } - // Use hardware divider to get the slope (add 1/2 to get better rounding ) - *MATH_MULTINA_INT0 = dx*2+1; - *MATH_MULTINB_INT0 = dy*2; + // Use hardware divider to get the slope + *MATH_MULTINA_INT0 = dx; + *MATH_MULTINB_INT0 = dy; *MATH_MULTINA_INT1 = 0; *MATH_MULTINB_INT1 = 0; @@ -229,9 +229,9 @@ void draw_line(int x1, int y1, int x2, int y2, unsigned char colour) { lda MATH_DIVOUT_FRAC_INT1 @nooptimize lda MATH_DIVOUT_FRAC_INT1 @nooptimize } - // Slope is the most significant bytes of the fractional part - // of the division result - unsigned int slope = (unsigned int)*MATH_DIVOUT_FRAC_INT1; + // Slope is the most significant bytes of the fractional part of the division result + // Perform rounding by examining the next bit also + unsigned int slope = (unsigned int)*MATH_DIVOUT_FRAC_INT1 + (((char)*MATH_DIVOUT_FRAC_CHAR1&0x80)?1:0); unsigned int slope_init = 32768; unsigned long addr = GRAPHICS + (unsigned int)(x1/8) * 64 * 25 + (unsigned int)(y1*8) + (unsigned char)(x1&7); unsigned int count = (unsigned int)dy; @@ -249,9 +249,9 @@ void draw_line(int x1, int y1, int x2, int y2, unsigned char colour) { y2 = temp; } - // Use hardware divider to get the slope (add 1/2 to get better rounding ) - *MATH_MULTINA_INT0 = dy*2+1; - *MATH_MULTINB_INT0 = dx*2; + // Use hardware divider to get the slope + *MATH_MULTINA_INT0 = dy; + *MATH_MULTINB_INT0 = dx; *MATH_MULTINA_INT1 = 0; *MATH_MULTINB_INT1 = 0; @@ -264,7 +264,8 @@ void draw_line(int x1, int y1, int x2, int y2, unsigned char colour) { } // Slope is the most significant bytes of the fractional part of the division result - unsigned int slope = (unsigned int)*MATH_DIVOUT_FRAC_INT1; + // Perform rounding by examining the next bit also + unsigned int slope = (unsigned int)*MATH_DIVOUT_FRAC_INT1 + (((char)*MATH_DIVOUT_FRAC_CHAR1&0x80)?1:0); unsigned long addr = GRAPHICS + (unsigned int)(x1/8) * 64 * 25 + (unsigned int)(y1*8) + (unsigned char)(x1&7); unsigned int count = (unsigned int)dx; char is_slope_negative = ((y2 - y1) < 0) ? 1 : 0;