Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FastLED/FastLED.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kriegsman <kriegsman@tr.org>2015-01-03 23:40:52 +0300
committerMark Kriegsman <kriegsman@tr.org>2015-01-03 23:40:52 +0300
commit23f568979b6812a6ea05028806271634f8103c9d (patch)
tree236f4e23e59c3dd02b49c0b066e8dd740669e362
parentd861255d1b354a47e309993447c13408b0c26c9a (diff)
Adding mod8 and addmod8, fast modulo specifically designed for the case where 'i' is already less than 'j'. The addmod8 is designed for easy 'mode' or 'state' switching.
-rw-r--r--lib8tion.h52
1 files changed, 52 insertions, 0 deletions
diff --git a/lib8tion.h b/lib8tion.h
index b6e03ed6..a32e6b49 100644
--- a/lib8tion.h
+++ b/lib8tion.h
@@ -524,6 +524,58 @@ LIB8STATIC int8_t avg7( int8_t i, int8_t j)
#endif
}
+// mod8: Calculate the remainder of one unsigned 8-bit
+// value divided by anoter, aka A % M.
+// Implemented by repeated subtraction, which is
+// very compact, and very fast if A is 'probably'
+// less than M. If A is a large multiple of M,
+// the loop has to execute multiple times. However,
+// even in that case, the loop is only two
+// instructions long on AVR, i.e., quick.
+LIB8STATIC uint8_t mod8( uint8_t a, uint8_t m)
+{
+#if defined(__AVR__)
+ asm volatile (
+ "L_%=: sub %[a],%[m] \n\t"
+ " brcc L_%= \n\t"
+ " add %[a],%[m] \n\t"
+ : [a] "+r" (a)
+ : [m] "r" (m)
+ );
+#else
+ while( a >= m) a -= m;
+#endif
+ return a;
+}
+
+// addmod8: Add two numbers, and calculate the modulo
+// of the sum and a third number, M.
+// In other words, it returns (A+B) % M.
+// It is designed as a compact mechanism for
+// incrementing a 'mode' switch and wrapping
+// around back to 'mode 0' when the switch
+// goes past the end of the available range.
+// e.g. if you have seven modes, this switches
+// to the next one and wraps around if needed:
+// mode = addmod8( mode, 1, 7);
+// See 'mod8' for notes on performance.
+LIB8STATIC uint8_t addmod8( uint8_t a, uint8_t b, uint8_t m)
+{
+#if defined(__AVR__)
+ asm volatile (
+ " add %[a],%[b] \n\t"
+ "L_%=: sub %[a],%[m] \n\t"
+ " brcc L_%= \n\t"
+ " add %[a],%[m] \n\t"
+ : [a] "+r" (a)
+ : [b] "r" (b), [m] "r" (m)
+ );
+#else
+ a += b;
+ while( a >= m) a -= m;
+#endif
+ return a;
+}
// scale8: scale one byte by a second one, which is treated as