diff --git a/src/include/86box/vid_8514a.h b/src/include/86box/vid_8514a.h index 983e98cd1..da4e9e700 100644 --- a/src/include/86box/vid_8514a.h +++ b/src/include/86box/vid_8514a.h @@ -41,7 +41,7 @@ typedef struct ibm8514_t { int type; int local; int bpp; - int on; + int on[2]; int accel_bpp; uint32_t vram_size; @@ -64,7 +64,7 @@ typedef struct ibm8514_t { struct { uint16_t subsys_cntl; uint16_t setup_md; - uint8_t advfunc_cntl; + uint16_t advfunc_cntl; uint8_t ext_advfunc_cntl; uint16_t cur_y; uint16_t cur_y_bitres; diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index a2cabfb0d..314fee307 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -964,8 +964,8 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) if (!val) break; dev->accel.advfunc_cntl = val & 0x0f; - dev->on = val & 0x01; - vga_on = !dev->on; + dev->on[0] = val & 0x01; + vga_on = !dev->on[0]; ibm8514_log("IBM 8514/A: VGA ON = %i, val = %02x\n", vga_on, val); svga_recalctimings(svga); break; @@ -1200,17 +1200,16 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (cpu_input) { if ((dev->accel.cmd & 2) || (pixcntl == 2)) { - if ((frgd_mix == 2) || (bkgd_mix == 2)) { + if ((frgd_mix == 2) || (bkgd_mix == 2)) count >>= 3; - } else if (pixcntl == 2) { - if (dev->accel.cmd & 2) { + else if (pixcntl == 2) { + if (dev->accel.cmd & 2) count >>= 1; - } else + else count >>= 3; } - } else { + } else count >>= 3; - } if (dev->bpp) { if ((dev->accel.cmd & 0x200) && (count == 2)) @@ -1299,7 +1298,8 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat /*Bit 4 of the Command register is the draw yes bit, which enables writing to memory/reading from memory when enabled. When this bit is disabled, no writing to memory/reading from memory is allowed. (This bit is almost meaningless on the NOP command)*/ - ibm8514_log("CMD8514: CMD=%d, full=%04x, pixcntl=%x, count=%d, frgdmix = %02x, bkgdmix = %02x, polygon=%x.\n", cmd, dev->accel.cmd, pixcntl, count, frgd_mix, bkgd_mix, dev->accel.multifunc[0x0a] & 6); + if (dev->accel.cmd == 0x53b1 && !cpu_dat) + ibm8514_log("CMD8514: CMD=%d, full=%04x, pixcntl=%x, count=%d, frgdmix = %02x, bkgdmix = %02x, polygon=%x, cpu=%08x, frgdmix=%02x, bkgdmix=%02x.\n", cmd, dev->accel.cmd, pixcntl, count, frgd_mix, bkgd_mix, dev->accel.multifunc[0x0a] & 6, cpu_dat, dev->accel.frgd_mix, dev->accel.bkgd_mix); switch (cmd) { case 0: /*NOP (Short Stroke Vectors)*/ @@ -4243,7 +4243,7 @@ ibm8514_recalctimings(svga_t *svga) { ibm8514_t *dev = (ibm8514_t *) svga->dev8514; - if (dev->on) { + if (dev->on[0]) { dev->h_disp = (dev->hdisp + 1) << 3; dev->pitch = (dev->accel.advfunc_cntl & 4) ? 1024 : 640; dev->h_total = (dev->htotal + 1); diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 8e7174666..90e41d9ba 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -100,8 +100,8 @@ typedef struct mach_t { uint8_t bank_w; uint8_t bank_r; uint16_t shadow_set; - int ext_on; - int ati_mode; + int ext_on[2]; + int ati_mode[2]; struct { uint8_t line_idx; @@ -1140,9 +1140,9 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 mix = 1; break; case 1: - if (mach->accel.mono_pattern_enable) { + if (mach->accel.mono_pattern_enable) mix = mach->accel.mono_pattern[dev->accel.dy & 7][dev->accel.dx & 7]; - } else { + else { if ((dev->accel_bpp == 24) && (frgd_sel == 5) && (mach->accel.patt_len_reg & 0x4000)) mix = 1; else { @@ -1205,18 +1205,16 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 src_dat = cpu_dat; else { READ(dev->accel.src + (dev->accel.cx), src_dat); - if (mono_src == 3) { + if (mono_src == 3) src_dat = (src_dat & rd_mask) == rd_mask; - } } break; case 5: if (mix) { - if (dev->bpp) { + if (dev->bpp) src_dat = mach->accel.color_pattern_word[mach->accel.color_pattern_idx]; - } else { + else src_dat = mach->accel.color_pattern[mach->accel.color_pattern_idx]; - } } else src_dat = 0; break; @@ -1318,9 +1316,9 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 mach->accel.color_pattern_idx++; if (mach->accel.color_pattern_idx == 3) mach->accel.color_pattern_idx = 0; - } else { + } else mach->accel.color_pattern_idx = (mach->accel.color_pattern_idx + mach->accel.stepx) & mach->accel.patt_len; - } + } else if ((dev->accel_bpp == 24) && (mach->accel.patt_len_reg & 0x4000) && (frgd_sel == 5)) { mach->accel.color_pattern_idx++; if (mach->accel.color_pattern_idx == 3) @@ -1346,9 +1344,9 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (dev->bpp) dev->accel.dest = (mach->accel.ge_offset << 1) + (dev->accel.dy * (dev->pitch)); - else { + else dev->accel.dest = (mach->accel.ge_offset << 2) + (dev->accel.dy * (dev->pitch)); - } + if ((mono_src == 1) && (dev->accel_bpp == 24) && (frgd_sel == 5)) mach->accel.color_pattern_idx = 0; else @@ -2347,7 +2345,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv) mach->bank_r |= ((mach->regs[0xae] & 0x0c) << 2); mach->bank_w |= ((mach->regs[0xae] & 3) << 4); } - if (dev->on) + if (dev->on[0] || dev->on[1]) mach_log("Separate B2Bank = %02x, AEbank = %02x.\n", mach->regs[0xb2], mach->regs[0xae]); } else { /* Single bank mode */ mach->bank_w = ((mach->regs[0xb2] & 0x1e) >> 1); @@ -2355,7 +2353,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv) mach->bank_w |= ((mach->regs[0xae] & 3) << 4); } mach->bank_r = mach->bank_w; - if (dev->on) + if (dev->on[0] || dev->on[1]) mach_log("Single B2Bank = %02x, AEbank = %02x.\n", mach->regs[0xb2], mach->regs[0xae]); } svga->read_bank = mach->bank_r << 16; @@ -2590,7 +2588,7 @@ mach_recalctimings(svga_t *svga) if (mach->regs[0xb0] & 0x20) svga->gdcreg[5] |= 0x40; - if (dev->on) { + if (dev->on[0] || dev->on[1]) { mach_log("8514/A ON.\n"); if (dev->local >= 2) { dev->h_disp = (dev->hdisp + 1) << 3; @@ -3686,19 +3684,16 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) case 0x4ae8: case 0x4ae9: - if (!(port & 1)) { - if (dev->local < 2) - dev->ext_crt_pitch = 128; + if (dev->local < 2) + dev->ext_crt_pitch = 128; - dev->accel.advfunc_cntl = val & 0x0f; - } else { - dev->on = (dev->accel.advfunc_cntl & 0x01); - vga_on = !dev->on; - mach->ext_on = dev->on; - mach_log("ATI 8514/A: (0x4ae9) val = %04x, ext = %d.\n", dev->accel.advfunc_cntl & 0x01, mach->ext_on); - mach32_updatemapping(mach); - } - mach->ati_mode = 0; + WRITE8(port, dev->accel.advfunc_cntl, val); + dev->on[port & 1] = (dev->accel.advfunc_cntl & 0x01); + mach_log("%04x: ON=%d.\n", port, dev->on[port & 1]); + vga_on = !dev->on[port & 1]; + mach->ext_on[port & 1] = dev->on[port & 1]; + mach32_updatemapping(mach); + mach->ati_mode[port & 1] = 0; svga_recalctimings(svga); break; @@ -3806,29 +3801,22 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) break; case 0x42ee: - mach->accel.test2[0] = val; - break; case 0x42ef: - mach->accel.test2[1] = val; + mach->accel.test2[port & 1] = val; break; case 0x46ee: - mach->accel.test3[0] = val; - break; case 0x46ef: - mach->accel.test3[1] = val; + mach->accel.test3[port & 1] = val; break; case 0x4aee: case 0x4aef: WRITE8(port, mach->accel.clock_sel, val); - if (port & 1) { - dev->on = mach->accel.clock_sel & 0x01; - mach->ext_on = dev->on; - vga_on = !dev->on; - mach_log("ATI 8514/A: (0x4aef) val = %04x, ext = %d.\n", mach->accel.clock_sel & 0x01, mach->ext_on); - } - mach->ati_mode = 1; + dev->on[port & 1] = mach->accel.clock_sel & 0x01; + mach->ext_on[port & 1] = dev->on[port & 1]; + vga_on = !dev->on[port & 1]; + mach->ati_mode[port & 1] = 1; svga_recalctimings(svga); break; @@ -3836,16 +3824,14 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) case 0x52ef: mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); WRITE8(port, mach->accel.scratch0, val); - if (port & 1) - mach->ext_on = 1; + mach->ext_on[port & 1] = 1; break; case 0x56ee: case 0x56ef: mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); WRITE8(port, mach->accel.scratch1, val); - if (port & 1) - mach->ext_on = 1; + mach->ext_on[port & 1] = 1; break; case 0x5aee: @@ -3926,11 +3912,8 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) break; } svga_set_ramdac_type(svga, !!(mach->accel.ext_ge_config & 0x4000)); - if (port & 1) { - mach->ati_mode = 1; - mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); - mach32_updatemapping(mach); - } + mach->ati_mode[port & 1] = 1; + mach32_updatemapping(mach); } svga_recalctimings(svga); break; @@ -5115,10 +5098,12 @@ mach32_updatemapping(mach_t *mach) mach->ap_size = 4; mem_mapping_disable(&mach->mmio_linear_mapping); } - if (mach->ext_on && (dev->local >= 2) && mach->ati_mode) { + if ((mach->ext_on[0] || mach->ext_on[1]) && (dev->local >= 2) && (mach->ati_mode[0] || mach->ati_mode[1])) { + mach_log("ExtON.\n"); mem_mapping_set_handler(&svga->mapping, mach32_read, mach32_readw, mach32_readl, mach32_write, mach32_writew, mach32_writel); mem_mapping_set_p(&svga->mapping, mach); } else { + mach_log("ExtOFF.\n"); mem_mapping_set_handler(&svga->mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); mem_mapping_set_p(&svga->mapping, svga); } @@ -5456,7 +5441,8 @@ mach_mca_reset(void *priv) mem_mapping_disable(&mach->bios_rom.mapping); mem_mapping_disable(&mach->bios_rom2.mapping); mach_log("MCA reset.\n"); - dev->on = 0; + dev->on[0] = 0; + dev->on[1] = 0; vga_on = 1; mach_mca_write(0x102, 0, mach); } @@ -5564,12 +5550,10 @@ mach32_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) case 0x12: mach->linear_base = (mach->linear_base & 0xff000000) | ((val & 0xc0) << 16); - mach->ati_mode = 1; mach32_updatemapping(mach); break; case 0x13: mach->linear_base = (mach->linear_base & 0xc00000) | (val << 24); - mach->ati_mode = 1; mach32_updatemapping(mach); break; @@ -5722,7 +5706,8 @@ mach8_init(const device_t *info) dev->bpp = 0; svga->getclock = ics2494_getclock; - dev->on = 0; + dev->on[0] = 0; + dev->on[1] = 0; dev->ext_pitch = 1024; dev->ext_crt_pitch = 0x80; dev->accel_bpp = 8; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 8ec645016..c48baeb6e 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -212,10 +212,12 @@ svga_out(uint16_t addr, uint8_t val, void *priv) svga_recalctimings(svga); break; case 0x3c3: - if (xga_active) + if (xga_active && xga) xga->on = (val & 0x01) ? 0 : 1; - if (ibm8514_active) - dev->on = (val & 0x01) ? 0 : 1; + if (ibm8514_active && dev) { + dev->on[0] = (val & 0x01) ? 0 : 1; + dev->on[1] = dev->on[0]; + } svga_log("3C3: XGA ON = %d.\n", xga->on); vga_on = val & 0x01; @@ -527,7 +529,7 @@ svga_set_ramdac_type(svga_t *svga, int type) svga->ramdac_type = type; for (int c = 0; c < 256; c++) { - if (ibm8514_active) { + if (ibm8514_active && dev) { if (svga->ramdac_type == RAMDAC_8BIT) dev->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b); else @@ -535,7 +537,7 @@ svga_set_ramdac_type(svga_t *svga, int type) (svga->vgapal[c].g & 0x3f) * 4, (svga->vgapal[c].b & 0x3f) * 4); } - if (xga_active) { + if (xga_active && xga) { if (svga->ramdac_type == RAMDAC_8BIT) xga->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b); else @@ -834,11 +836,11 @@ svga_poll(void *priv) int old_ma; if (!svga->override) { - if (ibm8514_active && dev->on) { + if (ibm8514_active && dev && (dev->on[0] || dev->on[1])) { ibm8514_poll(dev, svga); return; } - if (xga_active && xga->on) { + if (xga_active && xga && xga->on) { if ((xga->disp_cntl_2 & 7) >= 2) { xga_poll(xga, svga); return; @@ -1253,7 +1255,7 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *priv) cycles -= svga->monitor->mon_video_timing_write_b; if (!linear) { - if (xga_active) { + if (xga_active && xga) { if (((xga->op_mode & 7) >= 4) && (xga->aperture_cntl >= 1)) { if (val == 0xa5) { /*Memory size test of XGA*/ xga->test = val; @@ -1474,7 +1476,7 @@ svga_read_common(uint32_t addr, uint8_t linear, void *priv) cycles -= svga->monitor->mon_video_timing_read_b; if (!linear) { - if (xga_active) { + if (xga_active && xga) { if (((xga->op_mode & 7) >= 4) && (xga->aperture_cntl >= 1)) { if (xga->test == 0xa5) { /*Memory size test of XGA*/ if (addr == 0xa0001) {