diff --git a/src/video/vid_ati18800.c b/src/video/vid_ati18800.c index c6cb987e1..d5c7a2bbd 100644 --- a/src/video/vid_ati18800.c +++ b/src/video/vid_ati18800.c @@ -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; diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index 6ceae881e..d6630ccf8 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -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); diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index 0d816ba7f..61973875e 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -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; diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 155253610..9045dbfb8 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -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; + } } diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index 92f0e8ef4..570a676d3 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -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; diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index d22a6e6af..740be207e 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -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; } diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 1652615af..36f8b67fb 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -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) diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index ab1a86814..eafc7400c 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -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; diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 8ac16f2d6..ffe5cabff 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -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)) diff --git a/src/video/vid_oak_oti.c b/src/video/vid_oak_oti.c index cd7d4e26e..892967837 100644 --- a/src/video/vid_oak_oti.c +++ b/src/video/vid_oak_oti.c @@ -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; diff --git a/src/video/vid_paradise.c b/src/video/vid_paradise.c index 567d7fd4c..f79b93407 100644 --- a/src/video/vid_paradise.c +++ b/src/video/vid_paradise.c @@ -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(¶dise->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); + } } } diff --git a/src/video/vid_rtg310x.c b/src/video/vid_rtg310x.c index 55509352f..4442af6ef 100644 --- a/src/video/vid_rtg310x.c +++ b/src/video/vid_rtg310x.c @@ -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; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 14d0683c8..66bfb77d7 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -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); diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 4bd38a5bb..a3a5a1941 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -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; diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index 4b6772dab..eff0e093d 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -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"); diff --git a/src/video/vid_tvga.c b/src/video/vid_tvga.c index ad89b88e8..36420aeab 100644 --- a/src/video/vid_tvga.c +++ b/src/video/vid_tvga.c @@ -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) { diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index 8a3808322..426563250 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -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",