diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 91559aa72..90282a578 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -23,7 +23,8 @@ #define FLAG_EXT_WRITE 4 #define FLAG_LATCH8 8 #define FLAG_NOSKEW 16 -#define FLAG_ADDR_BY16 32 +#define FLAG_ADDR_BY16 32 +#define FLAG_RAMDAC_SHIFT 64 typedef struct { diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index 8264f30ca..50bedb377 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -59,7 +59,7 @@ typedef struct ht216_t uint8_t bg_plane_sel, fg_plane_sel; uint8_t ht_regs[256]; - uint8_t extensions; + uint8_t extensions, reg_3cb; uint8_t pos_regs[8]; } ht216_t; @@ -179,7 +179,7 @@ ht216_out(uint16_t addr, uint8_t val, void *p) 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: @@ -300,6 +300,12 @@ ht216_out(uint16_t addr, uint8_t val, void *p) svga->hwcursor.ena = !!(val & 0x80); break; + case 0xc0: + break; + + case 0xc1: + break; + case 0xc8: if ((old ^ val) & HT_REG_C8_E256) { svga->fullchange = changeframecount; @@ -313,6 +319,10 @@ ht216_out(uint16_t addr, uint8_t val, void *p) break; case 0xe0: + svga->adv_flags &= ~FLAG_RAMDAC_SHIFT; + if (val & 0x04) + svga->adv_flags |= FLAG_RAMDAC_SHIFT; + /* FALLTHROUGH */ /*Bank registers*/ case 0xe8: case 0xe9: ht216_log("HT216 reg 0x%02x write = %02x, mode = 1, chain4 = %x\n", svga->seqaddr & 0xff, val, svga->chain4); @@ -377,70 +387,76 @@ ht216_out(uint16_t addr, uint8_t val, void *p) } break; - case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: + case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: if (ht216->id == 0x7152) sc1148x_ramdac_out(addr, 0, val, svga->ramdac, svga); else svga_out(addr, val, svga); return; - case 0x3cf: - if (svga->gdcaddr == 5) { - svga->chain2_read = val & 0x10; - ht216_remap(ht216); - } else if (svga->gdcaddr == 6) { - if (val & 8) - svga->banked_mask = 0x7fff; - else - svga->banked_mask = 0xffff; - } - - if (svga->gdcaddr <= 8) { - svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && - !svga->gdcreg[1]) && svga->chain4 && svga->packed_chain4; - } - break; + case 0x3cb: + if (ht216->id == 0x7152) { + ht216->reg_3cb = val; + svga_set_ramdac_type(svga, (val & 0x20) ? RAMDAC_6BIT : RAMDAC_8BIT); + } + break; - case 0x3D4: - svga->crtcreg = val & 0x3f; + case 0x3cf: + if (svga->gdcaddr == 5) { + svga->chain2_read = val & 0x10; + ht216_remap(ht216); + } else if (svga->gdcaddr == 6) { + if (val & 8) + svga->banked_mask = 0x7fff; + else + svga->banked_mask = 0xffff; + } + + if (svga->gdcaddr <= 8) { + svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && + !svga->gdcreg[1]) && svga->chain4 && svga->packed_chain4; + } + break; + + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; - if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) - { + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { - svga->fullchange = 3; + 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; + } + break; - case 0x46e8: + case 0x46e8: + 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) - 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) - 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); - } - break; + 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); + } + break; } svga_out(addr, val, svga); @@ -457,10 +473,10 @@ ht216_in(uint16_t addr, void *p) if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; - if ((ht216->id == 0x7152) && ht216->isabus) { - if (addr == 0x105) - return ht216->extensions; - } + if ((ht216->id == 0x7152) && ht216->isabus) { + if (addr == 0x105) + return ht216->extensions; + } switch (addr) { case 0x3c4: @@ -523,6 +539,11 @@ ht216_in(uint16_t addr, void *p) return sc1148x_ramdac_in(addr, 0, svga->ramdac, svga); return svga_in(addr, svga); + case 0x3cb: + if (ht216->id == 0x7152) + return ht216->reg_3cb; + break; + case 0x3cc: return svga->miscout; @@ -1400,7 +1421,7 @@ void 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 + else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_v7vga_isa); svga_init(info, svga, ht216, mem_size, @@ -1476,11 +1497,11 @@ void mem_mapping_disable(&ht216->linear_mapping); 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); + 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; @@ -1488,6 +1509,9 @@ void if (ht216->id == 0x7861) ht216->ht_regs[0xb4] = 0x08; /*32-bit DRAM bus*/ + if (ht216->id == 0x7152) + ht216->reg_3cb = 0x20; + /* Initialize the cursor pointer towards the end of its segment, needed for ht256sf.drv to work correctly when Windows 3.1 is started after boot. */ ht216->ht_regs[0x94] = 0xff; diff --git a/src/video/vid_sc1148x_ramdac.c b/src/video/vid_sc1148x_ramdac.c index 06df1188b..046624bf4 100644 --- a/src/video/vid_sc1148x_ramdac.c +++ b/src/video/vid_sc1148x_ramdac.c @@ -43,10 +43,10 @@ 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); + rs |= ((!!rs2) << 2); - switch (addr) { - case 0x3c6: + switch (addr) { + case 0x3c6: if (ramdac->state == 4) { ramdac->state = 0; ramdac->ctrl = val; @@ -55,22 +55,20 @@ sc1148x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) svga->bpp = 16; else svga->bpp = 15; - } else { + } else svga->bpp = 8; - } svga_recalctimings(svga); return; } ramdac->state = 0; break; - - case 0x3c7: - case 0x3c8: - case 0x3c9: + + case 0x3c7: case 0x3c8: + case 0x3c9: ramdac->state = 0; svga_out(addr, val, svga); break; - } + } } @@ -78,35 +76,34 @@ uint8_t 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 ret = 0xff; uint8_t rs = (addr & 0x03); - rs |= ((!!rs2) << 2); - - switch (addr) { + rs |= ((!!rs2) << 2); + + switch (addr) { case 0x3c6: if (ramdac->state == 4) { ramdac->state = 0; - temp = ramdac->ctrl; + ret = ramdac->ctrl; if (ramdac->type == 1) { if (((ramdac->ctrl >> 5) == 1) || ((ramdac->ctrl >> 5) == 3)) - temp |= 1; + ret |= 1; else - temp &= ~1; + ret &= ~1; } - return temp; + return ret; } ramdac->state++; break; - case 0x3c7: - case 0x3c8: + case 0x3c7: case 0x3c8: case 0x3c9: - temp = svga_in(addr, svga); + ret = svga_in(addr, svga); ramdac->state = 0; break; - } + } - return temp; + return ret; } diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index b38353701..2544fd361 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -192,6 +192,8 @@ svga_out(uint16_t addr, uint8_t val, void *p) svga->dac_addr = (val + (addr & 0x01)) & 255; break; case 0x3c9: + if (svga->adv_flags & FLAG_RAMDAC_SHIFT) + val <<= 2; svga->fullchange = changeframecount; switch (svga->dac_pos) { case 0: @@ -330,6 +332,8 @@ svga_in(uint16_t addr, void *p) ret = svga->vgapal[index].b & 0x3f; break; } + if (svga->adv_flags & FLAG_RAMDAC_SHIFT) + ret >>= 2; break; case 0x3cc: ret = svga->miscout;