diff -ur qemu-2-orig/hw/omap3_lcd_panel_template.h qemu-2/hw/omap3_lcd_panel_template.h --- qemu-2-orig/hw/omap3_lcd_panel_template.h 2009-03-27 22:11:02.000000000 +0000 +++ qemu-2/hw/omap3_lcd_panel_template.h 2009-03-27 22:30:02.000000000 +0000 @@ -52,19 +52,169 @@ # define SWAP_WORDS 1 #endif - -static void glue(omap3_lcd_panel_draw_line16_, DEPTH)(PIXEL_TYPE *dest, - const uint16_t *src, unsigned int width) -{ -#if !defined(SWAP_WORDS) && DEPTH == 16 - memcpy(dest, src, width); -#else - uint16_t data; - unsigned int r, g, b; - const uint16_t *end = (const void *) src + width; - while (src < end) { - data = lduw_raw(src ++); - b = (data & 0x1f) << 3; +/* + * 1-bit colour + */ +static void glue(omap3_lcd_panel_draw_line1_, DEPTH)( + PIXEL_TYPE *dest, const uint8_t *src, unsigned int width, const uint32_t *pal) +{ + unsigned int v, r, g, b; + const uint8_t *end = src + (width>>3); + + while (src < end) { + v = ldub_raw((void *) (src++)); + b = pal[v&0x1] & 0xff; + g = (pal[v&0x1]>>8) & 0xff; + r = (pal[v&0x1]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + v=v>>1; + b = pal[v&0x1] & 0xff; + g = (pal[v&0x1]>>8) & 0xff; + r = (pal[v&0x1]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + v=v>>1; + b = pal[v&0x1] & 0xff; + g = (pal[v&0x1]>>8) & 0xff; + r = (pal[v&0x1]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + v=v>>1; + b = pal[v&0x1] & 0xff; + g = (pal[v&0x1]>>8) & 0xff; + r = (pal[v&0x1]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + v=v>>1; + b = pal[v&0x1] & 0xff; + g = (pal[v&0x1]>>8) & 0xff; + r = (pal[v&0x1]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + v=v>>1; + b = pal[v&0x1] & 0xff; + g = (pal[v&0x1]>>8) & 0xff; + r = (pal[v&0x1]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + v=v>>1; + b = pal[v&0x1] & 0xff; + g = (pal[v&0x1]>>8) & 0xff; + r = (pal[v&0x1]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + v=v>>1; + b = pal[v] & 0xff; + g = (pal[v]>>8) & 0xff; + r = (pal[v]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + } +} + +/* + * 2-bit colour + */ +static void glue(omap3_lcd_panel_draw_line2_, DEPTH)( + PIXEL_TYPE *dest, const uint8_t *src, unsigned int width, const uint32_t *pal) +{ + unsigned int v, r, g, b; + const uint8_t *end = src + (width>>2); + + while (src < end) { + v = ldub_raw((void *) (src++)); + b = pal[v&0x3] & 0xff; + g = (pal[v&0x3]>>8) & 0xff; + r = (pal[v&0x3]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + v=v>>2; + b = pal[v&0x3] & 0xff; + g = (pal[v&0x3]>>8) & 0xff; + r = (pal[v&0x3]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + v=v>>2; + b = pal[v&0x3] & 0xff; + g = (pal[v&0x3]>>8) & 0xff; + r = (pal[v&0x3]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + v=v>>2; + b = pal[v] & 0xff; + g = (pal[v]>>8) & 0xff; + r = (pal[v]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + } +} + +/* + * 4-bit colour + */ +static void glue(omap3_lcd_panel_draw_line4_, DEPTH)( + PIXEL_TYPE *dest, const uint8_t *src, unsigned int width, const uint32_t *pal) +{ + unsigned int v, r, g, b; + const uint8_t *end = src + (width>>1); + + while (src < end) { + v = ldub_raw((void *) (src++)); + b = pal[v&0xf] & 0xff; + g = (pal[v&0xf]>>8) & 0xff; + r = (pal[v&0xf]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + v=v>>4; + b = pal[v] & 0xff; + g = (pal[v]>>8) & 0xff; + r = (pal[v]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + } +} + +/* + * 8-bit colour + */ +static void glue(omap3_lcd_panel_draw_line8_, DEPTH)( + PIXEL_TYPE *dest, const uint8_t *src, unsigned int width, const uint32_t *pal) +{ + unsigned int v, r, g, b; + const uint8_t *end = src + width; + + while (src < end) { + v = ldub_raw((void *) (src++)); + r = pal[v] & 0xff; + g = (pal[v]>>8) & 0xff; + b = (pal[v]>>16) & 0xff; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + } +} + +/* + * 16-bit colour with alpha + */ +static void glue(omap3_lcd_panel_draw_line16a_, DEPTH)(PIXEL_TYPE *dest, + const uint16_t *src, unsigned int width, const uint32_t *pal) +{ + uint16_t data; + unsigned int r, g, b; + const uint16_t *end = src + width; + while (src < end) { + data = lduw_raw(src ++); + b = (data & 0xf) << 4; + data >>= 4; + g = (data & 0xf) << 4; + data >>= 4; + r = (data & 0xf) << 4; + data >>= 4; + COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); + } +} + +/* + * 16-bit colour + */ +static void glue(omap3_lcd_panel_draw_line16_, DEPTH)(PIXEL_TYPE *dest, + const uint16_t *src, unsigned int width, const uint32_t *pal) +{ +#if !defined(SWAP_WORDS) && DEPTH == 16 + memcpy(dest, src, width); +#else + uint16_t data; + unsigned int r, g, b; + const uint16_t *end = src + width; + while (src < end) { + data = lduw_raw(src ++); + b = (data & 0x1f) << 3; data >>= 5; g = (data & 0x3f) << 2; data >>= 6; @@ -91,12 +241,12 @@ /* No rotation */ static omap3_lcd_panel_fn_t glue(omap3_lcd_panel_draw_fn_, DEPTH)[0x10] = { - NULL, /*0x0*/ - NULL, /*0x1*/ - NULL, /*0x2*/ - NULL, /*0x3*/ - NULL, /*0x4:RGB 12 */ - NULL, /*0x5: ARGB16 */ + (omap3_lcd_panel_fn_t)glue(omap3_lcd_panel_draw_line1_, DEPTH), /*0x0*/ + (omap3_lcd_panel_fn_t)glue(omap3_lcd_panel_draw_line2_, DEPTH), /*0x1*/ + (omap3_lcd_panel_fn_t)glue(omap3_lcd_panel_draw_line4_, DEPTH), /*0x2*/ + (omap3_lcd_panel_fn_t)glue(omap3_lcd_panel_draw_line8_, DEPTH), /*0x3*/ + NULL, /*0x4:RGB 12 */ + (omap3_lcd_panel_fn_t)glue(omap3_lcd_panel_draw_line16a_, DEPTH), /*0x5: ARGB16 */ (omap3_lcd_panel_fn_t)glue(omap3_lcd_panel_draw_line16_, DEPTH), /*0x6: RGB 16 */ NULL, /*0x7*/ NULL, /*0x8: RGB 24 (un-packed in 32-bit container) */ diff -ur qemu-2-orig/hw/omap_dss.c qemu-2/hw/omap_dss.c --- qemu-2-orig/hw/omap_dss.c 2009-03-27 22:11:02.000000000 +0000 +++ qemu-2/hw/omap_dss.c 2009-03-27 22:40:53.000000000 +0000 @@ -955,6 +955,25 @@ (fb & ~TARGET_PAGE_MASK); } +static void *omap_rfbi_get_palette(struct omap_dss_s *s) +{ + target_phys_addr_t fb; + uint32_t pd; + + /* TODO */ + fb = s->dispc.l[0].addr[2]; + + pd = cpu_get_physical_page_desc(fb); + if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) + /* TODO */ + cpu_abort(cpu_single_env, "%s: palette outside RAM!\n", + __FUNCTION__); + else + return phys_ram_base + + (pd & TARGET_PAGE_MASK) + + (fb & ~TARGET_PAGE_MASK); +} + static void omap_rfbi_transfer_stop(struct omap_dss_s *s) { if (!s->rfbi.busy) @@ -1520,23 +1539,23 @@ /*omap3 lcd panel stuff*/ -/* Bytes(!) per pixel */ +/* Bits per pixel */ static const int omap3_lcd_panel_bpp[0x10] = { - 0, /* 0x0: BITMAP1 (CLUT) */ - 0, /* 0x1: BITMAP2 (CLUT) */ - 0, /* 0x2: BITMAP4 (CLUT) */ - 0, /* 0x3: BITMAP8 (CLUT) */ - 2, /* 0x4: RGB12 (unpacked 16-bit container)*/ - 2, /* 0x5: ARGB16 */ - 2, /* 0x6: RGB16 */ + 1, /* 0x0: BITMAP1 (CLUT) */ + 2, /* 0x1: BITMAP2 (CLUT) */ + 4, /* 0x2: BITMAP4 (CLUT) */ + 8, /* 0x3: BITMAP8 (CLUT) */ + 16, /* 0x4: RGB12 (unpacked 16-bit container)*/ + 16, /* 0x5: ARGB16 */ + 16, /* 0x6: RGB16 */ 0, /* 0x7: reserved */ - 4, /* 0x8: RGB24 (unpacked in 32-bit container) */ - 3, /* 0x9: RGB24 (packed in 24-bit container) */ + 32, /* 0x8: RGB24 (unpacked in 32-bit container) */ + 24, /* 0x9: RGB24 (packed in 24-bit container) */ 0, /* 0xa: reserved */ 0, /* 0xb: reserved */ - 4, /* 0xc: ARGB32 */ - 4, /* 0xd: RGBA32 */ - 4, /* 0xe: RGBx32 (24-bit RGB aligned on MSB of the 32-bit container) */ + 32, /* 0xc: ARGB32 */ + 32, /* 0xd: RGBA32 */ + 32, /* 0xe: RGBx32 (24-bit RGB aligned on MSB of the 32-bit container) */ 0, /* 0xf: reserved */ }; @@ -1600,7 +1619,7 @@ dss_Bpp = linesize / ds_get_width(s->state); dest += linesize * start_y; - dest += start_x * dss_Bpp; + dest += (start_x * dss_Bpp)>>3; if ((start_x + graphic_width) > lcd_width) copy_width = lcd_width - start_x; @@ -1608,9 +1627,15 @@ copy_width = graphic_width; copy_height = lcd_height>graphic_height ? graphic_height:lcd_height; + uint32_t *pal = 0; + if(dss->dispc.l[0].gfx_format < 4) + pal = (uint32_t *) omap_rfbi_get_palette(dss); + else + pal = (uint32_t *) src; // Avoid crash? + for (y = start_y; y < copy_height; y++) { - s->line_fn(dest, src, copy_width * lcd_Bpp); - src += graphic_width * lcd_Bpp; + s->line_fn(dest, src, copy_width, pal); + src += (graphic_width * lcd_Bpp)>>3; dest += linesize; } diff -ur qemu-2-orig/hw/omap.h qemu-2/hw/omap.h --- qemu-2-orig/hw/omap.h 2009-03-27 22:11:02.000000000 +0000 +++ qemu-2/hw/omap.h 2009-03-27 22:32:01.000000000 +0000 @@ -959,7 +959,7 @@ void (*block)(void *opaque, int dc, void *buf, size_t len, int pitch); uint16_t (*read)(void *opaque, int dc); }; -typedef void (*omap3_lcd_panel_fn_t)(uint8_t *, const uint8_t *, unsigned int); +typedef void (*omap3_lcd_panel_fn_t)(uint8_t *, const uint8_t *, unsigned int,const uint32_t *); struct omap3_lcd_panel_s; struct omap_dss_s; void omap_dss_reset(struct omap_dss_s *s); diff -ur qemu-2-orig/target-arm/helper.c qemu-2/target-arm/helper.c --- qemu-2-orig/target-arm/helper.c 2009-03-27 22:11:04.000000000 +0000 +++ qemu-2/target-arm/helper.c 2009-03-27 22:37:11.000000000 +0000 @@ -1583,7 +1583,13 @@ case 10: /* MMU TLB lockdown. */ /* ??? TLB lockdown not implemented. */ break; - case 12: /* Reserved. */ + case 12: + if((op1 == 0) && (op2 == 0) && (crm == 0)) + { + /* Exception vector base - ignore */ + break; + } + /* Else reserved. */ goto bad_reg; case 13: /* Process ID. */ switch (op2) { @@ -1904,7 +1910,25 @@ /* ??? TLB lockdown not implemented. */ return 0; case 11: /* TCM DMA control. */ - case 12: /* Reserved. */ + case 12: /* Interrupt status register */ + if((op1 == 0) && (op2 == 0) && (crm == 1)) + { + /* Just claim that both IRQ and FIQ are pending; the code below doesn't work reliably (or at all?) */ + return 0xC0; + /* switch(env->exception_index) + { + case EXCP_IRQ: + return 0x80; + case EXCP_FIQ: + return 0x40; + default: + return 0; + } */ + } + else if((op1 == 0) && (op2 == 0) && (crm == 0)) + { + return 0; + } goto bad_reg; case 13: /* Process ID. */ switch (op2) {