Bochs VBE fixes, fixes #4410.
This commit is contained in:
@@ -124,6 +124,7 @@ typedef struct bochs_vbe_t {
|
||||
|
||||
mem_mapping_t linear_mapping;
|
||||
mem_mapping_t linear_mapping_2;
|
||||
uint32_t ma_latch_old;
|
||||
|
||||
void * i2c;
|
||||
void * ddc;
|
||||
@@ -322,10 +323,10 @@ bochs_vbe_recalctimings(svga_t* svga)
|
||||
svga->hblankend = mode.hdisplay + (mode.htotal - mode.hdisplay - 1);
|
||||
svga->vblankstart = svga->dispend; /* no vertical overscan. */
|
||||
svga->rowcount = 0;
|
||||
svga->hoverride = 1;
|
||||
if (dev->vbe_regs[VBE_DISPI_INDEX_BPP] != 4) {
|
||||
svga->fb_only = 1;
|
||||
svga->adv_flags |= FLAG_NO_SHIFT3;
|
||||
|
||||
} else {
|
||||
svga->fb_only = 0;
|
||||
svga->adv_flags &= ~FLAG_NO_SHIFT3;
|
||||
@@ -334,26 +335,29 @@ bochs_vbe_recalctimings(svga_t* svga)
|
||||
svga->bpp = dev->vbe_regs[VBE_DISPI_INDEX_BPP];
|
||||
|
||||
if (svga->bpp == 4) {
|
||||
svga->rowoffset = dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] >> 3;
|
||||
svga->rowoffset = (dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] / 2) >> 3;
|
||||
svga->ma_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) +
|
||||
(dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] >> 3);
|
||||
} else {
|
||||
svga->rowoffset = dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] * (svga->bpp / 8);
|
||||
svga->rowoffset = dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8));
|
||||
svga->ma_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) +
|
||||
(dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] * (svga->bpp / 8));
|
||||
(dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8)));
|
||||
}
|
||||
|
||||
if ((svga->ma_latch + dev->vbe_regs[VBE_DISPI_INDEX_YRES] * svga->rowoffset) >
|
||||
svga->vram_max) {
|
||||
dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
|
||||
svga->ma_latch = (svga->bpp == 4) ? (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] >> 3) :
|
||||
(dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] * (svga->bpp / 8));
|
||||
if ((svga->ma_latch + dev->vbe_regs[VBE_DISPI_INDEX_YRES] * svga->rowoffset) >
|
||||
svga->vram_max) {
|
||||
svga->ma_latch = 0;
|
||||
dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
|
||||
if (svga->ma_latch != dev->ma_latch_old) {
|
||||
if (svga->bpp == 4) {
|
||||
svga->maback = (svga->maback - (dev->ma_latch_old << 2)) +
|
||||
(svga->ma_latch << 2);
|
||||
} else {
|
||||
svga->maback = (svga->maback - (dev->ma_latch_old)) +
|
||||
(svga->ma_latch);
|
||||
dev->ma_latch_old = svga->ma_latch;
|
||||
}
|
||||
}
|
||||
|
||||
if (svga->bpp == 4)
|
||||
dev->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = (svga->vram_max * 2) / dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH];
|
||||
else
|
||||
dev->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = (svga->vram_max / ((svga->bpp == 15) ? 2 : (svga->bpp / 8))) / dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH];
|
||||
svga->split = 0xffffff;
|
||||
|
||||
switch (svga->bpp) {
|
||||
@@ -381,6 +385,7 @@ bochs_vbe_recalctimings(svga_t* svga)
|
||||
svga->fb_only = 0;
|
||||
svga->packed_4bpp = 0;
|
||||
svga->adv_flags &= ~FLAG_NO_SHIFT3;
|
||||
svga->hoverride = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -417,8 +422,10 @@ bochs_vbe_inw(const uint16_t addr, void *priv)
|
||||
case VBE_DISPI_INDEX_DDC:
|
||||
if (dev->vbe_regs[dev->vbe_index] & (1 << 7)) {
|
||||
ret = dev->vbe_regs[dev->vbe_index] & ((1 << 7) | 0x3);
|
||||
ret |= i2c_gpio_get_scl(dev->i2c) << 2;
|
||||
ret |= i2c_gpio_get_sda(dev->i2c) << 3;
|
||||
if ((ret & 0x01) && i2c_gpio_get_scl(dev->i2c))
|
||||
ret |= 0x04;
|
||||
if ((ret & 0x02) && i2c_gpio_get_sda(dev->i2c))
|
||||
ret |= 0x08;
|
||||
} else
|
||||
ret = 0x000f;
|
||||
break;
|
||||
@@ -466,7 +473,30 @@ bochs_vbe_outw(const uint16_t addr, const uint16_t val, void *priv)
|
||||
case VBE_DISPI_INDEX_X_OFFSET:
|
||||
case VBE_DISPI_INDEX_Y_OFFSET:
|
||||
dev->vbe_regs[dev->vbe_index] = val;
|
||||
svga_recalctimings(&dev->svga);
|
||||
if (dev->vbe_index == VBE_DISPI_INDEX_X_OFFSET || dev->vbe_index == VBE_DISPI_INDEX_Y_OFFSET) {
|
||||
svga_t *svga = &dev->svga;
|
||||
if (svga->bpp == 4) {
|
||||
svga->rowoffset = (dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] / 2) >> 3;
|
||||
svga->ma_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) +
|
||||
(dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] >> 3);
|
||||
} else {
|
||||
svga->rowoffset = dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8));
|
||||
svga->ma_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) +
|
||||
(dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8)));
|
||||
}
|
||||
if (svga->ma_latch != dev->ma_latch_old) {
|
||||
if (svga->bpp == 4) {
|
||||
svga->maback = (svga->maback - (dev->ma_latch_old << 2)) +
|
||||
(svga->ma_latch << 2);
|
||||
} else {
|
||||
svga->maback = (svga->maback - (dev->ma_latch_old)) +
|
||||
(svga->ma_latch);
|
||||
dev->ma_latch_old = svga->ma_latch;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
svga_recalctimings(&dev->svga);
|
||||
break;
|
||||
|
||||
case VBE_DISPI_INDEX_BANK:
|
||||
@@ -788,6 +818,21 @@ bochs_vbe_init(const device_t *info)
|
||||
0xc0000, 0x10000, 0xffff, 0x0000,
|
||||
MEM_MAPPING_EXTERNAL);
|
||||
|
||||
if (dev->id5_val == VBE_DISPI_ID4) {
|
||||
/* Patch the BIOS to match the PCI ID. */
|
||||
dev->bios_rom.rom[0x010c] = 0xee;
|
||||
dev->bios_rom.rom[0x8dff] -= (0xee - 0x34);
|
||||
|
||||
dev->bios_rom.rom[0x010d] = 0x80;
|
||||
dev->bios_rom.rom[0x8dff] -= (0x80 - 0x12);
|
||||
|
||||
dev->bios_rom.rom[0x010e] = 0xef;
|
||||
dev->bios_rom.rom[0x8dff] -= (0xef - 0x11);
|
||||
|
||||
dev->bios_rom.rom[0x010f] = 0xbe;
|
||||
dev->bios_rom.rom[0x8dff] -= (0xbe - 0x11);
|
||||
}
|
||||
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_bochs);
|
||||
|
||||
svga_init(info, &dev->svga, dev, dev->vram_size,
|
||||
@@ -826,6 +871,7 @@ bochs_vbe_init(const device_t *info)
|
||||
|
||||
dev->i2c = i2c_gpio_init("ddc_bochs");
|
||||
dev->ddc = ddc_init(i2c_gpio_get_bus(dev->i2c));
|
||||
dev->svga.packed_chain4 = 1;
|
||||
|
||||
pci_add_card(PCI_ADD_NORMAL, bochs_vbe_pci_read, bochs_vbe_pci_write, dev, &dev->slot);
|
||||
|
||||
|
Reference in New Issue
Block a user