diff --git a/apps/plugins/lib/playergfx.c b/apps/plugins/lib/playergfx.c index d7e1ce26e8..b6e7ccfc64 100644 --- a/apps/plugins/lib/playergfx.c +++ b/apps/plugins/lib/playergfx.c @@ -152,7 +152,10 @@ static void fgblock(unsigned char *address, unsigned mask, unsigned bits) static void solidblock(unsigned char *address, unsigned mask, unsigned bits) { - *address = (*address & ~mask) | (bits & mask); + unsigned data = *(char *)address; + + bits ^= data; + *address = data ^ (bits & mask); } static void flipinvblock(unsigned char *address, unsigned mask, unsigned bits) @@ -172,7 +175,10 @@ static void fginvblock(unsigned char *address, unsigned mask, unsigned bits) static void solidinvblock(unsigned char *address, unsigned mask, unsigned bits) { - *address = (*address & ~mask) | (~bits & mask); + unsigned data = *(char *)address; + + bits = ~bits ^ data; + *address = data ^ (bits & mask); } lcd_blockfunc_type* pgfx_blockfuncs[8] = { diff --git a/firmware/drivers/lcd-2bit-horz.c b/firmware/drivers/lcd-2bit-horz.c index 14bf952bb2..e70df3fb84 100644 --- a/firmware/drivers/lcd-2bit-horz.c +++ b/firmware/drivers/lcd-2bit-horz.c @@ -197,24 +197,29 @@ static void bgblock(unsigned char *address, unsigned mask, unsigned bits) ICODE_ATTR; static void bgblock(unsigned char *address, unsigned mask, unsigned bits) { - mask &= ~bits; - *address = (*address & ~mask) | (bg_pattern & mask); + unsigned data = *address; + + *address = data ^ ((data ^ bg_pattern) & mask & ~bits); } static void fgblock(unsigned char *address, unsigned mask, unsigned bits) ICODE_ATTR; static void fgblock(unsigned char *address, unsigned mask, unsigned bits) { - mask &= bits; - *address = (*address & ~mask) | (fg_pattern & mask); + unsigned data = *address; + + *address = data ^ ((data ^ fg_pattern) & mask & bits); } static void solidblock(unsigned char *address, unsigned mask, unsigned bits) ICODE_ATTR; static void solidblock(unsigned char *address, unsigned mask, unsigned bits) { - *address = (*address & ~mask) | (bits & mask & fg_pattern) - | (~bits & mask & bg_pattern); + unsigned data = *address; + unsigned bgp = bg_pattern; + + bits = bgp ^ ((bgp ^ fg_pattern) & bits); + *address = data ^ ((data ^ bits) & mask); } static void flipinvblock(unsigned char *address, unsigned mask, unsigned bits) @@ -228,24 +233,29 @@ static void bginvblock(unsigned char *address, unsigned mask, unsigned bits) ICODE_ATTR; static void bginvblock(unsigned char *address, unsigned mask, unsigned bits) { - mask &= bits; - *address = (*address & ~mask) | (bg_pattern & mask); + unsigned data = *address; + + *address = data ^ ((data ^ bg_pattern) & mask & bits); } static void fginvblock(unsigned char *address, unsigned mask, unsigned bits) ICODE_ATTR; static void fginvblock(unsigned char *address, unsigned mask, unsigned bits) { - mask &= ~bits; - *address = (*address & ~mask) | (fg_pattern & mask); + unsigned data = *address; + + *address = data ^ ((data ^ fg_pattern) & mask & ~bits); } static void solidinvblock(unsigned char *address, unsigned mask, unsigned bits) ICODE_ATTR; static void solidinvblock(unsigned char *address, unsigned mask, unsigned bits) { - *address = (*address & ~mask) | (~bits & mask & fg_pattern) - | (bits & mask & bg_pattern); + unsigned data = *address; + unsigned fgp = fg_pattern; + + bits = fgp ^ ((fgp ^ bg_pattern) & bits); + *address = data ^ ((data ^ bits) & mask); } lcd_blockfunc_type* const lcd_blockfuncs[8] = { @@ -255,7 +265,10 @@ lcd_blockfunc_type* const lcd_blockfuncs[8] = { static inline void setblock(unsigned char *address, unsigned mask, unsigned bits) { - *address = (*address & ~mask) | (bits & mask); + unsigned data = *address; + + bits ^= data; + *address = data ^ (bits & mask); } /*** drawing functions ***/ diff --git a/firmware/drivers/lcd-h100-remote.c b/firmware/drivers/lcd-h100-remote.c index 4d58db9a56..f7b3c21f48 100644 --- a/firmware/drivers/lcd-h100-remote.c +++ b/firmware/drivers/lcd-h100-remote.c @@ -716,7 +716,10 @@ static void solidblock(unsigned char *address, unsigned mask, unsigned bits) ICODE_ATTR; static void solidblock(unsigned char *address, unsigned mask, unsigned bits) { - *address = (*address & ~mask) | (bits & mask); + unsigned data = *address; + + bits ^= data; + *address = data ^ (bits & mask); } static void flipinvblock(unsigned char *address, unsigned mask, unsigned bits) @@ -744,7 +747,10 @@ static void solidinvblock(unsigned char *address, unsigned mask, unsigned bits) ICODE_ATTR; static void solidinvblock(unsigned char *address, unsigned mask, unsigned bits) { - *address = (*address & ~mask) | (~bits & mask); + unsigned data = *address; + + bits = ~bits ^ data; + *address = data ^ (bits & mask); } lcd_blockfunc_type* const lcd_remote_blockfuncs[8] = { diff --git a/firmware/drivers/lcd-h100.c b/firmware/drivers/lcd-h100.c index 42bf13a888..f460165534 100644 --- a/firmware/drivers/lcd-h100.c +++ b/firmware/drivers/lcd-h100.c @@ -397,24 +397,29 @@ static void bgblock(unsigned char *address, unsigned mask, unsigned bits) ICODE_ATTR; static void bgblock(unsigned char *address, unsigned mask, unsigned bits) { - mask &= ~bits; - *address = (*address & ~mask) | (bg_pattern & mask); + unsigned data = *address; + + *address = data ^ ((data ^ bg_pattern) & mask & ~bits); } static void fgblock(unsigned char *address, unsigned mask, unsigned bits) ICODE_ATTR; static void fgblock(unsigned char *address, unsigned mask, unsigned bits) { - mask &= bits; - *address = (*address & ~mask) | (fg_pattern & mask); + unsigned data = *address; + + *address = data ^ ((data ^ fg_pattern) & mask & bits); } static void solidblock(unsigned char *address, unsigned mask, unsigned bits) ICODE_ATTR; static void solidblock(unsigned char *address, unsigned mask, unsigned bits) { - *address = (*address & ~mask) | (bits & mask & fg_pattern) - | (~bits & mask & bg_pattern); + unsigned data = *address; + unsigned bgp = bg_pattern; + + bits = bgp ^ ((bgp ^ fg_pattern) & bits); + *address = data ^ ((data ^ bits) & mask); } static void flipinvblock(unsigned char *address, unsigned mask, unsigned bits) @@ -428,24 +433,29 @@ static void bginvblock(unsigned char *address, unsigned mask, unsigned bits) ICODE_ATTR; static void bginvblock(unsigned char *address, unsigned mask, unsigned bits) { - mask &= bits; - *address = (*address & ~mask) | (bg_pattern & mask); + unsigned data = *address; + + *address = data ^ ((data ^ bg_pattern) & mask & bits); } static void fginvblock(unsigned char *address, unsigned mask, unsigned bits) ICODE_ATTR; static void fginvblock(unsigned char *address, unsigned mask, unsigned bits) { - mask &= ~bits; - *address = (*address & ~mask) | (fg_pattern & mask); + unsigned data = *address; + + *address = data ^ ((data ^ fg_pattern) & mask & ~bits); } static void solidinvblock(unsigned char *address, unsigned mask, unsigned bits) ICODE_ATTR; static void solidinvblock(unsigned char *address, unsigned mask, unsigned bits) { - *address = (*address & ~mask) | (~bits & mask & fg_pattern) - | (bits & mask & bg_pattern); + unsigned data = *address; + unsigned fgp = fg_pattern; + + bits = fgp ^ ((fgp ^ bg_pattern) & bits); + *address = data ^ ((data ^ bits) & mask); } lcd_blockfunc_type* const lcd_blockfuncs[8] = { @@ -455,7 +465,10 @@ lcd_blockfunc_type* const lcd_blockfuncs[8] = { static inline void setblock(unsigned char *address, unsigned mask, unsigned bits) { - *address = (*address & ~mask) | (bits & mask); + unsigned data = *address; + + bits ^= data; + *address = data ^ (bits & mask); } /*** drawing functions ***/ diff --git a/firmware/drivers/lcd-recorder.c b/firmware/drivers/lcd-recorder.c index d75b989dd2..22bfebe289 100644 --- a/firmware/drivers/lcd-recorder.c +++ b/firmware/drivers/lcd-recorder.c @@ -441,7 +441,10 @@ static void solidblock(unsigned char *address, unsigned mask, unsigned bits) ICODE_ATTR; static void solidblock(unsigned char *address, unsigned mask, unsigned bits) { - *address = (*address & ~mask) | (bits & mask); + unsigned data = *(char*)address; + + bits ^= data; + *address = data ^ (bits & mask); } static void flipinvblock(unsigned char *address, unsigned mask, unsigned bits) @@ -469,7 +472,10 @@ static void solidinvblock(unsigned char *address, unsigned mask, unsigned bits) ICODE_ATTR; static void solidinvblock(unsigned char *address, unsigned mask, unsigned bits) { - *address = (*address & ~mask) | (~bits & mask); + unsigned data = *(char *)address; + + bits = ~bits ^ data; + *address = data ^ (bits & mask); } lcd_blockfunc_type* const lcd_blockfuncs[8] = {