//#define DEBUG_VGA_MEM
//#define DEBUG_VGA_REG
-//#define DEBUG_S3
//#define DEBUG_BOCHS_VBE
-/* S3 VGA is deprecated - another graphic card will be emulated */
-//#define CONFIG_S3VGA
-
/* force some bits to zero */
const uint8_t sr_mask[8] = {
(uint8_t)~0xfc,
VGAState *vga_state;
int vga_io_memory;
+static void vga_screen_dump(void *opaque, const char *filename);
+
static uint32_t vga_ioport_read(void *opaque, uint32_t addr)
{
VGAState *s = opaque;
#ifdef DEBUG_VGA_REG
printf("vga: read CR%x = 0x%02x\n", s->cr_index, val);
#endif
-#ifdef DEBUG_S3
- if (s->cr_index >= 0x20)
- printf("S3: CR read index=0x%x val=0x%x\n",
- s->cr_index, val);
-#endif
break;
case 0x3ba:
case 0x3da:
case 0x12: /* veritcal display end */
s->cr[s->cr_index] = val;
break;
-
-#ifdef CONFIG_S3VGA
- /* S3 registers */
- case 0x2d:
- case 0x2e:
- case 0x2f:
- case 0x30:
- /* chip ID, cannot write */
- break;
- case 0x31:
- /* update start address */
- {
- int v;
- s->cr[s->cr_index] = val;
- v = (val >> 4) & 3;
- s->cr[0x69] = (s->cr[69] & ~0x03) | v;
- }
- break;
- case 0x51:
- /* update start address */
- {
- int v;
- s->cr[s->cr_index] = val;
- v = val & 3;
- s->cr[0x69] = (s->cr[69] & ~0x0c) | (v << 2);
- }
- break;
-#endif
default:
s->cr[s->cr_index] = val;
break;
}
-#ifdef DEBUG_S3
- if (s->cr_index >= 0x20)
- printf("S3: CR write index=0x%x val=0x%x\n",
- s->cr_index, val);
-#endif
break;
case 0x3ba:
case 0x3da:
return (r << 16) | (g << 8) | b;
}
+static inline unsigned int rgb_to_pixel32bgr(unsigned int r, unsigned int g, unsigned b)
+{
+ return (b << 16) | (g << 8) | r;
+}
+
#define DEPTH 8
#include "vga_template.h"
#define DEPTH 32
#include "vga_template.h"
+#define BGR_FORMAT
+#define DEPTH 32
+#include "vga_template.h"
+
static unsigned int rgb_to_pixel8_dup(unsigned int r, unsigned int g, unsigned b)
{
unsigned int col;
return col;
}
+static unsigned int rgb_to_pixel32bgr_dup(unsigned int r, unsigned int g, unsigned b)
+{
+ unsigned int col;
+ col = rgb_to_pixel32bgr(r, g, b);
+ return col;
+}
+
/* return true if the palette was modified */
static int update_palette16(VGAState *s)
{
{
/* compute line_offset in bytes */
line_offset = s->cr[0x13];
-#ifdef CONFIG_S3VGA
- {
- uinr32_t v;
- v = (s->cr[0x51] >> 4) & 3; /* S3 extension */
- if (v == 0)
- v = (s->cr[0x43] >> 2) & 1; /* S3 extension */
- line_offset |= (v << 8);
- }
-#endif
line_offset <<= 3;
-
+
/* starting address */
start_addr = s->cr[0x0d] | (s->cr[0x0c] << 8);
-#ifdef CONFIG_S3VGA
- start_addr |= (s->cr[0x69] & 0x1f) << 16; /* S3 extension */
-#endif
}
*pline_offset = line_offset;
*pstart_addr = start_addr;
return full_update;
}
-static inline int get_depth_index(int depth)
+#define NB_DEPTHS 5
+
+static inline int get_depth_index(DisplayState *s)
{
- switch(depth) {
+ switch(s->depth) {
default:
case 8:
return 0;
case 16:
return 2;
case 32:
- return 3;
+ if (s->bgr)
+ return 4;
+ else
+ return 3;
}
}
-static vga_draw_glyph8_func *vga_draw_glyph8_table[4] = {
+static vga_draw_glyph8_func *vga_draw_glyph8_table[NB_DEPTHS] = {
vga_draw_glyph8_8,
vga_draw_glyph8_16,
vga_draw_glyph8_16,
vga_draw_glyph8_32,
+ vga_draw_glyph8_32,
};
-static vga_draw_glyph8_func *vga_draw_glyph16_table[4] = {
+static vga_draw_glyph8_func *vga_draw_glyph16_table[NB_DEPTHS] = {
vga_draw_glyph16_8,
vga_draw_glyph16_16,
vga_draw_glyph16_16,
vga_draw_glyph16_32,
+ vga_draw_glyph16_32,
};
-static vga_draw_glyph9_func *vga_draw_glyph9_table[4] = {
+static vga_draw_glyph9_func *vga_draw_glyph9_table[NB_DEPTHS] = {
vga_draw_glyph9_8,
vga_draw_glyph9_16,
vga_draw_glyph9_16,
vga_draw_glyph9_32,
+ vga_draw_glyph9_32,
};
static const uint8_t cursor_glyph[32 * 4] = {
}
cursor_ptr = s->vram_ptr + (s->start_addr + cursor_offset) * 4;
- depth_index = get_depth_index(s->ds->depth);
+ depth_index = get_depth_index(s->ds);
if (cw == 16)
vga_draw_glyph8 = vga_draw_glyph16_table[depth_index];
else
VGA_DRAW_LINE_NB,
};
-static vga_draw_line_func *vga_draw_line_table[4 * VGA_DRAW_LINE_NB] = {
+static vga_draw_line_func *vga_draw_line_table[NB_DEPTHS * VGA_DRAW_LINE_NB] = {
vga_draw_line2_8,
vga_draw_line2_16,
vga_draw_line2_16,
vga_draw_line2_32,
+ vga_draw_line2_32,
vga_draw_line2d2_8,
vga_draw_line2d2_16,
vga_draw_line2d2_16,
vga_draw_line2d2_32,
+ vga_draw_line2d2_32,
vga_draw_line4_8,
vga_draw_line4_16,
vga_draw_line4_16,
vga_draw_line4_32,
+ vga_draw_line4_32,
vga_draw_line4d2_8,
vga_draw_line4d2_16,
vga_draw_line4d2_16,
vga_draw_line4d2_32,
+ vga_draw_line4d2_32,
vga_draw_line8d2_8,
vga_draw_line8d2_16,
vga_draw_line8d2_16,
vga_draw_line8d2_32,
+ vga_draw_line8d2_32,
vga_draw_line8_8,
vga_draw_line8_16,
vga_draw_line8_16,
vga_draw_line8_32,
+ vga_draw_line8_32,
vga_draw_line15_8,
vga_draw_line15_15,
vga_draw_line15_16,
vga_draw_line15_32,
+ vga_draw_line15_32bgr,
vga_draw_line16_8,
vga_draw_line16_15,
vga_draw_line16_16,
vga_draw_line16_32,
+ vga_draw_line16_32bgr,
vga_draw_line24_8,
vga_draw_line24_15,
vga_draw_line24_16,
vga_draw_line24_32,
+ vga_draw_line24_32bgr,
vga_draw_line32_8,
vga_draw_line32_15,
vga_draw_line32_16,
vga_draw_line32_32,
+ vga_draw_line32_32bgr,
+};
+
+typedef unsigned int rgb_to_pixel_dup_func(unsigned int r, unsigned int g, unsigned b);
+
+static rgb_to_pixel_dup_func *rgb_to_pixel_dup_table[NB_DEPTHS] = {
+ rgb_to_pixel8_dup,
+ rgb_to_pixel15_dup,
+ rgb_to_pixel16_dup,
+ rgb_to_pixel32_dup,
+ rgb_to_pixel32bgr_dup,
};
static int vga_get_bpp(VGAState *s)
break;
}
}
- vga_draw_line = vga_draw_line_table[v * 4 + get_depth_index(s->ds->depth)];
+ vga_draw_line = vga_draw_line_table[v * NB_DEPTHS + get_depth_index(s->ds)];
if (disp_width != s->last_width ||
height != s->last_height) {
#define GMODE_GRAPH 1
#define GMODE_BLANK 2
-void vga_update_display(void)
+static void vga_update_display(void *opaque)
{
- VGAState *s = vga_state;
+ VGAState *s = (VGAState *)opaque;
int full_update, graphic_mode;
if (s->ds->depth == 0) {
/* nothing to do */
} else {
- switch(s->ds->depth) {
- case 8:
- s->rgb_to_pixel = rgb_to_pixel8_dup;
- break;
- case 15:
- s->rgb_to_pixel = rgb_to_pixel15_dup;
- break;
- default:
- case 16:
- s->rgb_to_pixel = rgb_to_pixel16_dup;
- break;
- case 32:
- s->rgb_to_pixel = rgb_to_pixel32_dup;
- break;
- }
+ s->rgb_to_pixel =
+ rgb_to_pixel_dup_table[get_depth_index(s->ds)];
full_update = 0;
if (!(s->ar_index & 0x20)) {
}
/* force a full display refresh */
-void vga_invalidate_display(void)
+static void vga_invalidate_display(void *opaque)
{
- VGAState *s = vga_state;
+ VGAState *s = (VGAState *)opaque;
s->last_width = -1;
s->last_height = -1;
static void vga_reset(VGAState *s)
{
memset(s, 0, sizeof(VGAState));
-#ifdef CONFIG_S3VGA
- /* chip ID for 8c968 */
- s->cr[0x2d] = 0x88;
- s->cr[0x2e] = 0xb0;
- s->cr[0x2f] = 0x01; /* XXX: check revision code */
- s->cr[0x30] = 0xe1;
-#endif
s->graphic_mode = -1; /* force full update */
}
uint32_t addr, uint32_t size, int type)
{
VGAState *s = vga_state;
-
- cpu_register_physical_memory(addr, s->vram_size, s->vram_offset);
+ if (region_num == PCI_ROM_SLOT) {
+ cpu_register_physical_memory(addr, s->bios_size, s->bios_offset);
+ } else {
+ cpu_register_physical_memory(addr, s->vram_size, s->vram_offset);
+ }
}
void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base,
s->get_bpp = vga_get_bpp;
s->get_offsets = vga_get_offsets;
s->get_resolution = vga_get_resolution;
+ graphic_console_init(s->ds, vga_update_display, vga_invalidate_display,
+ vga_screen_dump, s);
/* XXX: currently needed for display */
vga_state = s;
}
int vga_initialize(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
- unsigned long vga_ram_offset, int vga_ram_size)
+ unsigned long vga_ram_offset, int vga_ram_size,
+ unsigned long vga_bios_offset, int vga_bios_size)
{
VGAState *s;
/* XXX: vga_ram_size must be a power of two */
pci_register_io_region(d, 0, vga_ram_size,
PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map);
+ if (vga_bios_size != 0) {
+ unsigned int bios_total_size;
+ s->bios_offset = vga_bios_offset;
+ s->bios_size = vga_bios_size;
+ /* must be a power of two */
+ bios_total_size = 1;
+ while (bios_total_size < vga_bios_size)
+ bios_total_size <<= 1;
+ pci_register_io_region(d, PCI_ROM_SLOT, bios_total_size,
+ PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map);
+ }
} else {
#ifdef CONFIG_BOCHS_VBE
/* XXX: use optimized standard vga accesses */
/* save the vga display in a PPM image even if no display is
available */
-void vga_screen_dump(const char *filename)
+static void vga_screen_dump(void *opaque, const char *filename)
{
- VGAState *s = vga_state;
+ VGAState *s = (VGAState *)opaque;
DisplayState *saved_ds, ds1, *ds = &ds1;
/* XXX: this is a little hackish */
- vga_invalidate_display();
+ vga_invalidate_display(s);
saved_ds = s->ds;
memset(ds, 0, sizeof(DisplayState));
s->ds = ds;
s->graphic_mode = -1;
- vga_update_display();
+ vga_update_display(s);
if (ds->data) {
ppm_save(filename, ds->data, vga_save_w, vga_save_h,