summaryrefslogtreecommitdiff
path: root/firmware/drivers/lcd-16bit-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/lcd-16bit-common.c')
-rw-r--r--firmware/drivers/lcd-16bit-common.c168
1 files changed, 72 insertions, 96 deletions
diff --git a/firmware/drivers/lcd-16bit-common.c b/firmware/drivers/lcd-16bit-common.c
index b9c9060216..1b84847929 100644
--- a/firmware/drivers/lcd-16bit-common.c
+++ b/firmware/drivers/lcd-16bit-common.c
@@ -283,12 +283,6 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
283 int src_y, int stride, int x, int y, 283 int src_y, int stride, int x, int y,
284 int width, int height) 284 int width, int height)
285{ 285{
286 const unsigned char *src_end;
287 fb_data *dst, *dst_col;
288 unsigned dmask = 0x100; /* bit 8 == sentinel */
289 int drmode = lcd_current_viewport->drawmode;
290 int row;
291
292 /******************** Image in viewport clipping **********************/ 286 /******************** Image in viewport clipping **********************/
293 /* nothing to draw? */ 287 /* nothing to draw? */
294 if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || 288 if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) ||
@@ -312,22 +306,10 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
312 if (y + height > lcd_current_viewport->height) 306 if (y + height > lcd_current_viewport->height)
313 height = lcd_current_viewport->height - y; 307 height = lcd_current_viewport->height - y;
314 308
315 /* adjust for viewport */ 309 /* convert to viewport coordinates */
316 x += lcd_current_viewport->x; 310 x += lcd_current_viewport->x;
317 y += lcd_current_viewport->y; 311 y += lcd_current_viewport->y;
318 312
319 /* 'Bugfix' mono_bitmap_part reads ahead in the buffer, While this is a bug
320 * if the height is <= char bit pixels other memory gets read but is not used
321 * the other option is to check in the hot code path but this appears
322 * sufficient, limit to the sim to stop Address Sanitizer errors
323 */
324#if defined(SIMULATOR) && \
325 (!defined(LCD_STRIDEFORMAT) || LCD_STRIDEFORMAT != VERTICAL_STRIDE)
326 /* vertical stride targets don't seem affected by this */
327 if (height <= CHAR_BIT)
328 stride = 0;
329#endif
330
331#if defined(HAVE_VIEWPORT_CLIP) 313#if defined(HAVE_VIEWPORT_CLIP)
332 /********************* Viewport on screen clipping ********************/ 314 /********************* Viewport on screen clipping ********************/
333 /* nothing to draw? */ 315 /* nothing to draw? */
@@ -342,7 +324,6 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
342 src_x -= x; 324 src_x -= x;
343 x = 0; 325 x = 0;
344 } 326 }
345
346 if (y < 0) 327 if (y < 0)
347 { 328 {
348 height += y; 329 height += y;
@@ -354,14 +335,17 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
354 if (y + height > LCD_HEIGHT) 335 if (y + height > LCD_HEIGHT)
355 height = LCD_HEIGHT - y; 336 height = LCD_HEIGHT - y;
356#endif 337#endif
357 src += stride * (src_y >> 3) + src_x; /* move starting point */ 338
358 src_y &= 7; 339 /* move starting point */
359 src_end = src + width; 340 src += stride * (src_y >> 3) + src_x;
360 dst_col = FBADDR(x, y); 341 src_y &= 7;
342
343 unsigned dmask = 0;
344 int drmode = lcd_current_viewport->drawmode;
361 345
362 if (drmode & DRMODE_INVERSEVID) 346 if (drmode & DRMODE_INVERSEVID)
363 { 347 {
364 dmask = 0x1ff; /* bit 8 == sentinel */ 348 dmask = 0xff;
365 drmode &= DRMODE_SOLID; /* mask out inversevid */ 349 drmode &= DRMODE_SOLID; /* mask out inversevid */
366 } 350 }
367 351
@@ -369,107 +353,99 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
369 if ((drmode & DRMODE_BG) && lcd_backdrop) 353 if ((drmode & DRMODE_BG) && lcd_backdrop)
370 drmode |= DRMODE_INT_BD; 354 drmode |= DRMODE_INT_BD;
371 355
372 /* go through each column and update each pixel */ 356 fb_data* dst = FBADDR(x, y);
373 do 357 while(height > 0)
374 { 358 {
375 const unsigned char *src_col = src++; 359 const unsigned char* src_col = src;
376 unsigned data = (*src_col ^ dmask) >> src_y; 360 const unsigned char* src_end = src + width;
361 fb_data* dst_col = dst;
362
363 unsigned data;
377 int fg, bg; 364 int fg, bg;
378 uintptr_t bo; 365 uintptr_t bo;
379 366
380 dst = dst_col; 367 switch (drmode) {
381 dst_col += COL_INC; 368 case DRMODE_COMPLEMENT:
382 row = height; 369 do {
383 370 data = (*src_col++ ^ dmask) >> src_y;
384#define UPDATE_SRC do { \ 371 if(data & 0x01)
385 data >>= 1; \ 372 *dst_col = ~(*dst_col);
386 if (data == 0x001) { \
387 src_col += stride; \
388 data = *src_col ^ dmask; \
389 } \
390 } while (0)
391
392 switch (drmode)
393 {
394 case DRMODE_COMPLEMENT:
395 do
396 {
397 if (data & 0x01)
398 *dst = ~(*dst);
399 373
400 dst += ROW_INC; 374 dst_col += COL_INC;
401 UPDATE_SRC; 375 } while(src_col != src_end);
402 }
403 while (--row);
404 break; 376 break;
405 377
406 case DRMODE_BG|DRMODE_INT_BD: 378 case DRMODE_BG|DRMODE_INT_BD:
407 bo = lcd_backdrop_offset; 379 bo = lcd_backdrop_offset;
408 do 380 do {
409 { 381 data = (*src_col++ ^ dmask) >> src_y;
410 if (!(data & 0x01)) 382 if(!(data & 0x01))
411 *dst = *PTR_ADD(dst, bo); 383 *dst_col = *PTR_ADD(dst_col, bo);
412 384
413 dst += ROW_INC; 385 dst_col += COL_INC;
414 UPDATE_SRC; 386 } while(src_col != src_end);
415 }
416 while (--row);
417 break; 387 break;
418 388
419 case DRMODE_BG: 389 case DRMODE_BG:
420 bg = lcd_current_viewport->bg_pattern; 390 bg = lcd_current_viewport->bg_pattern;
421 do 391 do {
422 { 392 data = (*src_col++ ^ dmask) >> src_y;
423 if (!(data & 0x01)) 393 if(!(data & 0x01))
424 *dst = bg; 394 *dst_col = bg;
425 395
426 dst += ROW_INC; 396 dst_col += COL_INC;
427 UPDATE_SRC; 397 } while(src_col != src_end);
428 }
429 while (--row);
430 break; 398 break;
431 399
432 case DRMODE_FG: 400 case DRMODE_FG:
433 fg = lcd_current_viewport->fg_pattern; 401 fg = lcd_current_viewport->fg_pattern;
434 do 402 do {
435 { 403 data = (*src_col++ ^ dmask) >> src_y;
436 if (data & 0x01) 404 if(data & 0x01)
437 *dst = fg; 405 *dst_col = fg;
438 406
439 dst += ROW_INC; 407 dst_col += COL_INC;
440 UPDATE_SRC; 408 } while(src_col != src_end);
441 }
442 while (--row);
443 break; 409 break;
444 410
445 case DRMODE_SOLID|DRMODE_INT_BD: 411 case DRMODE_SOLID|DRMODE_INT_BD:
446 fg = lcd_current_viewport->fg_pattern; 412 fg = lcd_current_viewport->fg_pattern;
447 bo = lcd_backdrop_offset; 413 bo = lcd_backdrop_offset;
448 do 414 do {
449 { 415 data = (*src_col++ ^ dmask) >> src_y;
450 *dst = (data & 0x01) ? fg 416 if(data & 0x01)
451 : *PTR_ADD(dst, bo); 417 *dst_col = fg;
452 dst += ROW_INC; 418 else
453 UPDATE_SRC; 419 *dst_col = *PTR_ADD(dst_col, bo);
454 } 420
455 while (--row); 421 dst_col += COL_INC;
422 } while(src_col != src_end);
456 break; 423 break;
457 424
458 case DRMODE_SOLID: 425 case DRMODE_SOLID:
459 fg = lcd_current_viewport->fg_pattern; 426 fg = lcd_current_viewport->fg_pattern;
460 bg = lcd_current_viewport->bg_pattern; 427 bg = lcd_current_viewport->bg_pattern;
461 do 428 do {
462 { 429 data = (*src_col++ ^ dmask) >> src_y;
463 *dst = (data & 0x01) ? fg : bg; 430 if(data & 0x01)
464 dst += ROW_INC; 431 *dst_col = fg;
465 UPDATE_SRC; 432 else
466 } 433 *dst_col = bg;
467 while (--row); 434
435 dst_col += COL_INC;
436 } while(src_col != src_end);
468 break; 437 break;
469 } 438 }
439
440 src_y = (src_y + 1) & 7;
441 if(src_y == 0)
442 src += stride;
443
444 dst += ROW_INC;
445 height--;
470 } 446 }
471 while (src < src_end);
472} 447}
448
473/* Draw a full monochrome bitmap */ 449/* Draw a full monochrome bitmap */
474void lcd_mono_bitmap(const unsigned char *src, int x, int y, int width, int height) 450void lcd_mono_bitmap(const unsigned char *src, int x, int y, int width, int height)
475{ 451{