summaryrefslogtreecommitdiff
path: root/firmware/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers')
-rw-r--r--firmware/drivers/lcd-2bit-horz.c109
-rw-r--r--firmware/drivers/lcd-2bit-vert.c112
2 files changed, 209 insertions, 12 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
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