1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Jens Arnold 2006-04-04 00:55:16 +00:00
parent ec5f783988
commit fcab617331
3 changed files with 39 additions and 43 deletions

View file

@ -46,7 +46,7 @@ static const unsigned char dibits[16] ICONST_ATTR = {
}; };
static const unsigned char pixmask[4] 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 */ 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]; bfunc = lcd_blockfuncs[drawmode];
dst = &lcd_framebuffer[y][x1>>2]; dst = &lcd_framebuffer[y][x1>>2];
nx = x2 - (x1 & ~3); nx = x2 - (x1 & ~3);
mask = 0xFFu << (2 * (x1 & 3)); mask = 0xFFu >> (2 * (x1 & 3));
mask_right = 0xFFu >> (2 * (~nx & 3)); mask_right = 0xFFu << (2 * (~nx & 3));
for (; nx >= 4; nx -= 4) for (; nx >= 4; nx -= 4)
{ {
@ -479,8 +479,8 @@ void lcd_fillrect(int x, int y, int width, int height)
bfunc = lcd_blockfuncs[drawmode]; bfunc = lcd_blockfuncs[drawmode];
dst = &lcd_framebuffer[y][x>>2]; dst = &lcd_framebuffer[y][x>>2];
nx = width - 1 + (x & 3); nx = width - 1 + (x & 3);
mask = 0xFFu << (2 * (x & 3)); mask = 0xFFu >> (2 * (x & 3));
mask_right = 0xFFu >> (2 * (~nx & 3)); mask_right = 0xFFu << (2 * (~nx & 3));
for (; nx >= 4; nx -= 4) for (; nx >= 4; nx -= 4)
{ {
@ -515,9 +515,7 @@ void lcd_fillrect(int x, int y, int width, int height)
* at top. * at top.
* The bytes are stored in row-major order, with byte 0 being top left, * 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 * byte 1 2nd from left etc. The first row of bytes defines pixel row
* 0, the second row defines pixel row 1 etc. * 0, the second row defines pixel row 1 etc. */
*
* This is similar to the internal lcd hw format. */
/* Draw a partial monochrome bitmap */ /* Draw a partial monochrome bitmap */
void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, 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, * 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, * 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, * 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. * 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; shift = x & 3;
nx = width - 1 + shift + src_x; nx = width - 1 + shift + src_x;
mask = 0xFFu << (2 * (shift + src_x)); mask = 0xFF00u >> (2 * (shift + src_x));
mask_right = 0xFFu >> (2 * (~nx & 3)); mask_right = 0xFFu << (2 * (~nx & 3));
shift *= 2; shift *= 2;
dst_end = dst + height * LCD_FBWIDTH; 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; const unsigned char *src_row = src;
unsigned char *dst_row = dst; unsigned char *dst_row = dst;
unsigned mask_row = mask; unsigned mask_row = mask >> 8;
unsigned data = 0; unsigned data = 0;
for (x = nx; x >= 4; x -= 4) for (x = nx; x >= 4; x -= 4)
{ {
data |= *src_row++ << shift; data = (data << 8) | *src_row++;
if (mask_row & 0xFF) if (mask_row & 0xFF)
{ {
setblock(dst_row, mask_row, data); setblock(dst_row, mask_row, data >> shift);
mask_row = 0xFF; mask_row = 0xFF;
} }
else else
mask_row >>= 8; mask_row = mask;
dst_row++; dst_row++;
data >>= 8;
} }
data |= *src_row << shift; data = (data << 8) | *src_row;
setblock(dst_row, mask_row & mask_right, data); setblock(dst_row, mask_row & mask_right, data >> shift);
src += stride; src += stride;
dst += LCD_FBWIDTH; dst += LCD_FBWIDTH;

View file

@ -71,13 +71,13 @@ static inline bool timer_check(int clock_start, int usecs)
#define R_RAM_DATA 0x12 #define R_RAM_DATA 0x12
/* needed for flip */ /* needed for flip */
static int addr_offset = 0; static int addr_offset;
#if defined(IPOD_MINI) || defined(IPOD_MINI2G) #if defined(IPOD_MINI) || defined(IPOD_MINI2G)
static int pix_offset = 0; static int pix_offset;
#endif #endif
/* wait for LCD with timeout */ /* wait for LCD with timeout */
static void lcd_wait_write(void) static inline void lcd_wait_write(void)
{ {
int start = USEC_TIMER; int start = USEC_TIMER;
@ -127,7 +127,7 @@ void lcd_init_device(void)
{ {
lcd_cmd_and_data(R_DISPLAY_CONTROL, 0x0015); lcd_cmd_and_data(R_DISPLAY_CONTROL, 0x0015);
lcd_set_flip(false); lcd_set_flip(false);
lcd_cmd_and_data(R_ENTRY_MODE, 0x0010); lcd_cmd_and_data(R_ENTRY_MODE, 0x0000);
#ifdef APPLE_IPOD4G #ifdef APPLE_IPOD4G
outl(inl(0x6000d004) | 0x4, 0x6000d004); /* B02 enable */ 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 defined(IPOD_MINI) || defined(IPOD_MINI2G)
if (yesno) { if (yesno) {
/* 160x112, inverse SEG & COM order */ /* 168x112, inverse COM order */
lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x030d); lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x020d);
lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x8316); /* 22..131 */ 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; pix_offset = 6;
} else { } else {
/* 160x112 */ /* 168x112, inverse SEG order */
lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x000d); lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x010d);
lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x6d00); /* 0..109 */ lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x6d00); /* 0..109 */
addr_offset = 0; addr_offset = 20;
pix_offset = 0; pix_offset = 0;
} }
#else #else
if (yesno) { if (yesno) {
/* 160x128, inverse COM order */ /* 168x128, inverse SEG & COM order */
lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x020f); lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x030f);
lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x8304); /* 0..127 */ lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x8304); /* 0..127 */
addr_offset = (4 << 5) | 1; addr_offset = (4 << 5) | (20 - 1);
} else { } else {
/* 160x128, inverse SEG order */ /* 168x128 */
lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x010f); lcd_cmd_and_data(R_DRV_OUTPUT_CONTROL, 0x000f);
lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x7f00); /* 4..131 */ lcd_cmd_and_data(R_1ST_SCR_DRV_POS, 0x7f00); /* 4..131 */
addr_offset = 0; addr_offset = 20;
} }
#endif #endif
} }
@ -230,7 +230,7 @@ void lcd_update_rect(int x, int y, int width, int height)
for (; y <= ymax; y++) { for (; y <= ymax; y++) {
unsigned char *data, *data_end; 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_cmd_and_data(R_RAM_ADDR_SET, ram_addr);
lcd_prepare_cmd(R_RAM_DATA); 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) { if (pix_offset == 6) {
data -= 2; data -= 2;
data_end -= 1; data_end -= 1;
unsigned cur_word = *data++ >> 4; unsigned cur_word = *data++;
do { do {
cur_word |= *data++ << 4; cur_word = (cur_word << 8) | *data++;
cur_word |= *data++ << 12; cur_word = (cur_word << 8) | *data++;
lcd_send_data(cur_word & 0xffff); lcd_send_data((cur_word >> 4) & 0xffff);
cur_word >>= 16;
} while (data < data_end); } while (data < data_end);
} else } else
#endif #endif
{ {
do { do {
unsigned lowbyte = *data++; unsigned highbyte = *data++;
lcd_send_data(lowbyte | (*data++ << 8)); lcd_send_data((highbyte << 8) | *data++);
} while (data < data_end); } while (data < data_end);
} }
} }

View file

@ -402,7 +402,7 @@ int transform_bitmap(const struct RGBQUAD *src, int width, int height,
for (col = 0; col < width; col++) for (col = 0; col < width; col++)
{ {
(*dest)[row * dst_w + (col/4)] |= (*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; break;
} }