Merge pull request #6509 from 86Box/TC1995

Fixes for most video cards, ramdacs and clock generators
This commit is contained in:
Miran Grča
2025-11-27 00:49:15 +01:00
committed by GitHub
10 changed files with 163 additions and 90 deletions

View File

@@ -25,7 +25,7 @@
#include <86box/device.h>
typedef struct ics90c64a_t {
float freq[32];
float freq[17];
} ics90c64a_t;
#ifdef ENABLE_ICS90C64A_LOG
@@ -51,23 +51,12 @@ ics90c64a_vclk_getclock(int clock, void *priv)
{
const ics90c64a_t *ics90c64a = (ics90c64a_t *) priv;
if (clock > 15)
clock = 15;
if (clock > 16)
clock = 16;
return ics90c64a->freq[clock];
}
float
ics90c64a_mclk_getclock(int clock, void *priv)
{
const ics90c64a_t *ics90c64a = (ics90c64a_t *) priv;
if (clock > 7)
clock = 7;
return ics90c64a->freq[clock + 0x10];
}
static void *
ics90c64a_init(const device_t *info)
{
@@ -76,32 +65,24 @@ ics90c64a_init(const device_t *info)
switch (info->local) {
case 903:
/* ICS90C64A-903 for PVGA chip series */
ics90c64a->freq[0x0] = 30000000.0;
ics90c64a->freq[0x1] = 77250000.0;
ics90c64a->freq[0x2] = 0.0;
ics90c64a->freq[0x3] = 80000000.0;
ics90c64a->freq[0x4] = 31500000.0;
ics90c64a->freq[0x5] = 36000000.0;
ics90c64a->freq[0x6] = 75000000.0;
ics90c64a->freq[0x7] = 50000000.0;
ics90c64a->freq[0x8] = 40000000.0;
ics90c64a->freq[0x9] = 50000000.0;
ics90c64a->freq[0xa] = 32000000.0;
ics90c64a->freq[0xb] = 44900000.0;
ics90c64a->freq[0xc] = 25175000.0;
ics90c64a->freq[0xd] = 28322000.0;
ics90c64a->freq[0xe] = 65000000.0;
ics90c64a->freq[0xf] = 36000000.0;
ics90c64a->freq[0x10] = 33000000.0;
ics90c64a->freq[0x11] = 49218000.0;
ics90c64a->freq[0x12] = 60000000.0;
ics90c64a->freq[0x13] = 30500000.0;
ics90c64a->freq[0x14] = 41612000.0;
ics90c64a->freq[0x15] = 37500000.0;
ics90c64a->freq[0x16] = 36000000.0;
ics90c64a->freq[0x17] = 44296000.0;
/* ICS90C64A-903 for PVGA chip series, also per debian svgatext mode textconfig */
ics90c64a->freq[0] = 25175000.0;
ics90c64a->freq[1] = 28322000.0;
ics90c64a->freq[2] = 65000000.0;
ics90c64a->freq[3] = 36000000.0;
ics90c64a->freq[4] = 40000000.0;
ics90c64a->freq[5] = 50000000.0;
ics90c64a->freq[6] = 32000000.0;
ics90c64a->freq[7] = 45000000.0;
ics90c64a->freq[8] = 31500000.0;
ics90c64a->freq[9] = 35500000.0;
ics90c64a->freq[0x0a] = 74500000.0;
ics90c64a->freq[0x0b] = 72000000.0;
ics90c64a->freq[0x0c] = 30000000.0;
ics90c64a->freq[0x0d] = 77000000.0;
ics90c64a->freq[0x0e] = 86000000.0;
ics90c64a->freq[0x0f] = 80000000.0;
ics90c64a->freq[0x10] = 60000000.0;
break;
default:

View File

@@ -56,9 +56,9 @@ bt48x_set_bpp(bt48x_ramdac_t *ramdac, svga_t *svga)
{
if ((!(ramdac->cmd_r2 & 0x20)) || ((ramdac->type >= BT485A) && ((ramdac->cmd_r3 & 0x60) == 0x60)))
svga->bpp = 8;
else if ((ramdac->type >= BT485A) && ((ramdac->cmd_r3 & 0x60) == 0x40))
else if ((ramdac->type >= BT485A) && ((ramdac->cmd_r3 & 0x60) == 0x20))
svga->bpp = 24;
else
else {
switch (ramdac->cmd_r1 & 0x60) {
case 0x00:
svga->bpp = 32;
@@ -71,14 +71,18 @@ bt48x_set_bpp(bt48x_ramdac_t *ramdac, svga_t *svga)
break;
case 0x40:
svga->bpp = 8;
svga->gdcreg[5] &= ~0x60;
svga->gdcreg[5] |= 0x40;
break;
case 0x60:
svga->bpp = 4;
svga->gdcreg[5] &= ~0x60;
break;
default:
break;
}
}
svga_recalctimings(svga);
}

View File

@@ -4996,6 +4996,7 @@ mach64ct_init(const device_t *info)
mem_mapping_disable(&mach64->bios_rom.mapping);
svga->vblank_start = mach64_vblank_start;
svga->adv_flags |= FLAG_PANNING_ATI;
return mach64;
}

View File

@@ -3114,7 +3114,7 @@ mach_recalctimings(svga_t *svga)
svga->ati_4color = 0;
}
mach_log("ON=%d, override=%d, gelo=%04x, gehi=%04x, crtlo=%04x, crthi=%04x, vgahdisp=%d.\n", dev->on, svga->override, mach->accel.ge_offset_lo, mach->accel.ge_offset_hi, mach->accel.crt_offset_lo, mach->accel.crt_offset_hi, svga->hdisp);
mach_log("ON=%d, override=%d, gelo=%04x, gehi=%04x, crtlo=%04x, crthi=%04x, vgahdisp=%d, ibmon=%x, ation=%x, graph1=%x.\n", dev->on, svga->override, mach->accel.ge_offset_lo, mach->accel.ge_offset_hi, mach->accel.crt_offset_lo, mach->accel.crt_offset_hi, svga->hdisp, dev->accel.advfunc_cntl & 0x01, mach->accel.clock_sel & 0x01, svga->gdcreg[6] & 0x01);
if (dev->on) {
dev->memaddr_latch = 0; /*(mach->accel.crt_offset_lo | (mach->accel.crt_offset_hi << 16)) << 2;*/
@@ -4065,6 +4065,10 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u
}
if (!(dev->accel.advfunc_cntl & 0x01))
dev->on = mach->accel.clock_sel & 0x01;
else {
if (!(mach->regs[0xb0] & 0x20) && !(mach->accel.clock_sel & 0x01))
dev->on = 0;
}
dev->vendor_mode = 1;
dev->mode = ATI_MODE;

View File

@@ -667,8 +667,12 @@ et4000_recalctimings(svga_t *svga)
}
svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clk_sel, svga->clock_gen);
if (clk_sel < 2)
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) {
svga->clock *= 2.0;
} else {
if ((svga->bpp <= 8) || ((svga->gdcreg[5] & 0x60) <= 0x20))
svga->clock *= 2.0;
}
switch (svga->bpp) {
case 15:

View File

@@ -327,9 +327,7 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *priv)
}
} else if (et4000->rev == ET4000W32I_REVB) {
if (((svga->bpp == 15) || (svga->bpp == 16))) {
if (et4000->adjust_cursor_x == 1)
svga->hwcursor.x += 0x100;
else if (et4000->adjust_cursor_x == 2)
if (et4000->adjust_cursor_x == 2)
svga->hwcursor.x += 8;
}
}
@@ -454,6 +452,7 @@ et4000w32p_in(uint16_t addr, void *priv)
ret &= 0x7f;
else
ret |= 0x80;
return ret;
}
@@ -540,28 +539,18 @@ et4000w32p_recalctimings(svga_t *svga)
et4000->adjust_cursor_x = 0;
svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clk_sel, svga->clock_gen);
if (svga->getclock == ics2494_getclock) {
if (clk_sel < 2)
svga->clock *= 2.0;
}
if (svga->seqregs[7] & 0x01)
svga->clock *= 4.0;
else if (svga->seqregs[7] & 0x40)
svga->clock *= 2.0;
if ((svga->getclock != ics2494_getclock) &&
(svga->getclock != icd2061_getclock)) {
if (clk_sel <= 1)
svga->clock /= 2.0;
}
if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) {
et4000w32_log("Graphics Mode clk_sel=%d, cr35 bit7=%02x, seq7=%02x, clksel=%d, htotal=%03x.\n", clk_sel, svga->crtc[0x35] & 0x80, svga->seqregs[7] & 0x41, clk_sel, svga->htotal);
if (svga->getclock != ics2494_getclock) {
if (!(svga->crtc[0x35] & 0x80)) {
if (clk_sel >= 2) {
if (svga->seqregs[7] & 0x01)
svga->clock *= 4.0;
else if (svga->seqregs[7] & 0x40)
svga->clock *= 2.0;
} else {
if (svga->getclock == sdac_getclock) {
if ((svga->gdcreg[5] & 0x60) >= 0x40)
svga->clock /= 2.0;
}
}
}
}
if ((svga->gdcreg[5] & 0x60) >= 0x40) {
if (et4000->rev == ET4000W32) {
switch (svga->bpp) {
@@ -591,8 +580,8 @@ et4000w32p_recalctimings(svga_t *svga)
if (svga->hdisp != 1024)
et4000->adjust_cursor = 1;
} else {
et4000->adjust_cursor = 1;
if (et4000->rev <= ET4000W32I_REVB) {
et4000->adjust_cursor = 1;
if (svga->hdisp == 800)
et4000->adjust_cursor_x = 1;
else if (svga->hdisp == 640)
@@ -623,6 +612,7 @@ et4000w32p_recalctimings(svga_t *svga)
if (!svga->scrblank && svga->attr_palette_enable) {
if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) {
if (svga->gdcreg[5] & 0x40) {
et4000w32_log("bpp=%d, lowres=%x.\n", svga->bpp, svga->lowres);
switch (svga->bpp) {
case 8:
svga->map8 = svga->pallook;

View File

@@ -103,6 +103,8 @@ uint8_t ht216_in(uint16_t addr, void *priv);
#define BIOS_G2_GC205_PATH "roms/video/video7/BIOS.BIN"
#define BIOS_VIDEO7_VGA_1024I_219_PATH "roms/video/video7/Video Seven VGA 1024i - BIOS - v2.19 - 435-0062-05 - U17 - 27C256.BIN"
#define BIOS_VIDEO7_VGA_1024I_700_PATH "roms/video/video7/Headland Video7 VGA 1024i v7.0 32x8 (IP) NMC27C256B@DIP28.BIN"
#define BIOS_VIDEO7_VGA_1024I_704_HP_LO_PATH "roms/video/video7/Headland Video 7 VGA 1024i even v7.04 27C256 LO.bin"
#define BIOS_VIDEO7_VGA_1024I_704_HP_HI_PATH "roms/video/video7/Headland Video 7 VGA 1024i odd v7.04 27C256 HI.bin"
#define BIOS_RADIUS_SVGA_MULTIVIEW_PATH "roms/video/video7/U18.BIN"
#define BIOS_HT216_32_PATH "roms/video/video7/HT21632.BIN"
@@ -187,7 +189,7 @@ ht216_out(uint16_t addr, uint8_t val, void *priv)
/*Bit 17 of the display memory address, only active on odd/even modes, has no effect on graphics modes.*/
ht216->clk_sel = (ht216->clk_sel & ~0x03) | ((val & 0x0c) >> 2);
ht216->misc = val;
ht216_log("HT216 misc val = %02x, mode = 0, chain4 = %x\n", val, svga->chain4);
ht216_log("HT216 misc val=%02x, mode=0, chain4=%x\n", val, svga->chain4);
ht216_recalc_bank_regs(ht216, 0);
ht216_remap(ht216);
svga_recalctimings(svga);
@@ -306,7 +308,9 @@ ht216_out(uint16_t addr, uint8_t val, void *priv)
}
ht216->clk_sel = (val >> 2) & 0x07;
}
svga->miscout = (svga->miscout & ~0x0c) | ((ht216->clk_sel & 0x03) << 2);
if (ht216->id >= 0x7152)
svga->miscout = (svga->miscout & ~0x0c) | ((ht216->clk_sel & 0x03) << 2);
svga->fullchange = changeframecount;
svga_recalctimings(svga);
break;
@@ -485,7 +489,7 @@ ht216_out(uint16_t addr, uint8_t val, void *priv)
io_removehandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216);
mem_mapping_disable(&svga->mapping);
mem_mapping_disable(&ht216->linear_mapping);
if (val & 8) {
if (val & 0x08) {
io_sethandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216);
mem_mapping_enable(&svga->mapping);
ht216_remap(ht216);
@@ -565,6 +569,12 @@ ht216_in(uint16_t addr, void *priv)
ht216->bg_plane_sel = 0;
break;
case 0xff:
ret = ht216->ht_regs[0xff];
if (is286 && (ht216->id != 0x7861))
ret |= 0x80;
break;
default:
break;
}
@@ -589,11 +599,15 @@ ht216_in(uint16_t addr, void *priv)
return ht216->reg_3cb;
break;
case 0x3cc:
return ht216->misc;
case 0x3D4:
return svga->crtcreg;
case 0x3D5:
if (svga->crtcreg == 0x1f)
return svga->crtc[0xc] ^ 0xea;
return svga->crtc[svga->crtcreg];
default:
@@ -653,6 +667,8 @@ ht216_recalctimings(svga_t *svga)
ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
mach_t *mach = (mach_t *) svga->ext8514;
int high_res_256 = 0;
int clock0_override = 0;
int clock_sel;
if (ht216->id == 0x7861) {
if (ht216->ht_regs[0xe0] & 0x20) {
@@ -663,9 +679,55 @@ ht216_recalctimings(svga_t *svga)
}
}
svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(ht216->clk_sel, svga->clock_gen);
ht216_log("ClkSel V7=%02x, regf8=%02x, rega4=%02x, miscout=%x, vidclock=%02x.\n", ht216->clk_sel, ht216->ht_regs[0xf8], ht216->ht_regs[0xa4], (svga->miscout >> 2) & 0x03, svga->vidclock);
if (ht216->id <= 0x7140) {
clock_sel = (ht216->ht_regs[0xa4] >> 2) & 0x07;
if (ht216->ht_regs[0xf8] & 0x01) {
if (!(ht216->ht_regs[0xf8] & 0x10) && (((ht216->misc >> 2) & 0x03) == 0x03))
clock0_override = 1;
else if (!(ht216->ht_regs[0xf8] & 0x08) && (((ht216->misc >> 2) & 0x03) == 0x02))
clock0_override = 2;
}
if (!clock0_override) {
if (ht216->ht_regs[0xf8] & 0x02) {
if (ht216->ht_regs[0xf8] & 0x04)
clock_sel = (ht216->ht_regs[0xf8] >> 5) & 0x07;
}
switch (clock_sel) {
case 1:
if (!(ht216->ht_regs[0xf8] & 0x01))
svga->clock = (cpuclock * (double) (1ULL << 32)) / 48540000.0;
break;
case 2:
svga->clock = (cpuclock * (double) (1ULL << 32)) / 38000000.0;
break;
case 3:
svga->clock = (cpuclock * (double) (1ULL << 32)) / 32500000.0;
break;
case 4:
svga->clock = (cpuclock * (double) (1ULL << 32)) / 50350000.0;
break;
case 5:
svga->clock = (cpuclock * (double) (1ULL << 32)) / 65000000.0;
break;
case 6:
svga->clock = (cpuclock * (double) (1ULL << 32)) / 38000000.0;
break;
case 7:
svga->clock = (cpuclock * (double) (1ULL << 32)) / 40000000.0;
break;
default:
break;
}
} else {
if (clock0_override == 2)
svga->clock = (cpuclock * (double) (1ULL << 32)) / 38000000.0;
}
pclog("HT208 Select=%d, clock0override=%d, CRTC17=%02x, MISC=%02x, A4=%02x, FC=%02x, F8=%02x, FF=%02x, reset=%02x.\n", clock_sel, clock0_override, svga->crtc[0x17], ht216->misc & 0x0c, ht216->ht_regs[0xa4], ht216->ht_regs[0xfc], ht216->ht_regs[0xf8], ht216->ht_regs[0xff], svga->seqregs[0] & 0x03);
} else {
svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(ht216->clk_sel, svga->clock_gen);
ht216_log("ClkSel V7=%02x, regf8=%02x, rega4=%02x, miscout=%x, vidclock=%02x.\n", ht216->clk_sel, ht216->ht_regs[0xf8], ht216->ht_regs[0xa4], (svga->miscout >> 2) & 0x03, svga->vidclock);
}
svga->memaddr_latch |= ((ht216->ht_regs[0xf6] & 0x30) << 12);
if (ht216->ht_regs[0xf6] & 0x80)
@@ -713,7 +775,7 @@ ht216_recalctimings(svga_t *svga)
svga->hdisp >>= 1;
svga->dots_per_clock >>= 1;
ht216->adjust_cursor = 1;
svga->render = svga_render_8bpp_highres;
svga->render = svga_render_8bpp_highres;
} else {
ht216_log("8bpp low, packed = %02x, chain4 = %02x\n", svga->packed_chain4, svga->chain4);
svga->render = svga_render_8bpp_lowres;
@@ -723,6 +785,7 @@ ht216_recalctimings(svga_t *svga)
svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5);
if (!(svga->crtc[1] & 1))
svga->hdisp--;
svga->hdisp++;
svga->hdisp *= svga->dots_per_clock;
svga->rowoffset <<= 1;
@@ -737,6 +800,7 @@ ht216_recalctimings(svga_t *svga)
svga->dots_per_clock >>= 1;
if ((svga->crtc[0x17] & 0x60) == 0x20) /*Would result in a garbled screen with trailing cursor glitches*/
svga->crtc[0x17] |= 0x40;
svga->render = svga_render_15bpp_highres;
}
}
@@ -1520,6 +1584,7 @@ ht216_init(const device_t *info, uint32_t mem_size, int has_rom)
svga_t *svga;
const char *bios_ver = NULL;
const char *fn = NULL;
const char *fn2 = NULL;
memset(ht216, 0, sizeof(ht216_t));
svga = &ht216->svga;
@@ -1543,12 +1608,18 @@ ht216_init(const device_t *info, uint32_t mem_size, int has_rom)
switch (has_rom) {
case 1:
rom_init(&ht216->bios_rom, BIOS_G2_GC205_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
fn = BIOS_G2_GC205_PATH;
rom_init(&ht216->bios_rom, fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
break;
case 2:
bios_ver = (char *) device_get_config_bios("bios_ver");
fn = (char *) device_get_bios_file(info, bios_ver, 0);
rom_init(&ht216->bios_rom, fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
if (!strcmp(bios_ver, "v7_04_hp")) {
fn2 = (char *) device_get_bios_file(info, bios_ver, 1);
rom_init_interleaved(&ht216->bios_rom, fn, fn2,
0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
} else
rom_init(&ht216->bios_rom, fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
break;
case 3:
ht216->monitor_type = device_get_config_int("monitor_type");
@@ -1606,7 +1677,7 @@ ht216_init(const device_t *info, uint32_t mem_size, int has_rom)
svga->ramdac = device_add(&sc11484_nors2_ramdac_device);
svga->clock_gen = device_add(&ics1494m_540_radius_ht209_device);
svga->getclock = ics1494_getclock;
} else {
} else if (ht216->id == 0x7861) {
svga->clock_gen = device_add(&icd2047_20_device);
svga->getclock = icd2047_getclock;
}
@@ -1765,6 +1836,15 @@ static const device_config_t v7_vga_1024i_config[] = {
.size = 32768,
.files = { BIOS_VIDEO7_VGA_1024I_700_PATH, "" }
},
{
.name = "Version 7.04 (HP)",
.internal_name = "v7_04_hp",
.bios_type = BIOS_NORMAL,
.files_no = 2,
.local = 0,
.size = 32768,
.files = { BIOS_VIDEO7_VGA_1024I_704_HP_LO_PATH, BIOS_VIDEO7_VGA_1024I_704_HP_HI_PATH, "" }
},
{ .files_no = 0 }
}
},

View File

@@ -487,6 +487,7 @@ void
paradise_recalctimings(svga_t *svga)
{
paradise_t *paradise = (paradise_t *) svga->priv;
int clk_sel = 0;
svga->lowres = !(svga->gdcreg[0x0e] & 0x01);
@@ -526,6 +527,11 @@ paradise_recalctimings(svga_t *svga)
break;
}
} else {
clk_sel = ((svga->miscout >> 2) & 0x03);
if (!(svga->gdcreg[0x0c] & 0x02))
clk_sel |= 0x04;
svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clk_sel, svga->clock_gen);
if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) {
if ((svga->bpp >= 8) && !svga->lowres) {
if (svga->bpp == 16) {
@@ -777,6 +783,8 @@ paradise_init(const device_t *info, uint32_t memory)
paradise->vram_mask = (memory << 10) - 1;
svga->decode_mask = (memory << 10) - 1;
svga->ramdac = device_add(&sc11487_ramdac_device); /*Actually a Winbond W82c487-80, probably a clone.*/
svga->clock_gen = device_add(&ics90c64a_903_device);
svga->getclock = ics90c64a_vclk_getclock;
break;
default:

View File

@@ -4702,8 +4702,8 @@ s3_recalctimings(svga_t *svga)
svga->read_bank = 0;
}
/*In non-enhanced/IBM VGA modes, reset the misc index registers.*/
s3->accel.multifunc[0xd] = 0xd000;
s3->accel.multifunc[0xe] = 0xe000;
s3->accel.multifunc[0xd] = 0x000;
s3->accel.multifunc[0xe] = 0x000;
}
}
@@ -5306,6 +5306,7 @@ s3_accel_in(uint16_t port, void *priv)
case 0x9949:
case 0x9ae9:
temp = 0;
s3_log("FIFO=%x, cmd=%d, sy=%d.\n", s3_enable_fifo(s3), s3->accel.cmd >> 13, s3->accel.sy);
if (s3_enable_fifo(s3)) {
if (!s3->blitter_busy)
wake_fifo_thread(s3);
@@ -5332,17 +5333,26 @@ s3_accel_in(uint16_t port, void *priv)
else {
switch (s3->accel.cmd >> 13) { /*Some drivers may not set FIFO on but may still turn on FIFO empty bits!*/
case 0:
if (!s3->accel.ssv_len)
if (s3->accel.cmd & 0x100) {
if (!s3->accel.ssv_len)
temp |= 0x04;
} else
temp |= 0x04;
break;
case 1:
if (!s3->accel.sy)
if (s3->accel.cmd & 0x100) {
if (!s3->accel.sy)
temp |= 0x04;
} else
temp |= 0x04;
break;
case 2:
case 6:
case 7:
if (s3->accel.sy < 0)
if (s3->accel.cmd & 0x100) {
if (s3->accel.sy < 0)
temp |= 0x04;
} else
temp |= 0x04;
break;

View File

@@ -1672,19 +1672,10 @@ svga_init(const device_t *info, svga_t *svga, void *priv, int memsize,
void (*hwcursor_draw)(struct svga_t *svga, int displine),
void (*overlay_draw)(struct svga_t *svga, int displine))
{
int e;
svga->priv = priv;
svga->monitor_index = monitor_index_global;
svga->monitor = &monitors[svga->monitor_index];
for (int c = 0; c < 256; c++) {
e = c;
for (int d = 0; d < 8; d++) {
svga_rotate[d][c] = e;
e = (e >> 1) | ((e & 1) ? 0x80 : 0);
}
}
svga->readmode = 0;
svga->attrregs[0x11] = 0;