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 },