SVGA hskew

This commit is contained in:
Jasmine Iwanek
2023-08-06 20:29:39 -04:00
parent cb24ee27cb
commit 01ffb60df8
7 changed files with 306 additions and 32 deletions

View File

@@ -1828,6 +1828,28 @@ gd54xx_recalctimings(svga_t *svga)
}
svga->vram_display_mask = (svga->crtc[0x1b] & 2) ? gd54xx->vram_mask : 0x3ffff;
pclog("svga->crtc[0x1a] = %02X\n", svga->crtc[0x1a]);
pclog("svga->crtc[0x1b] = %02X\n", svga->crtc[0x1b]);
pclog("svga->crtc[0x1c] = %02X\n", svga->crtc[0x1c]);
if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5430)
svga->htotal += ((svga->crtc[0x1c] >> 3) & 0x07);
if (svga->crtc[0x1b] & ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5424) ? 0xa0 : 0x20)) {
/* Special blanking mode: the blank start and end become components of the window generator,
and the actual blanking comes from the display enable signal. */
/* Start blanking at the first character clock after the last active one. */
svga->hblankstart = svga->crtc[1] + 1;
svga->hblank_end_val = (svga->htotal + 6) & 0x3f;
/* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */
if (!svga->scrblank && svga->attr_palette_enable)
svga->dots_per_clock = (svga->seqregs[1] & 8) ? 16 : 8;
/* No overscan in this mode. */
svga->hblank_overscan = 0;
/* Also make sure vertical blanking starts on display end. */
svga->vblankstart = svga->dispend;
}
}
static void

View File

@@ -55,17 +55,19 @@
#include <86box/plat_fallthrough.h>
#include <86box/plat_unused.h>
#define ET4000_TYPE_TC6058AF 0 /* ISA ET4000AX (TC6058AF) */
#define ET4000_TYPE_ISA 1 /* ISA ET4000AX */
#define ET4000_TYPE_MCA 2 /* MCA ET4000AX */
#define ET4000_TYPE_KOREAN 3 /* Korean ET4000 */
#define ET4000_TYPE_TRIGEM 4 /* Trigem 286M ET4000 */
#define ET4000_TYPE_KASAN 5 /* Kasan ET4000 */
#define BIOS_ROM_PATH "roms/video/et4000/ET4000.BIN"
#define KOREAN_BIOS_ROM_PATH "roms/video/et4000/tgkorvga.bin"
#define KOREAN_FONT_ROM_PATH "roms/video/et4000/tg_ksc5601.rom"
#define KASAN_BIOS_ROM_PATH "roms/video/et4000/et4000_kasan16.bin"
#define KASAN_FONT_ROM_PATH "roms/video/et4000/kasan_ksc5601.rom"
#define BIOS_ROM_PATH "roms/video/et4000/ET4000.BIN"
#define TC6058AF_BIOS_ROM_PATH "roms/video/et4000/Tseng_Labs_VGA-4000_BIOS_V1.1.bin"
#define KOREAN_BIOS_ROM_PATH "roms/video/et4000/tgkorvga.bin"
#define KOREAN_FONT_ROM_PATH "roms/video/et4000/tg_ksc5601.rom"
#define KASAN_BIOS_ROM_PATH "roms/video/et4000/et4000_kasan16.bin"
#define KASAN_FONT_ROM_PATH "roms/video/et4000/kasan_ksc5601.rom"
typedef struct {
const char *name;
@@ -115,6 +117,7 @@ et4000_in(uint16_t addr, void *priv)
{
et4000_t *dev = (et4000_t *) priv;
svga_t *svga = &dev->svga;
uint8_t ret;
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
addr ^= 0x60;
@@ -138,7 +141,8 @@ et4000_in(uint16_t addr, void *priv)
case 0x3c7:
case 0x3c8:
case 0x3c9:
return sc1502x_ramdac_in(addr, svga->ramdac, svga);
if (dev->type >= ET4000_TYPE_ISA)
return sc1502x_ramdac_in(addr, svga->ramdac, svga);
case 0x3cd: /*Banking*/
return dev->banking;
@@ -149,6 +153,26 @@ et4000_in(uint16_t addr, void *priv)
case 0x3d5:
return svga->crtc[svga->crtcreg];
case 0x3da:
svga->attrff = 0;
if (svga->cgastat & 0x01)
svga->cgastat &= ~0x30;
else
svga->cgastat ^= 0x30;
ret = svga->cgastat;
if ((svga->fcr & 0x08) && svga->dispon)
ret |= 0x08;
if (ret & 0x08)
ret &= 0x7f;
else
ret |= 0x80;
return ret;
default:
break;
}
@@ -225,12 +249,33 @@ et4000_out(uint16_t addr, uint8_t val, void *priv)
addr ^= 0x60;
switch (addr) {
case 0x3c5:
if (svga->seqaddr == 4) {
svga->seqregs[4] = val;
svga->chain2_write = !(val & 4);
svga->chain4 = (svga->chain4 & ~8) | (val & 8);
svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && svga->chain4 && !(svga->adv_flags & FLAG_ADDR_BY8);
return;
} else if (svga->seqaddr == 0x0e) {
svga->seqregs[0x0e] = val;
svga->chain4 &= ~0x02;
if (svga->gdcreg[5] & 0x40)
svga->chain4 |= (svga->seqregs[0x0e] & 0x02);
svga_recalctimings(svga);
return;
}
break;
case 0x3c6:
case 0x3c7:
case 0x3c8:
case 0x3c9:
sc1502x_ramdac_out(addr, val, svga->ramdac, svga);
return;
if (dev->type >= ET4000_TYPE_ISA) {
sc1502x_ramdac_out(addr, val, svga->ramdac, svga);
return;
}
break;
case 0x3cd: /*Banking*/
if (!(svga->crtc[0x36] & 0x10) && !(svga->gdcreg[6] & 0x08)) {
@@ -241,7 +286,11 @@ et4000_out(uint16_t addr, uint8_t val, void *priv)
return;
case 0x3cf:
if ((svga->gdcaddr & 15) == 6) {
if ((svga->gdcaddr & 15) == 5) {
svga->chain4 &= ~0x02;
if (val & 0x40)
svga->chain4 |= (svga->seqregs[0x0e] & 0x02);
} else if ((svga->gdcaddr & 15) == 6) {
if (!(svga->crtc[0x36] & 0x10) && !(val & 0x08)) {
svga->write_bank = (dev->banking & 0x0f) * 0x10000;
svga->read_bank = ((dev->banking >> 4) & 0x0f) * 0x10000;
@@ -418,7 +467,8 @@ et4000_kasan_out(uint16_t addr, uint8_t val, void *priv)
break;
case 1:
case 2:
et4000->kasan_cfg_regs[et4000->kasan_cfg_index - 0xF0] = val;
if ((et4000->kasan_cfg_index - 0xF0) <= 16)
et4000->kasan_cfg_regs[et4000->kasan_cfg_index - 0xF0] = val;
io_removehandler(et4000->kasan_access_addr, 0x0008, et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, et4000);
et4000->kasan_access_addr = (et4000->kasan_cfg_regs[2] << 8) | et4000->kasan_cfg_regs[1];
io_sethandler(et4000->kasan_access_addr, 0x0008, et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, et4000);
@@ -465,7 +515,8 @@ et4000_kasan_out(uint16_t addr, uint8_t val, void *priv)
case 4:
case 5:
if (et4000->kasan_cfg_regs[0] & 1) {
et4000->kasan_font_data[addr - (((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1])) + 3)] = val;
if ((addr - (((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1])) + 3)) <= 4)
et4000->kasan_font_data[addr - (((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1])) + 3)] = val;
}
break;
case 6:
@@ -607,6 +658,19 @@ et4000_recalctimings(svga_t *svga)
}
}
}
if ((svga->seqregs[0x0e] & 0x02) && ((svga->gdcreg[5] & 0x60) >= 0x40)) {
svga->ma_latch <<= (1 << 0);
svga->rowoffset <<= (1 << 0);
svga->render = svga_render_8bpp_highres;
}
if (dev->type == ET4000_TYPE_TC6058AF) {
if (svga->render == svga_render_8bpp_lowres)
svga->render = svga_render_8bpp_tseng_lowres;
else if (svga->render == svga_render_8bpp_highres)
svga->render = svga_render_8bpp_tseng_highres;
}
}
static void
@@ -666,6 +730,7 @@ et4000_init(const device_t *info)
fn = BIOS_ROM_PATH;
switch (dev->type) {
case ET4000_TYPE_TC6058AF: /* ISA ET4000AX (TC6058AF) */
case ET4000_TYPE_ISA: /* ISA ET4000AX */
dev->vram_size = device_get_config_int("memory") << 10;
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_et4000_isa);
@@ -674,6 +739,8 @@ et4000_init(const device_t *info)
NULL, NULL);
io_sethandler(0x03c0, 32,
et4000_in, NULL, NULL, et4000_out, NULL, NULL, dev);
if (dev->type == ET4000_TYPE_TC6058AF)
fn = TC6058AF_BIOS_ROM_PATH;
break;
case ET4000_TYPE_MCA: /* MCA ET4000AX */
@@ -750,7 +817,8 @@ et4000_init(const device_t *info)
break;
}
dev->svga.ramdac = device_add(&sc1502x_ramdac_device);
if (dev->type >= ET4000_TYPE_ISA)
dev->svga.ramdac = device_add(&sc1502x_ramdac_device);
dev->vram_mask = dev->vram_size - 1;
@@ -790,6 +858,12 @@ et4000_force_redraw(void *priv)
dev->svga.fullchange = changeframecount;
}
static int
et4000_tc6058af_available(void)
{
return rom_present(TC6058AF_BIOS_ROM_PATH);
}
static int
et4000_available(void)
{
@@ -808,6 +882,33 @@ et4000_kasan_available(void)
return rom_present(KASAN_BIOS_ROM_PATH) && rom_present(KASAN_FONT_ROM_PATH);
}
static const device_config_t et4000_tc6058af_config[] = {
// clang-format off
{
.name = "memory",
.description = "Memory size",
.type = CONFIG_SELECTION,
.default_int = 512,
.selection = {
{
.description = "256 KB",
.value = 256
},
{
.description = "512 KB",
.value = 512
},
{
.description = ""
}
}
},
{
.type = CONFIG_END
}
// clang-format on
};
static const device_config_t et4000_config[] = {
// clang-format off
{
@@ -839,6 +940,20 @@ static const device_config_t et4000_config[] = {
// clang-format on
};
const device_t et4000_tc6058af_isa_device = {
.name = "Tseng Labs ET4000AX (TC6058AF) (ISA)",
.internal_name = "et4000ax_tc6058af",
.flags = DEVICE_ISA,
.local = 0,
.init = et4000_init,
.close = et4000_close,
.reset = NULL,
{ .available = et4000_tc6058af_available },
.speed_changed = et4000_speed_changed,
.force_redraw = et4000_force_redraw,
.config = et4000_tc6058af_config
};
const device_t et4000_isa_device = {
.name = "Tseng Labs ET4000AX (ISA)",
.internal_name = "et4000ax",

View File

@@ -457,6 +457,7 @@ et4000w32p_recalctimings(svga_t *svga)
}
}
#if 0
if (svga->adv_flags & FLAG_NOSKEW) {
/* On the Cardex ET4000/W32p-based cards, adjust text mode clocks by 1. */
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /* Text mode */
@@ -480,6 +481,7 @@ et4000w32p_recalctimings(svga_t *svga)
}
}
}
#endif
if (et4000->type == ET4000W32) {
if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) {
@@ -2561,6 +2563,9 @@ et4000w32p_pci_read(UNUSED(int func), int addr, void *priv)
{
et4000w32p_t *et4000 = (et4000w32p_t *) priv;
if (func > 0)
return 0xff;
addr &= 0xff;
switch (addr) {
@@ -2618,6 +2623,9 @@ et4000w32p_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
et4000w32p_t *et4000 = (et4000w32p_t *) priv;
svga_t *svga = &et4000->svga;
if (func > 0)
return;
addr &= 0xff;
switch (addr) {

View File

@@ -3038,6 +3038,8 @@ s3_recalctimings(svga_t *svga)
s3_t *s3 = (s3_t *) svga->priv;
int clk_sel = (svga->miscout >> 2) & 3;
svga->hdisp = svga->hdisp_old;
if (!svga->scrblank && svga->attr_palette_enable) {
if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) {
if (svga->crtc[0x3a] & 0x10) { /*256+ color register*/
@@ -3047,14 +3049,13 @@ s3_recalctimings(svga_t *svga)
}
svga->ma_latch |= (s3->ma_ext << 16);
if (s3->chip >= S3_86C928) {
svga->hdisp = svga->hdisp_old;
if (s3->chip >= S3_86C928) {
if (svga->crtc[0x5d] & 0x01)
svga->htotal |= 0x100;
if (svga->crtc[0x5d] & 0x02) {
svga->hdisp_time |= 0x100;
svga->hdisp |= 0x100 * ((svga->seqregs[1] & 8) ? 16 : 8);
svga->hdisp |= 0x100 * svga->dots_per_clock;
}
if (svga->crtc[0x5e] & 0x01)
svga->vtotal |= 0x400;
@@ -3072,7 +3073,8 @@ s3_recalctimings(svga_t *svga)
svga->rowoffset |= (svga->crtc[0x51] & 0x30) << 4;
else if (svga->crtc[0x43] & 0x04)
svga->rowoffset |= 0x100;
}
} else if (svga->crtc[0x43] & 0x04)
svga->rowoffset |= 0x100;
if (!svga->rowoffset)
svga->rowoffset = 0x100;
@@ -3341,6 +3343,30 @@ s3_recalctimings(svga_t *svga)
}
}
}
if (s3->chip >= S3_86C801) {
if (!svga->scrblank && svga->attr_palette_enable && (svga->crtc[0x43] & 0x80)) {
/* TODO: In case of bug reports, disable 9-dots-wide character clocks in graphics modes. */
svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18);
}
if (svga->crtc[0x5d] & 0x04)
svga->hblankstart += 0x100;
if (s3->chip >= S3_VISION964) {
/* NOTE: The S3 Trio64V+ datasheet says this is bit 7, but then where is bit 6?
The datasheets for the pre-Trio64V+ cards say +64, which implies bit 6,
and, contrary to VGADOC, it also exists on Trio32, Trio64, Vision868,
and Vision968. */
#if 0
pclog("svga->crtc[0x5d] = %02X\n", svga->crtc[0x5d]);
#endif
if (svga->crtc[0x5d] & 0x08)
svga->hblank_ext = 0x40;
svga->hblank_end_len = 0x00000040;
}
}
svga->hblank_overscan = !(svga->crtc[0x33] & 0x20);
}
static void

View File

@@ -202,7 +202,7 @@ svga_out(uint16_t addr, uint8_t val, void *priv)
break;
case 4:
svga->chain2_write = !(val & 4);
svga->chain4 = val & 8;
svga->chain4 = (svga->chain4 & ~8) | (val & 8);
svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) && !(svga->adv_flags & FLAG_ADDR_BY8);
break;
@@ -307,6 +307,9 @@ svga_out(uint16_t addr, uint8_t val, void *priv)
if (((svga->gdcaddr & 15) == 5 && (val ^ o) & 0x70) || ((svga->gdcaddr & 15) == 6 && (val ^ o) & 1))
svga_recalctimings(svga);
break;
case 0x3da:
svga->fcr = val;
break;
default:
break;
@@ -384,6 +387,9 @@ svga_in(uint16_t addr, void *priv)
if (svga->adv_flags & FLAG_RAMDAC_SHIFT)
ret >>= 2;
break;
case 0x3ca:
ret = svga->fcr;
break;
case 0x3cc:
ret = svga->miscout;
break;
@@ -420,6 +426,8 @@ svga_in(uint16_t addr, void *priv)
ret = svga->cgastat;
if ((svga->fcr & 0x08) && svga->dispon)
ret |= 0x08;
break;
default:
@@ -453,6 +461,14 @@ svga_recalctimings(svga_t *svga)
double _dispontime;
double _dispofftime;
double disptime;
#ifdef ENABLE_SVGA_LOG
int vsyncend;
int vblankend;
int hdispstart;
int hdispend;
int hsyncstart;
int hsyncend;
#endif
svga->vtotal = svga->crtc[6];
svga->dispend = svga->crtc[0x12];
@@ -490,7 +506,7 @@ svga_recalctimings(svga_t *svga)
svga->vblankstart |= 0x200;
svga->vblankstart++;
svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5);
svga->hdisp = svga->crtc[1] - ((svga->crtc[3] & 0x60) >> 5);
svga->hdisp++;
svga->htotal = svga->crtc[0];
@@ -513,20 +529,20 @@ svga_recalctimings(svga_t *svga)
svga->hdisp_time = svga->hdisp;
svga->render = svga_render_blank;
if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) {
/* TODO: In case of bug reports, disable 9-dots-wide character clocks in graphics modes. */
if (svga->seqregs[1] & 8)
svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18;
else
svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9;
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/
if (svga->seqregs[1] & 8) { /*40 column*/
svga->render = svga_render_text_40;
svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18;
/* Character clock is off by 1 now in 40-line modes, on all cards. */
svga->ma_latch--;
svga->hdisp += (svga->seqregs[1] & 1) ? 16 : 18;
} else {
svga->render = svga_render_text_80;
svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9;
}
svga->hdisp_old = svga->hdisp;
} else {
svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8;
svga->hdisp_old = svga->hdisp;
switch (svga->gdcreg[5] & 0x60) {
@@ -612,6 +628,26 @@ svga_recalctimings(svga_t *svga)
} else
svga->monitor->mon_overscan_x = 16;
svga->htotal = svga->crtc[0];
svga->hblankstart = svga->crtc[4] + 1;
svga->hblank_end_val = (svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00);
#if 0
pclog("htotal = %i, hblankstart = %i, hblank_end_val = %02X\n", svga->htotal, svga->hblankstart, svga->hblank_end_val);
#endif
svga->hblank_end_len = 0x00000040;
svga->hblank_overscan = 1;
if (!svga->scrblank && svga->attr_palette_enable) {
/* TODO: In case of bug reports, disable 9-dots-wide character clocks in graphics modes. */
if (svga->seqregs[1] & 8)
svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18);
else
svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 8 : 9);
} else
svga->dots_per_clock = 1;
/* Do svga->recalctimings_ex() here so that the above five variables can be
updated by said function. */
if (vga_on) {
if (svga->recalctimings_ex) {
svga->recalctimings_ex(svga);
@@ -629,6 +665,20 @@ svga_recalctimings(svga_t *svga)
xga_recalctimings(svga);
}
svga->htotal += 6; /*+6 is required for Tyrian*/
svga->hblankend = (svga->hblankstart & ~(svga->hblank_end_len - 1)) | svga->hblank_end_val;
if (svga->hblankend <= svga->hblankstart)
svga->hblankend += svga->hblank_end_len;
svga->hblankend += svga->hblank_ext;
svga->hblank_sub = 0;
if (svga->hblankend > svga->htotal) {
svga->hblankend &= (svga->hblank_end_len - 1);
svga->hblank_sub = svga->hblankend + svga->hblank_overscan;
svga->hdisp -= (svga->hblank_sub * svga->dots_per_clock);
}
if (svga->hdisp >= 2048)
svga->monitor->mon_overscan_x = 0;
@@ -640,6 +690,43 @@ svga_recalctimings(svga_t *svga)
crtcconst = svga->clock * svga->char_width;
#ifdef ENABLE_SVGA_LOG
vsyncend = (svga->vsyncstart & 0xfffffff0) | (svga->crtc[0x11] & 0x0f);
if (vsyncend <= svga->vsyncstart)
vsyncend += 0x00000010;
vblankend = (svga->vblankstart & 0xffffff80) | (svga->crtc[0x16] & 0x7f);
if (vblankend <= svga->vblankstart)
vblankend += 0x00000080;
hdispstart = ((svga->crtc[3] >> 5) & 3);
hdispend = svga->crtc[1] + 1;
hsyncstart = svga->crtc[4] + ((svga->crtc[5] >> 5) & 3) + 1;
hsyncend = (hsyncstart & 0xffffffe0) | (svga->crtc[5] & 0x1f);
if (hsyncend <= hsyncstart)
hsyncend += 0x00000020;
#endif
svga_log("Last scanline in the vertical period: %i\n"
"First scanline after the last of active display: %i\n"
"First scanline with vertical retrace asserted: %i\n"
"First scanline after the last with vertical retrace asserted: %i\n"
"First scanline of blanking: %i\n"
"First scanline after the last of blanking: %i\n"
"\n"
"Last character in the horizontal period: %i\n"
"First character of active display: %i\n"
"First character after the last of active display: %i\n"
"First character with horizontal retrace asserted: %i\n"
"First character after the last with horizontal retrace asserted: %i\n"
"First character of blanking: %i\n"
"First character after the last of blanking: %i\n"
"\n"
"\n",
svga->vtotal, svga->dispend, svga->vsyncstart, vsyncend,
svga->vblankstart, vblankend,
svga->htotal, hdispstart, hdispend, hsyncstart, hsyncend,
svga->hblankstart, svga->hblankend);
if (ibm8514_on && !svga->dev8514.local) {
disptime = svga->dev8514.h_total;
_dispontime = svga->dev8514.h_disp;
@@ -878,9 +965,9 @@ svga_poll(void *priv)
if (ret) {
if (svga->interlace && svga->oddeven)
svga->ma = svga->maback = (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5);
svga->ma = svga->maback = (svga->rowoffset << 1) + ((svga->crtc[3] & 0x60) >> 5) + svga->hblank_sub;
else
svga->ma = svga->maback = ((svga->crtc[5] & 0x60) >> 5);
svga->ma = svga->maback = ((svga->crtc[3] & 0x60) >> 5) + svga->hblank_sub;
svga->ma = (svga->ma << 2);
svga->maback = (svga->maback << 2);
@@ -951,9 +1038,9 @@ svga_poll(void *priv)
if ((dev->local && vga_on) || !dev->local) {
if (svga->interlace && svga->oddeven)
svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5);
svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + ((svga->crtc[3] & 0x60) >> 5) + svga->hblank_sub;
else
svga->ma = svga->maback = svga->ma_latch + ((svga->crtc[5] & 0x60) >> 5);
svga->ma = svga->maback = svga->ma_latch + ((svga->crtc[3] & 0x60) >> 5) + svga->hblank_sub;
} else if (dev->local && ibm8514_on) {
if (svga->interlace && svga->oddeven)
svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1);
@@ -968,6 +1055,9 @@ svga_poll(void *priv)
if (svga->vsync_callback)
svga->vsync_callback(svga);
}
#if 0
if (svga->vc == lines_num) {
#endif
if (svga->vc == svga->vtotal) {
svga->vc = 0;
svga->sc = 0;
@@ -1090,7 +1180,8 @@ svga_init(const device_t *info, svga_t *svga, void *priv, int memsize,
svga->ramdac_type = RAMDAC_6BIT;
svga->map8 = svga->pallook;
svga->map8 = svga->pallook;
svga->hblank_overscan = 1; /* Do at least 1 character of overscan after horizontal blanking. */
return 0;
}

View File

@@ -70,9 +70,20 @@ svga_render_blank(svga_t *svga)
break;
}
#if 0
pclog("svga->displine = %i, svga->y_add = %i, svga->x_add = %i\n", svga->displine, svga->y_add, svga->x_add);
#endif
uint32_t *line_ptr = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add];
#if 0
pclog("svga->hdisp = %i, svga->scrollcache = %i, char_width = %i, sizeof(uint32_t) = %i\n", svga->hdisp, svga->scrollcache, char_width, sizeof(uint32_t));
#endif
uint32_t line_width = (uint32_t) (svga->hdisp + svga->scrollcache) * char_width * sizeof(uint32_t);
memset(line_ptr, 0, line_width);
#if 0
pclog("line_width = %i\n", line_width);
#endif
if ((svga->hdisp + svga->scrollcache) > 0)
memset(line_ptr, 0, line_width);
}
void
@@ -81,7 +92,7 @@ svga_render_overscan_left(svga_t *svga)
if ((svga->displine + svga->y_add) < 0)
return;
if (svga->scrblank || (svga->hdisp == 0))
if (svga->scrblank || (svga->hdisp <= 0))
return;
uint32_t *line_ptr = svga->monitor->target_buffer->line[svga->displine + svga->y_add];
@@ -97,7 +108,7 @@ svga_render_overscan_right(svga_t *svga)
if ((svga->displine + svga->y_add) < 0)
return;
if (svga->scrblank || (svga->hdisp == 0))
if (svga->scrblank || (svga->hdisp <= 0))
return;
uint32_t *line_ptr = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add + svga->hdisp];

View File

@@ -148,6 +148,7 @@ video_cards[] = {
{ &et4000k_isa_device },
{ &et2000_device },
{ &et3000_isa_device },
{ &et4000_tc6058af_isa_device },
{ &et4000_isa_device },
{ &et4000w32_device },
{ &et4000w32i_isa_device },