123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542 |
- #ifndef __INC_LIB8TION_SCALE_H
- #define __INC_LIB8TION_SCALE_H
- LIB8STATIC_ALWAYS_INLINE uint8_t scale8( uint8_t i, fract8 scale)
- {
- #if SCALE8_C == 1
- #if (FASTLED_SCALE8_FIXED == 1)
- return (((uint16_t)i) * (1+(uint16_t)(scale))) >> 8;
- #else
- return ((uint16_t)i * (uint16_t)(scale) ) >> 8;
- #endif
- #elif SCALE8_AVRASM == 1
- #if defined(LIB8_ATTINY)
- #if (FASTLED_SCALE8_FIXED == 1)
- uint8_t work=i;
- #else
- uint8_t work=0;
- #endif
- uint8_t cnt=0x80;
- asm volatile(
- #if (FASTLED_SCALE8_FIXED == 1)
- " inc %[scale] \n\t"
- " breq DONE_%= \n\t"
- " clr %[work] \n\t"
- #endif
- "LOOP_%=: \n\t"
-
- " sbrc %[scale], 0 \n\t"
- " add %[work], %[i] \n\t"
- " ror %[work] \n\t"
- " lsr %[scale] \n\t"
- " lsr %[cnt] \n\t"
- "brcc LOOP_%= \n\t"
- "DONE_%=: \n\t"
- : [work] "+r" (work), [cnt] "+r" (cnt)
- : [scale] "r" (scale), [i] "r" (i)
- :
- );
- return work;
- #else
- asm volatile(
- #if (FASTLED_SCALE8_FIXED==1)
-
- "mul %0, %1 \n\t"
-
- "add r0, %0 \n\t"
-
- "ldi %0, 0x00 \n\t"
-
- "adc %0, r1 \n\t"
- #else
-
- "mul %0, %1 \n\t"
-
- "mov %0, r1 \n\t"
-
- #endif
- "clr __zero_reg__ \n\t"
- : "+a" (i)
- : "a" (scale)
- : "r0", "r1" );
-
- return i;
- #endif
- #else
- #error "No implementation for scale8 available."
- #endif
- }
- LIB8STATIC_ALWAYS_INLINE uint8_t scale8_video( uint8_t i, fract8 scale)
- {
- #if SCALE8_C == 1 || defined(LIB8_ATTINY)
- uint8_t j = (((int)i * (int)scale) >> 8) + ((i&&scale)?1:0);
-
-
- return j;
- #elif SCALE8_AVRASM == 1
- uint8_t j=0;
- asm volatile(
- " tst %[i]\n\t"
- " breq L_%=\n\t"
- " mul %[i], %[scale]\n\t"
- " mov %[j], r1\n\t"
- " clr __zero_reg__\n\t"
- " cpse %[scale], r1\n\t"
- " subi %[j], 0xFF\n\t"
- "L_%=: \n\t"
- : [j] "+a" (j)
- : [i] "a" (i), [scale] "a" (scale)
- : "r0", "r1");
- return j;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #else
- #error "No implementation for scale8_video available."
- #endif
- }
- LIB8STATIC_ALWAYS_INLINE uint8_t scale8_LEAVING_R1_DIRTY( uint8_t i, fract8 scale)
- {
- #if SCALE8_C == 1
- #if (FASTLED_SCALE8_FIXED == 1)
- return (((uint16_t)i) * ((uint16_t)(scale)+1)) >> 8;
- #else
- return ((int)i * (int)(scale) ) >> 8;
- #endif
- #elif SCALE8_AVRASM == 1
- asm volatile(
- #if (FASTLED_SCALE8_FIXED==1)
-
- "mul %0, %1 \n\t"
-
- "add r0, %0 \n\t"
-
- "ldi %0, 0x00 \n\t"
-
- "adc %0, r1 \n\t"
- #else
-
- "mul %0, %1 \n\t"
-
- "mov %0, r1 \n\t"
- #endif
-
-
- : "+a" (i)
- : "a" (scale)
- : "r0", "r1" );
-
- return i;
- #else
- #error "No implementation for scale8_LEAVING_R1_DIRTY available."
- #endif
- }
- LIB8STATIC_ALWAYS_INLINE uint8_t scale8_video_LEAVING_R1_DIRTY( uint8_t i, fract8 scale)
- {
- #if SCALE8_C == 1 || defined(LIB8_ATTINY)
- uint8_t j = (((int)i * (int)scale) >> 8) + ((i&&scale)?1:0);
-
-
- return j;
- #elif SCALE8_AVRASM == 1
- uint8_t j=0;
- asm volatile(
- " tst %[i]\n\t"
- " breq L_%=\n\t"
- " mul %[i], %[scale]\n\t"
- " mov %[j], r1\n\t"
- " breq L_%=\n\t"
- " subi %[j], 0xFF\n\t"
- "L_%=: \n\t"
- : [j] "+a" (j)
- : [i] "a" (i), [scale] "a" (scale)
- : "r0", "r1");
- return j;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #else
- #error "No implementation for scale8_video_LEAVING_R1_DIRTY available."
- #endif
- }
- LIB8STATIC_ALWAYS_INLINE void cleanup_R1(void)
- {
- #if CLEANUP_R1_AVRASM == 1
-
- asm volatile( "clr __zero_reg__ \n\t" : : : "r1" );
- #endif
- }
- LIB8STATIC_ALWAYS_INLINE uint16_t scale16by8( uint16_t i, fract8 scale )
- {
- #if SCALE16BY8_C == 1
- uint16_t result;
- #if FASTLED_SCALE8_FIXED == 1
- result = (i * (1+((uint16_t)scale))) >> 8;
- #else
- result = (i * scale) / 256;
- #endif
- return result;
- #elif SCALE16BY8_AVRASM == 1
- #if FASTLED_SCALE8_FIXED == 1
- uint16_t result = 0;
- asm volatile(
-
- " mul %A[i], %[scale] \n\t"
- " add r0, %A[i] \n\t"
-
-
- " adc %A[result], r1 \n\t"
-
- " mul %B[i], %[scale] \n\t"
- " add %A[result], r0 \n\t"
- " adc %B[result], r1 \n\t"
-
- " clr __zero_reg__ \n\t"
-
- " add %A[result], %B[i] \n\t"
- " adc %B[result], __zero_reg__ \n\t"
- : [result] "+r" (result)
- : [i] "r" (i), [scale] "r" (scale)
- : "r0", "r1"
- );
- return result;
- #else
- uint16_t result = 0;
- asm volatile(
-
- " mul %A[i], %[scale] \n\t"
- " mov %A[result], r1 \n\t"
-
-
- " mul %B[i], %[scale] \n\t"
- " add %A[result], r0 \n\t"
- " adc %B[result], r1 \n\t"
-
- " clr __zero_reg__ \n\t"
- : [result] "+r" (result)
- : [i] "r" (i), [scale] "r" (scale)
- : "r0", "r1"
- );
- return result;
- #endif
- #else
- #error "No implementation for scale16by8 available."
- #endif
- }
- LIB8STATIC uint16_t scale16( uint16_t i, fract16 scale )
- {
- #if SCALE16_C == 1
- uint16_t result;
- #if FASTLED_SCALE8_FIXED == 1
- result = ((uint32_t)(i) * (1+(uint32_t)(scale))) / 65536;
- #else
- result = ((uint32_t)(i) * (uint32_t)(scale)) / 65536;
- #endif
- return result;
- #elif SCALE16_AVRASM == 1
- #if FASTLED_SCALE8_FIXED == 1
-
-
-
-
-
-
-
- uint32_t result;
- asm volatile(
-
- " mul %A[i], %A[scale] \n\t"
-
-
-
-
-
- " movw %A[result], r0 \n\t"
-
-
-
-
-
- : [result] "=r" (result)
- : [i] "r" (i),
- [scale] "r" (scale)
- : "r0", "r1"
- );
- asm volatile(
-
- " mul %B[i], %B[scale] \n\t"
-
-
- " movw %C[result], r0 \n\t"
- : [result] "+r" (result)
- : [i] "r" (i),
- [scale] "r" (scale)
- : "r0", "r1"
- );
- const uint8_t zero = 0;
- asm volatile(
-
- " mul %B[i], %A[scale] \n\t"
- " add %B[result], r0 \n\t"
- " adc %C[result], r1 \n\t"
- " adc %D[result], %[zero] \n\t"
-
- " mul %A[i], %B[scale] \n\t"
- " add %B[result], r0 \n\t"
- " adc %C[result], r1 \n\t"
- " adc %D[result], %[zero] \n\t"
-
- " clr r1 \n\t"
- : [result] "+r" (result)
- : [i] "r" (i),
- [scale] "r" (scale),
- [zero] "r" (zero)
- : "r0", "r1"
- );
- asm volatile(
-
- " add %A[result], %A[i] \n\t"
- " adc %B[result], %B[i] \n\t"
- " adc %C[result], %[zero] \n\t"
- " adc %D[result], %[zero] \n\t"
- : [result] "+r" (result)
- : [i] "r" (i),
- [zero] "r" (zero)
- );
- result = result >> 16;
- return result;
- #else
- uint32_t result;
- asm volatile(
-
- " mul %A[i], %A[scale] \n\t"
-
-
-
-
-
- " movw %A[result], r0 \n\t"
-
-
-
-
-
-
- : [result] "=r" (result)
- : [i] "r" (i),
- [scale] "r" (scale)
- : "r0", "r1"
- );
- asm volatile(
-
- " mul %B[i], %B[scale] \n\t"
-
-
- " movw %C[result], r0 \n\t"
- : [result] "+r" (result)
- : [i] "r" (i),
- [scale] "r" (scale)
- : "r0", "r1"
- );
- const uint8_t zero = 0;
- asm volatile(
-
- " mul %B[i], %A[scale] \n\t"
- " add %B[result], r0 \n\t"
- " adc %C[result], r1 \n\t"
- " adc %D[result], %[zero] \n\t"
-
- " mul %A[i], %B[scale] \n\t"
- " add %B[result], r0 \n\t"
- " adc %C[result], r1 \n\t"
- " adc %D[result], %[zero] \n\t"
-
- " clr r1 \n\t"
- : [result] "+r" (result)
- : [i] "r" (i),
- [scale] "r" (scale),
- [zero] "r" (zero)
- : "r0", "r1"
- );
- result = result >> 16;
- return result;
- #endif
- #else
- #error "No implementation for scale16 available."
- #endif
- }
- LIB8STATIC uint8_t dim8_raw( uint8_t x)
- {
- return scale8( x, x);
- }
- LIB8STATIC uint8_t dim8_video( uint8_t x)
- {
- return scale8_video( x, x);
- }
- LIB8STATIC uint8_t dim8_lin( uint8_t x )
- {
- if( x & 0x80 ) {
- x = scale8( x, x);
- } else {
- x += 1;
- x /= 2;
- }
- return x;
- }
- LIB8STATIC uint8_t brighten8_raw( uint8_t x)
- {
- uint8_t ix = 255 - x;
- return 255 - scale8( ix, ix);
- }
- LIB8STATIC uint8_t brighten8_video( uint8_t x)
- {
- uint8_t ix = 255 - x;
- return 255 - scale8_video( ix, ix);
- }
- LIB8STATIC uint8_t brighten8_lin( uint8_t x )
- {
- uint8_t ix = 255 - x;
- if( ix & 0x80 ) {
- ix = scale8( ix, ix);
- } else {
- ix += 1;
- ix /= 2;
- }
- return 255 - ix;
- }
- #endif
|