summaryrefslogtreecommitdiff
path: root/firmware/drivers/lcd-2bit-horz.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/lcd-2bit-horz.c')
-rw-r--r--firmware/drivers/lcd-2bit-horz.c109
1 files changed, 104 insertions, 5 deletions
diff --git a/firmware/drivers/lcd-2bit-horz.c b/firmware/drivers/lcd-2bit-horz.c
index 5ca0426d12..54357433b9 100644
--- a/firmware/drivers/lcd-2bit-horz.c
+++ b/firmware/drivers/lcd-2bit-horz.c
@@ -44,6 +44,9 @@ static const unsigned char pixmask[4] ICONST_ATTR = {
44 0xC0, 0x30, 0x0C, 0x03 44 0xC0, 0x30, 0x0C, 0x03
45}; 45};
46 46
47static fb_data* lcd_backdrop = NULL;
48static long lcd_backdrop_offset IDATA_ATTR = 0;
49
47static unsigned fg_pattern IDATA_ATTR = 0xFF; /* initially black */ 50static unsigned fg_pattern IDATA_ATTR = 0xFF; /* initially black */
48static unsigned bg_pattern IDATA_ATTR = 0x00; /* initially white */ 51static unsigned bg_pattern IDATA_ATTR = 0x00; /* initially white */
49static int drawmode = DRMODE_SOLID; 52static int drawmode = DRMODE_SOLID;
@@ -164,6 +167,15 @@ static void clearpixel(int x, int y)
164 *address = data ^ ((data ^ bg_pattern) & mask); 167 *address = data ^ ((data ^ bg_pattern) & mask);
165} 168}
166 169
170static void clearimgpixel(int x, int y)
171{
172 unsigned mask = pixmask[x & 3];
173 fb_data *address = &lcd_framebuffer[y][x>>2];
174 unsigned data = *address;
175
176 *address = data ^ ((data ^ *(address + lcd_backdrop_offset)) & mask);
177}
178
167static void flippixel(int x, int y) 179static void flippixel(int x, int y)
168{ 180{
169 unsigned mask = pixmask[x & 3]; 181 unsigned mask = pixmask[x & 3];
@@ -178,11 +190,19 @@ static void nopixel(int x, int y)
178 (void)y; 190 (void)y;
179} 191}
180 192
181lcd_pixelfunc_type* const lcd_pixelfuncs[8] = { 193lcd_pixelfunc_type* const lcd_pixelfuncs_bgcolor[8] = {
182 flippixel, nopixel, setpixel, setpixel, 194 flippixel, nopixel, setpixel, setpixel,
183 nopixel, clearpixel, nopixel, clearpixel 195 nopixel, clearpixel, nopixel, clearpixel
184}; 196};
185 197
198lcd_pixelfunc_type* const lcd_pixelfuncs_backdrop[8] = {
199 flippixel, nopixel, setpixel, setpixel,
200 nopixel, clearimgpixel, nopixel, clearimgpixel
201};
202
203lcd_pixelfunc_type* const * lcd_pixelfuncs = lcd_pixelfuncs_bgcolor;
204
205
186/* 'mask' and 'bits' contain 2 bits per pixel */ 206/* 'mask' and 'bits' contain 2 bits per pixel */
187static void flipblock(fb_data *address, unsigned mask, unsigned bits) 207static void flipblock(fb_data *address, unsigned mask, unsigned bits)
188 ICODE_ATTR; 208 ICODE_ATTR;
@@ -200,6 +220,15 @@ static void bgblock(fb_data *address, unsigned mask, unsigned bits)
200 *address = data ^ ((data ^ bg_pattern) & mask & ~bits); 220 *address = data ^ ((data ^ bg_pattern) & mask & ~bits);
201} 221}
202 222
223static void bgimgblock(fb_data *address, unsigned mask, unsigned bits)
224 ICODE_ATTR;
225static void bgimgblock(fb_data *address, unsigned mask, unsigned bits)
226{
227 unsigned data = *address;
228
229 *address = data ^ ((data ^ *(address + lcd_backdrop_offset)) & mask & ~bits);
230}
231
203static void fgblock(fb_data *address, unsigned mask, unsigned bits) 232static void fgblock(fb_data *address, unsigned mask, unsigned bits)
204 ICODE_ATTR; 233 ICODE_ATTR;
205static void fgblock(fb_data *address, unsigned mask, unsigned bits) 234static void fgblock(fb_data *address, unsigned mask, unsigned bits)
@@ -220,6 +249,17 @@ static void solidblock(fb_data *address, unsigned mask, unsigned bits)
220 *address = data ^ ((data ^ bits) & mask); 249 *address = data ^ ((data ^ bits) & mask);
221} 250}
222 251
252static void solidimgblock(fb_data *address, unsigned mask, unsigned bits)
253 ICODE_ATTR;
254static void solidimgblock(fb_data *address, unsigned mask, unsigned bits)
255{
256 unsigned data = *address;
257 unsigned bgp = *(address + lcd_backdrop_offset);
258
259 bits = bgp ^ ((bgp ^ fg_pattern) & bits);
260 *address = data ^ ((data ^ bits) & mask);
261}
262
223static void flipinvblock(fb_data *address, unsigned mask, unsigned bits) 263static void flipinvblock(fb_data *address, unsigned mask, unsigned bits)
224 ICODE_ATTR; 264 ICODE_ATTR;
225static void flipinvblock(fb_data *address, unsigned mask, unsigned bits) 265static void flipinvblock(fb_data *address, unsigned mask, unsigned bits)
@@ -236,6 +276,15 @@ static void bginvblock(fb_data *address, unsigned mask, unsigned bits)
236 *address = data ^ ((data ^ bg_pattern) & mask & bits); 276 *address = data ^ ((data ^ bg_pattern) & mask & bits);
237} 277}
238 278
279static void bgimginvblock(fb_data *address, unsigned mask, unsigned bits)
280 ICODE_ATTR;
281static void bgimginvblock(fb_data *address, unsigned mask, unsigned bits)
282{
283 unsigned data = *address;
284
285 *address = data ^ ((data ^ *(address + lcd_backdrop_offset)) & mask & bits);
286}
287
239static void fginvblock(fb_data *address, unsigned mask, unsigned bits) 288static void fginvblock(fb_data *address, unsigned mask, unsigned bits)
240 ICODE_ATTR; 289 ICODE_ATTR;
241static void fginvblock(fb_data *address, unsigned mask, unsigned bits) 290static void fginvblock(fb_data *address, unsigned mask, unsigned bits)
@@ -256,11 +305,53 @@ static void solidinvblock(fb_data *address, unsigned mask, unsigned bits)
256 *address = data ^ ((data ^ bits) & mask); 305 *address = data ^ ((data ^ bits) & mask);
257} 306}
258 307
259lcd_blockfunc_type* const lcd_blockfuncs[8] = { 308static void solidimginvblock(fb_data *address, unsigned mask, unsigned bits)
309 ICODE_ATTR;
310static void solidimginvblock(fb_data *address, unsigned mask, unsigned bits)
311{
312 unsigned data = *address;
313 unsigned fgp = fg_pattern;
314
315 bits = fgp ^ ((fgp ^ *(address + lcd_backdrop_offset)) & bits);
316 *address = data ^ ((data ^ bits) & mask);
317}
318
319lcd_blockfunc_type* const lcd_blockfuncs_bgcolor[8] = {
260 flipblock, bgblock, fgblock, solidblock, 320 flipblock, bgblock, fgblock, solidblock,
261 flipinvblock, bginvblock, fginvblock, solidinvblock 321 flipinvblock, bginvblock, fginvblock, solidinvblock
262}; 322};
263 323
324lcd_blockfunc_type* const lcd_blockfuncs_backdrop[8] = {
325 flipblock, bgimgblock, fgblock, solidimgblock,
326 flipinvblock, bgimginvblock, fginvblock, solidimginvblock
327};
328
329lcd_blockfunc_type* const * lcd_blockfuncs = lcd_blockfuncs_bgcolor;
330
331
332void lcd_set_backdrop(fb_data* backdrop)
333{
334 lcd_backdrop = backdrop;
335 if (backdrop)
336 {
337 lcd_backdrop_offset = (long)backdrop - (long)lcd_framebuffer;
338 lcd_pixelfuncs = lcd_pixelfuncs_backdrop;
339 lcd_blockfuncs = lcd_blockfuncs_backdrop;
340 }
341 else
342 {
343 lcd_backdrop_offset = 0;
344 lcd_pixelfuncs = lcd_pixelfuncs_bgcolor;
345 lcd_blockfuncs = lcd_blockfuncs_bgcolor;
346 }
347}
348
349fb_data* lcd_get_backdrop(void)
350{
351 return lcd_backdrop;
352}
353
354
264static inline void setblock(fb_data *address, unsigned mask, unsigned bits) 355static inline void setblock(fb_data *address, unsigned mask, unsigned bits)
265{ 356{
266 unsigned data = *address; 357 unsigned data = *address;
@@ -274,9 +365,17 @@ static inline void setblock(fb_data *address, unsigned mask, unsigned bits)
274/* Clear the whole display */ 365/* Clear the whole display */
275void lcd_clear_display(void) 366void lcd_clear_display(void)
276{ 367{
277 unsigned bits = (drawmode & DRMODE_INVERSEVID) ? fg_pattern : bg_pattern; 368 if (drawmode & DRMODE_INVERSEVID)
278 369 {
279 memset(lcd_framebuffer, bits, sizeof lcd_framebuffer); 370 memset(lcd_framebuffer, fg_pattern, sizeof lcd_framebuffer);
371 }
372 else
373 {
374 if (lcd_backdrop)
375 memcpy(lcd_framebuffer, lcd_backdrop, sizeof lcd_framebuffer);
376 else
377 memset(lcd_framebuffer, bg_pattern, sizeof lcd_framebuffer);
378 }
280 scrolling_lines = 0; 379 scrolling_lines = 0;
281} 380}
282 381