diff options
Diffstat (limited to 'firmware/drivers')
-rw-r--r-- | firmware/drivers/lcd-2bit-horz.c | 109 | ||||
-rw-r--r-- | firmware/drivers/lcd-2bit-vert.c | 112 |
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 | ||
47 | static fb_data* lcd_backdrop = NULL; | ||
48 | static long lcd_backdrop_offset IDATA_ATTR = 0; | ||
49 | |||
47 | static unsigned fg_pattern IDATA_ATTR = 0xFF; /* initially black */ | 50 | static unsigned fg_pattern IDATA_ATTR = 0xFF; /* initially black */ |
48 | static unsigned bg_pattern IDATA_ATTR = 0x00; /* initially white */ | 51 | static unsigned bg_pattern IDATA_ATTR = 0x00; /* initially white */ |
49 | static int drawmode = DRMODE_SOLID; | 52 | static 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 | ||
170 | static 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 | |||
167 | static void flippixel(int x, int y) | 179 | static 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 | ||
181 | lcd_pixelfunc_type* const lcd_pixelfuncs[8] = { | 193 | lcd_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 | ||
198 | lcd_pixelfunc_type* const lcd_pixelfuncs_backdrop[8] = { | ||
199 | flippixel, nopixel, setpixel, setpixel, | ||
200 | nopixel, clearimgpixel, nopixel, clearimgpixel | ||
201 | }; | ||
202 | |||
203 | lcd_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 */ |
187 | static void flipblock(fb_data *address, unsigned mask, unsigned bits) | 207 | static 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 | ||
223 | static void bgimgblock(fb_data *address, unsigned mask, unsigned bits) | ||
224 | ICODE_ATTR; | ||
225 | static 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 | |||
203 | static void fgblock(fb_data *address, unsigned mask, unsigned bits) | 232 | static void fgblock(fb_data *address, unsigned mask, unsigned bits) |
204 | ICODE_ATTR; | 233 | ICODE_ATTR; |
205 | static void fgblock(fb_data *address, unsigned mask, unsigned bits) | 234 | static 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 | ||
252 | static void solidimgblock(fb_data *address, unsigned mask, unsigned bits) | ||
253 | ICODE_ATTR; | ||
254 | static 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 | |||
223 | static void flipinvblock(fb_data *address, unsigned mask, unsigned bits) | 263 | static void flipinvblock(fb_data *address, unsigned mask, unsigned bits) |
224 | ICODE_ATTR; | 264 | ICODE_ATTR; |
225 | static void flipinvblock(fb_data *address, unsigned mask, unsigned bits) | 265 | static 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 | ||
279 | static void bgimginvblock(fb_data *address, unsigned mask, unsigned bits) | ||
280 | ICODE_ATTR; | ||
281 | static 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 | |||
239 | static void fginvblock(fb_data *address, unsigned mask, unsigned bits) | 288 | static void fginvblock(fb_data *address, unsigned mask, unsigned bits) |
240 | ICODE_ATTR; | 289 | ICODE_ATTR; |
241 | static void fginvblock(fb_data *address, unsigned mask, unsigned bits) | 290 | static 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 | ||
259 | lcd_blockfunc_type* const lcd_blockfuncs[8] = { | 308 | static void solidimginvblock(fb_data *address, unsigned mask, unsigned bits) |
309 | ICODE_ATTR; | ||
310 | static 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 | |||
319 | lcd_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 | ||
324 | lcd_blockfunc_type* const lcd_blockfuncs_backdrop[8] = { | ||
325 | flipblock, bgimgblock, fgblock, solidimgblock, | ||
326 | flipinvblock, bgimginvblock, fginvblock, solidimginvblock | ||
327 | }; | ||
328 | |||
329 | lcd_blockfunc_type* const * lcd_blockfuncs = lcd_blockfuncs_bgcolor; | ||
330 | |||
331 | |||
332 | void 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 | |||
349 | fb_data* lcd_get_backdrop(void) | ||
350 | { | ||
351 | return lcd_backdrop; | ||
352 | } | ||
353 | |||
354 | |||
264 | static inline void setblock(fb_data *address, unsigned mask, unsigned bits) | 355 | static 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 */ |
275 | void lcd_clear_display(void) | 366 | void 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 | ||
51 | static fb_data* lcd_backdrop = NULL; | ||
52 | static long lcd_backdrop_offset IDATA_ATTR = 0; | ||
53 | |||
51 | static unsigned fg_pattern IDATA_ATTR = 0xFF; /* initially black */ | 54 | static unsigned fg_pattern IDATA_ATTR = 0xFF; /* initially black */ |
52 | static unsigned bg_pattern IDATA_ATTR = 0x00; /* initially white */ | 55 | static unsigned bg_pattern IDATA_ATTR = 0x00; /* initially white */ |
53 | static int drawmode = DRMODE_SOLID; | 56 | static 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 | ||
173 | static 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 | |||
170 | static void flippixel(int x, int y) | 182 | static 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 | ||
184 | lcd_pixelfunc_type* const lcd_pixelfuncs[8] = { | 196 | lcd_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 | ||
201 | lcd_pixelfunc_type* const lcd_pixelfuncs_backdrop[8] = { | ||
202 | flippixel, nopixel, setpixel, setpixel, | ||
203 | nopixel, clearimgpixel, nopixel, clearimgpixel | ||
204 | }; | ||
205 | |||
206 | |||
207 | lcd_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 */ |
190 | static void flipblock(fb_data *address, unsigned mask, unsigned bits) | 210 | static 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 | ||
226 | static void bgimgblock(fb_data *address, unsigned mask, unsigned bits) | ||
227 | ICODE_ATTR; | ||
228 | static 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 | |||
206 | static void fgblock(fb_data *address, unsigned mask, unsigned bits) | 235 | static void fgblock(fb_data *address, unsigned mask, unsigned bits) |
207 | ICODE_ATTR; | 236 | ICODE_ATTR; |
208 | static void fgblock(fb_data *address, unsigned mask, unsigned bits) | 237 | static 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 | ||
255 | static void solidimgblock(fb_data *address, unsigned mask, unsigned bits) | ||
256 | ICODE_ATTR; | ||
257 | static 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 | |||
226 | static void flipinvblock(fb_data *address, unsigned mask, unsigned bits) | 266 | static void flipinvblock(fb_data *address, unsigned mask, unsigned bits) |
227 | ICODE_ATTR; | 267 | ICODE_ATTR; |
228 | static void flipinvblock(fb_data *address, unsigned mask, unsigned bits) | 268 | static 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 | ||
282 | static void bgimginvblock(fb_data *address, unsigned mask, unsigned bits) | ||
283 | ICODE_ATTR; | ||
284 | static 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 | |||
242 | static void fginvblock(fb_data *address, unsigned mask, unsigned bits) | 291 | static void fginvblock(fb_data *address, unsigned mask, unsigned bits) |
243 | ICODE_ATTR; | 292 | ICODE_ATTR; |
244 | static void fginvblock(fb_data *address, unsigned mask, unsigned bits) | 293 | static 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 | ||
262 | lcd_blockfunc_type* const lcd_blockfuncs[8] = { | 311 | static void solidimginvblock(fb_data *address, unsigned mask, unsigned bits) |
312 | ICODE_ATTR; | ||
313 | static 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 | |||
322 | lcd_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 | ||
327 | lcd_blockfunc_type* const lcd_blockfuncs_backdrop[8] = { | ||
328 | flipblock, bgimgblock, fgblock, solidimgblock, | ||
329 | flipinvblock, bgimginvblock, fginvblock, solidimginvblock | ||
330 | }; | ||
331 | |||
332 | lcd_blockfunc_type* const * lcd_blockfuncs = lcd_blockfuncs_bgcolor; | ||
333 | |||
334 | |||
335 | void 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 | |||
352 | fb_data* lcd_get_backdrop(void) | ||
353 | { | ||
354 | return lcd_backdrop; | ||
355 | } | ||
356 | |||
357 | |||
267 | static inline void setblock(fb_data *address, unsigned mask, unsigned bits) | 358 | static 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 */ |
278 | void lcd_clear_display(void) | 369 | void 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 | |||