From d2c6452ff5866fa44542be6c48d28e6a44a174ec Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 20 May 2021 20:57:54 +0200 Subject: [PATCH] Reworked the HTVGA/Video7 clocks. Fixes the HT209 2401 error on MCA. Fixed 16 color in the Realtek 3106 card. Reworked the Sierra 1148x for the second time. Registers that only exist on 928/80x and up are not used by the 911/924 anymore. --- src/include/86box/vid_svga.h | 1 + src/include/86box/video.h | 2 +- src/video/vid_ht216.c | 185 ++++++++++++++++----------------- src/video/vid_rtg310x.c | 48 ++++++--- src/video/vid_s3.c | 74 +++++++------ src/video/vid_sc1148x_ramdac.c | 161 ++++++++++++++++++---------- src/video/vid_table.c | 2 +- 7 files changed, 280 insertions(+), 193 deletions(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 2b2512db9..53cb5592b 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -274,6 +274,7 @@ extern const device_t ics9161_device; extern const device_t sc11483_ramdac_device; extern const device_t sc11487_ramdac_device; extern const device_t sc11484_ramdac_device; +extern const device_t sc11484_nors2_ramdac_device; extern const device_t sc1502x_ramdac_device; extern const device_t sdac_ramdac_device; extern const device_t stg_ramdac_device; diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 887be489b..187bd86fc 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -285,7 +285,7 @@ extern const device_t incolor_device; extern const device_t g2_gc205_device; extern const device_t v7_vga_1024i_device; extern const device_t radius_svga_multiview_isa_device; -extern const device_t radius_svga_multiview_mc_device; +extern const device_t radius_svga_multiview_mca_device; extern const device_t ht216_32_pb410a_device; extern const device_t ht216_32_standalone_device; diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index b33a1f2bd..96d2af838 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -47,8 +47,8 @@ typedef struct ht216_t uint8_t adjust_cursor, monitor_type; int ext_reg_enable; - int clk_sel; int isabus; + int mca; uint8_t read_bank_reg[2], write_bank_reg[2]; uint16_t id, misc; @@ -100,11 +100,11 @@ uint8_t ht216_in(uint16_t addr, void *p); #define BIOS_G2_GC205_PATH "roms/video/video7/BIOS.BIN" #define BIOS_VIDEO7_VGA_1024I_PATH "roms/video/video7/Video Seven VGA 1024i - BIOS - v2.19 - 435-0062-05 - U17 - 27C256.BIN" -#define BIOS_RADIUS_SVGA_MULTIVIEW_MC_PATH "roms/video/video7/U18.BIN" +#define BIOS_RADIUS_SVGA_MULTIVIEW_PATH "roms/video/video7/U18.BIN" #define BIOS_HT216_32_PATH "roms/video/video7/HT21632.BIN" static video_timings_t timing_v7vga_isa = {VIDEO_ISA, 3, 3, 6, 5, 5, 10}; -static video_timings_t timing_v7vga_mca = {VIDEO_MCA, 5, 5, 9, 20, 20, 30}; +static video_timings_t timing_v7vga_mca = {VIDEO_MCA, 4, 5, 10, 5, 5, 10}; static video_timings_t timing_v7vga_vlb = {VIDEO_BUS, 5, 5, 9, 20, 20, 30}; @@ -167,20 +167,19 @@ ht216_out(uint16_t addr, uint8_t val, void *p) uint8_t old; ht216_log("ht216 %i out %04X %02X %04X:%04X\n", svga->miscout & 1, addr, val, CS, cpu_state.pc); - + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + addr ^= 0x60; switch (addr) { case 0x3c2: - ht216->clk_sel = (ht216->clk_sel & ~3) | ((val & 0x0c) >> 2); /*Bit 17 of the display memory address, only active on odd/even modes, has no effect on graphics modes.*/ - ht216->misc = val; + ht216->misc = val; + svga->miscout = val; ht216_log("HT216 misc val = %02x, mode = 0, chain4 = %x\n", val, svga->chain4); ht216_recalc_bank_regs(ht216, 0); ht216_remap(ht216); - svga->fullchange = changeframecount; - svga_recalctimings(svga); + svga_recalctimings(svga); break; case 0x3c4: @@ -280,12 +279,13 @@ ht216_out(uint16_t addr, uint8_t val, void *p) case 0xa3: svga->latch.b[3] = val; break; + case 0xa4: - ht216->clk_sel = (val >> 2) & 0xf; - svga->miscout = (svga->miscout & ~0xc) | ((ht216->clk_sel & 3) << 2); + case 0xf8: svga->fullchange = changeframecount; svga_recalctimings(svga); break; + case 0xa5: svga->hwcursor.ena = !!(val & 0x80); break; @@ -355,11 +355,11 @@ ht216_out(uint16_t addr, uint8_t val, void *p) break; case 0xfc: - ht216_log("HT216 reg 0xfc write = %02x, mode = 0, chain4 = %x\n", val, svga->chain4); + ht216_log("HT216 reg 0xfc write = %02x, mode = 0, chain4 = %x, bit 7 = %02x\n", val, svga->chain4, val & 0x80); ht216_recalc_bank_regs(ht216, 0); ht216_remap(ht216); svga->fullchange = changeframecount; - svga_recalctimings(svga); + svga_recalctimings(svga); break; } return; @@ -368,16 +368,13 @@ ht216_out(uint16_t addr, uint8_t val, void *p) case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: if (ht216->id == 0x7152) - sc1148x_ramdac_out(addr, 1, val, svga->ramdac, svga); + sc1148x_ramdac_out(addr, 0, val, svga->ramdac, svga); else svga_out(addr, val, svga); return; case 0x3cf: - if (svga->gdcaddr == 4) { - svga->readplane = val & 3; - ht216_remap(ht216); - } else if (svga->gdcaddr == 5) { + if (svga->gdcaddr == 5) { svga->chain2_read = val & 0x10; ht216_remap(ht216); } else if (svga->gdcaddr == 6) { @@ -409,16 +406,14 @@ ht216_out(uint16_t addr, uint8_t val, void *p) break; case 0x46e8: - if (ht216->id == 0x7152 && ht216->isabus) { + if ((ht216->id == 0x7152) && ht216->isabus) io_removehandler(0x0105, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); - } 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 (ht216->id == 0x7152 && ht216->isabus) { + if ((ht216->id == 0x7152) && ht216->isabus) io_sethandler(0x0105, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); - } io_sethandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); mem_mapping_enable(&svga->mapping); ht216_remap(ht216); @@ -438,21 +433,21 @@ ht216_in(uint16_t addr, void *p) uint8_t ret = 0xff; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + addr ^= 0x60; + + if ((ht216->id == 0x7152) && ht216->isabus) { + if (addr == 0x105) + return ht216->extensions; + } switch (addr) { - case 0x105: - if (ht216->id == 0x7152 && ht216->isabus) - return ht216->extensions; - break; - case 0x3c4: return svga->seqaddr; case 0x3c5: - if (svga->seqaddr == 6) { + if (svga->seqaddr == 6) return ht216->ext_reg_enable; - } else if (svga->seqaddr >= 0x80) { + else if (svga->seqaddr >= 0x80) { if (ht216->ext_reg_enable) { ret = ht216->ht_regs[svga->seqaddr & 0xff]; @@ -503,33 +498,23 @@ ht216_in(uint16_t addr, void *p) case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: if (ht216->id == 0x7152) - return sc1148x_ramdac_in(addr, 1, svga->ramdac, svga); + return sc1148x_ramdac_in(addr, 0, svga->ramdac, svga); return svga_in(addr, svga); case 0x3cc: - return ht216->misc; + return svga->miscout; case 0x3D4: return svga->crtcreg; case 0x3D5: if (svga->crtcreg == 0x1f) return svga->crtc[0xc] ^ 0xea; - if (svga->crtcreg == 0x22) - return svga->latch.b[svga->readplane]; - if (svga->crtcreg == 0x24) { - if (svga->attrff) - return svga->attraddr | 0x80; - else - return svga->attraddr; - break; - } return svga->crtc[svga->crtcreg]; } return svga_in(addr, svga); } - void ht216_remap(ht216_t *ht216) { @@ -655,15 +640,26 @@ ht216_recalctimings(svga_t *svga) { ht216_t *ht216 = (ht216_t *)svga->p; int high_res_256 = 0; - - switch (ht216->clk_sel) { - case 5: svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; break; - case 6: svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; break; - case 10: svga->clock = (cpuclock * (double)(1ull << 32)) / 80000000.0; break; - } - - if (ht216->id == 0x7152) - svga->clock *= 2; + + switch ((((((svga->miscout >> 2) & 3) || ((ht216->ht_regs[0xa4] >> 2) & 3)) | + ((ht216->ht_regs[0xa4] >> 2) & 4)) || ((ht216->ht_regs[0xf8] >> 5) & 0x0f)) | + ((ht216->ht_regs[0xf8] << 1) & 8)) { + case 0: + case 1: + break; + case 4: + svga->clock = (cpuclock * (double)(1ull << 32)) / 50350000.0; + break; + case 5: + svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; + break; + case 7: + svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; + break; + default: + svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; + break; + } svga->ma_latch |= ((ht216->ht_regs[0xf6] & 0x30) << 12); @@ -1400,16 +1396,14 @@ ht216_read_linear(uint32_t addr, void *p) return ht216_read_common(ht216, addr); } - static uint8_t radius_mca_read(int port, void *priv) { ht216_t *ht216 = (ht216_t *)priv; - - return(ht216->pos_regs[port & 7]); + ht216_log("Port %03x MCA read = %02x\n", port, ht216->pos_regs[port & 7]); + return (ht216->pos_regs[port & 7]); } - static void radius_mca_write(int port, uint8_t val, void *priv) { @@ -1418,19 +1412,18 @@ radius_mca_write(int port, uint8_t val, void *priv) /* MCA does not write registers below 0x0100. */ if (port < 0x0102) return; + ht216_log("Port %03x MCA write = %02x, setup mode = %02x\n", port, val, ht216->ht_regs[0xfc] & 0x80); + /* Save the MCA register value. */ ht216->pos_regs[port & 7] = val; - ht216_remap(ht216); } - static uint8_t radius_mca_feedb(void *priv) { - return 1; + return 1; } - void *ht216_init(const device_t *info, uint32_t mem_size, int has_rom) { @@ -1440,8 +1433,18 @@ void memset(ht216, 0, sizeof(ht216_t)); svga = &ht216->svga; - io_sethandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); - io_sethandler(0x46e8, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); + if (info->flags & DEVICE_VLB) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_v7vga_vlb); + else if (info->flags & DEVICE_MCA) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_v7vga_mca); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_v7vga_isa); + + svga_init(info, svga, ht216, mem_size, + ht216_recalctimings, + ht216_in, ht216_out, + ht216_hwcursor_draw, + NULL); switch (has_rom) { case 1: @@ -1481,31 +1484,23 @@ void } break; case 4: - if ((info->flags & DEVICE_ISA) && info->local == 0x7152) + if ((info->local == 0x7152) && (info->flags & DEVICE_ISA)) ht216->extensions = device_get_config_int("extensions"); - - rom_init(&ht216->bios_rom, BIOS_RADIUS_SVGA_MULTIVIEW_MC_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + else if ((info->local == 0x7152) && (info->flags & DEVICE_MCA)) { + ht216->pos_regs[0] = 0xb7; + ht216->pos_regs[1] = 0x80; + mca_add(radius_mca_read, radius_mca_write, radius_mca_feedb, NULL, ht216); + } + rom_init(&ht216->bios_rom, BIOS_RADIUS_SVGA_MULTIVIEW_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); break; } - if (info->flags & DEVICE_VLB) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_v7vga_vlb); - else if (info->flags & DEVICE_MCA) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_v7vga_mca); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_v7vga_isa); - - svga_init(info, svga, ht216, mem_size, - ht216_recalctimings, - ht216_in, ht216_out, - ht216_hwcursor_draw, - NULL); svga->hwcursor.ysize = 32; ht216->vram_mask = mem_size - 1; svga->decode_mask = mem_size - 1; if (has_rom == 4) - svga->ramdac = device_add(&sc11484_ramdac_device); + svga->ramdac = device_add(&sc11484_nors2_ramdac_device); if ((info->flags & DEVICE_VLB) || (info->flags & DEVICE_MCA)) { mem_mapping_set_handler(&svga->mapping, ht216_read, NULL, NULL, ht216_write, ht216_writew, ht216_writel); @@ -1517,12 +1512,16 @@ void mem_mapping_set_p(&svga->mapping, ht216); mem_mapping_disable(&ht216->linear_mapping); - svga->bpp = 8; - svga->miscout = 1; - ht216->id = info->local; ht216->isabus = (info->flags & DEVICE_ISA); - + ht216->mca = (info->flags & DEVICE_MCA); + + io_sethandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); + io_sethandler(0x46e8, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); + + svga->bpp = 8; + svga->miscout = 1; + if (ht216->id == 0x7861) ht216->ht_regs[0xb4] = 0x08; /*32-bit DRAM bus*/ @@ -1531,12 +1530,6 @@ void ht216->ht_regs[0x94] = 0xff; svga->adv_flags = 0; - if (info->flags & DEVICE_MCA) { - ht216->pos_regs[0] = 0xb7; - ht216->pos_regs[1] = 0x80; - mca_add(radius_mca_read, radius_mca_write, radius_mca_feedb, NULL, ht216); - } - return ht216; } @@ -1578,7 +1571,7 @@ ht216_standalone_init(const device_t *info) } static void * -radius_svga_multiview_mc_init(const device_t *info) +radius_svga_multiview_init(const device_t *info) { ht216_t *ht216 = ht216_init(info, 1 << 20, 4); @@ -1607,9 +1600,9 @@ ht216_standalone_available(void) } static int -radius_svga_multiview_mc_available(void) +radius_svga_multiview_available(void) { - return rom_present(BIOS_RADIUS_SVGA_MULTIVIEW_MC_PATH); + return rom_present(BIOS_RADIUS_SVGA_MULTIVIEW_PATH); } @@ -1770,24 +1763,24 @@ const device_t radius_svga_multiview_isa_device = "Radius SVGA Multiview ISA (HT209)", DEVICE_ISA | DEVICE_AT, 0x7152, /*HT209*/ - radius_svga_multiview_mc_init, + radius_svga_multiview_init, ht216_close, NULL, - { radius_svga_multiview_mc_available }, + { radius_svga_multiview_available }, ht216_speed_changed, ht216_force_redraw, radius_svga_multiview_config }; -const device_t radius_svga_multiview_mc_device = +const device_t radius_svga_multiview_mca_device = { - "Radius SVGA Multiview MC (HT209)", + "Radius SVGA Multiview MCA (HT209)", DEVICE_MCA, 0x7152, /*HT209*/ - radius_svga_multiview_mc_init, + radius_svga_multiview_init, ht216_close, NULL, - { radius_svga_multiview_mc_available }, + { radius_svga_multiview_available }, ht216_speed_changed, ht216_force_redraw, NULL diff --git a/src/video/vid_rtg310x.c b/src/video/vid_rtg310x.c index 7ad1d7ab6..56f60be44 100644 --- a/src/video/vid_rtg310x.c +++ b/src/video/vid_rtg310x.c @@ -234,18 +234,42 @@ rtg_recalctimings(svga_t *svga) break; } - if (svga->bpp == 8) { - if (svga->crtc[0x19] & 2) { - svga->render = svga_render_8bpp_highres; - - svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5); - svga->hdisp++; - svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; - - if (svga->hdisp == 1280) { - svga->hdisp >>= 1; - } else - svga->rowoffset <<= 1; + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + switch (svga->gdcreg[5] & 0x60) { + case 0x00: + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_4bpp_lowres; + else { + svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5); + svga->hdisp++; + svga->hdisp *= 8; + + if (svga->hdisp == 1280) + svga->rowoffset >>= 1; + + svga->render = svga_render_4bpp_highres; + } + break; + case 0x20: /*4 colours*/ + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_2bpp_lowres; + else + svga->render = svga_render_2bpp_highres; + break; + case 0x40: case 0x60: + if (svga->crtc[0x19] & 2) { + svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5); + svga->hdisp++; + svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; + + if (svga->hdisp == 1280) { + svga->hdisp >>= 1; + } else + svga->rowoffset <<= 1; + + svga->render = svga_render_8bpp_highres; + } + break; } } } diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 9585aae3f..27b46b489 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -2210,8 +2210,8 @@ s3_out(uint16_t addr, uint8_t val, void *p) ibm_rgb528_ramdac_out(addr, rs2, val, svga->ramdac, svga); else if ((s3->chip == S3_86C801) || (s3->chip == S3_86C805)) att49x_ramdac_out(addr, rs2, val, svga->ramdac, svga); - else if (s3->chip < S3_86C928) - sc1148x_ramdac_out(addr, rs2, val, svga->ramdac, svga); + else if (s3->chip <= S3_86C924) + sc1148x_ramdac_out(addr, 0, val, svga->ramdac, svga); else sdac_ramdac_out(addr, rs2, val, svga->ramdac, svga); return; @@ -2242,7 +2242,10 @@ s3_out(uint16_t addr, uint8_t val, void *p) s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4); break; case 0x32: - svga->vram_display_mask = (val & 0x40) ? 0x3ffff : s3->vram_mask; + if (svga->crtc[0x31] & 0x30) + svga->vram_display_mask = (val & 0x40) ? 0x3ffff : s3->vram_mask; + else + svga->vram_display_mask = s3->vram_mask; break; case 0x40: @@ -2465,7 +2468,7 @@ s3_in(uint16_t addr, void *p) else if ((s3->chip == S3_86C801) || (s3->chip == S3_86C805)) return att49x_ramdac_in(addr, rs2, svga->ramdac, svga); else if (s3->chip <= S3_86C924) - return sc1148x_ramdac_in(addr, rs2, svga->ramdac, svga); + return sc1148x_ramdac_in(addr, 0, svga->ramdac, svga); else return sdac_ramdac_in(addr, rs2, svga->ramdac, svga); break; @@ -2513,21 +2516,23 @@ static void s3_recalctimings(svga_t *svga) s3_t *s3 = (s3_t *)svga->p; int clk_sel = (svga->miscout >> 2) & 3; - svga->hdisp = svga->hdisp_old; - svga->ma_latch |= (s3->ma_ext << 16); - 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); + if (s3->chip >= S3_86C928) { + svga->hdisp = svga->hdisp_old; + + 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); + } + if (svga->crtc[0x5e] & 0x01) svga->vtotal |= 0x400; + if (svga->crtc[0x5e] & 0x02) svga->dispend |= 0x400; + if (svga->crtc[0x5e] & 0x04) svga->vblankstart |= 0x400; + if (svga->crtc[0x5e] & 0x10) svga->vsyncstart |= 0x400; + if (svga->crtc[0x5e] & 0x40) svga->split |= 0x400; + if (svga->crtc[0x51] & 0x30) svga->rowoffset |= (svga->crtc[0x51] & 0x30) << 4; + else if (svga->crtc[0x43] & 0x04) svga->rowoffset |= 0x100; } - if (svga->crtc[0x5e] & 0x01) svga->vtotal += 0x400; - if (svga->crtc[0x5e] & 0x02) svga->dispend += 0x400; - if (svga->crtc[0x5e] & 0x04) svga->vblankstart += 0x400; - if (svga->crtc[0x5e] & 0x10) svga->vsyncstart += 0x400; - if (svga->crtc[0x5e] & 0x40) svga->split += 0x400; - if (svga->crtc[0x51] & 0x30) svga->rowoffset += (svga->crtc[0x51] & 0x30) << 4; - else if (svga->crtc[0x43] & 0x04) svga->rowoffset += 0x100; if (!svga->rowoffset) svga->rowoffset = 256; if ((s3->chip == S3_VISION964) || (s3->chip == S3_86C928)) { @@ -2550,7 +2555,7 @@ static void s3_recalctimings(svga_t *svga) svga->clock /= 2; break; } - + svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)); if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { switch (svga->bpp) { @@ -2562,12 +2567,14 @@ static void s3_recalctimings(svga_t *svga) svga->hdisp *= 2; } else if ((s3->chip != S3_86C801) && (s3->chip != S3_86C805)) { if (s3->width == 1280 || s3->width == 1600) - svga->hdisp *= 2; + svga->hdisp *= 2; } } break; case 15: svga->render = svga_render_15bpp_highres; + if (s3->chip <= S3_86C924) + svga->rowoffset >>= 1; if ((s3->chip != S3_VISION964) && (s3->chip != S3_86C801)) { if (s3->chip == S3_86C928) svga->hdisp *= 2; @@ -2579,8 +2586,10 @@ static void s3_recalctimings(svga_t *svga) svga->hdisp *= 2; } break; - case 16: + case 16: svga->render = svga_render_16bpp_highres; + if (s3->chip <= S3_86C924) + svga->rowoffset >>= 1; if ((s3->chip != S3_VISION964) && (s3->chip != S3_86C801)) { if (s3->chip == S3_86C928) svga->hdisp *= 2; @@ -2612,6 +2621,11 @@ static void s3_recalctimings(svga_t *svga) svga->hdisp *= 2; break; } + } else { + if (svga->gdcreg[5] & 0x40) { + if (!svga->lowres) + svga->rowoffset <<= 1; + } } } @@ -2622,16 +2636,16 @@ static void s3_trio64v_recalctimings(svga_t *svga) svga->hdisp = svga->hdisp_old; - if (svga->crtc[0x5d] & 0x01) svga->htotal += 0x100; + 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_time |= 0x100; + svga->hdisp |= 0x100 * ((svga->seqregs[1] & 8) ? 16 : 8); } - if (svga->crtc[0x5e] & 0x01) svga->vtotal += 0x400; - if (svga->crtc[0x5e] & 0x02) svga->dispend += 0x400; - if (svga->crtc[0x5e] & 0x04) svga->vblankstart += 0x400; - if (svga->crtc[0x5e] & 0x10) svga->vsyncstart += 0x400; - if (svga->crtc[0x5e] & 0x40) svga->split += 0x400; + if (svga->crtc[0x5e] & 0x01) svga->vtotal |= 0x400; + if (svga->crtc[0x5e] & 0x02) svga->dispend |= 0x400; + if (svga->crtc[0x5e] & 0x04) svga->vblankstart |= 0x400; + if (svga->crtc[0x5e] & 0x10) svga->vsyncstart |= 0x400; + if (svga->crtc[0x5e] & 0x40) svga->split |= 0x400; svga->interlace = svga->crtc[0x42] & 0x20; svga->clock = (cpuclock * (double)(1ull << 32)) / svga->getclock(clk_sel, svga->clock_gen); @@ -2639,8 +2653,8 @@ static void s3_trio64v_recalctimings(svga_t *svga) if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/ { svga->ma_latch |= (s3->ma_ext << 16); - if (svga->crtc[0x51] & 0x30) svga->rowoffset += (svga->crtc[0x51] & 0x30) << 4; - else if (svga->crtc[0x43] & 0x04) svga->rowoffset += 0x100; + if (svga->crtc[0x51] & 0x30) svga->rowoffset |= (svga->crtc[0x51] & 0x30) << 4; + else if (svga->crtc[0x43] & 0x04) svga->rowoffset |= 0x100; if (!svga->rowoffset) svga->rowoffset = 256; if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { diff --git a/src/video/vid_sc1148x_ramdac.c b/src/video/vid_sc1148x_ramdac.c index 170b1cd66..88f81d77c 100644 --- a/src/video/vid_sc1148x_ramdac.c +++ b/src/video/vid_sc1148x_ramdac.c @@ -42,37 +42,63 @@ sc1148x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) { sc1148x_ramdac_t *ramdac = (sc1148x_ramdac_t *) p; uint8_t rs = (addr & 0x03); - rs |= ((!!rs2) << 2); - - switch (rs) { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x04: - case 0x05: - case 0x07: - svga_out(addr, val, svga); - ramdac->state = 0; - break; - case 0x06: - if (ramdac->state == 4) { - ramdac->state = 0; - ramdac->ctrl = val; - if (ramdac->ctrl & 0x80) { - if (ramdac->ctrl & 0x40) - svga->bpp = 16; - else + rs |= ((!!rs2) << 2); + + if (ramdac->type == 0 || ramdac->type == 3) { + switch (addr) { + case 0x3c6: + if (ramdac->state == 4) { + ramdac->state = 0; + ramdac->ctrl = val; + if (ramdac->ctrl & 0x80) { svga->bpp = 15; - } else { - svga->bpp = 8; + } else { + svga->bpp = 8; + } + svga_recalctimings(svga); + return; } - svga_recalctimings(svga); - return; + ramdac->state = 0; + break; + + case 0x3c7: + case 0x3c8: + case 0x3c9: + ramdac->state = 0; + svga_out(addr, val, svga); + break; } - ramdac->state = 0; - break; - } + } else { + switch (rs) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x07: + svga_out(addr, val, svga); + ramdac->state = 0; + break; + case 0x06: + if (ramdac->state == 4) { + ramdac->state = 0; + ramdac->ctrl = val; + if (ramdac->ctrl & 0x80) { + if ((ramdac->ctrl & 0x40) && (ramdac->type == 1)) + svga->bpp = 16; + else + svga->bpp = 15; + } else { + svga->bpp = 8; + } + svga_recalctimings(svga); + return; + } + ramdac->state = 0; + break; + } + } } @@ -82,33 +108,54 @@ sc1148x_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) sc1148x_ramdac_t *ramdac = (sc1148x_ramdac_t *) p; uint8_t temp = 0xff; uint8_t rs = (addr & 0x03); - rs |= ((!!rs2) << 2); - - switch (rs) { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x04: - case 0x05: - case 0x07: - temp = svga_in(addr, svga); - ramdac->state = 0; - break; - case 0x06: - if (ramdac->state == 4) { - ramdac->state = 0; - temp = ramdac->ctrl; - if (ramdac->type == 1) { - if (((ramdac->ctrl >> 4) == 1) || ((ramdac->ctrl >> 4) == 3)) - temp |= 1; - else - temp &= ~1; + rs |= ((!!rs2) << 2); + + if (ramdac->type == 0 || ramdac->type == 3) { + switch (addr) { + case 0x3c6: + if (ramdac->state == 4) { + ramdac->state = 0; + temp = ramdac->ctrl; + return temp; } + ramdac->state++; + break; + + case 0x3c7: + case 0x3c8: + case 0x3c9: + ramdac->state = 0; + temp = svga_in(addr, svga); + break; } - ramdac->state++; - break; - } + } else { + switch (rs) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x07: + temp = svga_in(addr, svga); + ramdac->state = 0; + break; + case 0x06: + if (ramdac->state == 4) { + ramdac->state = 0; + temp = ramdac->ctrl; + if (ramdac->type == 1) { + if (((ramdac->ctrl >> 4) == 1) || ((ramdac->ctrl >> 4) == 3)) + temp |= 1; + else + temp &= ~1; + } + return temp; + } + ramdac->state++; + break; + } + } return temp; } @@ -158,3 +205,11 @@ const device_t sc11484_ramdac_device = sc1148x_ramdac_init, sc1148x_ramdac_close, NULL, { NULL }, NULL, NULL }; + +const device_t sc11484_nors2_ramdac_device = +{ + "Sierra SC11484 RAMDAC (no RS2 signal)", + 0, 3, + sc1148x_ramdac_init, sc1148x_ramdac_close, + NULL, { NULL }, NULL, NULL +}; \ No newline at end of file diff --git a/src/video/vid_table.c b/src/video/vid_table.c index b9faeb9b6..6b1eafa02 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -119,7 +119,7 @@ video_cards[] = { { "wy700", &wy700_device }, { "ibm1mbsvga", &gd5428_mca_device }, { "et4000mca", &et4000_mca_device }, - { "radius_mc", &radius_svga_multiview_mc_device }, + { "radius_mc", &radius_svga_multiview_mca_device }, { "mach64gx_pci", &mach64gx_pci_device }, { "mach64vt2", &mach64vt2_device }, { "et4000w32p_pci", &et4000w32p_cardex_pci_device },