On Thu, Jun 16, 2011 at 3:02 AM, Andreas Färber <andreas.faer...@web.de> wrote: > The IBM E15 is equivalent to an S3 Vision864. > > Lacking S3 SDAC (86C716) support, the DAC indizes are translated > to greyscale colors. This works sufficiently to observe firmware > boot progress. > > Cc: Hervé Poussineau <hpous...@reactos.org> > > Fixed off-by-one drawing issue. > Replaced hardcoded color for RECT. > Separate I/O debug output for readability. > Start cleaning up the naming s3 vs. ibm8514. > Prepare support for DAC_MASK, DAC_R_INDEX, DAC_W_INDEX, DAC_DATA regs. > > Cc: Roy Tam <roy...@gmail.com> > Signed-off-by: Andreas Färber <andreas.faer...@web.de> > --- > Makefile.objs | 1 + > default-configs/ppc-softmmu.mak | 1 + > hw/pci_ids.h | 3 + > hw/ppc_prep.c | 2 + > hw/vga-ibm8514.c | 780 > +++++++++++++++++++++++++++++++++++++++ > 5 files changed, 787 insertions(+), 0 deletions(-) > create mode 100644 hw/vga-ibm8514.c > > diff --git a/Makefile.objs b/Makefile.objs > index 7ceeee5..95dcd91 100644 > --- a/Makefile.objs > +++ b/Makefile.objs > @@ -270,6 +270,7 @@ hw-obj-y += qdev-addr.o > hw-obj-$(CONFIG_VGA_PCI) += vga-pci.o > hw-obj-$(CONFIG_VGA_ISA) += vga-isa.o > hw-obj-$(CONFIG_VGA_ISA_MM) += vga-isa-mm.o > +hw-obj-$(CONFIG_VGA_IBM8514) += vga-ibm8514.o > hw-obj-$(CONFIG_VMWARE_VGA) += vmware_vga.o > hw-obj-$(CONFIG_VMMOUSE) += vmmouse.o > > diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak > index 303929f..f9c97b7 100644 > --- a/default-configs/ppc-softmmu.mak > +++ b/default-configs/ppc-softmmu.mak > @@ -6,6 +6,7 @@ CONFIG_ISA_MMIO=y > CONFIG_ESCC=y > CONFIG_M48T59=y > CONFIG_VGA_PCI=y > +CONFIG_VGA_IBM8514=y > CONFIG_SERIAL=y > CONFIG_PARALLEL=y > CONFIG_I8254=y > diff --git a/hw/pci_ids.h b/hw/pci_ids.h > index d3bef0e..821421c 100644 > --- a/hw/pci_ids.h > +++ b/hw/pci_ids.h > @@ -97,6 +97,9 @@ > #define PCI_VENDOR_ID_FREESCALE 0x1957 > #define PCI_DEVICE_ID_MPC8533E 0x0030 > > +#define PCI_VENDOR_ID_S3 0x5333 > +#define PCI_DEVICE_ID_S3_864 0x88c0 > + > #define PCI_VENDOR_ID_INTEL 0x8086 > #define PCI_DEVICE_ID_INTEL_82378 0x0484 > #define PCI_DEVICE_ID_INTEL_82441 0x1237 > diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c > index 6ae1635..c215b0f 100644 > --- a/hw/ppc_prep.c > +++ b/hw/ppc_prep.c > @@ -747,6 +747,8 @@ static void ibm_40p_init(ram_addr_t ram_size, > qdev_prop_set_uint8(&isa->qdev, "board-identification", 0xfc); > qdev_init_nofail(&isa->qdev); > > + pci_create_simple(pci_bus, PCI_DEVFN(2, 0), "s3-vision864"); > + > /* Super I/O (parallel + serial ports) */ > isa = isa_create("isa-pc87312"); > qdev_prop_set_chr(&isa->qdev, "parallel", parallel_hds[0]); > diff --git a/hw/vga-ibm8514.c b/hw/vga-ibm8514.c > new file mode 100644 > index 0000000..a87afe1 > --- /dev/null > +++ b/hw/vga-ibm8514.c > @@ -0,0 +1,780 @@ > +/* > + * QEMU PCI IBM 8514/A Emulator. > + * > + * Copyright (c) 2010 Hervé Poussineau > + * Copyright (c) 2010-2011 Andreas Färber > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > copy > + * of this software and associated documentation files (the "Software"), to > deal > + * in the Software without restriction, including without limitation the > rights > + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell > + * copies of the Software, and to permit persons to whom the Software is > + * furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING > FROM, > + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN > + * THE SOFTWARE. > + */ > + > +/* Documentation available at > + * http://www.datasheetarchive.com/Indexer/Datasheet-06/DSA0091551.html > + */ > + > +#include "console.h" > +#include "pci.h" > +#include "vga_int.h" > +#include "pixel_ops.h" > + > +//#define DEBUG_8514 > +//#define DEBUG_8514_IO > + > +#ifdef DEBUG_8514 > +#define DPRINTF(fmt, ...) \ > +do { printf("8514: " fmt , ## __VA_ARGS__); } while (0) > +#else > +#define DPRINTF(fmt, ...) do {} while (0) > +#endif > +#ifdef DEBUG_8514_IO > +#define DPRINTF_IO(fmt, ...) \ > +do { printf("8514: " fmt , ## __VA_ARGS__); } while (0) > +#else > +#define DPRINTF_IO(fmt, ...) do {} while (0) > +#endif > +#define BADF(fmt, ...) \ > +do { fprintf(stderr, "8514 ERROR: " fmt , ## __VA_ARGS__);} while (0) > + > +enum { > + REG_CMD = 0x9AE8, > + REG_PIX_TRANS = 0xE2E8, > +}; > + > +#define GP_STAT_BUSY 0x0200 > + > +#define CMD_WRTDATA 0x0001 > +#define CMD_PLANAR 0x0002 > +#define CMD_LASTPIX 0x0004 > +#define CMD_LINETYPE 0x0008 > +#define CMD_DRAW 0x0010 > +#define CMD_INC_X 0x0020 > +#define CMD_YMAJAXIS 0x0040 > +#define CMD_INC_Y 0x0080 > +#define CMD_PCDATA 0x0100 > +#define CMD_16BIT 0x0200 > +#define CMD_BYTSEQ 0x1000 > +#define CMD_CMD_MASK 0xE000 > + > +#define CMD_CMD_NOP 0x0000 > +#define CMD_CMD_LINE 0x2000 > +#define CMD_CMD_RECT 0x4000 > +#define CMD_CMD_RECTV1 0x6000 > +#define CMD_CMD_RECTV2 0x8000 > +#define CMD_CMD_LINEAF 0xA000 > +#define CMD_CMD_BITBLT 0xC000 > + > +#define BKGD_MIX_BSS_MASK 0x0060 > +enum { > + BKGD_MIX_BSS_BKGD = 0x0000, > + BKGD_MIX_BSS_FRGD = 0x0020, > + BKGD_MIX_BSS_PIX = 0x0040, > + BKGD_MIX_BSS_BMP = 0x0060, > +}; > + > +#define FRGD_MIX_FSS_MASK 0x0060 > +enum { > + FRGD_MIX_FSS_BKGD = 0x0000, > + FRGD_MIX_FSS_FRGD = 0x0020, > + FRGD_MIX_FSS_PIX = 0x0040, > + FRGD_MIX_FSS_BMP = 0x0060, > +}; > + > +#define PIX_CNTL_MIXSEL_MASK 0x00C0 > +enum { > + PIX_CNTL_MIXSEL_FOREMIX = 0x0000, > + PIX_CNTL_MIXSEL_PATTERN = 0x0040, > + PIX_CNTL_MIXSEL_VAR = 0x0080, > + PIX_CNTL_MIXSEL_TRANS = 0x00C0, > +}; > + > +// 40f3 = CMD_CMD_RECT | CMD_INC_Y | CMD_YMAJAXIS | CMD_INC_X | CMD_DRAW | > CMD_PLANAR | CMD_WRTDATA > +// 4331 = CMD_CMD_RECT | CMD_16BIT | CMD_PCDATA | CMD_INC_X | CMD_DRAW | > CMD_WRTDATA > +// c0b3 = CMD_CMD_BITBLT | CMD_INC_Y | CMD_INC_X | CMD_DRAW | CMD_PLANAR | > CMD_WRTDATA
C89 comments? > + > +typedef struct IBM8514State { > + VGACommonState vga; > + uint16_t maj_axis, min_axis; > + > + uint8_t dac_mask; /* 02ea */ > + uint8_t dac_r_index; /* 02eb */ > + uint8_t dac_w_index; /* 02ec */ > + uint8_t dac_state[4]; > + > + uint16_t disp_stat; /* 02e8 */ > + uint16_t h_disp; /* 06e8 */ > + uint16_t h_sync_strt; /* 0ae8 */ > + uint16_t h_sync_wid; /* 0ee8 */ > + uint16_t v_total; /* 12e8 */ > + uint16_t v_disp; /* 16e8 */ > + uint16_t v_sync_strt; /* 1ae8 */ > + uint16_t v_sync_wid; /* 1ee8 */ > + uint16_t disp_cntl; /* 22e8 */ > + uint16_t h_total; /* 26e8 */ > + uint16_t subsys_cntl; /* 42e8 (W) */ > + uint16_t subsys_stat; /* 42e8 (R) */ > + uint16_t rom_page_sel; /* 46e8 */ > + uint16_t advfunc_cntl; /* 4ae8 */ > + uint16_t cur_y; /* 82e8 */ > + uint16_t cur_x; /* 86e8 */ > + uint16_t desty_axstep; /* 8ae8 */ > + uint16_t destx_diastp; /* 8ee8 */ > + uint16_t err_term; /* 92e8 */ > + uint16_t maj_axis_pcnt; /* 96e8 */ > + uint16_t gp_stat; /* 9ae8 (R) */ > + uint16_t cmd; /* 9ae8 (W) */ > + uint16_t short_stroke; /* 9ee8 */ > + uint16_t bkgd_color; /* a2e8 */ > + uint16_t frgd_color; /* a6e8 */ > + uint16_t wrt_mask; /* aae8 */ > + uint16_t rd_mask; /* aee8 */ > + uint16_t color_cmp; /* b2e8 */ > + uint16_t bkgd_mix; /* b6e8 */ > + uint16_t frgd_mix; /* bae8 */ > + uint16_t mfc[16]; /* bee8 */ > + uint16_t pix_trans; /* e2e8 */ > +} IBM8514State; > + > +#define dac_byte dac_state[3] > + > +#define min_axis_pcnt mfc[0] > +#define scissors_t mfc[1] > +#define scissors_l mfc[2] > +#define scissors_b mfc[3] > +#define scissors_r mfc[4] > +#define mem_cntl mfc[5] > +#define pattern_l mfc[8] > +#define pattern_h mfc[9] > +#define pix_cntl mfc[10] > + > +static VMStateDescription vmstate_ibm8514 = { > + .version_id = 1, > + .minimum_version_id = 1, > + .fields = (VMStateField []) { > + VMSTATE_END_OF_LIST() > + }, > +}; > + > +static inline void do_cmd_done(IBM8514State *s) > +{ > + s->gp_stat &= ~GP_STAT_BUSY; > +} > + > +static void do_cmd_write_pixel(IBM8514State *s, uint16_t value) > +{ > + uint16_t maj_axis_pcnt = s->maj_axis_pcnt + 1; > + uint8_t* p8 = s->vga.vram_ptr + (s->cur_y * 640 + s->cur_x) * 4; > + int dx = s->cmd & CMD_INC_X ? 1 : -1; > + int dy = s->cmd & CMD_INC_Y ? 1 : -1; > + > + if (!(s->gp_stat & GP_STAT_BUSY)) { > + return; > + } > + > + ++s->maj_axis; > + if ((s->maj_axis < maj_axis_pcnt) || > + (s->maj_axis == maj_axis_pcnt && !(s->cmd & CMD_LASTPIX))) { > + p8[0] = p8[1] = p8[2] = p8[3] = value; > + } > + if (s->maj_axis < maj_axis_pcnt) { > + s->cur_x += dx; > + } else if (s->maj_axis == maj_axis_pcnt) { > + if ((maj_axis_pcnt % 2 == 0) || !(s->cmd & CMD_16BIT)) { > + s->maj_axis = 0; > + } > + s->cur_x -= (s->maj_axis_pcnt) * dx; > + s->cur_y += dy; > + s->min_axis++; > + if (s->min_axis == s->min_axis_pcnt + 1) { > + do_cmd_done(s); > + } > + } else { > + //DPRINTF("%s: (skip - maj_axis = %u, maj_axis_pcnt = %u)\n", > + // __func__, s->maj_axis, maj_axis_pcnt); > + s->maj_axis = 0; > + } > +} > + > +static uint16_t get_source_operand(IBM8514State *s) > +{ > + switch (s->pix_cntl & PIX_CNTL_MIXSEL_MASK) { > + case PIX_CNTL_MIXSEL_FOREMIX: > + switch (s->frgd_mix & FRGD_MIX_FSS_MASK) { > + case FRGD_MIX_FSS_BKGD: > + return s->bkgd_color & 0xff; > + case FRGD_MIX_FSS_FRGD: > + return s->frgd_color & 0xff; > + default: > + BADF("%s: Unimplemented FSS %x\n", > + __func__, (s->frgd_mix & FRGD_MIX_FSS_MASK) >> 5); > + return 0; > + } > + default: > + BADF("%s: Unimplemented MIXSEL %x\n", > + __func__, (s->pix_cntl & PIX_CNTL_MIXSEL_MASK) >> 6); > + return 0; > + } > +} > + > +static void do_cmd_init(IBM8514State *s) > +{ > + s->gp_stat |= GP_STAT_BUSY; > + s->maj_axis = 0; > + s->min_axis = 0; > + > + if ((s->cmd & CMD_CMD_MASK) == CMD_CMD_RECT) { > + DPRINTF("cmd RECT: cur_x=%d cur_y=%d inc_x=%d inc_y=%d width=%d > height=%d\n", > + s->cur_x, s->cur_y, > + s->cmd & CMD_INC_X ? 1 : -1, s->cmd & CMD_INC_Y ? 1 : -1, > + s->maj_axis_pcnt, s->min_axis_pcnt); > + > + if (!(s->cmd & CMD_PCDATA)) { > + while (s->gp_stat & GP_STAT_BUSY) { > + do_cmd_write_pixel(s, get_source_operand(s)); > + } > + } > + } > +} > + > +static void do_cmd(IBM8514State *s) > +{ > + DPRINTF("%s: execute cmd %04x\n", __func__, s->cmd); > + > + do_cmd_init(s); > +} > + > +static uint32_t ibm8514_ramdac_ioport_readb(void *opaque, uint32_t addr) > +{ > + IBM8514State *s = opaque; > + uint32_t val; > + > + switch (addr) { > + case 0x02ea: > + val = s->dac_mask; > + break; > + case 0x02eb: > + val = s->dac_r_index; > + break; > + case 0x02ec: > + val = s->dac_w_index; > + break; > + case 0x02ed: > + if (s->dac_byte == 0) { > + // XXX load dac_state[0-2] from palette > + } > + val = s->dac_state[s->dac_byte]; > + s->dac_byte = (s->dac_byte + 1) % 3; > + if (s->dac_byte == 0) { > + s->dac_r_index++; > + s->dac_w_index++; > + } > + break; > + default: > + BADF("%s: invalid register at 0x%04x\n", __func__, addr); > + val = 0; > + break; > + } > + DPRINTF_IO("%s: read %02x at %04x\n", __func__, val, addr); > + return val; > +} > + > +static void ibm8514_ramdac_ioport_writeb(void *opaque, uint32_t addr, > uint32_t val) > +{ > + IBM8514State *s = opaque; > + > + DPRINTF_IO("%s: write %02x at %04x\n", __func__, val, addr); > + switch (addr) { > + case 0x02ea: > + s->dac_mask = val & 0xff; > + break; > + case 0x02eb: > + s->dac_r_index = val & 0xff; > + s->dac_byte = 0; > + break; > + case 0x02ec: > + s->dac_w_index = val & 0xff; > + s->dac_byte = 0; > + break; > + case 0x02ed: > + s->dac_state[s->dac_byte] = val & 0xff; > + s->dac_byte = (s->dac_byte + 1) % 3; > + if (s->dac_byte == 0) { > + // XXX store s->dac_state[0-2] to palette > + s->dac_r_index++; > + s->dac_w_index++; > + } > + break; > + default: > + BADF("%s: invalid register at 0x%04x\n", __func__, addr); > + break; > + } > +} > + > +static uint16_t* ibm8514_get_register(IBM8514State *s, uint32_t addr, int > is_write, uint32_t* val_if_write) > +{ > + uint16_t *p; > + > + switch (addr) { > + case 0x02e8: > + p = is_write ? &s->h_total : &s->disp_stat; > + break; > + case 0x06e8: > + p = is_write ? &s->h_disp : NULL; > + break; > + case 0x0ae8: > + p = is_write ? &s->h_sync_strt : NULL; > + break; > + case 0x0ee8: > + p = is_write ? &s->h_sync_wid : NULL; > + break; > + case 0x12e8: > + p = is_write ? &s->v_total : NULL; > + break; > + case 0x16e8: > + p = is_write ? &s->v_disp : NULL; > + break; > + case 0x1ae8: > + p = is_write ? &s->v_sync_strt : NULL; > + break; > + case 0x1ee8: > + p = is_write ? &s->v_sync_wid : NULL; > + break; > + case 0x22e8: > + p = is_write ? &s->disp_cntl : NULL; > + break; > + case 0x26e8: > + p = is_write ? NULL: &s->h_total; > + break; > + case 0x42e8: > + p = is_write ? &s->subsys_cntl : &s->subsys_stat; > + break; > + case 0x46e8: > + p = is_write ? &s->rom_page_sel : NULL; > + break; > + case 0x4ae8: > + p = is_write ? &s->advfunc_cntl : NULL; > + break; > + case 0x82e8: > + p = &s->cur_y; > + break; > + case 0x86e8: > + p = &s->cur_x; > + break; > + case 0x8ae8: > + p = is_write ? &s->desty_axstep : NULL; > + break; > + case 0x8ee8: > + p = is_write ? &s->destx_diastp : NULL; > + break; > + case 0x92e8: > + p = &s->err_term; > + break; > + case 0x96e8: > + p = is_write ? &s->maj_axis_pcnt : NULL; > + break; > + case 0x9ae8: > + p = is_write ? &s->cmd : &s->gp_stat; > + break; > + case 0x9ee8: > + p = is_write ? &s->short_stroke : NULL; > + break; > + case 0xa2e8: > + p = is_write ? &s->bkgd_color : NULL; > + break; > + case 0xa6e8: > + p = is_write ? &s->frgd_color : NULL; > + break; > + case 0xaae8: > + p = is_write ? &s->wrt_mask : NULL; > + break; > + case 0xaee8: > + p = is_write ? &s->rd_mask : NULL; > + break; > + case 0xb2e8: > + p = is_write ? &s->color_cmp : NULL; > + break; > + case 0xb6e8: > + p = is_write ? &s->bkgd_mix : NULL; > + break; > + case 0xbae8: > + p = is_write ? &s->frgd_mix : NULL; > + break; > + case 0xbee8: > + if (is_write) { > + p = &s->mfc[(*val_if_write >> 12) & 0xf]; > + *val_if_write &= 0x0fff; > + } else { > + p = NULL; > + } > + break; > + case 0xe2e8: > + p = &s->pix_trans; > + break; > + default: > + BADF("%s: invalid register at 0x%x\n", __func__, addr); > + p = NULL; > + break; > + } > + > + return p; > +} > + > +static uint32_t ibm8514_ioport_readb(void *opaque, uint32_t addr) > +{ > + IBM8514State *s = opaque; > + uint32_t val; > + uint16_t *p; > + > + p = ibm8514_get_register(s, addr & ~0x1, 0, NULL); > + > + if (p) { > + val = (be16_to_cpu(*p) >> ((~addr & 1) * 8)) & 0xff; > + } else { > + val = 0; > + } > + > + DPRINTF_IO("%s: read %x at %x\n", __func__, val, addr); > + return val; > +} > + > +static uint32_t ibm8514_ioport_readw(void *opaque, uint32_t addr) > +{ > + IBM8514State *s = opaque; > + uint32_t val; > + uint16_t *p; > + > + p = ibm8514_get_register(s, addr, 0, NULL); > + > + if (p) { > + val = be16_to_cpu(*p); > + } else { > + val = 0; > + } > + > + DPRINTF_IO("%s: read %x at %x\n", __func__, val, addr); > + return val; > +} > + > +static void ibm8514_ioport_writeb(void *opaque, uint32_t addr, uint32_t val) > +{ > + IBM8514State *s = opaque; > + uint16_t *p; > + uint8_t *c; > + > + DPRINTF_IO("%s: write %x at %x\n", __func__, val, addr); > + p = ibm8514_get_register(s, addr & ~0x1, 1, &val); > + > + if (p) { > + c = (uint8_t*)p; > + c[~addr & 1] = val; > + } > + if ((addr & ~0x1) == REG_CMD) { > + do_cmd(s); > + } else if ((addr & ~0x1) == REG_PIX_TRANS) { > + BADF("%s: ibm8514: 8-byte PIX_TRANS access (0x%08" PRIx32 ")\n", > + __func__, addr); > + } > +} > + > +static void ibm8514_ioport_writew(void *opaque, uint32_t addr, uint32_t val) > +{ > + IBM8514State *s = opaque; > + uint16_t *p; > + > + val = cpu_to_be16(val); > + DPRINTF_IO("%s: write %x at %x\n", __func__, val, addr); > + p = ibm8514_get_register(s, addr, 1, &val); > + > + if (p) { > + *p = val & 0xffff; > + } > + if (addr == REG_CMD) { > + do_cmd(s); > + } else if (addr == REG_PIX_TRANS) { > + if (!(s->cmd & CMD_16BIT)) { > + do_cmd_write_pixel(s, val & 0xff); > + } else if (s->cmd & CMD_BYTSEQ) { > + do_cmd_write_pixel(s, val & 0xff); > + do_cmd_write_pixel(s, val >> 8); > + } else { > + do_cmd_write_pixel(s, val >> 8); > + do_cmd_write_pixel(s, val & 0xff); > + } > + } > +} > + > +static void ibm8514_register_ramdac_port(IBM8514State *s, uint32_t addr) > +{ > + register_ioport_read(addr, 1, 1, ibm8514_ramdac_ioport_readb, s); > + register_ioport_write(addr, 1, 1, ibm8514_ramdac_ioport_writeb, s); > +} > + > +static void ibm8514_register_port(IBM8514State *s, uint32_t addr) > +{ > + register_ioport_read(addr, 2, 1, ibm8514_ioport_readb, s); > + register_ioport_read(addr, 1, 2, ibm8514_ioport_readw, s); > + register_ioport_write(addr, 2, 1, ibm8514_ioport_writeb, s); > + register_ioport_write(addr, 1, 2, ibm8514_ioport_writew, s); > +} > + > +static void my_update_display(void *opaque) > +{ > + VGACommonState *s = opaque; > + int w; > + uint8_t *vram; > + uint8_t *data_display, *dd; > + int x, y; > + unsigned int (*rgb_to_pixel)(unsigned int r, unsigned int g, unsigned > int b); > + > + if (ds_get_width(s->ds) != 640 || ds_get_height(s->ds) != 480) { > + qemu_console_resize(s->ds, 640, 480); > + } > + > + switch (ds_get_bits_per_pixel(s->ds)) { > + case 8: > + rgb_to_pixel = rgb_to_pixel8; > + w = 1; > + break; > + case 15: > + rgb_to_pixel = rgb_to_pixel15; > + w = 2; > + break; > + case 16: > + rgb_to_pixel = rgb_to_pixel16; > + w = 2; > + break; > + case 32: > + rgb_to_pixel = rgb_to_pixel32; > + w = 4; > + break; > + default: > + BADF("unknown host depth %d\n", ds_get_bits_per_pixel(s->ds)); > + return; > + } > + > + vram = s->vram_ptr; > + /* XXX: out of range in vram? */ > + data_display = dd = ds_get_data(s->ds); > + for (y = 0; y < 480; y++) { > + for (x = 0; x < 640; x++) { > + unsigned int color; > + color = (*rgb_to_pixel)(vram[0], vram[1], vram[2]); > + memcpy(dd, &color, w); Please take a look at tcx.c for a 8 bit mode frame buffer with palette translation. Also VGA_DIRTY bit handling should be added to this loop to speed it up. > + dd += w; > + vram += 4; > + } > + data_display = dd = data_display + ds_get_linesize(s->ds); > + } > + > + dpy_update(s->ds, 0, 0, 640, 480); > +} > + > +static void ibm8514_init(IBM8514State *s) > +{ > + VGACommonState *vga = &s->vga; > + > + vga->vram_size = 0x200000; > + > + /* vga + console init */ > + vga_common_init(vga, vga->vram_size); > + vga_init(vga); > + > + vga->ds = graphic_console_init(/*vga->update*/my_update_display, > vga->invalidate, > + vga->screen_dump, vga->text_update, > + vga); > + > + ibm8514_register_port(s, 0x02e8); > + ibm8514_register_ramdac_port(s, 0x02ea); > + ibm8514_register_ramdac_port(s, 0x02eb); > + ibm8514_register_ramdac_port(s, 0x02ec); > + ibm8514_register_ramdac_port(s, 0x02ed); > + ibm8514_register_port(s, 0x06e8); > + ibm8514_register_port(s, 0x0ae8); > + ibm8514_register_port(s, 0x0ee8); > + ibm8514_register_port(s, 0x12e8); > + ibm8514_register_port(s, 0x16e8); > + ibm8514_register_port(s, 0x1ae8); > + ibm8514_register_port(s, 0x1ee8); > + ibm8514_register_port(s, 0x22e8); > + ibm8514_register_port(s, 0x26e8); > + ibm8514_register_port(s, 0x42e8); > + ibm8514_register_port(s, 0x46e8); > + ibm8514_register_port(s, 0x4ae8); > + ibm8514_register_port(s, 0x82e8); > + ibm8514_register_port(s, 0x86e8); > + ibm8514_register_port(s, 0x8ae8); > + ibm8514_register_port(s, 0x8ee8); > + ibm8514_register_port(s, 0x92e8); > + ibm8514_register_port(s, 0x96e8); > + ibm8514_register_port(s, 0x9ae8); > + ibm8514_register_port(s, 0x9ae8); > + ibm8514_register_port(s, 0x9ee8); > + ibm8514_register_port(s, 0xa2e8); > + ibm8514_register_port(s, 0xa6e8); > + ibm8514_register_port(s, 0xaae8); > + ibm8514_register_port(s, 0xaee8); > + ibm8514_register_port(s, 0xb2e8); > + ibm8514_register_port(s, 0xb6e8); > + ibm8514_register_port(s, 0xbae8); > + ibm8514_register_port(s, 0xbee8); > + ibm8514_register_port(s, 0xe2e8); > + > + cpu_register_physical_memory(isa_mem_base + 0x02800000, vga->vram_size, > vga->vram_offset); > + qemu_register_coalesced_mmio(isa_mem_base + 0x02800000, vga->vram_size); > +} > + > +typedef struct PCIIBM8514State { > + PCIDevice dev; > + IBM8514State state; > +} PCIIBM8514State; > + > +static void s3_vision864_write_config(PCIDevice *d, > + uint32_t address, uint32_t val, int > len) > +{ > + BADF("%s: 0x%08" PRIx32 "\n", __func__, address); > +} > + > +static int s3_vision864_init(PCIDevice *dev) > +{ > + PCIIBM8514State *pci = DO_UPCAST(PCIIBM8514State, dev, dev); > + IBM8514State *s = &pci->state; > + uint8_t *pci_conf = dev->config; > + > + DPRINTF("%s\n", __func__); > + > + pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_S3); > + pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_S3_864); > + pci_config_set_class(pci_conf, PCI_CLASS_DISPLAY_VGA); > + > + ibm8514_init(s); > + > + return 0; > +} > + > +static PCIDeviceInfo s3_vision864_info = { > + .qdev.name = "s3-vision864", > + .qdev.size = sizeof(PCIIBM8514State), > + .qdev.vmsd = &vmstate_ibm8514, > + // XXX these depend on mst's PCI tree > +#if 0 > + .vendor_id = PCI_VENDOR_ID_S3, > + .device_id = PCI_DEVICE_ID_S3_864, > + .class_id = PCI_CLASS_DISPLAY_VGA, > +#endif > + .init = s3_vision864_init, > + .config_write = s3_vision864_write_config, > + .qdev.props = (Property[]) { > + DEFINE_PROP_END_OF_LIST() > + }, > +}; > + > +static void ibm8514_register(void) > +{ > + pci_qdev_register(&s3_vision864_info); > +} > + > +device_init(ibm8514_register); > + > +/* > +21: > + DEVICE_ID > + BusId = PCI > + DevId = 0x41d00909 (PNP0909) > + SerialNum = 0x00000000 > + Flags = 0x000061c5 > + : Output > + : ConsoleOut > + : PowerManaged > + : Disableable > + : Configurable > + : Integrated > + : Enabled > + BaseType = DisplayController (3) > + SubType = SVGAController (1) > + Interface = GeneralSVGA (0) > + BUS_ACCESS > + info0 = 0 > + info1 = 112 > + AllocatedOffset = 0x00000767 > + IRQ: 15 > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0x102 size 0x1 bytes > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0x3b4 size 0x2 bytes > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0x3b8 size 0x4 bytes > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0x3bf size 0xc bytes > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0x3cc size 0x1 bytes > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0x3ce size 0x2 bytes > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0x3d4 size 0x2 bytes > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0x3d8 size 0x5 bytes > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0x42e8 size 0x1 bytes > ok > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0x46e8 size 0x1 bytes > ok > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0x4ae8 size 0x1 bytes > ok > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0x82e8 size 0x1 bytes > ok > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0x86e8 size 0x1 bytes > ok > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0x8ae8 size 0x1 bytes > ok > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0x8ee8 size 0x1 bytes > ok > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0x92e8 size 0x1 bytes > ok > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0x96e8 size 0x1 bytes > ok > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0x9ae8 size 0x1 bytes > ok > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0x9ee8 size 0x1 bytes > ok > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0xa2e8 size 0x1 bytes > ok > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0xa6e8 size 0x1 bytes > ok > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0xaae8 size 0x1 bytes > ok > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0xaee8 size 0x1 bytes > ok > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0xb2e8 size 0x1 bytes > ok > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0xb6e8 size 0x1 bytes > ok > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0xbae8 size 0x1 bytes > ok > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0xbee8 size 0x1 bytes > ok > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0xe2e8 size 0x1 bytes > ok > + LargeVendorItem: Generic Address > + I/O address (32 bits), at 0xe2ea size 0x1 bytes > + LargeVendorItem: Generic Address > + Memory address (32 bits), at 0x2800000 size 0x200000 bytes ok > + LargeVendorItem: Display > + 01 00 80 02 e0 01 80 02 00 00 80 c2 00 00 00 00 > + 00 00 20 00 00 00 00 00 78 > + PossibleOffset = 0x00000a58 > + CompatibleOffset = 0x00000a59 > + > +*/ > -- > 1.7.5.3 > > >