From 59811075db633c01e98f1cf0e98bd0e8af14da2e Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 15 Aug 2023 00:11:56 +0200 Subject: [PATCH] New batch of ATI Mach8/32 changes: 1. Hopefully fixed the passthrough stuff for good and fixed typo's in the IBM 8514/A poll function about the cursor. 2. Eliminated the ibm8514_on global variable in favor of a struct variable to be consistent with XGA. --- src/include/86box/vid_8514a.h | 2 + src/include/86box/vid_svga.h | 2 +- src/video/vid_8514a.c | 16 +- src/video/vid_ati_mach8.c | 730 ++++++++++++++++++++++++---------- src/video/vid_svga.c | 70 +--- 5 files changed, 547 insertions(+), 273 deletions(-) diff --git a/src/include/86box/vid_8514a.h b/src/include/86box/vid_8514a.h index 72235520a..a78434bd2 100644 --- a/src/include/86box/vid_8514a.h +++ b/src/include/86box/vid_8514a.h @@ -42,6 +42,8 @@ typedef struct ibm8514_t { int type; int local; int bpp; + int on; + int accel_bpp; uint32_t vram_size; uint32_t vram_mask; diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 2456f40d6..2fd2acf50 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -182,6 +182,7 @@ typedef struct svga_t { hwcursor_t overlay_latch; void (*render)(struct svga_t *svga); + void (*render8514)(struct svga_t *svga); void (*recalctimings_ex)(struct svga_t *svga); void (*video_out)(uint16_t addr, uint8_t val, void *priv); @@ -271,7 +272,6 @@ typedef struct svga_t { } svga_t; extern int vga_on; -extern int ibm8514_on; extern void ibm8514_poll(ibm8514_t *dev, svga_t *svga); extern void ibm8514_recalctimings(svga_t *svga); diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index e24054b93..70561ede8 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -962,8 +962,8 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) if (!val) break; dev->accel.advfunc_cntl = val & 0x0f; - ibm8514_on = val & 0x01; - vga_on = !ibm8514_on; + dev->on = val & 0x01; + vga_on = !dev->on; ibm8514_log("IBM 8514/A: VGA ON = %i, val = %02x\n", vga_on, val); svga_recalctimings(svga); break; @@ -4028,7 +4028,7 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga) dev->hwcursor_oddeven = 0; } - if ((dev->displine == (svga->hwcursor_latch.y + 1)) && dev->hwcursor_latch.ena && dev->interlace) { + if ((dev->displine == (dev->hwcursor_latch.y + 1)) && dev->hwcursor_latch.ena && dev->interlace) { dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - (dev->hwcursor_latch.yoff + 1); dev->hwcursor_oddeven = 1; } @@ -4044,13 +4044,13 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga) if (dev->firstline == 2000) { dev->firstline = dev->displine; - video_wait_for_buffer(); + video_wait_for_buffer_monitor(svga->monitor_index); } if (dev->hwcursor_on) dev->changedvram[dev->ma >> 12] = dev->changedvram[(dev->ma >> 12) + 1] = dev->interlace ? 3 : 2; - svga->render(svga); + svga->render8514(svga); svga->x_add = (overscan_x >> 1); ibm8514_render_overscan_left(dev, svga); @@ -4136,7 +4136,7 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga) dev->oddeven ^= 1; - changeframecount = dev->interlace ? 3 : 2; + svga->monitor->mon_changeframecount = dev->interlace ? 3 : 2; svga->vslines = 0; if (dev->interlace && dev->oddeven) @@ -4166,7 +4166,7 @@ ibm8514_recalctimings(svga_t *svga) { ibm8514_t *dev = &svga->dev8514; - if (ibm8514_on) { + if (dev->on) { dev->h_disp = (dev->hdisp + 1) << 3; dev->pitch = (dev->accel.advfunc_cntl & 4) ? 1024 : 640; dev->h_total = (dev->htotal + 1); @@ -4223,7 +4223,7 @@ ibm8514_recalctimings(svga_t *svga) svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; } - svga->render = ibm8514_render_8bpp; + svga->render8514 = ibm8514_render_8bpp; ibm8514_log("BPP=%d, Pitch = %d, rowoffset = %d, crtc13 = %02x, mode = %d, highres bit = %02x, has_vga? = %d.\n", dev->bpp, dev->pitch, dev->rowoffset, svga->crtc[0x13], dev->ibm_mode, dev->accel.advfunc_cntl & 4, ibm8514_has_vga); } ibm8514_log("8514 enabled, hdisp=%d, vtotal=%d, htotal=%d, dispend=%d, rowoffset=%d, split=%d, vsyncstart=%d, split=%08x\n", dev->hdisp, dev->vtotal, dev->htotal, dev->dispend, dev->rowoffset, dev->split, dev->vsyncstart, dev->split); diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 012703bee..34244a722 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -116,8 +116,8 @@ typedef struct mach_t { uint16_t src_y; int16_t bres_count; uint16_t clock_sel; - uint16_t crt_offset_lo; - uint16_t crt_offset_hi; + uint16_t crt_pitch; + uint16_t ge_pitch; uint16_t dest_cmp_fn; uint16_t dp_config; uint16_t ext_ge_config; @@ -254,26 +254,26 @@ mach_log(const char *fmt, ...) temp |= (dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ } \ } else if ((mach->accel.cmd_type == 2) || (mach->accel.cmd_type == 5)) { \ - if (!dev->bpp) { \ + if (dev->bpp) \ + temp = vram_w[((dev->accel.dest) + (cx) + (n)) & (dev->vram_mask >> 1)]; \ + else { \ temp = dev->vram[((dev->accel.dest) + (cx) + (n)) & dev->vram_mask]; \ temp |= (dev->vram[((dev->accel.dest) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ - } else { \ - temp = vram_w[((dev->accel.dest) + (cx) + (n)) & (dev->vram_mask >> 1)]; \ } \ } else if ((mach->accel.cmd_type == 3) || (mach->accel.cmd_type == 4)) { \ - if (!dev->bpp) { \ + if (dev->bpp) \ + temp = vram_w[((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (cx) + (n)) & (dev->vram_mask >> 1)]; \ + else { \ temp = dev->vram[((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (cx) + (n)) & dev->vram_mask]; \ temp |= (dev->vram[((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ - } else { \ - temp = vram_w[((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (cx) + (n)) & (dev->vram_mask >> 1)]; \ } \ } #define READ(addr, dat) \ - if (!dev->bpp) \ - dat = dev->vram[(addr) & (dev->vram_mask)]; \ + if (dev->bpp) \ + dat = vram_w[(addr) & (dev->vram_mask >> 1)]; \ else \ - dat = vram_w[(addr) & (dev->vram_mask >> 1)]; + dat = dev->vram[(addr) & (dev->vram_mask)]; #define MIX(mixmode, dest_dat, src_dat) \ { \ @@ -379,12 +379,12 @@ mach_log(const char *fmt, ...) #define WRITE(addr, dat) \ - if (!dev->bpp) { \ - dev->vram[((addr)) & (dev->vram_mask)] = dat; \ - dev->changedvram[(((addr)) & (dev->vram_mask)) >> 12] = changeframecount; \ - } else { \ + if (dev->bpp) { \ vram_w[((addr)) & (dev->vram_mask >> 1)] = dat; \ dev->changedvram[(((addr)) & (dev->vram_mask >> 1)) >> 11] = changeframecount; \ + } else { \ + dev->vram[((addr)) & (dev->vram_mask)] = dat; \ + dev->changedvram[(((addr)) & (dev->vram_mask)) >> 12] = changeframecount; \ } static int @@ -456,11 +456,11 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } } - if ((svga->bpp == 8) || (svga->bpp == 15) || (svga->bpp == 16) || (svga->bpp == 24)) { - if (svga->bpp == 24) + if ((dev->accel_bpp == 8) || (dev->accel_bpp == 15) || (dev->accel_bpp == 16) || (dev->accel_bpp == 24)) { + if (dev->accel_bpp == 24) mach_log("24BPP: CMDType=%d, cwh(%d,%d,%d,%d), dpconfig=%04x\n", cmd_type, clip_l, clip_r, clip_t, clip_b, mach->accel.dp_config); else - mach_log("BPP=%d, CMDType = %d, offs=%08x, DPCONFIG = %04x, cnt = %d, input = %d, mono_src = %d, frgdsel = %d, dstx = %d, dstxend = %d, pitch = %d, extcrt = %d, rw = %x, monpattern = %x.\n", svga->bpp, cmd_type, mach->accel.ge_offset, mach->accel.dp_config, count, cpu_input, mono_src, frgd_sel, dev->accel.cur_x, mach->accel.dest_x_end, dev->ext_pitch, dev->ext_crt_pitch, mach->accel.dp_config & 1, mach->accel.mono_pattern_enable); + mach_log("BPP=%d, CMDType = %d, offs=%08x, DPCONFIG = %04x, cnt = %d, input = %d, mono_src = %d, frgdsel = %d, dstx = %d, dstxend = %d, pitch = %d, extcrt = %d, rw = %x, monpattern = %x.\n", dev->accel_bpp, cmd_type, mach->accel.ge_offset, mach->accel.dp_config, count, cpu_input, mono_src, frgd_sel, dev->accel.cur_x, mach->accel.dest_x_end, dev->ext_pitch, dev->ext_crt_pitch, mach->accel.dp_config & 1, mach->accel.mono_pattern_enable); } switch (cmd_type) { @@ -972,10 +972,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 dev->accel.sx = 0; mach->accel.poly_fill = 0; mach->accel.color_pattern_idx = ((dev->accel.dx + (dev->accel.dy << 3)) & mach->accel.patt_len); - if ((svga->bpp == 24) && (mono_src != 1)) { + if ((dev->accel_bpp == 24) && (mono_src != 1)) { if (mach->accel.color_pattern_idx == mach->accel.patt_len) mach->accel.color_pattern_idx = mach->accel.patt_data_idx; - } else if ((svga->bpp == 24) && (frgd_sel == 5) && (mono_src == 1) && (mach->accel.patt_len_reg & 0x4000)) + } else if ((dev->accel_bpp == 24) && (frgd_sel == 5) && (mono_src == 1) && (mach->accel.patt_len_reg & 0x4000)) mach->accel.color_pattern_idx = 0; /*Height*/ @@ -1043,7 +1043,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 else dev->accel.src = (mach->accel.ge_offset << 2) + (dev->accel.cy * (dev->pitch)); - if ((svga->bpp == 24) && (frgd_sel == 5)) { + if ((dev->accel_bpp == 24) && (frgd_sel == 5)) { mach_log("BitBLT=%04x, WH(%d,%d), SRCWidth=%d, c(%d,%d), s(%d,%d).\n", mach->accel.dp_config, mach->accel.width, mach->accel.height, mach->accel.src_width, dev->accel.dx, dev->accel.dy, dev->accel.cx, dev->accel.cy); } else mach_log("BitBLT=%04x, Pitch=%d, C(%d,%d), SRCWidth=%d, WH(%d,%d), geoffset=%08x.\n", mach->accel.dp_config, dev->ext_pitch, dev->accel.cx, dev->accel.cy, mach->accel.src_width, mach->accel.width, mach->accel.height, (mach->accel.ge_offset << 2)); @@ -1096,7 +1096,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 mach->accel.color_pattern_word[x + (mach->accel.color_pattern_idx & 1)] |= (mach->accel.patt_data[(x + 1) & mach->accel.patt_len] << 8); } } else { - if ((svga->bpp == 24) && (mach->accel.patt_len < 3)) { + if ((dev->accel_bpp == 24) && (mach->accel.patt_len < 3)) { for (int x = 0; x <= mach->accel.patt_len; x++) { mach->accel.color_pattern[x] = mach->accel.patt_data[x]; mach_log("BITBLT: Color Pattern 24bpp[%d]=%02x, dataidx=%d, pattlen=%d.\n", x, mach->accel.color_pattern[x], mach->accel.patt_data_idx, mach->accel.patt_len); @@ -1141,7 +1141,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (mach->accel.mono_pattern_enable) { mix = mach->accel.mono_pattern[dev->accel.dy & 7][dev->accel.dx & 7]; } else { - if ((svga->bpp == 24) && (frgd_sel == 5) && (mach->accel.patt_len_reg & 0x4000)) + if ((dev->accel_bpp == 24) && (frgd_sel == 5) && (mach->accel.patt_len_reg & 0x4000)) mix = 1; else { if (!dev->accel.temp_cnt) { @@ -1224,7 +1224,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } } - if ((svga->bpp == 24) && (mono_src == 1) && (frgd_sel == 5) && (mach->accel.patt_len_reg & 0x4000)) { + if ((dev->accel_bpp == 24) && (mono_src == 1) && (frgd_sel == 5) && (mach->accel.patt_len_reg & 0x4000)) { if (dev->accel.sy & 1) { READ(dev->accel.dest + dev->accel.dx - dev->ext_pitch, dest_dat); } else { @@ -1270,7 +1270,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } if (mach->accel.dp_config & 0x10) { - if ((svga->bpp == 24) && (mono_src == 1) && (frgd_sel == 5) && (mach->accel.patt_len_reg & 0x4000)) { + if ((dev->accel_bpp == 24) && (mono_src == 1) && (frgd_sel == 5) && (mach->accel.patt_len_reg & 0x4000)) { if (dev->accel.sy & 1) { WRITE(dev->accel.dest + dev->accel.dx - dev->ext_pitch, dest_dat); } else { @@ -1306,12 +1306,12 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 dev->accel.dx += mach->accel.stepx; - if ((svga->bpp == 8) || ((svga->bpp == 24) && (mach->accel.patt_len >= 3) && (mono_src != 1))) + if ((dev->accel_bpp == 8) || ((dev->accel_bpp == 24) && (mach->accel.patt_len >= 3) && (mono_src != 1))) mach->accel.color_pattern_idx = (mach->accel.color_pattern_idx + mach->accel.stepx) & mach->accel.patt_len; - if ((svga->bpp == 24) && (mach->accel.color_pattern_idx == mach->accel.patt_len) && (mach->accel.patt_len >= 3) && (mono_src != 1)) { + if ((dev->accel_bpp == 24) && (mach->accel.color_pattern_idx == mach->accel.patt_len) && (mach->accel.patt_len >= 3) && (mono_src != 1)) { mach->accel.color_pattern_idx = mach->accel.patt_data_idx; - } else if ((svga->bpp == 24) && (mach->accel.patt_len < 3)) { + } else if ((dev->accel_bpp == 24) && (mach->accel.patt_len < 3)) { if (mach->accel.patt_len == 2) { mach->accel.color_pattern_idx++; if (mach->accel.color_pattern_idx == 3) @@ -1319,7 +1319,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } else { mach->accel.color_pattern_idx = (mach->accel.color_pattern_idx + mach->accel.stepx) & mach->accel.patt_len; } - } else if ((svga->bpp == 24) && (mach->accel.patt_len_reg & 0x4000) && (frgd_sel == 5)) { + } 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) mach->accel.color_pattern_idx = 0; @@ -1347,12 +1347,12 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 else { dev->accel.dest = (mach->accel.ge_offset << 2) + (dev->accel.dy * (dev->pitch)); } - if ((mono_src == 1) && (svga->bpp == 24) && (frgd_sel == 5)) + if ((mono_src == 1) && (dev->accel_bpp == 24) && (frgd_sel == 5)) mach->accel.color_pattern_idx = 0; else mach->accel.color_pattern_idx = ((dev->accel.dx + (dev->accel.dy << 3)) & mach->accel.patt_len); - if ((svga->bpp == 24) && (mach->accel.color_pattern_idx == mach->accel.patt_len) && (mono_src != 1)) + if ((dev->accel_bpp == 24) && (mach->accel.color_pattern_idx == mach->accel.patt_len) && (mono_src != 1)) mach->accel.color_pattern_idx = 0; if ((mono_src == 1) && !mach->accel.mono_pattern_enable && !(mach->accel.patt_len_reg & 0x4000)) { dev->accel.cur_x = dev->accel.dx; @@ -1362,7 +1362,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (dev->accel.sy >= mach->accel.height) { if ((mono_src == 2) || (mono_src == 3) || (frgd_sel == 2) || (frgd_sel == 3) || (bkgd_sel == 2) || (bkgd_sel == 3)) return; - if ((mono_src == 1) && (frgd_sel == 5) && (svga->bpp == 24) && (mach->accel.patt_len_reg & 0x4000)) + if ((mono_src == 1) && (frgd_sel == 5) && (dev->accel_bpp == 24) && (mach->accel.patt_len_reg & 0x4000)) return; dev->accel.cur_x = dev->accel.dx; dev->accel.cur_y = dev->accel.dy; @@ -1953,7 +1953,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } dev->accel.sx = 0; - if ((svga->bpp == 24) && (mach->accel.patt_len < 0x17)) + if ((dev->accel_bpp == 24) && (mach->accel.patt_len < 0x17)) mach->accel.color_pattern_idx = 0; /*Step Y*/ @@ -2014,7 +2014,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 else dev->accel.src = (mach->accel.ge_offset << 2) + (dev->accel.cy * (dev->pitch)); - if ((svga->bpp == 24) && (frgd_sel == 5)) { + if ((dev->accel_bpp == 24) && (frgd_sel == 5)) { if (mach->accel.patt_len == 0x17) mach->accel.color_pattern_idx = 0; dev->accel.x1 = dev->accel.dx + mach->accel.width; @@ -2051,7 +2051,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } if (frgd_sel == 5) { - if (svga->bpp != 24) { + if (dev->accel_bpp != 24) { for (int x = 0; x <= mach->accel.patt_len; x++) { mach->accel.color_pattern[x] = mach->accel.patt_data[x & mach->accel.patt_len]; } @@ -2132,7 +2132,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 break; case 5: if (mix) { - if (svga->bpp == 24) { + if (dev->accel_bpp == 24) { if (mach->accel.patt_len == 0x17) src_dat = mach->accel.color_pattern_full[mach->accel.color_pattern_idx]; else @@ -2210,7 +2210,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } dev->accel.dx += mach->accel.stepx; - if ((svga->bpp == 24) && (mach->accel.patt_len == 0x17)) { + if ((dev->accel_bpp == 24) && (mach->accel.patt_len == 0x17)) { mach->accel.color_pattern_idx++; if (dev->accel.x3) { if (mach->accel.color_pattern_idx == 9) @@ -2219,7 +2219,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (mach->accel.color_pattern_idx == 6) mach->accel.color_pattern_idx = 0; } - } else if ((svga->bpp == 24) && (mach->accel.patt_len < 3)) { + } else if ((dev->accel_bpp == 24) && (mach->accel.patt_len < 3)) { mach->accel.color_pattern_idx++; if (mach->accel.color_pattern_idx == 3) mach->accel.color_pattern_idx = 0; @@ -2249,7 +2249,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } static void -mach_accel_out_pixtrans(mach_t *mach, ibm8514_t *dev, UNUSED(uint16_t port), uint16_t val, UNUSED(uint16_t len)) +mach_accel_out_pixtrans(mach_t *mach, ibm8514_t *dev, UNUSED(uint16_t port), uint16_t val) { int frgd_sel; int bkgd_sel; @@ -2345,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 (ibm8514_on) + if (dev->on) 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); @@ -2353,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 (ibm8514_on) + if (dev->on) mach_log("Single B2Bank = %02x, AEbank = %02x.\n", mach->regs[0xb2], mach->regs[0xae]); } svga->read_bank = mach->bank_r << 16; @@ -2373,7 +2373,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv) ati_eeprom_write(&mach->eeprom, val & 8, val & 2, val & 1); break; case 0xb6: - if ((old ^ val) & 0x11) + if ((old ^ val) & 0x10) svga_recalctimings(svga); break; case 0xb8: @@ -2461,17 +2461,6 @@ mach_out(uint16_t addr, uint8_t val, void *priv) } break; - case 0x46e8: - io_removehandler(0x03c0, 32, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&mach->mmio_linear_mapping); - if (val & 8) { - io_sethandler(0x03c0, 32, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); - mem_mapping_enable(&svga->mapping); - mach32_updatemapping(mach); - } - break; - default: break; } @@ -2602,59 +2591,13 @@ mach_recalctimings(svga_t *svga) svga->gdcreg[5] &= ~0x40; } - if (mach->regs[0xb0] & 0x20) { + if (mach->regs[0xb0] & 0x20) svga->gdcreg[5] |= 0x40; - } - if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { - if (((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1))) { - if (!ibm8514_on) { - mach_log("VGA ON.\n"); - svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel, svga->clock_gen); - if (mach->regs[0xa7] & 0x80) - svga->clock *= 3; - } - switch (svga->gdcreg[5] & 0x60) { - case 0x00: - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_4bpp_lowres; - else - 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: /*256+ colours*/ - switch (svga->bpp) { - case 8: - svga->map8 = svga->pallook; - if (svga->lowres) - svga->render = svga_render_8bpp_lowres; - else { - svga->render = svga_render_8bpp_highres; - svga->ma_latch <<= 1; - svga->rowoffset <<= 1; - } - break; - - default: - break; - } - break; - - default: - break; - } - } - } - - if (dev->local >= 2) { - if (ibm8514_on) { - svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); + if (dev->on) { + mach_log("8514/A ON.\n"); + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); + if (dev->local >= 2) { dev->h_disp = (dev->hdisp + 1) << 3; dev->h_total = (dev->htotal + 1); dev->v_total = (dev->vtotal + 1); @@ -2677,10 +2620,9 @@ mach_recalctimings(svga_t *svga) dev->v_syncstart = 1536; } } - mach_log("1024x768 clock mode, hdisp = %d, htotal = %d, vtotal = %d, vsyncstart = %d, interlace = %02x\n", dev->h_disp, dev->h_total, dev->v_total, dev->v_syncstart, dev->interlace); } else { if (mach->shadow_set & 1) { - if ((dev->h_disp == 1024) && !dev->internal_pitch) { + if (dev->h_disp == 1024) { dev->h_disp = 640; dev->dispend = 480; } @@ -2695,47 +2637,45 @@ mach_recalctimings(svga_t *svga) dev->v_syncstart >>= 1; dev->v_total >>= 1; } + dev->pitch = dev->ext_pitch; dev->rowoffset = dev->ext_crt_pitch; - if ((mach->accel.ext_ge_config & 0x800) || (!(mach->accel.ext_ge_config & 0x8000) && !(mach->accel.ext_ge_config & 0x800))) { + if ((mach->accel.ext_ge_config & 0x800) || ((!(mach->accel.ext_ge_config & 0x8000) && !(mach->accel.ext_ge_config & 0x800)))) { if ((mach->accel.ext_ge_config & 0x30) == 0x20) { if ((mach->accel.ext_ge_config & 0xc0) == 0x40) - svga->bpp = 16; + dev->accel_bpp = 16; else - svga->bpp = 15; + dev->accel_bpp = 15; } else if ((mach->accel.ext_ge_config & 0x30) == 0x30) { if (mach->accel.ext_ge_config & 0x200) - svga->bpp = 32; + dev->accel_bpp = 32; else - svga->bpp = 24; + dev->accel_bpp = 24; } else - svga->bpp = 8; + dev->accel_bpp = 8; - mach_log("hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x.\n", dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, mach->accel.ext_ge_config & 0xcec0); - switch (svga->bpp) { + mach_log("hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, bpp=%d.\n", dev->h_disp, dev->dispend, dev->pitch, dev->ext_crt_pitch, mach->accel.ext_ge_config & 0xcec0, dev->accel_bpp); + switch (dev->accel_bpp) { case 8: - svga->render = ibm8514_render_8bpp; + svga->render8514 = ibm8514_render_8bpp; break; case 15: - svga->render = ibm8514_render_15bpp; + svga->render8514 = ibm8514_render_15bpp; break; case 16: - svga->render = ibm8514_render_16bpp; + svga->render8514 = ibm8514_render_16bpp; break; case 24: if (mach->accel.ext_ge_config & 0x400) - svga->render = ibm8514_render_BGR; + svga->render8514 = ibm8514_render_BGR; else - svga->render = ibm8514_render_24bpp; + svga->render8514 = ibm8514_render_24bpp; break; case 32: if (mach->accel.ext_ge_config & 0x400) - svga->render = ibm8514_render_ABGR8888; + svga->render8514 = ibm8514_render_ABGR8888; else - svga->render = ibm8514_render_RGBA8888; - break; - - default: + svga->render8514 = ibm8514_render_RGBA8888; break; } } @@ -2749,20 +2689,14 @@ mach_recalctimings(svga_t *svga) case 0xc0: svga->clock *= 4; break; - - default: - break; } - } - } else { - if (ibm8514_on) { - svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); - dev->h_disp = (dev->hdisp + 1) << 3; - dev->h_total = (dev->htotal + 1); - dev->v_total = (dev->vtotal + 1); - dev->v_syncstart = (dev->vsyncstart + 1); - dev->rowcount = !!(dev->disp_cntl & 0x08); - dev->dispend = ((dev->vdisp >> 1) + 1); + } else { + dev->h_disp = (dev->hdisp + 1) << 3; + dev->h_total = (dev->htotal + 1); + dev->v_total = (dev->vtotal + 1); + dev->v_syncstart = (dev->vsyncstart + 1); + dev->rowcount = !!(dev->disp_cntl & 0x08); + dev->dispend = ((dev->vdisp >> 1) + 1); if (dev->dispend == 766) dev->dispend += 2; @@ -2781,7 +2715,7 @@ mach_recalctimings(svga_t *svga) } } else { if (mach->shadow_set & 1) { - if ((dev->h_disp == 1024) && !dev->internal_pitch) { + if (dev->h_disp == 1024) { dev->h_disp = 640; dev->dispend = 480; } @@ -2795,16 +2729,54 @@ mach_recalctimings(svga_t *svga) dev->v_syncstart >>= 1; dev->v_total >>= 1; } - dev->pitch = dev->ext_pitch; dev->rowoffset = dev->ext_crt_pitch; mach_log("hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x.\n", dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, mach->accel.ext_ge_config & 0xcec0); svga->map8 = dev->pallook; - svga->render = ibm8514_render_8bpp; + svga->render8514 = ibm8514_render_8bpp; if (mach->regs[0xb8] & 0x40) svga->clock *= 2; } } + + if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { + if (((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1))) { + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel, svga->clock_gen); + if (mach->regs[0xa7] & 0x80) + svga->clock *= 3; + switch (svga->gdcreg[5] & 0x60) { + case 0x00: + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_4bpp_lowres; + else + 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: /*256+ colours*/ + switch (svga->bpp) { + default: + case 8: + svga->map8 = svga->pallook; + if (svga->lowres) + svga->render = svga_render_8bpp_lowres; + else { + svga->render = svga_render_8bpp_highres; + svga->ma_latch <<= 1; + svga->rowoffset <<= 1; + } + break; + + } + break; + } + } + } } static void @@ -2941,7 +2913,6 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u dev->accel.cmd_back = 0; } ibm8514_accel_start(-1, 0, -1, 0, svga, len); - svga_recalctimings(svga); } break; case 0x9ae9: @@ -3247,10 +3218,11 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u if ((dev->accel.multifunc_cntl >> 12) == 4) { dev->accel.multifunc[4] = val & 0x7ff; } - mach_log("CLIPBOTTOM=%d, CLIPRIGHT=%d, bpp=%d, pitch=%d.\n", dev->accel.multifunc[3], dev->accel.multifunc[4], svga->bpp, dev->pitch); + mach_log("CLIPBOTTOM=%d, CLIPRIGHT=%d, bpp=%d, pitch=%d.\n", dev->accel.multifunc[3], dev->accel.multifunc[4], dev->accel_bpp, dev->pitch); if ((dev->accel.multifunc_cntl >> 12) == 5) { - if (!dev->ext_crt_pitch || (dev->local < 2)) + if (dev->local < 2) dev->ext_crt_pitch = 128; + svga_recalctimings(svga); } if (port == 0xfee8) @@ -3271,8 +3243,9 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u dev->accel.clip_left = dev->accel.multifunc_cntl & 0x7ff; } if ((dev->accel.multifunc_cntl >> 12) == 5) { - if (!dev->ext_crt_pitch || (dev->local < 2)) + if (dev->local < 2) dev->ext_crt_pitch = 128; + svga_recalctimings(svga); } if (port == 0xfee9) @@ -3299,11 +3272,11 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u else { frgd_sel = (mach->accel.dp_config >> 13) & 7; mono_src = (mach->accel.dp_config >> 5) & 3; - if ((svga->bpp == 24) && (mach->accel.patt_len == 0x17) && (frgd_sel == 5)) { + if ((dev->accel_bpp == 24) && (mach->accel.patt_len == 0x17) && (frgd_sel == 5)) { mach->accel.patt_data_idx += 2; dev->accel.y1 = 1; } else { - if (svga->bpp == 24) + if (dev->accel_bpp == 24) mach->accel.patt_data_idx += 2; else mach->accel.patt_data_idx = (mach->accel.patt_data_idx + 2) & mach->accel.patt_len; @@ -3319,7 +3292,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u mach->accel.patt_data_idx = (mach->accel.patt_data_idx + 2) & 7; else { frgd_sel = (mach->accel.dp_config >> 13) & 7; - if ((svga->bpp == 24) && (mach->accel.patt_len == 0x17) && (frgd_sel == 5)) { + if ((dev->accel_bpp == 24) && (mach->accel.patt_len == 0x17) && (frgd_sel == 5)) { mach->accel.patt_data_idx += 2; dev->accel.y1 = 1; } else @@ -3634,8 +3607,11 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) svga_recalctimings(svga); break; case 0x6e8: - dev->hdisp = val; - mach_log("ATI 8514/A: H_DISP write 06E8 = %d\n", dev->hdisp + 1); + case 0x6e9: + if (!(port & 1)) { + dev->hdisp = val; + mach_log("ATI 8514/A: H_DISP write 06E8 = %d\n", dev->hdisp + 1); + } svga_recalctimings(svga); break; @@ -3670,8 +3646,8 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) svga_recalctimings(svga); break; - case 0x1ee8: - dev->vsyncwidth = val; + case 0x1ee8: + case 0x1ee9: mach_log("ATI 8514/A: V_SYNC_WID write 1EE8 = %02x\n", val); svga_recalctimings(svga); break; @@ -3679,8 +3655,8 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) case 0x22e8: dev->disp_cntl = val & 0x7e; dev->interlace = !!(val & 0x10); - mach_log("ATI 8514/A: DISP_CNTL write 22E8 = %02x, SCANMODULOS = %d\n", dev->disp_cntl, dev->scanmodulos); svga_recalctimings(svga); + mach_log("ATI 8514/A: DISP_CNTL write 22E8 = %02x, SCANMODULOS = %d\n", dev->disp_cntl, dev->scanmodulos); break; case 0x42e8: @@ -3691,19 +3667,17 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) break; case 0x4ae8: - if (!val) - break; - if (!dev->ext_crt_pitch || (dev->local < 2)) - dev->ext_crt_pitch = 128; + case 0x4ae9: + if (!(port & 1)) { + if (dev->local < 2) + dev->ext_crt_pitch = 128; - dev->accel.advfunc_cntl = val & 0x0f; - ibm8514_on = val & 0x01; - if (!ibm8514_on && mach->old_mode) { - ibm8514_on = 1; - mach->old_mode = 0; + dev->accel.advfunc_cntl = val & 0x0f; + } else { + dev->on = (dev->accel.advfunc_cntl & 0x01); + vga_on = !dev->on; + pclog("ATI 8514/A: (0x4ae8) val = %04x\n", val & 0x01); } - vga_on = !ibm8514_on; - mach_log("ATI 8514/A: VGA ON (0x4ae8) = %i, val = %02x, 8514 = %i, gdcreg6 = %02x\n", vga_on, val, ibm8514_on, svga->gdcreg[6] & 0x0c); svga_recalctimings(svga); break; @@ -3769,23 +3743,17 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) break; case 0x26ee: - mach_log("CRT Pitch = %d, original val = %d.\n", val << 3, val); - dev->ext_crt_pitch = val; - dev->internal_pitch = val; - if (svga->bpp > 8) { - if (svga->bpp == 24) + case 0x26ef: + WRITE8(port, mach->accel.crt_pitch, val); + dev->ext_crt_pitch = mach->accel.crt_pitch & 0xff; + if (dev->accel_bpp > 8) { + if (dev->accel_bpp == 24) dev->ext_crt_pitch *= 3; - else if (svga->bpp == 32) + else if (dev->accel_bpp == 32) dev->ext_crt_pitch <<= 2; else dev->ext_crt_pitch <<= 1; } - if (dev->local >= 2) { - if (!ibm8514_on) { - ibm8514_on = 1; - svga->adv_flags |= FLAG_ATI; - } - } svga_recalctimings(svga); break; @@ -3831,19 +3799,12 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) case 0x4aee: case 0x4aef: - if (!(port & 1)) - mach->old_mode = mach->accel.clock_sel & 0x01; - WRITE8(port, mach->accel.clock_sel, val); - ibm8514_on = mach->accel.clock_sel & 0x01; - vga_on = !ibm8514_on; - if (dev->local >= 2) { - if (ibm8514_on) - svga->adv_flags |= FLAG_ATI; - else - svga->adv_flags &= ~FLAG_ATI; + if (port & 1) { + pclog("ATI 8514/A: (0x4aee) val = %04x\n", mach->accel.clock_sel & 0x01); + dev->on = mach->accel.clock_sel & 0x01; + vga_on = !dev->on; } - mach_log("ATI 8514/A: VGA ON (0x4aee) = %i, Ext = %i, val = %04x\n", vga_on, ibm8514_on, mach->accel.clock_sel); svga_recalctimings(svga); break; @@ -3860,6 +3821,9 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) case 0x5aee: case 0x5aef: WRITE8(port, mach->shadow_set, val); + if (port & 1) + mach_log("Shadow set = %02x.\n", mach->shadow_set & 0x03); + svga_recalctimings(svga); break; @@ -3899,9 +3863,11 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) break; case 0x76ee: - mach_log("76EE write val=%d shifted, normal=%d.\n", val << 3, val); - dev->ext_pitch = val << 3; - mach->old_mode = 1; + case 0x76ef: + WRITE8(port, mach->accel.ge_pitch, val); + if (port & 1) + dev->ext_pitch = ((mach->accel.ge_pitch & 0xff) << 3); + svga_recalctimings(svga); break; @@ -3909,7 +3875,8 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) case 0x7aef: WRITE8(port, mach->accel.ext_ge_config, val); if (dev->local >= 2) { - dev->ext_crt_pitch = dev->internal_pitch; + if (mach->accel.crt_pitch & 0xff) + dev->ext_crt_pitch = mach->accel.crt_pitch & 0xff; switch (mach->accel.ext_ge_config & 0x30) { case 0: case 0x10: @@ -3931,10 +3898,9 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) break; } svga_set_ramdac_type(svga, !!(mach->accel.ext_ge_config & 0x4000)); - mach_log("Passthrough override = %04x.\n", val & 0x1000); - svga_recalctimings(svga); + mach_log("7AEE write val = %04x.\n", mach->accel.ext_ge_config); } - mach_log("7AEE write val = %04x.\n", mach->accel.ext_ge_config); + svga_recalctimings(svga); break; case 0x7eee: @@ -4495,10 +4461,7 @@ mach_accel_in(uint16_t port, mach_t *mach) case 0x5eef: if (mach->pci_bus) mach->memory_aperture = (mach->memory_aperture & ~0xfff0) | ((mach->linear_base >> 20) << 4); - if ((port & 1) && ibm8514_on) { - ibm8514_on = 0; - vga_on = 1; - } + READ8(port, mach->memory_aperture); break; @@ -4639,10 +4602,327 @@ mach_accel_inl(uint16_t port, void *priv) return temp; } +static void +mach32_write_linear(uint32_t addr, uint8_t val, void *priv) +{ + svga_t *svga = (svga_t *) priv; + ibm8514_t *dev = &svga->dev8514; + int writemask2 = svga->writemask; + int reset_wm = 0; + latch_t vall; + uint8_t wm = svga->writemask; + uint8_t count; + uint8_t i; + + cycles -= svga->monitor->mon_video_timing_write_b; + + if (!(svga->gdcreg[6] & 1)) + svga->fullchange = 2; + + if (((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) && (svga->writemode < 4)) { + writemask2 = 1 << (addr & 3); + addr &= ~3; + } else if (svga->chain4 && (svga->writemode < 4)) { + writemask2 = 1 << (addr & 3); + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + } else if (svga->chain2_write) { + writemask2 &= ~0xa; + if (addr & 1) + writemask2 <<= 1; + addr &= ~1; + addr &= dev->vram_mask; + } else { + writemask2 = 1 << (addr & 3); + addr &= ~3; + addr &= dev->vram_mask; + } + addr &= svga->decode_mask; + + if (addr >= dev->vram_size) + return; + + addr &= dev->vram_mask; + + dev->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; + + count = 4; + + switch (svga->writemode) { + case 0: + val = ((val >> (svga->gdcreg[3] & 7)) | (val << (8 - (svga->gdcreg[3] & 7)))); + if ((svga->gdcreg[8] == 0xff) && !(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { + for (i = 0; i < count; i++) { + if (writemask2 & (1 << i)) + dev->vram[addr | i] = val; + } + return; + } else { + for (i = 0; i < count; i++) { + if (svga->gdcreg[1] & (1 << i)) + vall.b[i] = !!(svga->gdcreg[0] & (1 << i)) * 0xff; + else + vall.b[i] = val; + } + } + break; + case 1: + for (i = 0; i < count; i++) { + if (writemask2 & (1 << i)) + dev->vram[addr | i] = svga->latch.b[i]; + } + return; + case 2: + for (i = 0; i < count; i++) + vall.b[i] = !!(val & (1 << i)) * 0xff; + + if (!(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { + for (i = 0; i < count; i++) { + if (writemask2 & (1 << i)) + dev->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (svga->latch.b[i] & ~svga->gdcreg[8]); + } + return; + } + break; + case 3: + val = ((val >> (svga->gdcreg[3] & 7)) | (val << (8 - (svga->gdcreg[3] & 7)))); + wm = svga->gdcreg[8]; + svga->gdcreg[8] &= val; + + for (i = 0; i < count; i++) + vall.b[i] = !!(svga->gdcreg[0] & (1 << i)) * 0xff; + + reset_wm = 1; + break; + default: + break; + } + + switch (svga->gdcreg[3] & 0x18) { + case 0x00: /* Set */ + for (i = 0; i < count; i++) { + if (writemask2 & (1 << i)) + dev->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (svga->latch.b[i] & ~svga->gdcreg[8]); + } + break; + case 0x08: /* AND */ + for (i = 0; i < count; i++) { + if (writemask2 & (1 << i)) + dev->vram[addr | i] = (vall.b[i] | ~svga->gdcreg[8]) & svga->latch.b[i]; + } + break; + case 0x10: /* OR */ + for (i = 0; i < count; i++) { + if (writemask2 & (1 << i)) + dev->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | svga->latch.b[i]; + } + break; + case 0x18: /* XOR */ + for (i = 0; i < count; i++) { + if (writemask2 & (1 << i)) + dev->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) ^ svga->latch.b[i]; + } + break; + + default: + break; + } + + if (reset_wm) + svga->gdcreg[8] = wm; +} + +static void +mach32_write(uint32_t addr, uint8_t val, void *priv) +{ + svga_t *svga = (svga_t *) priv; + mach_t *mach = (mach_t *) svga->priv; + ibm8514_t *dev = &svga->dev8514; + + if (!dev->on) { + svga_write(addr, val, svga); + return; + } + + addr = (addr & svga->banked_mask) + svga->write_bank; + mach32_write_linear(addr, val, svga); +} + +static void +mach32_writew(uint32_t addr, uint16_t val, void *priv) +{ + svga_t *svga = (svga_t *) priv; + mach_t *mach = (mach_t *) svga->priv; + ibm8514_t *dev = &svga->dev8514; + + if (!dev->on) { + svga_writew(addr, val, svga); + return; + } + + mach32_write(addr, val & 0xff, svga); + mach32_write(addr + 1, val >> 8, svga); +} + +static void +mach32_writel(uint32_t addr, uint32_t val, void *priv) +{ + svga_t *svga = (svga_t *) priv; + mach_t *mach = (mach_t *) svga->priv; + ibm8514_t *dev = &svga->dev8514; + + if (!dev->on) { + svga_writel(addr, val, svga); + return; + } + + mach32_write(addr, val & 0xff, svga); + mach32_write(addr + 1, val >> 8, svga); + mach32_write(addr + 2, val >> 16, svga); + mach32_write(addr + 3, val >> 24, svga); +} + +static uint8_t +mach32_read_linear(uint32_t addr, void *priv) +{ + svga_t *svga = (svga_t *) priv; + ibm8514_t *dev = &svga->dev8514; + uint32_t latch_addr = 0; + int readplane = svga->readplane; + uint8_t count; + uint8_t temp; + uint8_t ret; + + cycles -= svga->monitor->mon_video_timing_read_b; + + count = 2; + + latch_addr = (addr << count) & svga->decode_mask; + count = (1 << count); + + if ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) { + addr &= svga->decode_mask; + if (addr >= dev->vram_size) + return 0xff; + latch_addr = (addr & dev->vram_mask) & ~3; + for (uint8_t i = 0; i < count; i++) + svga->latch.b[i] = dev->vram[latch_addr | i]; + return dev->vram[addr & dev->vram_mask]; + } else if (svga->chain4 && !svga->force_old_addr) { + readplane = addr & 3; + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + } else if (svga->chain2_read) { + readplane = (readplane & 2) | (addr & 1); + addr &= ~1; + addr &= dev->vram_mask; + } else { + addr &= svga->decode_mask; + if (addr >= dev->vram_size) + return 0xff; + latch_addr = (addr & dev->vram_mask) & ~3; + for (uint8_t i = 0; i < count; i++) + svga->latch.b[i] = dev->vram[latch_addr | i]; + return dev->vram[addr & dev->vram_mask]; + } + + addr &= svga->decode_mask; + + /* standard VGA latched access */ + if (latch_addr >= dev->vram_size) { + for (uint8_t i = 0; i < count; i++) + svga->latch.b[i] = 0xff; + } else { + latch_addr &= dev->vram_mask; + + for (uint8_t i = 0; i < count; i++) + svga->latch.b[i] = dev->vram[latch_addr | i]; + } + + if (addr >= dev->vram_size) + return 0xff; + + addr &= dev->vram_mask; + + if (svga->readmode) { + temp = 0xff; + + for (uint8_t pixel = 0; pixel < 8; pixel++) { + for (uint8_t plane = 0; plane < count; plane++) { + if (svga->colournocare & (1 << plane)) { + /* If we care about a plane, and the pixel has a mismatch on it, clear its bit. */ + if (((svga->latch.b[plane] >> pixel) & 1) != ((svga->colourcompare >> plane) & 1)) + temp &= ~(1 << pixel); + } + } + } + + ret = temp; + } else + ret = dev->vram[addr | readplane]; + + return ret; +} + +static uint8_t +mach32_read(uint32_t addr, void *priv) +{ + svga_t *svga = (svga_t *) priv; + mach_t *mach = (mach_t *) svga->priv; + ibm8514_t *dev = &svga->dev8514; + uint8_t ret; + + if (!dev->on) { + ret = svga_read(addr, svga); + return ret; + } + + addr = (addr & svga->banked_mask) + svga->read_bank; + ret = mach32_read_linear(addr, svga); + return ret; +} + +static uint16_t +mach32_readw(uint32_t addr, void *priv) +{ + svga_t *svga = (svga_t *) priv; + mach_t *mach = (mach_t *) svga->priv; + ibm8514_t *dev = &svga->dev8514; + uint16_t ret; + + if (!dev->on) { + ret = svga_readw(addr, svga); + return ret; + } + + ret = mach32_read(addr, svga); + ret |= (mach32_read(addr + 1, svga) << 8); + return ret; +} + +static uint32_t +mach32_readl(uint32_t addr, void *priv) +{ + svga_t *svga = (svga_t *) priv; + mach_t *mach = (mach_t *) svga->priv; + ibm8514_t *dev = &svga->dev8514; + uint32_t ret; + + if (!dev->on) { + ret = svga_readl(addr, svga); + return ret; + } + + ret = mach32_read(addr, svga); + ret |= (mach32_read(addr + 1, svga) << 8); + ret |= (mach32_read(addr + 2, svga) << 16); + ret |= (mach32_read(addr + 3, svga) << 24); + return ret; +} + static void mach32_ap_writeb(uint32_t addr, uint8_t val, void *priv) { mach_t *mach = (mach_t *) priv; + svga_t *svga = &mach->svga; uint8_t port_dword = addr & 0xfc; if (((mach->local_cntl & 0x20) || (mach->pci_cntl_reg & 0x80)) && @@ -4656,7 +4936,7 @@ mach32_ap_writeb(uint32_t addr, uint8_t val, void *priv) } } else { mach_log("Linear WORDB Write=%08x.\n", addr); - svga_write_linear(addr, val, &mach->svga); + mach32_write_linear(addr, val, svga); } } @@ -4664,6 +4944,7 @@ static void mach32_ap_writew(uint32_t addr, uint16_t val, void *priv) { mach_t *mach = (mach_t *) priv; + svga_t *svga = &mach->svga; uint8_t port_dword = addr & 0xfc; if (((mach->local_cntl & 0x20) || (mach->pci_cntl_reg & 0x80)) && @@ -4677,7 +4958,8 @@ mach32_ap_writew(uint32_t addr, uint16_t val, void *priv) } } else { mach_log("Linear WORDW Write=%08x.\n", addr); - svga_writew_linear(addr, val, &mach->svga); + mach32_write_linear(addr, val & 0xff, svga); + mach32_write_linear(addr + 1, val >> 8, svga); } } @@ -4685,6 +4967,7 @@ static void mach32_ap_writel(uint32_t addr, uint32_t val, void *priv) { mach_t *mach = (mach_t *) priv; + svga_t *svga = &mach->svga; uint8_t port_dword = addr & 0xfc; if (((mach->local_cntl & 0x20) || (mach->pci_cntl_reg & 0x80)) && @@ -4700,7 +4983,10 @@ mach32_ap_writel(uint32_t addr, uint32_t val, void *priv) } } else { mach_log("Linear WORDL Write=%08x, val=%08x, mode=%d, rop=%02x.\n", addr, val, mach->svga.writemode, mach->svga.gdcreg[3] & 0x18); - svga_writel_linear(addr, val, &mach->svga); + mach32_write_linear(addr, val & 0xff, svga); + mach32_write_linear(addr + 1, val >> 8, svga); + mach32_write_linear(addr + 2, val >> 16, svga); + mach32_write_linear(addr + 3, val >> 24, svga); } } @@ -4708,6 +4994,7 @@ static uint8_t mach32_ap_readb(uint32_t addr, void *priv) { mach_t *mach = (mach_t *) priv; + svga_t *svga = &mach->svga; uint8_t temp; uint8_t port_dword = addr & 0xfc; @@ -4719,7 +5006,7 @@ mach32_ap_readb(uint32_t addr, void *priv) temp = mach_accel_inb(0x02e8 + (addr & 1) + (port_dword << 8), mach); } } else - temp = svga_read_linear(addr, &mach->svga); + temp = mach32_read_linear(addr, svga); return temp; } @@ -4728,6 +5015,7 @@ static uint16_t mach32_ap_readw(uint32_t addr, void *priv) { mach_t *mach = (mach_t *) priv; + svga_t *svga = &mach->svga; uint16_t temp; uint8_t port_dword = addr & 0xfc; @@ -4738,8 +5026,10 @@ mach32_ap_readw(uint32_t addr, void *priv) } else { temp = mach_accel_inw(0x02e8 + (port_dword << 8), mach); } - } else - temp = svga_readw_linear(addr, &mach->svga); + } else { + temp = mach32_read_linear(addr, svga); + temp |= (mach32_read_linear(addr + 1, svga) << 8); + } return temp; } @@ -4748,6 +5038,7 @@ static uint32_t mach32_ap_readl(uint32_t addr, void *priv) { mach_t *mach = (mach_t *) priv; + svga_t *svga = &mach->svga; uint32_t temp; uint8_t port_dword = addr & 0xfc; @@ -4760,8 +5051,12 @@ mach32_ap_readl(uint32_t addr, void *priv) temp = mach_accel_inw(0x02e8 + (port_dword << 8), mach); temp |= (mach_accel_inw(0x02e8 + (port_dword << 8) + 4, mach) << 8); } - } else - temp = svga_readl_linear(addr, &mach->svga); + } else { + temp = mach32_read_linear(addr, svga); + temp |= (mach32_read_linear(addr + 1, svga) << 8); + temp |= (mach32_read_linear(addr + 2, svga) << 16); + temp |= (mach32_read_linear(addr + 3, svga) << 24); + } return temp; } @@ -4832,13 +5127,13 @@ mach32_hwcursor_draw(svga_t *svga, int displine) uint32_t color0; uint32_t color1; - if (svga->bpp == 8) { + if (dev->accel_bpp == 8) { color0 = dev->pallook[mach->cursor_col_0]; color1 = dev->pallook[mach->cursor_col_1]; - } else if (svga->bpp == 15) { + } else if (dev->accel_bpp == 15) { color0 = video_15to32[((mach->ext_cur_col_0_r << 16) | (mach->ext_cur_col_0_g << 8) | mach->cursor_col_0) & 0xffff]; color1 = video_15to32[((mach->ext_cur_col_1_r << 16) | (mach->ext_cur_col_1_g << 8) | mach->cursor_col_1) & 0xffff]; - } else if (svga->bpp == 16) { + } else if (dev->accel_bpp == 16) { color0 = video_16to32[((mach->ext_cur_col_0_r << 16) | (mach->ext_cur_col_0_g << 8) | mach->cursor_col_0) & 0xffff]; color1 = video_16to32[((mach->ext_cur_col_1_r << 16) | (mach->ext_cur_col_1_g << 8) | mach->cursor_col_1) & 0xffff]; } else { @@ -5145,11 +5440,13 @@ static void mach_mca_reset(void *priv) { mach_t *mach = (mach_t *) priv; + svga_t *svga = &mach->svga; + ibm8514_t *dev = &svga->dev8514; mem_mapping_disable(&mach->bios_rom.mapping); mem_mapping_disable(&mach->bios_rom2.mapping); mach_log("MCA reset.\n"); - ibm8514_on = 0; + dev->on = 0; vga_on = 1; mach_mca_write(0x102, 0, mach); } @@ -5348,13 +5645,12 @@ mach8_init(const device_t *info) mach_in, mach_out, mach32_hwcursor_draw, NULL); + dev->vram_size = mach->memory << 10; + dev->vram = calloc(dev->vram_size, 1); + dev->changedvram = calloc(dev->vram_size >> 12, 1); + dev->vram_mask = dev->vram_size - 1; dev->hwcursor.cur_ysize = 64; - dev->vram_size = svga->vram_max; - dev->vram = svga->vram; - dev->changedvram = svga->changedvram; - dev->vram_mask = svga->vram_mask; mach->config1 = 0x20; - mach->config2 = 0x08; if (mach->pci_bus && !mach->ramdac_type) svga->ramdac = device_add(&ati68860_ramdac_device); else @@ -5390,6 +5686,7 @@ mach8_init(const device_t *info) mach->config1 |= 0x0400; svga->clock_gen = device_add(&ati18811_0_device); } + mem_mapping_set_handler(&svga->mapping, mach32_read, mach32_readw, mach32_readl, mach32_write, mach32_writew, mach32_writel); mem_mapping_add(&mach->mmio_linear_mapping, 0, 0, mach32_ap_readb, mach32_ap_readw, mach32_ap_readl, mach32_ap_writeb, mach32_ap_writew, mach32_ap_writel, NULL, MEM_MAPPING_EXTERNAL, mach); mem_mapping_disable(&mach->mmio_linear_mapping); } else { @@ -5410,8 +5707,10 @@ mach8_init(const device_t *info) dev->bpp = 0; svga->getclock = ics2494_getclock; + dev->on = 0; dev->ext_pitch = 1024; dev->ext_crt_pitch = 0x80; + dev->accel_bpp = 8; svga->force_old_addr = 1; svga->miscout = 1; svga->bpp = 8; @@ -5420,7 +5719,6 @@ mach8_init(const device_t *info) io_sethandler(0x01ce, 2, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); io_sethandler(0x03c0, 32, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); io_sethandler(0x02ea, 4, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); - io_sethandler(0x46e8, 1, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); mach_io_set(mach); if (dev->local >= 2) { @@ -5494,7 +5792,7 @@ mach_close(void *priv) svga_t *svga = &mach->svga; ibm8514_t *dev = &svga->dev8514; - if (dev && (dev->local < 2)) { + if (dev) { free(dev->vram); free(dev->changedvram); } diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 9e23a9871..fac4420d0 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -56,7 +56,6 @@ uint8_t svga_rotate[8][256]; only SVGA device.*/ static svga_t *svga_pri; int vga_on; -int ibm8514_on; #ifdef ENABLE_SVGA_LOG int svga_do_log = ENABLE_SVGA_LOG; @@ -211,7 +210,7 @@ svga_out(uint16_t addr, uint8_t val, void *priv) if (xga_enabled) xga->on = (val & 0x01) ? 0 : 1; if (ibm8514_enabled) - ibm8514_on = (val & 0x01) ? 0 : 1; + dev->on = (val & 0x01) ? 0 : 1; vga_on = val & 0x01; break; @@ -518,21 +517,20 @@ svga_set_ramdac_type(svga_t *svga, int type) svga->ramdac_type = type; for (int c = 0; c < 256; c++) { - if (ibm8514_on) { + if (ibm8514_enabled) { if (svga->ramdac_type == RAMDAC_8BIT) dev->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b); else dev->pallook[c] = makecol32((svga->vgapal[c].r & 0x3f) * 4, (svga->vgapal[c].g & 0x3f) * 4, (svga->vgapal[c].b & 0x3f) * 4); - } else { - if (svga->ramdac_type == RAMDAC_8BIT) - svga->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b); - else - svga->pallook[c] = makecol32((svga->vgapal[c].r & 0x3f) * 4, - (svga->vgapal[c].g & 0x3f) * 4, - (svga->vgapal[c].b & 0x3f) * 4); } + if (svga->ramdac_type == RAMDAC_8BIT) + svga->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b); + else + svga->pallook[c] = makecol32((svga->vgapal[c].r & 0x3f) * 4, + (svga->vgapal[c].g & 0x3f) * 4, + (svga->vgapal[c].b & 0x3f) * 4); } } } @@ -540,7 +538,7 @@ svga_set_ramdac_type(svga_t *svga, int type) void svga_recalctimings(svga_t *svga) { - const ibm8514_t *dev = &svga->dev8514; + ibm8514_t *dev = &svga->dev8514; double crtcconst; double _dispontime; double _dispofftime; @@ -727,13 +725,8 @@ svga_recalctimings(svga_t *svga) crtcconst = svga->clock * svga->char_width; - if (ibm8514_on) { - disptime = dev->h_total; - _dispontime = dev->h_disp; - } else { - disptime = svga->htotal; - _dispontime = svga->hdisp_time; - } + disptime = svga->htotal; + _dispontime = svga->hdisp_time; if (svga->seqregs[1] & 8) { disptime *= 2; @@ -822,10 +815,11 @@ svga_poll(void *priv) int ret; int old_ma; - if (ibm8514_enabled && ibm8514_on) { + if (ibm8514_enabled && dev->on) { ibm8514_poll(dev, svga); return; - } else if (xga_enabled && xga->on) { + } + if (xga_enabled && xga->on) { xga_poll(xga, svga); return; } @@ -1283,18 +1277,10 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *priv) if (addr & 1) writemask2 <<= 1; addr &= ~1; - if (linear && ibm8514_on && (svga->adv_flags & FLAG_ATI)) { - addr &= svga->vram_mask; - } else - addr <<= 2; - } else { - if (linear && ibm8514_on && (svga->adv_flags & FLAG_ATI)) { - writemask2 = 1 << (addr & 3); - addr &= ~3; - addr &= svga->vram_mask; - } else - addr <<= 2; - } + addr <<= 2; + } else + addr <<= 2; + addr &= svga->decode_mask; if (svga->translate_address) @@ -1504,22 +1490,10 @@ svga_read_common(uint32_t addr, uint8_t linear, void *priv) } else if (svga->chain2_read) { readplane = (readplane & 2) | (addr & 1); addr &= ~1; - if (linear && ibm8514_on && (svga->adv_flags & FLAG_ATI)) - addr &= svga->vram_mask; - else - addr <<= 2; - } else { - if (linear && ibm8514_on && (svga->adv_flags & FLAG_ATI)) { - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return 0xff; - latch_addr = (addr & svga->vram_mask) & ~3; - for (uint8_t i = 0; i < count; i++) - svga->latch.b[i] = svga->vram[latch_addr | i]; - return svga->vram[addr & svga->vram_mask]; - } else - addr <<= 2; - } + addr <<= 2; + } else + addr <<= 2; + addr &= svga->decode_mask; if (svga->translate_address) {