|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552 |
- #ifndef __INC_LIB8TION_MATH_H
- #define __INC_LIB8TION_MATH_H
-
- #include "scale8.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- LIB8STATIC_ALWAYS_INLINE uint8_t qadd8( uint8_t i, uint8_t j)
- {
- #if QADD8_C == 1
- unsigned int t = i + j;
- if( t > 255) t = 255;
- return t;
- #elif QADD8_AVRASM == 1
- asm volatile(
-
- "add %0, %1 \n\t"
-
-
-
- "brcc L_%= \n\t"
- "ldi %0, 0xFF \n\t"
- "L_%=: "
- : "+a" (i)
- : "a" (j) );
- return i;
- #elif QADD8_ARM_DSP_ASM == 1
- asm volatile( "uqadd8 %0, %0, %1" : "+r" (i) : "r" (j));
- return i;
- #else
- #error "No implementation for qadd8 available."
- #endif
- }
-
-
-
-
-
- LIB8STATIC_ALWAYS_INLINE int8_t qadd7( int8_t i, int8_t j)
- {
- #if QADD7_C == 1
- int16_t t = i + j;
- if( t > 127) t = 127;
- return t;
- #elif QADD7_AVRASM == 1
- asm volatile(
-
- "add %0, %1 \n\t"
-
-
-
- "brvc L_%= \n\t"
- "ldi %0, 0x7F \n\t"
- "L_%=: "
- : "+a" (i)
- : "a" (j) );
-
- return i;
- #elif QADD7_ARM_DSP_ASM == 1
- asm volatile( "qadd8 %0, %0, %1" : "+r" (i) : "r" (j));
- return i;
- #else
- #error "No implementation for qadd7 available."
- #endif
- }
-
-
-
- LIB8STATIC_ALWAYS_INLINE uint8_t qsub8( uint8_t i, uint8_t j)
- {
- #if QSUB8_C == 1
- int t = i - j;
- if( t < 0) t = 0;
- return t;
- #elif QSUB8_AVRASM == 1
-
- asm volatile(
-
- "sub %0, %1 \n\t"
-
-
-
- "brcc L_%= \n\t"
- "ldi %0, 0x00 \n\t"
- "L_%=: "
- : "+a" (i)
- : "a" (j) );
-
- return i;
- #else
- #error "No implementation for qsub8 available."
- #endif
- }
-
-
- LIB8STATIC_ALWAYS_INLINE uint8_t add8( uint8_t i, uint8_t j)
- {
- #if ADD8_C == 1
- int t = i + j;
- return t;
- #elif ADD8_AVRASM == 1
-
- asm volatile( "add %0, %1" : "+a" (i) : "a" (j));
- return i;
- #else
- #error "No implementation for add8 available."
- #endif
- }
-
-
- LIB8STATIC_ALWAYS_INLINE uint16_t add8to16( uint8_t i, uint16_t j)
- {
- #if ADD8_C == 1
- uint16_t t = i + j;
- return t;
- #elif ADD8_AVRASM == 1
-
- asm volatile( "add %A[j], %[i] \n\t"
- "adc %B[j], __zero_reg__ \n\t"
- : [j] "+a" (j)
- : [i] "a" (i)
- );
- return i;
- #else
- #error "No implementation for add8to16 available."
- #endif
- }
-
-
-
- LIB8STATIC_ALWAYS_INLINE uint8_t sub8( uint8_t i, uint8_t j)
- {
- #if SUB8_C == 1
- int t = i - j;
- return t;
- #elif SUB8_AVRASM == 1
-
- asm volatile( "sub %0, %1" : "+a" (i) : "a" (j));
- return i;
- #else
- #error "No implementation for sub8 available."
- #endif
- }
-
-
-
-
- LIB8STATIC_ALWAYS_INLINE uint8_t avg8( uint8_t i, uint8_t j)
- {
- #if AVG8_C == 1
- return (i + j) >> 1;
- #elif AVG8_AVRASM == 1
- asm volatile(
-
- "add %0, %1 \n\t"
-
- "ror %0 \n\t"
- : "+a" (i)
- : "a" (j) );
- return i;
- #else
- #error "No implementation for avg8 available."
- #endif
- }
-
-
-
-
- LIB8STATIC_ALWAYS_INLINE uint16_t avg16( uint16_t i, uint16_t j)
- {
- #if AVG16_C == 1
- return (uint32_t)((uint32_t)(i) + (uint32_t)(j)) >> 1;
- #elif AVG16_AVRASM == 1
- asm volatile(
-
- "add %A[i], %A[j] \n\t"
-
- "adc %B[i], %B[j] \n\t"
-
- "ror %B[i] \n\t"
-
- "ror %A[i] \n\t"
- : [i] "+a" (i)
- : [j] "a" (j) );
- return i;
- #else
- #error "No implementation for avg16 available."
- #endif
- }
-
-
-
-
-
-
- LIB8STATIC_ALWAYS_INLINE int8_t avg7( int8_t i, int8_t j)
- {
- #if AVG7_C == 1
- return ((i + j) >> 1) + (i & 0x1);
- #elif AVG7_AVRASM == 1
- asm volatile(
- "asr %1 \n\t"
- "asr %0 \n\t"
- "adc %0, %1 \n\t"
- : "+a" (i)
- : "a" (j) );
- return i;
- #else
- #error "No implementation for avg7 available."
- #endif
- }
-
-
-
-
-
- LIB8STATIC_ALWAYS_INLINE int16_t avg15( int16_t i, int16_t j)
- {
- #if AVG15_C == 1
- return ((int32_t)((int32_t)(i) + (int32_t)(j)) >> 1) + (i & 0x1);
- #elif AVG15_AVRASM == 1
- asm volatile(
-
- "asr %B[j] \n\t"
- "ror %A[j] \n\t"
-
- "asr %B[i] \n\t"
- "ror %A[i] \n\t"
-
- "adc %A[i], %A[j] \n\t"
- "adc %B[i], %B[j] \n\t"
- : [i] "+a" (i)
- : [j] "a" (j) );
- return i;
- #else
- #error "No implementation for avg15 available."
- #endif
- }
-
-
-
-
-
-
-
-
-
-
- LIB8STATIC_ALWAYS_INLINE 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;
- }
-
-
-
-
-
-
-
-
-
-
-
-
- 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;
- }
-
-
-
-
-
-
-
-
-
-
-
-
- LIB8STATIC uint8_t submod8( uint8_t a, uint8_t b, uint8_t m)
- {
- #if defined(__AVR__)
- asm volatile (
- " sub %[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;
- }
-
-
- LIB8STATIC_ALWAYS_INLINE uint8_t mul8( uint8_t i, uint8_t j)
- {
- #if MUL8_C == 1
- return ((int)i * (int)(j) ) & 0xFF;
- #elif MUL8_AVRASM == 1
- asm volatile(
-
- "mul %0, %1 \n\t"
-
- "mov %0, r0 \n\t"
-
- "clr __zero_reg__ \n\t"
- : "+a" (i)
- : "a" (j)
- : "r0", "r1");
-
- return i;
- #else
- #error "No implementation for mul8 available."
- #endif
- }
-
-
-
-
- LIB8STATIC_ALWAYS_INLINE uint8_t qmul8( uint8_t i, uint8_t j)
- {
- #if QMUL8_C == 1
- int p = ((int)i * (int)(j) );
- if( p > 255) p = 255;
- return p;
- #elif QMUL8_AVRASM == 1
- asm volatile(
-
- " mul %0, %1 \n\t"
-
- " tst r1 \n\t"
- " breq Lnospill_%= \n\t"
-
- " ldi %0,0xFF \n\t"
- " rjmp Ldone_%= \n\t"
- "Lnospill_%=: \n\t"
-
- " mov %0, r0 \n\t"
- "Ldone_%=: \n\t"
-
- " clr __zero_reg__ \n\t"
- : "+a" (i)
- : "a" (j)
- : "r0", "r1");
-
- return i;
- #else
- #error "No implementation for qmul8 available."
- #endif
- }
-
-
-
- LIB8STATIC_ALWAYS_INLINE int8_t abs8( int8_t i)
- {
- #if ABS8_C == 1
- if( i < 0) i = -i;
- return i;
- #elif ABS8_AVRASM == 1
-
-
- asm volatile(
-
- "sbrc %0, 7 \n"
-
-
- "neg %0 \n"
-
- : "+r" (i) : "r" (i) );
- return i;
- #else
- #error "No implementation for abs8 available."
- #endif
- }
-
-
-
-
- LIB8STATIC uint8_t sqrt16(uint16_t x)
- {
- if( x <= 1) {
- return x;
- }
-
- uint8_t low = 1;
- uint8_t hi, mid;
-
- if( x > 7904) {
- hi = 255;
- } else {
- hi = (x >> 5) + 8;
- }
-
- do {
- mid = (low + hi) >> 1;
- if ((uint16_t)(mid * mid) > x) {
- hi = mid - 1;
- } else {
- if( mid == 255) {
- return 255;
- }
- low = mid + 1;
- }
- } while (hi >= low);
-
- return low - 1;
- }
-
-
-
-
-
-
- #if (FASTLED_BLEND_FIXED == 1)
- LIB8STATIC uint8_t blend8( uint8_t a, uint8_t b, uint8_t amountOfB)
- {
- #if BLEND8_C == 1
- uint16_t partial;
- uint8_t result;
-
- uint8_t amountOfA = 255 - amountOfB;
-
- partial = (a * amountOfA);
- #if (FASTLED_SCALE8_FIXED == 1)
- partial += a;
-
- #endif
-
- partial += (b * amountOfB);
- #if (FASTLED_SCALE8_FIXED == 1)
- partial += b;
-
- #endif
-
- result = partial >> 8;
-
- return result;
-
- #elif BLEND8_AVRASM == 1
- uint16_t partial;
- uint8_t result;
-
- asm volatile (
-
- " mul %[b], %[amountOfB] \n\t"
- " movw %A[partial], r0 \n\t"
-
-
- " com %[amountOfB] \n\t"
-
-
- " mul %[a], %[amountOfB] \n\t"
-
- " add %A[partial], r0 \n\t"
- " adc %B[partial], r1 \n\t"
-
- " clr __zero_reg__ \n\t"
-
- #if (FASTLED_SCALE8_FIXED == 1)
-
- " add %A[partial], %[a] \n\t"
- " adc %B[partial], __zero_reg__ \n\t"
-
-
- " add %A[partial], %[b] \n\t"
- " adc %B[partial], __zero_reg__ \n\t"
- #endif
-
- : [partial] "=r" (partial),
- [amountOfB] "+a" (amountOfB)
- : [a] "a" (a),
- [b] "a" (b)
- : "r0", "r1"
- );
-
- result = partial >> 8;
-
- return result;
-
- #else
- #error "No implementation for blend8 available."
- #endif
- }
-
- #else
- LIB8STATIC uint8_t blend8( uint8_t a, uint8_t b, uint8_t amountOfB)
- {
-
-
-
- uint8_t result;
- uint8_t amountOfA = 255 - amountOfB;
- result = scale8_LEAVING_R1_DIRTY( a, amountOfA)
- + scale8_LEAVING_R1_DIRTY( b, amountOfB);
- cleanup_R1();
- return result;
- }
- #endif
-
-
-
- #endif
|