From 393f31cc43cd9dff55a92e615ca52209b79944ac Mon Sep 17 00:00:00 2001 From: Jens Arnold Date: Tue, 18 Jul 2006 00:04:43 +0000 Subject: 1bit and 2bit LCD drivers: Low-level bit handling optimisations. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10225 a1c6a512-1295-4272-9138-f99709370657 --- firmware/drivers/lcd-h100.c | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) (limited to 'firmware/drivers/lcd-h100.c') 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 ***/ -- cgit v1.2.3