From ceef5953578b92affcd54fdcf4a94c193f117afe Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Fri, 21 Apr 2017 18:46:29 -0400 Subject: [PATCH 1/3] Fix buffer underflow in drawPlusMask When sRow == -1 drawPlusMask can cause buffer underflow if it's interrupted by an interrupt that changes memory that it's in the middle of writing. Of course it shouldn't be writing to this memory at all. This fixes the issue. --- src/Sprites.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Sprites.cpp b/src/Sprites.cpp index 49a4ee0..e8a3439 100644 --- a/src/Sprites.cpp +++ b/src/Sprites.cpp @@ -285,19 +285,23 @@ void Sprites::drawBitmap(int16_t x, int16_t y, // FIRST PAGE - "ld %[data], %a[buffer_ofs]\n" // if sRow >= 0 "tst %[sRow]\n" - "brmi end_first_page\n" + "brmi skip_first_page\n" + "ld %[data], %a[buffer_ofs]\n" // then "com %A[mask_data]\n" "and %[data], %A[mask_data]\n" "or %[data], %A[bitmap_data]\n" - - "end_first_page:\n" // update buffer, increment "st %a[buffer_ofs]+, %[data]\n" + "jmp end_first_page\n" + "skip_first_page:\n" + // since no ST Z+ when skipped we need to do this manually + "adiw %[buffer_ofs], 1\n" + + "end_first_page:\n" // "x_loop_next:\n" "dec %[xi]\n" From 5fe9488b10c62d86d2c0ef8c3e62867f3bdcdd31 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Fri, 21 Apr 2017 20:11:18 -0400 Subject: [PATCH 2/3] tmp variables can be flagged as output only - this saves a few bytes --- src/Sprites.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Sprites.cpp b/src/Sprites.cpp index e8a3439..545a8a9 100644 --- a/src/Sprites.cpp +++ b/src/Sprites.cpp @@ -334,9 +334,9 @@ void Sprites::drawBitmap(int16_t x, int16_t y, : [xi] "+&r" (xi), [yi] "+&r" (yi), [sRow] "+&d" (sRow), // CPI requires an upper register - [data] "+&r" (data), - [mask_data] "+&r" (mask_data), - [bitmap_data] "+&r" (bitmap_data) + [data] "=&r" (data), + [mask_data] "=&r" (mask_data), + [bitmap_data] "=&r" (bitmap_data) : [x_count] "r" (rendered_width), [y_count] "r" (loop_h), From e307cdc725b385bf98e97f9c3826c9a5fe0492ed Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Fri, 21 Apr 2017 20:13:31 -0400 Subject: [PATCH 3/3] fix register pressure - declare a high register clobber This seems to have the side effect of freeing up a high register and preventing the error: "can't find a register in class 'LD_REGS' while reloading 'asm'"" --- src/Sprites.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Sprites.cpp b/src/Sprites.cpp index 545a8a9..0b3dbe2 100644 --- a/src/Sprites.cpp +++ b/src/Sprites.cpp @@ -347,7 +347,10 @@ void Sprites::drawBitmap(int16_t x, int16_t y, [sprite_ofs_jump] "r" ((w-rendered_width)*2), [yOffset] "r" (yOffset), [mul_amt] "r" (mul_amt) - : + // declaring an extra high register clobber here for some reason + // prevents a compile error for some sketches: + // can't find a register in class 'LD_REGS' while reloading 'asm' + : "r24" ); break; }