Fixed scrolling anomalies in the EGA and SVGA card cores for Commander Keen to work right without glitches.

This commit is contained in:
TC1995
2021-07-12 22:12:27 +02:00
parent b2c28e0767
commit fd5ac14f26
17 changed files with 178 additions and 80 deletions

View File

@@ -116,8 +116,13 @@ static void ati18800_out(uint16_t addr, uint8_t val, void *p)
{
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
{
svga->fullchange = changeframecount;
svga_recalctimings(svga);
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
svga->fullchange = 3;
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
} else {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}
}
break;

View File

@@ -199,12 +199,19 @@ ati28800_out(uint16_t addr, uint8_t val, void *p)
old = svga->crtc[svga->crtcreg];
svga->crtc[svga->crtcreg] = val;
if (old != val) {
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}
if (old != val)
{
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
{
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
svga->fullchange = 3;
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
} else {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}
}
break;
}
svga_out(addr, val, svga);

View File

@@ -418,12 +418,17 @@ void mach64_out(uint16_t addr, uint8_t val, void *p)
old = svga->crtc[svga->crtcreg];
svga->crtc[svga->crtcreg] = val;
if (old!=val)
if (old != val)
{
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
{
svga->fullchange = changeframecount;
svga_recalctimings(svga);
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
svga->fullchange = 3;
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
} else {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}
}
break;

View File

@@ -1142,10 +1142,16 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p)
break;
}
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
{
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
svga->fullchange = 3;
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
} else {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}
}
break;
}
@@ -1597,7 +1603,7 @@ gd54xx_recalctimings(svga_t *svga)
uint8_t clocksel, rdmask;
uint8_t linedbl = svga->dispend * 9 / 10 >= svga->hdisp;
svga->rowoffset = (svga->crtc[0x13]) | ((svga->crtc[0x1b] & 0x10) << 4);
svga->rowoffset = (svga->crtc[0x13]) | (((int) (uint32_t) (svga->crtc[0x1b] & 0x10)) << 4);
svga->interlace = (svga->crtc[0x1a] & 0x01);
@@ -1774,6 +1780,24 @@ gd54xx_recalctimings(svga_t *svga)
}
svga->vram_display_mask = (svga->crtc[0x1b] & 2) ? gd54xx->vram_mask : 0x3ffff;
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;
}
}

View File

@@ -224,8 +224,13 @@ ega_out(uint16_t addr, uint8_t val, void *p)
ega->crtc[ega->crtcreg] = val;
if (old != val) {
if (ega->crtcreg < 0xe || ega->crtcreg > 0x10) {
fullchange = changeframecount;
ega_recalctimings(ega);
if ((ega->crtcreg == 0xc) || (ega->crtcreg == 0xd)) {
fullchange = 3;
ega->ma_latch = ((ega->crtc[0xc] << 8) | ega->crtc[0xd]) + ((ega->crtc[8] & 0x60) >> 5);
} else {
fullchange = changeframecount;
ega_recalctimings(ega);
}
}
}
break;

View File

@@ -281,10 +281,16 @@ et4000_out(uint16_t addr, uint8_t val, void *priv)
}
if (old != val) {
if (svga->crtcreg < 0x0e || svga->crtcreg > 0x10) {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
{
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
svga->fullchange = 3;
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
} else {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}
}
break;
}

View File

@@ -231,10 +231,16 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *p)
svga->write_bank = svga->read_bank = 0;
}
if (old != val) {
if ((svga->crtcreg < 0xe) || (svga->crtcreg > 0x10)) {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
{
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
svga->fullchange = 3;
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
} else {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}
}
if (svga->crtcreg == 0x30) {
if (et4000->pci)

View File

@@ -414,10 +414,16 @@ ht216_out(uint16_t addr, uint8_t val, void *p)
svga->crtc[svga->crtcreg] = val;
if (old != val) {
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
{
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
svga->fullchange = 3;
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
} else {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
svga_recalctimings(svga);
}
}
}
break;

View File

@@ -674,8 +674,13 @@ mystique_out(uint16_t addr, uint8_t val, void *p)
svga->crtc[svga->crtcreg & 0x3f] = val;
if (old != val) {
if ((svga->crtcreg & 0x3f) < 0xE || (svga->crtcreg & 0x3f) > 0x10) {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
if (((svga->crtcreg & 0x3f) == 0xc) || ((svga->crtcreg & 0x3f) == 0xd)) {
svga->fullchange = 3;
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
} else {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}
if (svga->crtcreg == 0x11) {
if (!(val & 0x10))

View File

@@ -107,8 +107,13 @@ oti_out(uint16_t addr, uint8_t val, void *p)
svga->crtc[idx] = val;
if (old != val) {
if ((idx < 0x0e) || (idx > 0x10)) {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
if (idx == 0x0c || idx == 0x0d) {
svga->fullchange = 3;
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
} else {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}
}
break;

View File

@@ -151,10 +151,15 @@ void paradise_out(uint16_t addr, uint8_t val, void *p)
if (old != val)
{
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
{
svga->fullchange = changeframecount;
svga_recalctimings(&paradise->svga);
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
svga->fullchange = 3;
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
} else {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}
}

View File

@@ -169,10 +169,16 @@ rtg_out(uint16_t addr, uint8_t val, void *priv)
}
if (old != val) {
if (svga->crtcreg < 0x0e || svga->crtcreg > 0x10) {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
{
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
svga->fullchange = 3;
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
} else {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}
}
break;

View File

@@ -2414,16 +2414,21 @@ s3_out(uint16_t addr, uint8_t val, void *p)
default: svga->bpp = 8; break;
}
}
break;
}
if (old != val)
{
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
{
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
break;
}
if (old != val)
{
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
{
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
svga->fullchange = 3;
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
} else {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}
}
break;
}
svga_out(addr, val, svga);

View File

@@ -581,8 +581,13 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p)
{
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
{
svga->fullchange = changeframecount;
svga_recalctimings(svga);
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
svga->fullchange = 3;
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
} else {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}
}
break;

View File

@@ -308,7 +308,7 @@ tgui_out(uint16_t addr, uint8_t val, void *p)
break;
case 0xC:
if (svga->seqregs[0xe] & 0x80)
svga->seqregs[0xc] = val;
svga->seqregs[0xc] = val;
break;
case 0xd:
if (tgui->oldmode)
@@ -321,8 +321,8 @@ tgui_out(uint16_t addr, uint8_t val, void *p)
tgui->oldctrl1 = val;
tgui_update_irqs(tgui);
} else {
svga->seqregs[0xe] = val ^ 2;
svga->write_bank = (svga->seqregs[0xe] & 0xf) * 65536;
svga->seqregs[0xe] = (val ^ 2);
svga->write_bank = (svga->seqregs[0xe] & 0xf) * 65536;
if (!(svga->gdcreg[0xf] & 1))
svga->read_bank = svga->write_bank;
}
@@ -418,10 +418,15 @@ tgui_out(uint16_t addr, uint8_t val, void *p)
if (old != val)
{
if (svga->crtcreg < 0xE || svga->crtcreg > 0x10)
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
{
svga->fullchange = changeframecount;
svga_recalctimings(svga);
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
svga->fullchange = 3;
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
} else {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}
}
switch (svga->crtcreg) {
@@ -2155,7 +2160,7 @@ tgui_accel_write(uint32_t addr, uint8_t val, void *p)
if ((svga->crtc[0x36] & 0x03) == 0x02) {
if ((addr & ~0xff) != 0xbff00)
return;
} else if ((svga->crtc[0x36] & 0x03) == 0x01) {
} else if ((svga->crtc[0x36] & 0x03) == 0x01) {
if ((addr & ~0xff) != 0xb7f00)
return;
}
@@ -2783,6 +2788,7 @@ static void *tgui_init(const device_t *info)
int type = info->local;
tgui_t *tgui = malloc(sizeof(tgui_t));
svga_t *svga = &tgui->svga;
memset(tgui, 0, sizeof(tgui_t));
tgui->vram_size = device_get_config_int("memory") << 20;
@@ -2815,16 +2821,16 @@ static void *tgui_init(const device_t *info)
else
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tgui_vlb);
svga_init(info, &tgui->svga, tgui, tgui->vram_size,
svga_init(info, svga, tgui, tgui->vram_size,
tgui_recalctimings,
tgui_in, tgui_out,
tgui_hwcursor_draw,
NULL);
if (tgui->type == TGUI_9400CXI)
tgui->svga.ramdac = device_add(&tkd8001_ramdac_device);
svga->ramdac = device_add(&tkd8001_ramdac_device);
mem_mapping_add(&tgui->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, tgui_accel_write_fb_b, tgui_accel_write_fb_w, tgui_accel_write_fb_l, NULL, MEM_MAPPING_EXTERNAL, &tgui->svga);
mem_mapping_add(&tgui->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, tgui_accel_write_fb_b, tgui_accel_write_fb_w, tgui_accel_write_fb_l, NULL, MEM_MAPPING_EXTERNAL, svga);
mem_mapping_add(&tgui->accel_mapping, 0, 0, tgui_accel_read, tgui_accel_read_w, tgui_accel_read_l, tgui_accel_write, tgui_accel_write_w, tgui_accel_write_l, NULL, MEM_MAPPING_EXTERNAL, tgui);
if (tgui->type >= TGUI_9440)
mem_mapping_add(&tgui->mmio_mapping, 0, 0, tgui_mmio_read, tgui_mmio_read_w, tgui_mmio_read_l, tgui_mmio_write, tgui_mmio_write_w, tgui_mmio_write_l, NULL, MEM_MAPPING_EXTERNAL, tgui);
@@ -2838,14 +2844,12 @@ static void *tgui_init(const device_t *info)
tgui->pci_regs[PCI_REG_COMMAND] = 3;
tgui->int_line = 0;
tgui->pci_regs[0x30] = 0x00;
tgui->pci_regs[0x32] = 0x0c;
tgui->pci_regs[0x33] = 0x00;
if (tgui->type >= TGUI_9440)
tgui->svga.packed_chain4 = 1;
svga->packed_chain4 = 1;
if (tgui->type >= TGUI_9660) {
tgui->i2c = i2c_gpio_init("ddc_tgui");

View File

@@ -159,9 +159,15 @@ void tvga_out(uint16_t addr, uint8_t val, void *p)
val &= crtc_mask[svga->crtcreg];
svga->crtc[svga->crtcreg] = val;
if (old != val) {
if (svga->crtcreg < 0xE || svga->crtcreg > 0x10) {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
{
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
svga->fullchange = 3;
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
} else {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}
}
switch (svga->crtcreg) {

View File

@@ -329,8 +329,13 @@ static void banshee_out(uint16_t addr, uint8_t val, void *p)
}
if (svga->crtcreg < 0xe || svga->crtcreg > 0x11 || (svga->crtcreg == 0x11 && old != val))
{
svga->fullchange = changeframecount;
svga_recalctimings(svga);
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
svga->fullchange = 3;
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
} else {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}
}
break;
@@ -2622,12 +2627,6 @@ static const device_config_t banshee_sgram_config[] =
.type = CONFIG_BINARY,
.default_int = 1
},
{
.name = "dithersub",
.description = "Dither subtraction",
.type = CONFIG_BINARY,
.default_int = 1
},
{
.name = "dacfilter",
.description = "Screen Filter",
@@ -2679,12 +2678,6 @@ static const device_config_t banshee_sdram_config[] =
.type = CONFIG_BINARY,
.default_int = 1
},
{
.name = "dithersub",
.description = "Dither subtraction",
.type = CONFIG_BINARY,
.default_int = 1
},
{
.name = "dacfilter",
.description = "Screen Filter",