From fcab617331ad6aed89aaacb24b5901175151dd53 Mon Sep 17 00:00:00 2001 From: Jens Arnold Date: Tue, 4 Apr 2006 00:55:16 +0000 Subject: Grayscale iPods: Bit-flipped the 2bit LCD driver to use the same format as apple. No more mirrored display when loading retailos, after a bootloader update. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9478 a1c6a512-1295-4272-9138-f99709370657 --- firmware/drivers/lcd-2bit-horz.c | 33 +++++++++++++--------------- firmware/drivers/lcd-ipod.c | 47 ++++++++++++++++++++-------------------- tools/bmp2rb.c | 2 +- 3 files changed, 39 insertions(+), 43 deletions(-) diff --git a/firmware/drivers/lcd-2bit-horz.c b/firmware/drivers/lcd-2bit-horz.c index 826f68a06a..e15d8ddbc4 100644 --- a/firmware/drivers/lcd-2bit-horz.c +++ b/firmware/drivers/lcd-2bit-horz.c @@ -46,7 +46,7 @@ static const unsigned char dibits[16] ICONST_ATTR = { }; static const unsigned char pixmask[4] ICONST_ATTR = { - 0x03, 0x0C, 0x30, 0xC0 + 0xC0, 0x30, 0x0C, 0x03 }; static unsigned fg_pattern IDATA_ATTR = 0xFF; /* initially black */ @@ -381,8 +381,8 @@ void lcd_hline(int x1, int x2, int y) bfunc = lcd_blockfuncs[drawmode]; dst = &lcd_framebuffer[y][x1>>2]; nx = x2 - (x1 & ~3); - mask = 0xFFu << (2 * (x1 & 3)); - mask_right = 0xFFu >> (2 * (~nx & 3)); + mask = 0xFFu >> (2 * (x1 & 3)); + mask_right = 0xFFu << (2 * (~nx & 3)); for (; nx >= 4; nx -= 4) { @@ -479,8 +479,8 @@ void lcd_fillrect(int x, int y, int width, int height) bfunc = lcd_blockfuncs[drawmode]; dst = &lcd_framebuffer[y][x>>2]; nx = width - 1 + (x & 3); - mask = 0xFFu << (2 * (x & 3)); - mask_right = 0xFFu >> (2 * (~nx & 3)); + mask = 0xFFu >> (2 * (x & 3)); + mask_right = 0xFFu << (2 * (~nx & 3)); for (; nx >= 4; nx -= 4) { @@ -515,9 +515,7 @@ void lcd_fillrect(int x, int y, int width, int height) * at top. * The bytes are stored in row-major order, with byte 0 being top left, * byte 1 2nd from left etc. The first row of bytes defines pixel row - * 0, the second row defines pixel row 1 etc. - * - * This is similar to the internal lcd hw format. */ + * 0, the second row defines pixel row 1 etc. */ /* Draw a partial monochrome bitmap */ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, @@ -602,7 +600,7 @@ void lcd_mono_bitmap(const unsigned char *src, int x, int y, int width, int heig * * A bitmap contains two bits for every pixel. 00 = white, 01 = light grey, * 10 = dark grey, 11 = black. Bits within a byte are arranged horizontally, - * LSB at the left. + * MSB at the left. * The bytes are stored in row-major order, with byte 0 being top left, * byte 1 2nd from left etc. Each row of bytes defines one pixel row. * @@ -651,8 +649,8 @@ void lcd_bitmap_part(const unsigned char *src, int src_x, int src_y, shift = x & 3; nx = width - 1 + shift + src_x; - mask = 0xFFu << (2 * (shift + src_x)); - mask_right = 0xFFu >> (2 * (~nx & 3)); + mask = 0xFF00u >> (2 * (shift + src_x)); + mask_right = 0xFFu << (2 * (~nx & 3)); shift *= 2; dst_end = dst + height * LCD_FBWIDTH; @@ -660,26 +658,25 @@ void lcd_bitmap_part(const unsigned char *src, int src_x, int src_y, { const unsigned char *src_row = src; unsigned char *dst_row = dst; - unsigned mask_row = mask; + unsigned mask_row = mask >> 8; unsigned data = 0; for (x = nx; x >= 4; x -= 4) { - data |= *src_row++ << shift; + data = (data << 8) | *src_row++; if (mask_row & 0xFF) { - setblock(dst_row, mask_row, data); + setblock(dst_row, mask_row, data >> shift); mask_row = 0xFF; } else - mask_row >>= 8; + mask_row = mask; dst_row++; - data >>= 8; } - data |= *src_row << shift; - setblock(dst_row, mask_row & mask_right, data); + data = (data << 8) | *src_row; + setblock(dst_row, mask_row & mask_right, data >> shift); src += stride; dst += LCD_FBWIDTH; diff --git a/firmware/drivers/lcd-ipod.c b/firmware/drivers/lcd-ipod.c index 3f777cf7a9..ab0940d56b 100644 --- a/firmware/drivers/lcd-ipod.c +++ b/firmware/drivers/lcd-ipod.c @@ -71,13 +71,13 @@ static inline bool timer_check(int clock_start, int usecs) #define R_RAM_DATA 0x12 /* needed for flip */ -static int addr_offset = 0; +static int addr_offset; #if defined(IPOD_MINI) || defined(IPOD_MINI2G) -static int pix_offset = 0; +static int pix_offset; #endif /* wait for LCD with timeout */ -static void lcd_wait_write(void) +static inline void lcd_wait_write(void) { int start = USEC_TIMER; @@ -127,7 +127,7 @@ void lcd_init_device(void) { lcd_cmd_and_data(R_DISPLAY_CONTROL, 0x0015); lcd_set_flip(false); - lcd_cmd_and_data(R_ENTRY_MODE, 0x0010); + lcd_cmd_and_data(R_ENTRY_MODE, 0x0000); #ifdef APPLE_IPOD4G outl(inl(0x6000d004) | 0x4, 0x6000d004); /* B02 enable */ @@ -180,29 +180,29 @@ void lcd_set_flip(bool yesno) { #if defined(IPOD_MINI) || defined(IPOD_MINI2G) if (yesno) { - /* 160x112, inverse SEG & COM order */ - lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x030d); + /* 168x112, inverse COM order */ + lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x020d); lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x8316); /* 22..131 */ - addr_offset = (22 << 5) | 3; + addr_offset = (22 << 5) | (20 - 3); pix_offset = 6; } else { - /* 160x112 */ - lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x000d); + /* 168x112, inverse SEG order */ + lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x010d); lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x6d00); /* 0..109 */ - addr_offset = 0; + addr_offset = 20; pix_offset = 0; } #else if (yesno) { - /* 160x128, inverse COM order */ - lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x020f); + /* 168x128, inverse SEG & COM order */ + lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x030f); lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x8304); /* 0..127 */ - addr_offset = (4 << 5) | 1; + addr_offset = (4 << 5) | (20 - 1); } else { - /* 160x128, inverse SEG order */ - lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x010f); + /* 168x128 */ + lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x000f); lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x7f00); /* 4..131 */ - addr_offset = 0; + addr_offset = 20; } #endif } @@ -230,7 +230,7 @@ void lcd_update_rect(int x, int y, int width, int height) for (; y <= ymax; y++) { unsigned char *data, *data_end; - int ram_addr = (x | (y << 5)) + addr_offset; + int ram_addr = (y << 5) + addr_offset - x; lcd_cmd_and_data(R_RAM_ADDR_SET, ram_addr); lcd_prepare_cmd(R_RAM_DATA); @@ -241,19 +241,18 @@ void lcd_update_rect(int x, int y, int width, int height) if (pix_offset == 6) { data -= 2; data_end -= 1; - unsigned cur_word = *data++ >> 4; + unsigned cur_word = *data++; do { - cur_word |= *data++ << 4; - cur_word |= *data++ << 12; - lcd_send_data(cur_word & 0xffff); - cur_word >>= 16; + cur_word = (cur_word << 8) | *data++; + cur_word = (cur_word << 8) | *data++; + lcd_send_data((cur_word >> 4) & 0xffff); } while (data < data_end); } else #endif { do { - unsigned lowbyte = *data++; - lcd_send_data(lowbyte | (*data++ << 8)); + unsigned highbyte = *data++; + lcd_send_data((highbyte << 8) | *data++); } while (data < data_end); } } diff --git a/tools/bmp2rb.c b/tools/bmp2rb.c index 03da5895b8..0262473fc1 100644 --- a/tools/bmp2rb.c +++ b/tools/bmp2rb.c @@ -402,7 +402,7 @@ int transform_bitmap(const struct RGBQUAD *src, int width, int height, for (col = 0; col < width; col++) { (*dest)[row * dst_w + (col/4)] |= - (~brightness(src[row * width + col]) & 0xC0) >> (2 * (~col & 3)); + (~brightness(src[row * width + col]) & 0xC0) >> (2 * (col & 3)); } break; } -- cgit v1.2.3