[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [RFC v2 23/23] 40p: Add an IBM 8514/A graphics card
From: |
Blue Swirl |
Subject: |
Re: [Qemu-devel] [RFC v2 23/23] 40p: Add an IBM 8514/A graphics card |
Date: |
Sat, 18 Jun 2011 23:42:44 +0300 |
On Thu, Jun 16, 2011 at 3:02 AM, Andreas Färber <address@hidden> 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 <address@hidden>
>
> 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 <address@hidden>
> Signed-off-by: Andreas Färber <address@hidden>
> ---
> 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
>
>
>
- [Qemu-devel] [RFC v5 17/23] ide: Allow to discard I/O ports, (continued)
- [Qemu-devel] [RFC v5 17/23] ide: Allow to discard I/O ports, Andreas Färber, 2011/06/13
- [Qemu-devel] [RFC v5 18/23] ide: Implement ISA state callbacks, Andreas Färber, 2011/06/13
- [Qemu-devel] [RFC v5 19/23] prep: Add pc87312 Super I/O emulation, Andreas Färber, 2011/06/13
- [Qemu-devel] [RFC 20/23] 40p: Add the Super I/O chip (pc87312), Andreas Färber, 2011/06/13
- [Qemu-devel] [RFC 21/23] 40p: Add an audio card and a keyboard, Andreas Färber, 2011/06/13
- [Qemu-devel] [RFC 22/23] prep: qdev'ify System I/O (WIP), Andreas Färber, 2011/06/13
- [Qemu-devel] [RFC 23/23] 40p: Add an 8514/A graphics card, Andreas Färber, 2011/06/13
- Re: [Qemu-devel] [RFC 23/23] 40p: Add an 8514/A graphics card, Roy Tam, 2011/06/15
- Re: [Qemu-devel] [RFC 23/23] 40p: Add an 8514/A graphics card, Andreas Färber, 2011/06/15
- [Qemu-devel] [RFC v2 23/23] 40p: Add an IBM 8514/A graphics card, Andreas Färber, 2011/06/15
- Re: [Qemu-devel] [RFC v2 23/23] 40p: Add an IBM 8514/A graphics card,
Blue Swirl <=
- Re: [Qemu-devel] [RFC v2 23/23] 40p: Add an IBM 8514/A graphics card, Andreas Färber, 2011/06/19
- Re: [Qemu-devel] [RFC v2 23/23] 40p: Add an IBM 8514/A graphics card, Hervé Poussineau, 2011/06/19
- Re: [Qemu-devel] [RFC v2 23/23] 40p: Add an IBM 8514/A graphics card, Blue Swirl, 2011/06/19
- Re: [Qemu-devel] [RFC v2 23/23] 40p: Add an IBM 8514/A graphics card, Andreas Färber, 2011/06/19
- Re: [Qemu-devel] [RFC v2 23/23] 40p: Add an IBM 8514/A graphics card, Blue Swirl, 2011/06/19
- Re: [Qemu-devel] [RFC v2 23/23] 40p: Add an IBM 8514/A graphics card, Andreas Färber, 2011/06/19
- [Qemu-devel] [RFC v3 23/23] 40p: Add an IBM 8514/A graphics card, Andreas Färber, 2011/06/19
- Re: [Qemu-devel] [RFC 23/23] 40p: Add an 8514/A graphics card, Andreas Färber, 2011/06/15
- Re: [Qemu-devel] [RFC 23/23] 40p: Add an 8514/A graphics card, Roy Tam, 2011/06/15