summaryrefslogtreecommitdiff
path: root/firmware/drivers/lcd-2bit-vert.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/lcd-2bit-vert.c')
-rw-r--r--firmware/drivers/lcd-2bit-vert.c112
1 files changed, 105 insertions, 7 deletions
diff --git a/firmware/drivers/lcd-2bit-vert.c b/firmware/drivers/lcd-2bit-vert.c
index 799865c36d..ec20068d95 100644
--- a/firmware/drivers/lcd-2bit-vert.c
+++ b/firmware/drivers/lcd-2bit-vert.c
@@ -48,6 +48,9 @@ static const unsigned char pixmask[4] ICONST_ATTR = {
48 0x03, 0x0C, 0x30, 0xC0 48 0x03, 0x0C, 0x30, 0xC0
49}; 49};
50 50
51static fb_data* lcd_backdrop = NULL;
52static long lcd_backdrop_offset IDATA_ATTR = 0;
53
51static unsigned fg_pattern IDATA_ATTR = 0xFF; /* initially black */ 54static unsigned fg_pattern IDATA_ATTR = 0xFF; /* initially black */
52static unsigned bg_pattern IDATA_ATTR = 0x00; /* initially white */ 55static unsigned bg_pattern IDATA_ATTR = 0x00; /* initially white */
53static int drawmode = DRMODE_SOLID; 56static int drawmode = DRMODE_SOLID;
@@ -167,6 +170,15 @@ static void clearpixel(int x, int y)
167 *address = data ^ ((data ^ bg_pattern) & mask); 170 *address = data ^ ((data ^ bg_pattern) & mask);
168} 171}
169 172
173static void clearimgpixel(int x, int y)
174{
175 unsigned mask = pixmask[y & 3];
176 fb_data *address = &lcd_framebuffer[y>>2][x];
177 unsigned data = *address;
178
179 *address = data ^ ((data ^ *(address + lcd_backdrop_offset)) & mask);
180}
181
170static void flippixel(int x, int y) 182static void flippixel(int x, int y)
171{ 183{
172 unsigned mask = pixmask[y & 3]; 184 unsigned mask = pixmask[y & 3];
@@ -181,11 +193,19 @@ static void nopixel(int x, int y)
181 (void)y; 193 (void)y;
182} 194}
183 195
184lcd_pixelfunc_type* const lcd_pixelfuncs[8] = { 196lcd_pixelfunc_type* const lcd_pixelfuncs_bgcolor[8] = {
185 flippixel, nopixel, setpixel, setpixel, 197 flippixel, nopixel, setpixel, setpixel,
186 nopixel, clearpixel, nopixel, clearpixel 198 nopixel, clearpixel, nopixel, clearpixel
187}; 199};
188 200
201lcd_pixelfunc_type* const lcd_pixelfuncs_backdrop[8] = {
202 flippixel, nopixel, setpixel, setpixel,
203 nopixel, clearimgpixel, nopixel, clearimgpixel
204};
205
206
207lcd_pixelfunc_type* const * lcd_pixelfuncs = lcd_pixelfuncs_bgcolor;
208
189/* 'mask' and 'bits' contain 2 bits per pixel */ 209/* 'mask' and 'bits' contain 2 bits per pixel */
190static void flipblock(fb_data *address, unsigned mask, unsigned bits) 210static void flipblock(fb_data *address, unsigned mask, unsigned bits)
191 ICODE_ATTR; 211 ICODE_ATTR;
@@ -203,6 +223,15 @@ static void bgblock(fb_data *address, unsigned mask, unsigned bits)
203 *address = data ^ ((data ^ bg_pattern) & mask & ~bits); 223 *address = data ^ ((data ^ bg_pattern) & mask & ~bits);
204} 224}
205 225
226static void bgimgblock(fb_data *address, unsigned mask, unsigned bits)
227 ICODE_ATTR;
228static void bgimgblock(fb_data *address, unsigned mask, unsigned bits)
229{
230 unsigned data = *address;
231
232 *address = data ^ ((data ^ *(address + lcd_backdrop_offset)) & mask & ~bits);
233}
234
206static void fgblock(fb_data *address, unsigned mask, unsigned bits) 235static void fgblock(fb_data *address, unsigned mask, unsigned bits)
207 ICODE_ATTR; 236 ICODE_ATTR;
208static void fgblock(fb_data *address, unsigned mask, unsigned bits) 237static void fgblock(fb_data *address, unsigned mask, unsigned bits)
@@ -223,6 +252,17 @@ static void solidblock(fb_data *address, unsigned mask, unsigned bits)
223 *address = data ^ ((data ^ bits) & mask); 252 *address = data ^ ((data ^ bits) & mask);
224} 253}
225 254
255static void solidimgblock(fb_data *address, unsigned mask, unsigned bits)
256 ICODE_ATTR;
257static void solidimgblock(fb_data *address, unsigned mask, unsigned bits)
258{
259 unsigned data = *address;
260 unsigned bgp = *(address + lcd_backdrop_offset);
261
262 bits = bgp ^ ((bgp ^ fg_pattern) & bits);
263 *address = data ^ ((data ^ bits) & mask);
264}
265
226static void flipinvblock(fb_data *address, unsigned mask, unsigned bits) 266static void flipinvblock(fb_data *address, unsigned mask, unsigned bits)
227 ICODE_ATTR; 267 ICODE_ATTR;
228static void flipinvblock(fb_data *address, unsigned mask, unsigned bits) 268static void flipinvblock(fb_data *address, unsigned mask, unsigned bits)
@@ -239,6 +279,15 @@ static void bginvblock(fb_data *address, unsigned mask, unsigned bits)
239 *address = data ^ ((data ^ bg_pattern) & mask & bits); 279 *address = data ^ ((data ^ bg_pattern) & mask & bits);
240} 280}
241 281
282static void bgimginvblock(fb_data *address, unsigned mask, unsigned bits)
283 ICODE_ATTR;
284static void bgimginvblock(fb_data *address, unsigned mask, unsigned bits)
285{
286 unsigned data = *address;
287
288 *address = data ^ ((data ^ *(address + lcd_backdrop_offset)) & mask & bits);
289}
290
242static void fginvblock(fb_data *address, unsigned mask, unsigned bits) 291static void fginvblock(fb_data *address, unsigned mask, unsigned bits)
243 ICODE_ATTR; 292 ICODE_ATTR;
244static void fginvblock(fb_data *address, unsigned mask, unsigned bits) 293static void fginvblock(fb_data *address, unsigned mask, unsigned bits)
@@ -259,11 +308,53 @@ static void solidinvblock(fb_data *address, unsigned mask, unsigned bits)
259 *address = data ^ ((data ^ bits) & mask); 308 *address = data ^ ((data ^ bits) & mask);
260} 309}
261 310
262lcd_blockfunc_type* const lcd_blockfuncs[8] = { 311static void solidimginvblock(fb_data *address, unsigned mask, unsigned bits)
312 ICODE_ATTR;
313static void solidimginvblock(fb_data *address, unsigned mask, unsigned bits)
314{
315 unsigned data = *address;
316 unsigned fgp = fg_pattern;
317
318 bits = fgp ^ ((fgp ^ *(address + lcd_backdrop_offset)) & bits);
319 *address = data ^ ((data ^ bits) & mask);
320}
321
322lcd_blockfunc_type* const lcd_blockfuncs_bgcolor[8] = {
263 flipblock, bgblock, fgblock, solidblock, 323 flipblock, bgblock, fgblock, solidblock,
264 flipinvblock, bginvblock, fginvblock, solidinvblock 324 flipinvblock, bginvblock, fginvblock, solidinvblock
265}; 325};
266 326
327lcd_blockfunc_type* const lcd_blockfuncs_backdrop[8] = {
328 flipblock, bgimgblock, fgblock, solidimgblock,
329 flipinvblock, bgimginvblock, fginvblock, solidimginvblock
330};
331
332lcd_blockfunc_type* const * lcd_blockfuncs = lcd_blockfuncs_bgcolor;
333
334
335void lcd_set_backdrop(fb_data* backdrop)
336{
337 lcd_backdrop = backdrop;
338 if (backdrop)
339 {
340 lcd_backdrop_offset = (long)backdrop - (long)lcd_framebuffer;
341 lcd_pixelfuncs = lcd_pixelfuncs_backdrop;
342 lcd_blockfuncs = lcd_blockfuncs_backdrop;
343 }
344 else
345 {
346 lcd_backdrop_offset = 0;
347 lcd_pixelfuncs = lcd_pixelfuncs_bgcolor;
348 lcd_blockfuncs = lcd_blockfuncs_bgcolor;
349 }
350}
351
352fb_data* lcd_get_backdrop(void)
353{
354 return lcd_backdrop;
355}
356
357
267static inline void setblock(fb_data *address, unsigned mask, unsigned bits) 358static inline void setblock(fb_data *address, unsigned mask, unsigned bits)
268{ 359{
269 unsigned data = *address; 360 unsigned data = *address;
@@ -277,9 +368,17 @@ static inline void setblock(fb_data *address, unsigned mask, unsigned bits)
277/* Clear the whole display */ 368/* Clear the whole display */
278void lcd_clear_display(void) 369void lcd_clear_display(void)
279{ 370{
280 unsigned bits = (drawmode & DRMODE_INVERSEVID) ? fg_pattern : bg_pattern; 371 if (drawmode & DRMODE_INVERSEVID)
281 372 {
282 memset(lcd_framebuffer, bits, sizeof lcd_framebuffer); 373 memset(lcd_framebuffer, fg_pattern, sizeof lcd_framebuffer);
374 }
375 else
376 {
377 if (lcd_backdrop)
378 memcpy(lcd_framebuffer, lcd_backdrop, sizeof lcd_framebuffer);
379 else
380 memset(lcd_framebuffer, bg_pattern, sizeof lcd_framebuffer);
381 }
283 scrolling_lines = 0; 382 scrolling_lines = 0;
284} 383}
285 384
@@ -487,7 +586,7 @@ void lcd_fillrect(int x, int y, int width, int height)
487 586
488 if (drawmode & DRMODE_INVERSEVID) 587 if (drawmode & DRMODE_INVERSEVID)
489 { 588 {
490 if (drawmode & DRMODE_BG) 589 if ((drawmode & DRMODE_BG) && !lcd_backdrop)
491 { 590 {
492 fillopt = true; 591 fillopt = true;
493 bits = bg_pattern; 592 bits = bg_pattern;
@@ -1090,4 +1189,3 @@ static void scroll_thread(void)
1090 sleep(scroll_ticks); 1189 sleep(scroll_ticks);
1091 } 1190 }
1092} 1191}
1093