From 2ac3d289e624c85dc08fd00b79acc6af06974146 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 29 May 2024 20:47:22 +0200 Subject: [PATCH] Video changes part 1 for 4.2 1. Corrected the ATI 1881x clocks for use with the ATI Mach8/32 and VGA Wonder chips. The CPU slowdowns should now be gone. 2. Merged I/O ports common to both the ATI and IBM 8514/A compatible chips where they have identical code (extended behavior is still separate). Code duplication is now less than before. 3. Fixed a general polygon pattern issue in the Mach8/32 affecting calc.exe in Win3.x and other stuff. 4. Mode changes are, once again, changed (ATI and IBM), as close as possible to the real thing without destroying existing resolutions. 5. The 8514/A Vertical Counter has been extended to 0xfff so that it can take 1280x1024 resolutions well offered by the Mach32 as well as a better way to change the IBM/ATI modes through a callback swap where approprietate. 6. in 8514/A mode, reads from the 0x3c6-0x3c9 ramdac range is redirected to the 8514/A RAMDAC (0x2ea-0x2ed). 7. LFB access in the Mach32 now no longer takes account of the SVGA derived rops. Fixes Mach32 display on NeXTSTEP/OPENSTEP 3.x/4.x 8. Reworked the Display Sense Status and Subsystem Status ports so that they're not copycats from MAME and instead follow the datasheet. --- src/include/86box/vid_8514a.h | 3 +- src/include/86box/vid_ati_mach8.h | 1 + src/include/86box/vid_svga.h | 36 +- src/video/vid_8514a.c | 396 +++++++------- src/video/vid_ati_mach8.c | 836 ++++++++++++------------------ src/video/vid_ics2494.c | 97 ++-- src/video/vid_svga.c | 15 +- 7 files changed, 635 insertions(+), 749 deletions(-) diff --git a/src/include/86box/vid_8514a.h b/src/include/86box/vid_8514a.h index ac4085089..def3f0f2b 100644 --- a/src/include/86box/vid_8514a.h +++ b/src/include/86box/vid_8514a.h @@ -41,10 +41,10 @@ typedef union { typedef struct ibm8514_t { rom_t bios_rom; - rom_t bios_rom2; hwcursor8514_t hwcursor; hwcursor8514_t hwcursor_latch; uint8_t pos_regs[8]; + char *rom_path; int force_old_addr; int type; @@ -56,6 +56,7 @@ typedef struct ibm8514_t { uint32_t vram_size; uint32_t vram_mask; uint32_t pallook[512]; + uint32_t bios_addr; PALETTE vgapal; uint8_t hwcursor_oddeven; diff --git a/src/include/86box/vid_ati_mach8.h b/src/include/86box/vid_ati_mach8.h index 7b5862f35..a25432920 100644 --- a/src/include/86box/vid_ati_mach8.h +++ b/src/include/86box/vid_ati_mach8.h @@ -74,6 +74,7 @@ typedef struct mach_t { uint16_t shadow_set; uint16_t shadow_cntl; int ext_on[2]; + int extended_mode; int compat_mode; struct { diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 9eecebf2c..3d68c1a34 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -78,6 +78,7 @@ typedef struct svga_t { uint8_t overlay_oddeven; uint8_t fcr; uint8_t hblank_overscan; + uint8_t vidsys_ena; int dac_addr; int dac_pos; @@ -199,6 +200,7 @@ typedef struct svga_t { void (*ven_write)(struct svga_t *svga, uint8_t val, uint32_t addr); float (*getclock)(int clock, void *priv); + float (*getclock8514)(int clock, void *priv); /* Called when VC=R18 and friends. If this returns zero then MA resetting is skipped. Matrox Mystique in Power mode reuses this counter for @@ -288,26 +290,32 @@ typedef struct svga_t { void * dev8514; void * ext8514; + void * clock_gen8514; void * xga; } svga_t; -extern int vga_on; +extern int vga_on; -extern void ibm8514_poll(void *priv); -extern void ibm8514_recalctimings(svga_t *svga); -extern uint8_t ibm8514_ramdac_in(uint16_t port, void *priv); -extern void ibm8514_ramdac_out(uint16_t port, uint8_t val, void *priv); -extern int ibm8514_cpu_src(svga_t *svga); -extern int ibm8514_cpu_dest(svga_t *svga); -extern void ibm8514_accel_out_pixtrans(svga_t *svga, uint16_t port, uint32_t val, int len); -extern void ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, uint8_t ssv, int len); -extern void ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, int len); +extern void ibm8514_poll(void *priv); +extern void ibm8514_recalctimings(svga_t *svga); +extern uint8_t ibm8514_ramdac_in(uint16_t port, void *priv); +extern void ibm8514_ramdac_out(uint16_t port, uint8_t val, void *priv); +extern void ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len); +extern void ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len); +extern uint16_t ibm8514_accel_in_fifo(svga_t *svga, uint16_t port, int len); +extern uint8_t ibm8514_accel_in(uint16_t port, svga_t *svga); +extern int ibm8514_cpu_src(svga_t *svga); +extern int ibm8514_cpu_dest(svga_t *svga); +extern void ibm8514_accel_out_pixtrans(svga_t *svga, uint16_t port, uint32_t val, int len); +extern void ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, uint8_t ssv, int len); +extern void ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, int len); #ifdef ATI_8514_ULTRA -extern void ati8514_recalctimings(svga_t *svga); -extern uint8_t ati8514_mca_read(int port, void *priv); -extern void ati8514_mca_write(int port, uint8_t val, void *priv); -extern void ati8514_init(svga_t *svga, void *ext8514, void *dev8514); +extern void ati8514_recalctimings(svga_t *svga); +extern uint8_t ati8514_mca_read(int port, void *priv); +extern void ati8514_mca_write(int port, uint8_t val, void *priv); +extern void ati8514_pos_write(uint16_t port, uint8_t val, void *priv); +extern void ati8514_init(svga_t *svga, void *ext8514, void *dev8514); #endif extern void xga_poll(void *priv, svga_t *svga); diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index ff1470164..fc205dacf 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -44,6 +44,8 @@ #ifdef ATI_8514_ULTRA #define BIOS_MACH8_ROM_PATH "roms/video/mach8/11301113140.BIN" + +static video_timings_t timing_8514ultra_isa = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 5, .read_w = 5, .read_l = 10 }; #endif static void ibm8514_accel_outb(uint16_t port, uint8_t val, void *priv); @@ -469,7 +471,7 @@ regular_nibble: } } -static void +void ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) { ibm8514_t *dev = (ibm8514_t *) svga->dev8514; @@ -500,8 +502,9 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) break; case 0x86e9: case 0xc6e9: - if (len == 1) + if (len == 1) { dev->accel.cur_x = (dev->accel.cur_x & 0xff) | ((val & 0x07) << 8); + } break; case 0x8ae8: @@ -548,6 +551,7 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) if (len != 1) dev->test = val; fallthrough; + case 0xd2e8: if (len == 1) dev->accel.err_term = (dev->accel.err_term & 0x3f00) | val; @@ -577,9 +581,8 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) break; case 0x96e9: case 0xd6e9: - if (len == 1) { + if (len == 1) dev->accel.maj_axis_pcnt = (dev->accel.maj_axis_pcnt & 0xff) | ((val & 0x07) << 8); - } break; case 0x9ae8: @@ -624,7 +627,6 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) dev->accel.cy = dev->accel.cur_y; if (dev->accel.cur_x >= 0x600) dev->accel.cx |= ~0x5ff; - if (dev->accel.cur_y >= 0x600) dev->accel.cy |= ~0x5ff; @@ -646,9 +648,9 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) dev->accel.cy = dev->accel.cur_y; if (dev->accel.cur_x >= 0x600) dev->accel.cx |= ~0x5ff; - if (dev->accel.cur_y >= 0x600) dev->accel.cy |= ~0x5ff; + if (dev->accel.cmd & 0x1000) { ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke & 0xff, len); ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke >> 8, len); @@ -883,7 +885,7 @@ ibm8514_io_set(svga_t *svga) io_sethandler(0xfee8, 0x0002, ibm8514_accel_inb, ibm8514_accel_inw, NULL, ibm8514_accel_outb, ibm8514_accel_outw, NULL, svga); } -static void +void ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) { ibm8514_t *dev = (ibm8514_t *) svga->dev8514; @@ -894,88 +896,89 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) else { switch (port) { case 0x2e8: - case 0x2e9: + case 0x6e9: WRITE8(port, dev->htotal, val); + ibm8514_log("IBM 8514/A compatible: (0x%04x): htotal=0x%02x.\n", port, val); + svga_recalctimings(svga); break; case 0x6e8: - case 0x6e9: - if (!(port & 1)) { - if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { - dev->hdisped = val; - dev->hdisp = (dev->hdisped + 1) << 3; - } + /*In preparation to switch from VGA to 8514/A mode*/ + if (!dev->on[0] || !dev->on[1]) { + dev->hdisped = val; + dev->hdisp = (dev->hdisped + 1) << 3; } - ibm8514_log("IBM 8514/A: H_DISP write 06E8 = %d, advfunc=%x.\n", dev->hdisp, dev->accel.advfunc_cntl & 4); + ibm8514_log("[%04X:%08X]: IBM 8514/A: (0x%04x): hdisp=0x%02x.\n", CS, cpu_state.pc, port, val); + svga_recalctimings(svga); break; case 0xae8: - case 0xae9: - if (!(port & 1)) { - if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { - dev->hsync_start = val; - dev->hblankstart = (dev->hsync_start & 0x07); - } - } - ibm8514_log("IBM 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1); + dev->hsync_start = val; + ibm8514_log("IBM 8514/A compatible: (0x%04x): val=0x%02x, hsync_start=%d.\n", port, val, (val + 1) << 3); + svga_recalctimings(svga); break; case 0xee8: - case 0xee9: - if (!(port & 1)) { - if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { - dev->hsync_width = val; - dev->hblank_end_val = (dev->hblankstart + (dev->hsync_width & 0x1f) - 1) & 0x3f; - } - } - ibm8514_log("IBM 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1); + dev->hsync_width = val; + ibm8514_log("IBM 8514/A compatible: (0x%04x): val=0x%02x, hsync_width=%d, hsyncpol=%02x.\n", port, val & 0x1f, ((val & 0x1f) + 1) << 3, val & 0x20); + svga_recalctimings(svga); break; case 0x12e8: case 0x12e9: - if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { - WRITE8(port, dev->v_total_reg, val); - dev->v_total_reg &= 0x1fff; - dev->vtotal = dev->v_total_reg; - dev->vtotal++; - } + /*In preparation to switch from VGA to 8514/A mode*/ + WRITE8(port, dev->v_total_reg, val); + dev->v_total_reg &= 0x1fff; + dev->v_total = dev->v_total_reg + 1; + if (dev->interlace) + dev->v_total >>= 1; + + ibm8514_log("IBM 8514/A compatible: (0x%04x): vtotal=0x%02x.\n", port, val); + svga_recalctimings(svga); break; case 0x16e8: case 0x16e9: - if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { + /*In preparation to switch from VGA to 8514/A mode*/ + if (!dev->on[0] || !dev->on[1]) { WRITE8(port, dev->v_disp, val); dev->v_disp &= 0x1fff; - dev->vdisp = dev->v_disp; - dev->vdisp >>= 1; - dev->vdisp++; + dev->vdisp = (dev->v_disp + 1) >> 1; } - ibm8514_log("IBM 8514/A: V_DISP write 16E8 = %d\n", dev->vdisp); + ibm8514_log("IBM 8514/A: V_DISP write 16E8 = %d\n", dev->v_disp); + ibm8514_log("IBM 8514/A: (0x%04x): vdisp=0x%02x.\n", port, val); + svga_recalctimings(svga); break; case 0x1ae8: case 0x1ae9: - if (((dev->disp_cntl & 0x60) == 0x20) || (((dev->disp_cntl & 0x60) == 0x40) && !(dev->accel.advfunc_cntl & 0x04))) { - WRITE8(port, dev->v_sync_start, val); - dev->v_sync_start &= 0x1fff; - dev->vsyncstart = dev->v_sync_start; - dev->vsyncstart++; - } + /*In preparation to switch from VGA to 8514/A mode*/ + WRITE8(port, dev->v_sync_start, val); + dev->v_sync_start &= 0x1fff; + dev->v_syncstart = dev->v_sync_start + 1; + if (dev->interlace) + dev->v_syncstart >>= 1; + + ibm8514_log("IBM 8514/A compatible: V_SYNCSTART write 1AE8 = %d\n", dev->v_syncstart); + ibm8514_log("IBM 8514/A compatible: (0x%04x): vsyncstart=0x%02x.\n", port, val); + svga_recalctimings(svga); break; case 0x1ee8: case 0x1ee9: - ibm8514_log("IBM 8514/A: V_SYNC_WID write 1EE8 = %02x\n", val); + ibm8514_log("IBM 8514/A compatible: V_SYNC_WID write 1EE8 = %02x\n", val); + ibm8514_log("IBM 8514/A compatible: (0x%04x): vsyncwidth=0x%02x.\n", port, val); + svga_recalctimings(svga); break; case 0x22e8: - dev->disp_cntl = val & 0x7e; - dev->interlace = !!(val & 0x10); - ibm8514_log("IBM 8514/A: DISP_CNTL write 22E8 = %02x, interlace = %d\n", dev->disp_cntl, dev->interlace); + dev->disp_cntl = val; + dev->interlace = !!(dev->disp_cntl & 0x10); + ibm8514_log("IBM 8514/A compatible: DISP_CNTL write %04x=%02x, interlace=%d.\n", port, dev->disp_cntl, dev->interlace); + svga_recalctimings(svga); break; case 0x42e8: - old = dev->subsys_stat; if (val & 1) dev->subsys_stat &= ~1; if (val & 2) @@ -1004,11 +1007,11 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) dev->on[port & 1] = dev->accel.advfunc_cntl & 0x01; vga_on = !dev->on[port & 1]; dev->vendor_mode[port & 1] = 0; - ibm8514_log("IBM 8514/A: (0x%04x): ON=%d, shadow crt=%x.\n", port, dev->on[port & 1], dev->accel.advfunc_cntl & 4); + ibm8514_log("[%04X:%08X]: IBM 8514/A: (0x%04x): ON=%d, shadow crt=%x, hdisp=%d, vdisp=%d.\n", CS, cpu_state.pc, port, dev->on[port & 1], dev->accel.advfunc_cntl & 0x04, dev->hdisp, dev->vdisp); + ibm8514_log("IBM mode set %s resolution.\n", (dev->accel.advfunc_cntl & 0x04) ? "2: 1024x768" : "1: 640x480"); svga_recalctimings(svga); break; - default: break; } @@ -1031,73 +1034,14 @@ ibm8514_accel_outw(uint16_t port, uint16_t val, void *priv) ibm8514_accel_out(port, val, svga, 2); } -static uint32_t -ibm8514_accel_in(uint16_t port, svga_t *svga, int len) +uint16_t +ibm8514_accel_in_fifo(svga_t *svga, uint16_t port, int len) { - ibm8514_t *dev = (ibm8514_t *) svga->dev8514; - uint32_t temp = 0; - int cmd; - int vpos = 0; - int vblankend = svga->vblankstart + svga->crtc[0x16]; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint16_t temp = 0; + int cmd = 0; switch (port) { - case 0x2e8: - vpos = dev->vc & 0x7ff; - if (vblankend > dev->v_total) { - vblankend -= dev->v_total; - if ((vpos >= svga->vblankstart) || (vpos <= vblankend)) - temp |= 2; - } else { - if ((vpos >= svga->vblankstart) && (vpos <= vblankend)) - temp |= 2; - } - break; - - case 0x6e8: - temp = dev->hdisped; - break; - - case 0x22e8: - temp = dev->disp_cntl; - break; - - case 0x26e8: - if (len == 1) - temp = dev->htotal & 0xff; - else - temp = dev->htotal; - break; - case 0x26e9: - if (len == 1) - temp = dev->htotal >> 8; - break; - - case 0x2ee8: - temp = dev->subsys_cntl; - break; - - case 0x42e8: - cmd = dev->accel.cmd >> 13; - vpos = dev->vc & 0x7ff; - if (vblankend > dev->v_total) { - vblankend -= dev->v_total; - if (vpos >= svga->vblankstart || vpos <= vblankend) - dev->subsys_stat |= 1; - } else { - if (vpos >= svga->vblankstart && vpos <= vblankend) - dev->subsys_stat |= 1; - } - if (len != 1) { - temp = dev->subsys_stat | 0xa0 | 0x8000; - } else - temp = dev->subsys_stat | 0xa0; - break; - - case 0x42e9: - if (len == 1) - temp |= 0x80; - break; - case 0x82e8: case 0xc2e8: if (len != 1) @@ -1115,6 +1059,11 @@ ibm8514_accel_in(uint16_t port, svga_t *svga, int len) temp = dev->test; break; + case 0x96e8: + if (len != 1) + temp = dev->accel.maj_axis_pcnt; + break; + case 0x9ae8: case 0xdae8: if (len != 1) { @@ -1143,24 +1092,13 @@ ibm8514_accel_in(uint16_t port, svga_t *svga, int len) case 0xe2e8: case 0xe6e8: if (ibm8514_cpu_dest(svga)) { - if (len == 1) { - ; // READ_PIXTRANS_BYTE_IO(0) - } else { + if (len != 1) { cmd = (dev->accel.cmd >> 13); - READ_PIXTRANS_WORD(dev->accel.cx, 0) + READ_PIXTRANS_WORD(dev->accel.cx, 0); if (dev->accel.input && !dev->accel.odd_in && !dev->accel.sx) { temp &= ~0xff00; temp |= (dev->vram[(dev->accel.newdest_in + dev->accel.cur_x) & dev->vram_mask] << 8); } - } - ibm8514_accel_out_pixtrans(svga, port, temp, len); - } - break; - case 0xe2e9: - case 0xe6e9: - if (ibm8514_cpu_dest(svga)) { - if (len == 1) { - ; // READ_PIXTRANS_BYTE_IO(1) ibm8514_accel_out_pixtrans(svga, port, temp, len); } } @@ -1172,20 +1110,100 @@ ibm8514_accel_in(uint16_t port, svga_t *svga, int len) return temp; } +uint8_t +ibm8514_accel_in(uint16_t port, svga_t *svga) +{ + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint8_t temp = 0; + uint16_t clip_b_ibm = dev->accel.multifunc[3]; + uint16_t clip_r_ibm = dev->accel.multifunc[4]; + int cmd = (dev->accel.cmd >> 13); + + switch (port) { + case 0x2e8: + if (dev->vc == dev->v_syncstart) + temp |= 2; + + ibm8514_log("0x2E8 read: Display Status=%02x.\n", temp); + break; + + case 0x6e8: + temp = dev->hdisped; + break; + + case 0x22e8: + temp = dev->disp_cntl; + break; + + case 0x26e8: + case 0x26e9: + READ8(port, dev->htotal); + break; + + case 0x2ee8: + temp = dev->subsys_cntl; + break; + case 0x2ee9: + temp = 0xff; + break; + + case 0x42e8: + case 0x42e9: + if (dev->vc == dev->v_syncstart) + dev->subsys_stat |= 1; + + if (cmd == 6) { + if (((dev->accel.dx) >= dev->accel.clip_left) && ((dev->accel.dx) <= clip_r_ibm) && ((dev->accel.dy) >= dev->accel.clip_top) && ((dev->accel.dy) <= clip_b_ibm)) + temp |= 2; + } else { + if (((dev->accel.cx) >= dev->accel.clip_left) && ((dev->accel.dx) <= clip_r_ibm) && ((dev->accel.cy) >= dev->accel.clip_top) && ((dev->accel.cy) <= clip_b_ibm)) + temp |= 2; + } + + if (!dev->force_busy) + temp |= 8; + + if (port & 1) + temp = 0x80; + else { + temp |= (dev->subsys_stat | 0x80); + temp |= 0x20; + } + break; + + default: + break; + } + return temp; +} + static uint8_t ibm8514_accel_inb(uint16_t port, void *priv) { svga_t *svga = (svga_t *) priv; + uint8_t temp; - return ibm8514_accel_in(port, svga, 1); + if (port & 0x8000) + temp = ibm8514_accel_in_fifo(svga, port, 1); + else + temp = ibm8514_accel_in(port, svga); + + return temp; } static uint16_t ibm8514_accel_inw(uint16_t port, void *priv) { svga_t *svga = (svga_t *) priv; + uint16_t temp; - return ibm8514_accel_in(port, svga, 2); + if (port & 0x8000) + temp = ibm8514_accel_in_fifo(svga, port, 2); + else { + temp = ibm8514_accel_in(port, svga); + temp |= (ibm8514_accel_in(port + 1, svga) << 8); + } + return temp; } void @@ -2285,7 +2303,6 @@ rect_fill_pix: WRITE(dev->accel.dest + dev->accel.cx, dest_dat); } } - mix_dat <<= 1; mix_dat |= 1; if (dev->bpp) @@ -2448,6 +2465,7 @@ rect_fill_pix: } } } + mix_dat <<= 1; mix_dat |= 1; @@ -2525,6 +2543,7 @@ rect_fill_pix: } } } + mix_dat <<= 1; mix_dat |= 1; if (dev->bpp) @@ -3385,6 +3404,7 @@ bitblt_pix: WRITE(dev->accel.dest + dev->accel.dx, dest_dat); } } + mix_dat >>= 1; if (dev->bpp) cpu_dat >>= 16; @@ -3452,7 +3472,6 @@ bitblt_pix: } else { while (count-- && (dev->accel.sy >= 0)) { if (dev->accel.dx >= dev->accel.clip_left && dev->accel.dx <= clip_r && dev->accel.dy >= dev->accel.clip_top && dev->accel.dy <= clip_b) { - if (pixcntl == 3) { if (!(dev->accel.cmd & 0x10) && ((frgd_mix != 3) || (bkgd_mix != 3))) { READ(dev->accel.src + dev->accel.cx, mix_dat); @@ -3496,6 +3515,7 @@ bitblt_pix: WRITE(dev->accel.dest + dev->accel.dx, dest_dat); } } + mix_dat <<= 1; mix_dat |= 1; if (dev->bpp) @@ -3655,6 +3675,7 @@ bitblt: WRITE(dev->accel.dest + dev->accel.dx, dest_dat); } } + dev->accel.temp_cnt--; mix_dat >>= 1; @@ -3779,6 +3800,7 @@ bitblt: } } } + mix_dat <<= 1; mix_dat |= 1; @@ -4147,7 +4169,7 @@ ibm8514_poll(void *priv) dev->hwcursor_oddeven = 1; } - timer_advance_u64(&svga->timer8514, dev->dispofftime); + timer_advance_u64(&svga->timer, dev->dispofftime); svga->cgastat |= 1; dev->linepos = 1; @@ -4192,7 +4214,7 @@ ibm8514_poll(void *priv) if (dev->displine > 1500) dev->displine = 0; } else { - timer_advance_u64(&svga->timer8514, dev->dispontime); + timer_advance_u64(&svga->timer, dev->dispontime); if (dev->dispon) svga->cgastat &= ~1; dev->hdisp_on = 0; @@ -4215,7 +4237,7 @@ ibm8514_poll(void *priv) } dev->vc++; - dev->vc &= 0x7ff; + dev->vc &= 0xfff; if (dev->vc == dev->dispend) { dev->dispon = 0; @@ -4290,43 +4312,37 @@ ibm8514_recalctimings(svga_t *svga) #endif { if (dev->on[0] || dev->on[1]) { - dev->h_disp = dev->hdisp; - dev->h_total = dev->htotal + 1; - dev->h_blankstart = dev->hblankstart; - dev->h_blank_end_val = dev->hblank_end_val; - dev->v_total = dev->vtotal; - dev->v_syncstart = dev->vsyncstart; - dev->dispend = dev->vdisp; - dev->rowcount = !!(dev->disp_cntl & 0x08); + dev->h_total = dev->htotal + 1; + dev->rowcount = !!(dev->disp_cntl & 0x08); + + if (dev->accel.advfunc_cntl & 0x01) { + if (dev->accel.advfunc_cntl & 0x04) { + dev->h_disp = dev->hdisp; + dev->dispend = dev->vdisp; + } else { + dev->h_disp = 640; + dev->dispend = 480; + } + } else { + dev->h_disp = dev->hdisp; + dev->dispend = dev->vdisp; + } + + if (dev->accel.advfunc_cntl & 0x04) + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0; + else + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0; + + if (dev->interlace) + dev->dispend >>= 1; if (dev->dispend == 766) dev->dispend += 2; - if (dev->accel.advfunc_cntl & 4) { - dev->pitch = 1024; - if (!dev->h_disp) { - dev->h_disp = 1024; - dev->dispend = 768; - } - svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0; - } else { - dev->pitch = 640; - if (!dev->h_disp) { - dev->h_disp = 640; - dev->dispend = 480; - } - svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0; - } - - if (dev->interlace) { - dev->dispend >>= 1; - dev->v_syncstart >>= 2; - dev->v_total >>= 2; - } else { - dev->v_syncstart >>= 1; - dev->v_total >>= 1; - } + if (dev->dispend == 478) + dev->dispend += 2; + dev->pitch = 1024; dev->rowoffset = 0x80; svga->map8 = dev->pallook; svga->render8514 = ibm8514_render_8bpp; @@ -4378,7 +4394,12 @@ ibm8514_mca_reset(void *priv) dev->on[0] = 0; dev->on[1] = 0; vga_on = 1; - ibm8514_mca_write(0x102, 0, svga); +#ifdef ATI_8514_ULTRA + if (dev->extensions) + ati8514_mca_write(0x102, 0, svga); + else +#endif + ibm8514_mca_write(0x102, 0, svga); } static void * @@ -4409,27 +4430,28 @@ ibm8514_init(const device_t *info) switch (dev->extensions) { case 1: if (rom_present(BIOS_MACH8_ROM_PATH)) { - mach = (mach_t *) calloc(1, sizeof(mach_t)); + mach_t * mach = (mach_t *) calloc(1, sizeof(mach_t)); svga->ext8514 = mach; - ati8514_init(svga, svga->ext8514, svga->dev8514); if (dev->type & DEVICE_MCA) { rom_init(&dev->bios_rom, - BIOS_MACH8_ROM_PATH, - 0xc6800, 0x1000, 0x0fff, - 0x0800, MEM_MAPPING_EXTERNAL); - mem_mapping_disable(&dev->bios_rom.mapping); + BIOS_MACH8_ROM_PATH, + 0xc6000, 0x2000, 0x1fff, + 0, MEM_MAPPING_EXTERNAL); dev->pos_regs[0] = 0x88; dev->pos_regs[1] = 0x80; mca_add(ati8514_mca_read, ati8514_mca_write, ibm8514_mca_feedb, ibm8514_mca_reset, svga); ati_eeprom_load(&mach->eeprom, "ati8514_mca.nvr", 0); + mem_mapping_disable(&dev->bios_rom.mapping); } else { rom_init(&dev->bios_rom, - BIOS_MACH8_ROM_PATH, - 0xd0000, 0x1000, 0x0fff, - 0x0800, MEM_MAPPING_EXTERNAL); + BIOS_MACH8_ROM_PATH, + 0xd0000, 0x2000, 0x1fff, + 0, MEM_MAPPING_EXTERNAL); ati_eeprom_load(&mach->eeprom, "ati8514.nvr", 0); + dev->bios_addr = dev->bios_rom.mapping.base; } + ati8514_init(svga, svga->ext8514, svga->dev8514); break; } fallthrough; @@ -4454,8 +4476,6 @@ ibm8514_init(const device_t *info) } #endif - timer_add(&svga->timer8514, ibm8514_poll, svga, 1); - return svga; } @@ -4526,7 +4546,7 @@ static const device_config_t ext8514_config[] = { // clang-format off const device_t gen8514_isa_device = { - .name = "Generic 8514/A clone (ISA)", + .name = "IBM 8514/A clone (ISA)", .internal_name = "8514_isa", .flags = DEVICE_AT | DEVICE_ISA, .local = 0, @@ -4536,7 +4556,11 @@ const device_t gen8514_isa_device = { { .available = NULL }, .speed_changed = ibm8514_speed_changed, .force_redraw = ibm8514_force_redraw, +#ifdef ATI_8514_ULTRA + .config = ext8514_config +#else .config = NULL +#endif }; const device_t ibm8514_mca_device = { @@ -4550,7 +4574,11 @@ const device_t ibm8514_mca_device = { { .available = NULL }, .speed_changed = ibm8514_speed_changed, .force_redraw = ibm8514_force_redraw, +#ifdef ATI_8514_ULTRA + .config = ext8514_config +#else .config = NULL +#endif }; diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index be2c5d547..83edb4355 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -315,8 +315,6 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 bkgd_sel = (mach->accel.dp_config >> 7) & 3; mono_src = (mach->accel.dp_config >> 5) & 3; - mach->accel.ge_offset = (mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16)); - if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) { mach->force_busy = 1; dev->force_busy = 1; @@ -817,7 +815,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (dev->accel.cur_y >= 0x600) dev->accel.dy |= ~0x5ff; - if ((mach->accel.dp_config == 0x5211) || (mach->accel.dp_config == 0x3251)) { + if (mach->accel.dp_config == 0x5211) { if (mach->accel.dest_x_end == 1024) { goto skip_dx; } @@ -1008,6 +1006,7 @@ skip_dx: if (cpu_input) { if (mach->accel.dp_config == 0x3251) { + mach_log("DPCONFIG 3251: monosrc=%d, frgdsel=%d, bkgdsel=%d, pitch=%d.\n", mono_src, frgd_sel, bkgd_sel, dev->pitch); if (dev->accel.sy == mach->accel.height) return; } @@ -1386,15 +1385,7 @@ skip_dx: dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); } } - if (mach->accel.linedraw_opt & 0x04) { - if (count) { - if (dev->bpp) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); - } else { - WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); - } - } - } else { + if ((mach->accel.dp_config & 0x10) && (cmd_type == 3)) { if (dev->bpp) { WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } else { @@ -1647,20 +1638,10 @@ skip_dx: } if ((mach->accel.dp_config & 0x10) && (cmd_type == 3)) { - if (mach->accel.linedraw_opt & 0x04) { - if (count) { - if (dev->bpp) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); - } else { - WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); - } - } + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } else { - if (dev->bpp) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); - } else { - WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); - } + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } } } else @@ -2374,6 +2355,9 @@ mach_in(uint16_t addr, void *priv) if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60; + if ((addr >= 0x3c6) && (addr <= 0x3c9) && (dev->on[0] || dev->on[1])) + addr -= 0xdc; + switch (addr) { case 0x1ce: temp = mach->index; @@ -2399,9 +2383,9 @@ mach_in(uint16_t addr, void *priv) } break; case 0xb7: - temp = mach->regs[0xb7] & ~8; + temp = mach->regs[0xb7] & ~0x08; if (ati_eeprom_read(&mach->eeprom)) - temp |= 8; + temp |= 0x08; break; case 0xbd: @@ -2429,21 +2413,6 @@ mach_in(uint16_t addr, void *priv) temp = svga_in(addr, svga); break; - case 0x3C6: - case 0x3C7: - case 0x3C8: - case 0x3C9: - rs2 = !!(mach->regs[0xa0] & 0x20); - rs3 = !!(mach->regs[0xa0] & 0x40); - if ((dev->local & 0xff) >= 0x02) { - if (mach->pci_bus && !mach->ramdac_type) - temp = ati68860_ramdac_in((addr & 3) | (rs2 << 2) | (rs3 << 3), svga->ramdac, svga); - else - temp = ati68875_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); - } else - temp = svga_in(addr, svga); - break; - case 0x3D4: temp = svga->crtcreg; break; @@ -2466,7 +2435,7 @@ mach_in(uint16_t addr, void *priv) static void ati8514_out(uint16_t addr, uint8_t val, void *priv) { - mach_log("ADDON OUT addr=%03x, val=%02x.\n", addr, val); + mach_log("[%04X:%08X]: ADDON OUT addr=%03x, val=%02x.\n", CS, cpu_state.pc, addr, val); svga_out(addr, val, priv); } @@ -2477,26 +2446,43 @@ ati8514_in(uint16_t addr, void *priv) temp = svga_in(addr, priv); - mach_log("ADDON IN addr=%03x, temp=%02x.\n", addr, temp); + mach_log("[%04X:%08X]: ADDON IN addr=%03x, temp=%02x.\n", CS, cpu_state.pc, addr, temp); return temp; } void ati8514_recalctimings(svga_t *svga) { - const mach_t *mach = (mach_t *) svga->ext8514; + mach_t *mach = (mach_t *) svga->ext8514; ibm8514_t *dev = (ibm8514_t *) svga->dev8514; mach_log("ON0=%d, ON1=%d, vgahdisp=%d.\n", dev->on[0], dev->on[1], svga->hdisp); if (dev->on[0] || dev->on[1]) { - dev->h_disp = dev->hdisp; + mach_log("8514/A ON.\n"); dev->h_total = dev->htotal + 1; - dev->h_blankstart = dev->hblankstart; - dev->h_blank_end_val = dev->hblank_end_val; - dev->v_total = dev->vtotal; - dev->v_syncstart = dev->vsyncstart; dev->rowcount = !!(dev->disp_cntl & 0x08); - dev->dispend = dev->vdisp; + dev->accel.ge_offset = (mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16)); + mach->accel.ge_offset = dev->accel.ge_offset; + + mach_log("HDISP=%d, VDISP=%d, shadowset=%x, 8514/A mode=%x, clocksel=%02x.\n", dev->hdisp, dev->vdisp, mach->shadow_set & 0x03, dev->accel.advfunc_cntl & 0x04, mach->accel.clock_sel & 0xfe); + if (dev->accel.advfunc_cntl & 0x01) { + if (dev->accel.advfunc_cntl & 0x04) { + dev->h_disp = dev->hdisp; + dev->dispend = dev->vdisp; + } else { + dev->h_disp = 640; + dev->dispend = 480; + } + } else { + dev->h_disp = dev->hdisp; + dev->dispend = dev->vdisp; + } + + if (dev->accel.advfunc_cntl & 0x04) { + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0; + } else { + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0; + } if (dev->dispend == 766) dev->dispend += 2; @@ -2504,28 +2490,12 @@ ati8514_recalctimings(svga_t *svga) if (dev->dispend == 598) dev->dispend += 2; - if (dev->accel.advfunc_cntl & 4) { - if (dev->h_disp != 800) { - dev->h_disp = 1024; - dev->dispend = 768; - } - svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; - } else { - svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; - } - - if (dev->interlace) { - dev->dispend >>= 1; - dev->v_syncstart >>= 2; - dev->v_total >>= 2; - } else { - dev->v_syncstart >>= 1; - dev->v_total >>= 1; - } + if (dev->dispend == 478) + dev->dispend += 2; dev->pitch = dev->ext_pitch; dev->rowoffset = dev->ext_crt_pitch; - mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, advfunc_cntl=%x, shadow=%x.\n", dev->accel.advfunc_cntl & 4, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, dev->accel.advfunc_cntl & 4, mach->shadow_set & 3); + mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, shadow=%x interlace=%d.\n", dev->accel.advfunc_cntl & 0x04, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, mach->accel.ext_ge_config & 0xcec0, mach->shadow_set & 3, dev->interlace); svga->map8 = dev->pallook; svga->render8514 = ibm8514_render_8bpp; } else { @@ -2598,26 +2568,34 @@ mach_recalctimings(svga_t *svga) if (dev->on[0] || dev->on[1]) { mach_log("8514/A ON.\n"); dev->h_total = dev->htotal + 1; - dev->v_total = dev->v_total_reg + 1; - dev->v_syncstart = dev->v_sync_start + 1; dev->rowcount = !!(dev->disp_cntl & 0x08); + dev->accel.ge_offset = (mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16)); + mach->accel.ge_offset = dev->accel.ge_offset; - mach_log("HDISP=%d, VDISP=%d, shadowset=%x, 8514/A mode=%x.\n", dev->hdisp, dev->vdisp, mach->shadow_set & 0x03, dev->accel.advfunc_cntl & 0x04); - if ((dev->hdisp != 1024) || dev->bpp) { - /*For VESA/ATI modes in 8514/A mode.*/ + mach_log("HDISP=%d, VDISP=%d, shadowset=%x, 8514/A mode=%x, clocksel=%02x.\n", dev->hdisp, dev->vdisp, mach->shadow_set & 0x03, dev->accel.advfunc_cntl & 0x04, mach->accel.clock_sel & 0xfe); + if (!dev->bpp) { + if (dev->accel.advfunc_cntl & 0x01) { + if (dev->accel.advfunc_cntl & 0x04) { + dev->h_disp = dev->hdisp; + dev->dispend = dev->vdisp; + } else { + dev->h_disp = 640; + dev->dispend = 480; + } + } else { + dev->h_disp = dev->hdisp; + dev->dispend = dev->vdisp; + } + } else { dev->h_disp = dev->hdisp; dev->dispend = dev->vdisp; - } else { - /*Default modes for 8514/A mode*/ - if (dev->accel.advfunc_cntl & 0x04) { - dev->h_disp = 1024; - dev->dispend = 768; - } else { - dev->h_disp = 640; - dev->dispend = 480; - } } + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); + + if (dev->interlace) + dev->dispend >>= 1; + if (dev->dispend == 766) dev->dispend += 2; @@ -2628,27 +2606,6 @@ mach_recalctimings(svga_t *svga) dev->dispend += 2; if ((dev->local & 0xff) >= 0x02) { - if ((dev->accel.advfunc_cntl ^ dev->modechange) & 0x04) { - if ((mach->shadow_set ^ mach->compat_mode) & 0x03) - svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); - else - svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0; - } else { - if ((mach->shadow_set ^ mach->compat_mode) & 0x03) - svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); - else - svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0; - } - - if (dev->interlace) { - dev->dispend >>= 1; - dev->v_syncstart >>= 2; - dev->v_total >>= 2; - } else { - dev->v_syncstart >>= 1; - dev->v_total >>= 1; - } - mach_log("HDISP=%d.\n", dev->h_disp); dev->pitch = dev->ext_pitch; dev->rowoffset = dev->ext_crt_pitch; @@ -2696,58 +2653,38 @@ mach_recalctimings(svga_t *svga) break; } } - switch (mach->regs[0xb8] & 0xc0) { - case 0x40: - svga->clock8514 *= 2; - break; - case 0x80: - svga->clock8514 *= 3; - break; - case 0xc0: - svga->clock8514 *= 4; - break; - - default: - break; - } } else { - if ((dev->accel.advfunc_cntl ^ dev->modechange) & 0x04) { - if ((mach->shadow_set ^ mach->compat_mode) & 0x03) - svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); - else - svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0; - } else { - if ((mach->shadow_set ^ mach->compat_mode) & 0x03) - svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); - else - svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0; - } - - if (dev->interlace) { - dev->dispend >>= 1; - dev->v_syncstart >>= 2; - dev->v_total >>= 2; - } else { - dev->v_syncstart >>= 1; - dev->v_total >>= 1; - } - dev->pitch = dev->ext_pitch; dev->rowoffset = dev->ext_crt_pitch; - mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, shadow=%x interlace=%d.\n", dev->accel.advfunc_cntl & 4, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, mach->accel.ext_ge_config & 0xcec0, mach->shadow_set & 3, dev->interlace); + mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, shadow=%x interlace=%d.\n", dev->accel.advfunc_cntl & 0x04, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, mach->accel.ext_ge_config & 0xcec0, mach->shadow_set & 3, dev->interlace); svga->map8 = dev->pallook; svga->render8514 = ibm8514_render_8bpp; - if (mach->regs[0xb8] & 0x40) - svga->clock8514 *= 2; } } if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { if (((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1))) { - mach_log("VGA clock=%02x.\n", mach->regs[0xa7] & 0x80); svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel, svga->clock_gen); - if (mach->regs[0xa7] & 0x80) - svga->clock *= 3; + mach_log("VGA clock=%02x.\n", mach->regs[0xa7] & 0x80); + if ((dev->local & 0xff) >= 0x02) { + if (mach->regs[0xb8] & 0x40) + svga->clock *= 2; + } else { + switch (mach->regs[0xb8] & 0xc0) { + case 0x40: + svga->clock *= 2; + break; + case 0x80: + svga->clock *= 3; + break; + case 0xc0: + svga->clock *= 4; + break; + + default: + break; + } + } switch (svga->gdcreg[5] & 0x60) { case 0x00: if (svga->seqregs[1] & 8) /*Low res (320)*/ @@ -2799,114 +2736,56 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u switch (port) { case 0x82e8: - case 0xc2e8: - case 0xf6ee: - if (len == 1) - dev->accel.cur_y = (dev->accel.cur_y & 0x700) | val; - else - dev->accel.cur_y = val & 0x7ff; - break; case 0x82e9: - case 0xc2e9: - case 0xf6ef: - if (len == 1) - dev->accel.cur_y = (dev->accel.cur_y & 0xff) | ((val & 0x07) << 8); - break; - case 0x86e8: - case 0xc6e8: - if (len == 1) - dev->accel.cur_x = (dev->accel.cur_x & 0x700) | val; - else - dev->accel.cur_x = val & 0x7ff; - break; case 0x86e9: + case 0xc2e8: + case 0xc2e9: + case 0xc6e8: case 0xc6e9: - if (len == 1) { - dev->accel.cur_x = (dev->accel.cur_x & 0xff) | ((val & 0x07) << 8); - } + ibm8514_accel_out_fifo(svga, port, val, len); + break; + case 0xf6ee: + ibm8514_accel_out_fifo(svga, 0x82e8, val, len); + break; + case 0xf6ef: + ibm8514_accel_out_fifo(svga, 0x82e9, val, len); break; case 0x8ae8: case 0xcae8: - if (len == 1) - dev->accel.desty_axstp = (dev->accel.desty_axstp & 0x3f00) | val; - else { - mach->accel.src_y = val; - dev->accel.desty = val & 0x07ff; - dev->accel.desty_axstp = val & 0x3fff; - if (val & 0x2000) - dev->accel.desty_axstp |= ~0x1fff; - } + ibm8514_accel_out_fifo(svga, port, val, len); + if (len != 1) + mach->accel.src_y = val; break; case 0x8ae9: + case 0x8ee9: case 0xcae9: - if (len == 1) { - dev->accel.desty_axstp = (dev->accel.desty_axstp & 0xff) | ((val & 0x3f) << 8); - if (val & 0x20) - dev->accel.desty_axstp |= ~0x1fff; - } + case 0xcee9: + ibm8514_accel_out_fifo(svga, port, val, len); break; case 0x8ee8: case 0xcee8: - if (len == 1) - dev->accel.destx_distp = (dev->accel.destx_distp & 0x3f00) | val; - else { - mach->accel.src_x = val; - dev->accel.destx = val & 0x07ff; - dev->accel.destx_distp = val & 0x3fff; - if (val & 0x2000) - dev->accel.destx_distp |= ~0x1fff; - } - break; - case 0x8ee9: - case 0xcee9: - if (len == 1) { - dev->accel.destx_distp = (dev->accel.destx_distp & 0xff) | ((val & 0x3f) << 8); - if (val & 0x20) - dev->accel.destx_distp |= ~0x1fff; - } + ibm8514_accel_out_fifo(svga, port, val, len); + if (len != 1) + mach->accel.src_x = val; break; case 0x92e8: - if (len != 1) - dev->test = val; - fallthrough; - - case 0xd2e8: - if (len == 1) - dev->accel.err_term = (dev->accel.err_term & 0x3f00) | val; - else { - dev->accel.err_term = val & 0x3fff; - if (val & 0x2000) - dev->accel.err_term |= ~0x1fff; - } - break; case 0x92e9: + case 0x96e9: + case 0xd2e8: case 0xd2e9: - if (len == 1) { - dev->accel.err_term = (dev->accel.err_term & 0xff) | ((val & 0x3f) << 8); - if (val & 0x20) - dev->accel.err_term |= ~0x1fff; - } + case 0xd6e9: + ibm8514_accel_out_fifo(svga, port, val, len); break; case 0x96e8: case 0xd6e8: - if (len == 1) - dev->accel.maj_axis_pcnt = (dev->accel.maj_axis_pcnt & 0x0700) | val; - else { - mach->accel.test = val & 0x1fff; - dev->accel.maj_axis_pcnt = val & 0x07ff; - dev->accel.maj_axis_pcnt_no_limit = val; - } - break; - case 0x96e9: - case 0xd6e9: - if (len == 1) { - dev->accel.maj_axis_pcnt = (dev->accel.maj_axis_pcnt & 0xff) | ((val & 0x07) << 8); - } + ibm8514_accel_out_fifo(svga, port, val, len); + if (len != 1) + mach->accel.test = val & 0x1fff; break; case 0x9ae8: @@ -2952,12 +2831,11 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u dev->accel.cx = dev->accel.cur_x; dev->accel.cy = dev->accel.cur_y; - if (dev->accel.cur_x >= 0x600) { + if (dev->accel.cur_x >= 0x600) dev->accel.cx |= ~0x5ff; - } - if (dev->accel.cur_y >= 0x600) { + + if (dev->accel.cur_y >= 0x600) dev->accel.cy |= ~0x5ff; - } if (dev->accel.cmd & 0x1000) { ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke & 0xff, len); @@ -3163,56 +3041,22 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u break; case 0xaae8: - case 0xeae8: - if (len == 1) - dev->accel.wrt_mask = (dev->accel.wrt_mask & 0x00ff) | val; - else { - dev->accel.wrt_mask = val; - mach_log("WrtMask=%04x.\n", val); - } - break; case 0xaae9: - case 0xeae9: - if (len == 1) - dev->accel.wrt_mask = (dev->accel.wrt_mask & 0xff00) | (val << 8); - break; - case 0xaee8: - case 0xeee8: - if (len == 1) - dev->accel.rd_mask = (dev->accel.rd_mask & 0x00ff) | val; - else { - dev->accel.rd_mask = val; - mach_log("ReadMask=%04x.\n", val); - } - break; case 0xaee9: - case 0xeee9: - if (len == 1) - dev->accel.rd_mask = (dev->accel.rd_mask & 0xff00) | (val << 8); - break; - case 0xb2e8: - case 0xf2e8: - if (len == 1) - dev->accel.color_cmp = (dev->accel.color_cmp & 0x00ff) | val; - else - dev->accel.color_cmp = val; - break; case 0xb2e9: - case 0xf2e9: - if (len == 1) - dev->accel.color_cmp = (dev->accel.color_cmp & 0xff00) | (val << 8); - break; - case 0xb6e8: - case 0xf6e8: - dev->accel.bkgd_mix = val & 0xff; - break; - case 0xbae8: + case 0xeae8: + case 0xeae9: + case 0xeee8: + case 0xeee9: + case 0xf2e8: + case 0xf2e9: + case 0xf6e8: case 0xfae8: - dev->accel.frgd_mix = val & 0xff; + ibm8514_accel_out_fifo(svga, port, val, len); break; case 0xbee8: @@ -3274,9 +3118,9 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u break; case 0x8eee: - if (len == 1) { + if (len == 1) mach->accel.patt_data[mach->accel.patt_data_idx] = val; - } else { + else { mach->accel.patt_data[mach->accel.patt_data_idx] = val & 0xff; mach->accel.patt_data[mach->accel.patt_data_idx + 1] = (val >> 8) & 0xff; if (mach->accel.mono_pattern_enable) @@ -3359,9 +3203,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u } break; case 0xa2ef: - if (len == 1) { + if (len == 1) mach->accel.linedraw_opt = (mach->accel.linedraw_opt & 0x00ff) | (val << 8); - } break; case 0xa6ee: @@ -3378,9 +3221,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u case 0xaaee: if (len == 1) mach->accel.dest_x_end = (mach->accel.dest_x_end & 0x700) | val; - else { + else mach->accel.dest_x_end = val & 0x7ff; - } break; case 0xaaef: if (len == 1) @@ -3435,9 +3277,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u case 0xbeee: if (len == 1) mach->accel.src_x_end = (mach->accel.src_x_end & 0x700) | val; - else { + else mach->accel.src_x_end = val & 0x7ff; - } break; case 0xbeef: if (len == 1) @@ -3490,20 +3331,18 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u } break; case 0xceef: - if (len == 1) { + if (len == 1) mach->accel.dp_config = (mach->accel.dp_config & 0x00ff) | (val << 8); - } break; case 0xd2ee: mach->accel.patt_len = val & 0x1f; mach_log("Pattern Length = %d, val = %04x.\n", val & 0x1f, val); mach->accel.mono_pattern_enable = !!(val & 0x80); - if (len != 1) { + if (len != 1) mach->accel.patt_len_reg = val; - } else { + else mach->accel.patt_len_reg = (mach->accel.patt_len_reg & 0xff00) | val; - } break; case 0xd2ef: if (len == 1) @@ -3519,9 +3358,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u mach_log("DAEE (extclipl) write val = %d\n", val); if (len == 1) dev->accel.clip_left = (dev->accel.clip_left & 0x700) | val; - else { + else dev->accel.clip_left = val & 0x7ff; - } break; case 0xdaef: if (len == 1) @@ -3532,9 +3370,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u mach_log("DEEE (extclipt) write val = %d\n", val); if (len == 1) dev->accel.clip_top = (dev->accel.clip_top & 0x700) | val; - else { + else dev->accel.clip_top = val & 0x7ff; - } break; case 0xdeef: if (len == 1) @@ -3545,9 +3382,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u mach_log("E2EE (extclipr) write val = %d\n", val); if (len == 1) dev->accel.multifunc[4] = (dev->accel.multifunc[4] & 0x700) | val; - else { + else dev->accel.multifunc[4] = val & 0x7ff; - } break; case 0xe2ef: if (len == 1) @@ -3558,9 +3394,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u mach_log("E6EE (extclipb) write val = %d\n", val); if (len == 1) dev->accel.multifunc[3] = (dev->accel.multifunc[3] & 0x700) | val; - else { + else dev->accel.multifunc[3] = val & 0x7ff; - } break; case 0xe6ef: if (len == 1) @@ -3624,45 +3459,27 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 switch (port) { case 0x2e8: case 0x6e9: - if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) - dev->htotal = val; - - svga_recalctimings(svga); + case 0xae8: + case 0xee8: + case 0x12e8: + case 0x12e9: + case 0x1ae8: + case 0x1ae9: + case 0x1ee8: + case 0x1ee9: + case 0x22e8: + case 0x42e8: + case 0x42e9: + ibm8514_accel_out(port, val, svga, 2); break; case 0x6e8: - /*In preparation to switch from VGA to 8514/A mode*/ - if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) - dev->hdisped = val; - - mach_log("[%04X:%08X]: ATI 8514/A: H_DISP write 06E8 = %d, actual val=%d, set lock=%x, shadow set=%x, advfunc bit 2=%x, dispcntl=%02x, clocksel bit 0=%x.\n", CS, cpu_state.pc, dev->hdisp, ((val + 1) << 3), mach->shadow_cntl, mach->shadow_set, dev->accel.advfunc_cntl & 0x04, dev->disp_cntl & 0x60, mach->accel.clock_sel & 0x01); - mach_log("ATI 8514/A: (0x%04x): hdisp=0x%02x.\n", port, val); - svga_recalctimings(svga); - break; - - case 0xae8: - if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) - dev->hsync_start = val; - - mach_log("ATI 8514/A: (0x%04x): val=%d, hsync_start=%d.\n", port, val, (val + 1) << 3); - svga_recalctimings(svga); - break; - - case 0xee8: - if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) - dev->hsync_width = val; - - mach_log("ATI 8514/A: (0x%04x): val=%d, hsync_width=%d, hsyncpol=%02x.\n", port, val & 0x1f, ((val & 0x1f) + 1) << 3, val & 0x20); - svga_recalctimings(svga); - break; - - case 0x12e8: - case 0x12e9: /*In preparation to switch from VGA to 8514/A mode*/ if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) { - WRITE8(port, dev->v_total_reg, val); - dev->v_total_reg &= 0x1fff; + dev->hdisped = val; + dev->hdisp = (dev->hdisped + 1) << 3; } + mach_log("[%04X:%08X]: ATI 8514/A: (0x%04x): hdisp=0x%02x.\n", CS, cpu_state.pc, port, val); svga_recalctimings(svga); break; @@ -3672,59 +3489,13 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) { WRITE8(port, dev->v_disp, val); dev->v_disp &= 0x1fff; + dev->vdisp = (dev->v_disp + 1) >> 1; } - dev->modechange = dev->accel.advfunc_cntl & 0x04; - mach->compat_mode = mach->shadow_set & 0x03; mach_log("ATI 8514/A: V_DISP write 16E8 = %d\n", dev->v_disp); mach_log("ATI 8514/A: (0x%04x): vdisp=0x%02x.\n", port, val); svga_recalctimings(svga); break; - case 0x1ae8: - case 0x1ae9: - /*In preparation to switch from VGA to 8514/A mode*/ - if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) { - WRITE8(port, dev->v_sync_start, val); - dev->v_sync_start &= 0x1fff; - } - svga_recalctimings(svga); - break; - - case 0x1ee8: - case 0x1ee9: - mach_log("ATI 8514/A: V_SYNC_WID write 1EE8 = %02x\n", val); - break; - - case 0x22e8: - dev->disp_cntl = val; - dev->interlace = !!(val & 0x10); - mach_log("ATI 8514/A: DISP_CNTL write %04x=%02x, interlace=%d.\n", port, dev->disp_cntl, dev->interlace); - break; - - case 0x42e8: - old = dev->subsys_stat; - if (val & 1) - dev->subsys_stat &= ~1; - if (val & 2) - dev->subsys_stat &= ~2; - if (val & 4) - dev->subsys_stat &= ~4; - if (val & 8) - dev->subsys_stat &= ~8; - break; - case 0x42e9: - old = dev->subsys_cntl; - dev->subsys_cntl = val; - if ((old ^ val) & 1) - dev->subsys_stat |= 1; - if ((old ^ val) & 2) - dev->subsys_stat |= 2; - if ((old ^ val) & 4) - dev->subsys_stat |= 4; - if ((old ^ val) & 8) - dev->subsys_stat |= 8; - break; - case 0x4ae8: case 0x4ae9: WRITE8(port, dev->accel.advfunc_cntl, val); @@ -3736,9 +3507,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 mach->ext_on[port & 1] = dev->on[port & 1]; mach32_updatemapping(mach, svga); dev->vendor_mode[port & 1] = 0; - dev->hdisp = (dev->hdisped + 1) << 3; - dev->vdisp = (dev->v_disp >> 1) + 1; - mach_log("ATI 8514/A: (0x%04x): ON=%d, shadow crt=%x, hdisp=%d, vdisp=%d.\n", port, dev->on[port & 1], dev->accel.advfunc_cntl & 0x04, dev->hdisp, dev->vdisp); + mach_log("[%04X:%08X]: ATI 8514/A: (0x%04x): ON=%d, shadow crt=%x, hdisp=%d, vdisp=%d.\n", CS, cpu_state.pc, port, dev->on[port & 1], dev->accel.advfunc_cntl & 0x04, dev->hdisp, dev->vdisp); mach_log("IBM mode set %s resolution.\n", (dev->accel.advfunc_cntl & 0x04) ? "2: 1024x768" : "1: 640x480"); svga_recalctimings(svga); break; @@ -3817,7 +3586,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 else dev->ext_crt_pitch <<= 1; } - mach_log("ATI 8514/A: (0x%04x) val=%04x.\n", port, val); + mach_log("ATI 8514/A: (0x%04x) val=0x%02x.\n", port, val); svga_recalctimings(svga); break; @@ -3857,20 +3626,18 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 case 0x46ee: case 0x46ef: WRITE8(port, mach->shadow_cntl, val); - mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); + mach_log("ATI 8514/A: (0x%04x) val=%02x.\n", port, val); break; case 0x4aee: case 0x4aef: WRITE8(port, mach->accel.clock_sel, val); dev->on[port & 1] = mach->accel.clock_sel & 0x01; - mach_log("ATI 8514/A: (0x%04x): ON=%d, val=%04x, hdisp=%d, vdisp=%d.\n", port, dev->on[port & 1], val, dev->hdisp, dev->vdisp); + mach_log("ATI 8514/A: (0x%04x): ON=%d, val=%04x, hdisp=%d, vdisp=%d, val=0x%02x.\n", port, dev->on[port & 1], val, dev->hdisp, dev->vdisp, val & 0xfe); mach_log("ATI mode set %s resolution.\n", (dev->accel.advfunc_cntl & 0x04) ? "2: 1024x768" : "1: 640x480"); mach->ext_on[port & 1] = dev->on[port & 1]; vga_on = !dev->on[port & 1]; dev->vendor_mode[port & 1] = 1; - dev->hdisp = (dev->hdisped + 1) << 3; - dev->vdisp = (dev->v_disp >> 1) + 1; svga_recalctimings(svga); break; @@ -3889,13 +3656,13 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 case 0x5aee: case 0x5aef: WRITE8(port, mach->shadow_set, val); - mach_log("ATI 8514/A: (0x%04x) val=%04x.\n", port, val); + mach_log("ATI 8514/A: (0x%04x) val=0x%02x.\n", port, val); if ((mach->shadow_set & 0x03) == 0x00) mach_log("Primary CRT register set.\n"); else if ((mach->shadow_set & 0x03) == 0x01) - mach_log("Shadow Set 1: 640x480.\n"); + mach_log("CRT Shadow Set 1: 640x480.\n"); else if ((mach->shadow_set & 0x03) == 0x02) - mach_log("Shadow Set 2: 1024x768.\n"); + mach_log("CRT Shadow Set 2: 1024x768.\n"); break; case 0x5eee: @@ -3924,20 +3691,21 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 case 0x6eee: case 0x6eef: WRITE8(port, mach->accel.ge_offset_lo, val); - dev->accel.ge_offset = mach->accel.ge_offset_lo; + svga_recalctimings(svga); break; case 0x72ee: case 0x72ef: WRITE8(port, mach->accel.ge_offset_hi, val); - dev->accel.ge_offset = mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16); + mach_log("ATI 8514/A: (0x%04x) val=0x%02x, geoffset=%04x.\n", port, val, dev->accel.ge_offset); + svga_recalctimings(svga); break; case 0x76ee: case 0x76ef: WRITE8(port, mach->accel.ge_pitch, val); dev->ext_pitch = ((mach->accel.ge_pitch & 0xff) << 3); - mach_log("ATI 8514/A: (0x%04x) val=%04x, extpitch=%d.\n", port, val, dev->ext_pitch); + mach_log("ATI 8514/A: (0x%04x) val=0x%02x, extpitch=%d.\n", port, val, dev->ext_pitch); svga_recalctimings(svga); break; @@ -3973,15 +3741,14 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 mach_log("ATI 8514/A: (0x%04x) val=%02x.\n", port, val); svga_recalctimings(svga); } else { - if (mach->accel.ext_ge_config & 0x8080) - ati_eeprom_write(&mach->eeprom, mach->accel.ext_ge_config & 0x4040, mach->accel.ext_ge_config & 0x2020, mach->accel.ext_ge_config & 0x1010); + ati_eeprom_write(&mach->eeprom, !!(mach->accel.ext_ge_config & 0x4040), !!(mach->accel.ext_ge_config & 0x2020), !!(mach->accel.ext_ge_config & 0x1010)); } break; case 0x7eee: case 0x7eef: WRITE8(port, mach->accel.eeprom_control, val); - ati_eeprom_write(&mach->eeprom, mach->accel.eeprom_control & 8, mach->accel.eeprom_control & 2, mach->accel.eeprom_control & 1); + ati_eeprom_write(&mach->eeprom, !!(mach->accel.eeprom_control & 8), !!(mach->accel.eeprom_control & 2), !!(mach->accel.eeprom_control & 1)); mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); break; @@ -4012,25 +3779,12 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in switch (port) { case 0x82e8: - case 0xc2e8: - if (len != 1) - temp = dev->accel.cur_y; - break; - case 0x86e8: - case 0xc6e8: - if (len != 1) - temp = dev->accel.cur_x; - break; - case 0x92e8: - if (len != 1) - temp = dev->test; - break; - case 0x96e8: - if (len != 1) - temp = dev->accel.maj_axis_pcnt; + case 0xc2e8: + case 0xc6e8: + temp = ibm8514_accel_in_fifo(svga, port, len); break; case 0x9ae8: @@ -4254,16 +4008,13 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in case 0x96ee: if (len == 1) - temp = dev->accel.maj_axis_pcnt & 0xff; - else { - temp = dev->accel.maj_axis_pcnt; - if ((mach->accel.test == 0x1555) || (mach->accel.test == 0x0aaa)) - temp = mach->accel.test; - } + temp = mach->accel.test & 0xff; + else + temp = mach->accel.test; break; case 0x96ef: if (len == 1) - temp = dev->accel.maj_axis_pcnt >> 8; + temp = mach->accel.test >> 8; break; case 0xa2ee: @@ -4375,23 +4126,29 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in case 0xfaee: if (len != 1) { - if (mach->pci_bus) - temp = 0x0017; - else - temp = 0x22f7; + if ((dev->local & 0xff) >= 0x02) { + if (mach->pci_bus) + temp = 0x0017; + else + temp = 0x22f7; + } } else { - if (mach->pci_bus) - temp = 0x17; - else - temp = 0xf7; + if ((dev->local & 0xff) >= 0x02) { + if (mach->pci_bus) + temp = 0x17; + else + temp = 0xf7; + } } break; case 0xfaef: if (len == 1) { - if (mach->pci_bus) - temp = 0x00; - else - temp = 0x22; + if ((dev->local & 0xff) >= 0x02) { + if (mach->pci_bus) + temp = 0x00; + else + temp = 0x22; + } } break; @@ -4407,64 +4164,57 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in static uint8_t mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev) { - uint8_t temp = 0; - uint16_t vpos = 0; - uint16_t vblankend = svga->vblankstart + svga->crtc[0x16]; + uint8_t temp = 0; + uint16_t clip_b_ibm = dev->accel.multifunc[3]; + uint16_t clip_r_ibm = dev->accel.multifunc[4]; + int16_t clip_l = dev->accel.clip_left & 0x7ff; + int16_t clip_t = dev->accel.clip_top & 0x7ff; + int16_t clip_r = dev->accel.multifunc[4] & 0x7ff; + int16_t clip_b = dev->accel.multifunc[3] & 0x7ff; + int cmd = (dev->accel.cmd >> 13); switch (port) { case 0x2e8: - vpos = dev->vc & 0x7ff; - if (vblankend > dev->v_total) { - vblankend -= dev->v_total; - if ((vpos >= svga->vblankstart) || (vpos <= vblankend)) - temp |= 2; - } else { - if ((vpos >= svga->vblankstart) && (vpos <= vblankend)) - temp |= 2; - } - break; - case 0x6e8: - temp = dev->hdisped; - break; - case 0x22e8: - temp = dev->disp_cntl; - break; - case 0x26e8: - temp = dev->htotal; - break; - + case 0x26e9: case 0x2ee8: - temp = dev->subsys_cntl; - break; case 0x2ee9: - temp = 0xff; + temp = ibm8514_accel_in(port, svga); break; case 0x42e8: case 0x42e9: - vpos = dev->vc & 0x7ff; - if (vblankend > dev->v_total) { - vblankend -= dev->v_total; - if ((vpos >= svga->vblankstart) || (vpos <= vblankend)) - dev->subsys_stat |= 1; + if (dev->vc == dev->v_syncstart) + dev->subsys_stat |= 1; + + if (mach->accel.cmd_type >= 0) { + if (((dev->accel.dx) >= clip_l) && ((dev->accel.dx) <= clip_r) && ((dev->accel.dy) >= clip_t) && ((dev->accel.dy) <= clip_b)) + temp |= 2; } else { - if ((vpos >= svga->vblankstart) && (vpos <= vblankend)) - dev->subsys_stat |= 1; + if (cmd == 6) { + if (((dev->accel.dx) >= dev->accel.clip_left) && ((dev->accel.dx) <= clip_r_ibm) && ((dev->accel.dy) >= dev->accel.clip_top) && ((dev->accel.dy) <= clip_b_ibm)) + temp |= 2; + } else { + if (((dev->accel.cx) >= dev->accel.clip_left) && ((dev->accel.dx) <= clip_r_ibm) && ((dev->accel.cy) >= dev->accel.clip_top) && ((dev->accel.cy) <= clip_b_ibm)) + temp |= 2; + } } + if (!dev->force_busy) + temp |= 8; + if (port & 1) temp = 0x80; else { - temp = dev->subsys_stat | 0x80; + temp |= (dev->subsys_stat | 0x80); if (mach->accel.ext_ge_config & 0x08) temp |= ((mach->accel.ext_ge_config & 0x07) << 4); else temp |= 0x20; } - mach_log("Subsystem Status=%04x, 4ae8 shadow set=%02x.\n", temp, dev->accel.advfunc_cntl & 4); + mach_log("0x%04x read: Subsystem Status=%02x.\n", port, temp); break; /*ATI Mach8/32 specific registers*/ @@ -4478,6 +4228,11 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev) READ8(port, mach->config2); break; + case 0x1aee: + case 0x1aef: + temp = 0x00; + break; + case 0x22ee: if (mach->pci_bus) temp = mach->pci_cntl_reg; @@ -4541,11 +4296,14 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev) temp = dev->pos_regs[5]; } } else { - if (!(port & 1)) { - if (svga->ext8514 != NULL) { - temp = 0x20 | 0x80; + if (svga->ext8514 != NULL) { + temp = ((dev->bios_addr >> 7) - 0x1000) >> 4; + if (port & 1) { + temp &= ~0x80; + temp |= 0x01; } - } + } else + temp = 0x00; } #endif break; @@ -4574,6 +4332,7 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev) mach->force_busy = 0; if (ati_eeprom_read(&mach->eeprom)) temp |= 0x40; + mach_log("Mach busy temp=%02x.\n", temp); break; @@ -4860,9 +4619,8 @@ mach32_decode_addr(svga_t *svga, uint32_t addr, int write) } static __inline void -mach32_write_common(uint32_t addr, uint8_t val, int linear, mach_t *mach) +mach32_write_common(uint32_t addr, uint8_t val, int linear, mach_t *mach, svga_t *svga) { - svga_t *svga = &mach->svga; ibm8514_t *dev = (ibm8514_t *) svga->dev8514; int writemask2 = svga->writemask; int reset_wm = 0; @@ -5003,29 +4761,59 @@ mach32_write_common(uint32_t addr, uint8_t val, int linear, mach_t *mach) svga->gdcreg[8] = wm; } +#ifdef ATI_8514_ULTRA +static void +ati8514_write(uint32_t addr, uint8_t val, void *priv) +{ + svga_t *svga = (svga_t *) priv; + mach_t *mach = (mach_t *) svga->ext8514; + mach32_write_common(addr, val, 0, mach, svga); +} + +static void +ati8514_writew(uint32_t addr, uint16_t val, void *priv) +{ + svga_t *svga = (svga_t *) priv; + mach_t *mach = (mach_t *) svga->ext8514; + mach32_write_common(addr, val & 0xff, 0, mach, svga); + mach32_write_common(addr + 1, val >> 8, 0, mach, svga); +} + +static void +ati8514_writel(uint32_t addr, uint32_t val, void *priv) +{ + svga_t *svga = (svga_t *) priv; + mach_t *mach = (mach_t *) svga->ext8514; + mach32_write_common(addr, val & 0xff, 0, mach, svga); + mach32_write_common(addr + 1, val >> 8, 0, mach, svga); + mach32_write_common(addr + 2, val >> 16, 0, mach, svga); + mach32_write_common(addr + 3, val >> 24, 0, mach, svga); +} +#endif + static void mach32_write(uint32_t addr, uint8_t val, void *priv) { mach_t *mach = (mach_t *) priv; - mach32_write_common(addr, val, 0, mach); + mach32_write_common(addr, val, 0, mach, &mach->svga); } static void mach32_writew(uint32_t addr, uint16_t val, void *priv) { mach_t *mach = (mach_t *) priv; - mach32_write_common(addr, val & 0xff, 0, mach); - mach32_write_common(addr + 1, val >> 8, 0, mach); + mach32_write_common(addr, val & 0xff, 0, mach, &mach->svga); + mach32_write_common(addr + 1, val >> 8, 0, mach, &mach->svga); } static void mach32_writel(uint32_t addr, uint32_t val, void *priv) { mach_t *mach = (mach_t *) priv; - mach32_write_common(addr, val & 0xff, 0, mach); - mach32_write_common(addr + 1, val >> 8, 0, mach); - mach32_write_common(addr + 2, val >> 16, 0, mach); - mach32_write_common(addr + 3, val >> 24, 0, mach); + mach32_write_common(addr, val & 0xff, 0, mach, &mach->svga); + mach32_write_common(addr + 1, val >> 8, 0, mach, &mach->svga); + mach32_write_common(addr + 2, val >> 16, 0, mach, &mach->svga); + mach32_write_common(addr + 3, val >> 24, 0, mach, &mach->svga); } static __inline void @@ -5061,9 +4849,8 @@ mach32_writel_linear(uint32_t addr, uint32_t val, mach_t *mach) } static __inline uint8_t -mach32_read_common(uint32_t addr, int linear, mach_t *mach) +mach32_read_common(uint32_t addr, int linear, mach_t *mach, svga_t *svga) { - svga_t *svga = &mach->svga; ibm8514_t *dev = (ibm8514_t *) svga->dev8514; uint32_t latch_addr = 0; int readplane = svga->readplane; @@ -5153,13 +4940,52 @@ mach32_read_common(uint32_t addr, int linear, mach_t *mach) return ret; } +#ifdef ATI_8514_ULTRA +static uint8_t +ati8514_read(uint32_t addr, void *priv) +{ + svga_t *svga = (svga_t *) priv; + mach_t *mach = (mach_t *) svga->ext8514; + uint8_t ret; + + ret = mach32_read_common(addr, 0, mach, svga); + return ret; +} + +static uint16_t +ati8514_readw(uint32_t addr, void *priv) +{ + svga_t *svga = (svga_t *) priv; + mach_t *mach = (mach_t *) svga->ext8514; + uint16_t ret; + + ret = mach32_read_common(addr, 0, mach, svga); + ret |= (mach32_read_common(addr + 1, 0, mach, svga) << 8); + return ret; +} + +static uint32_t +ati8514_readl(uint32_t addr, void *priv) +{ + svga_t *svga = (svga_t *) priv; + mach_t *mach = (mach_t *) svga->ext8514; + uint32_t ret; + + ret = mach32_read_common(addr, 0, mach, svga); + ret |= (mach32_read_common(addr + 1, 0, mach, svga) << 8); + ret |= (mach32_read_common(addr + 2, 0, mach, svga) << 16); + ret |= (mach32_read_common(addr + 3, 0, mach, svga) << 24); + return ret; +} +#endif + static uint8_t mach32_read(uint32_t addr, void *priv) { mach_t *mach = (mach_t *) priv; uint8_t ret; - ret = mach32_read_common(addr, 0, mach); + ret = mach32_read_common(addr, 0, mach, &mach->svga); return ret; } @@ -5169,8 +4995,8 @@ mach32_readw(uint32_t addr, void *priv) mach_t *mach = (mach_t *) priv; uint16_t ret; - ret = mach32_read_common(addr, 0, mach); - ret |= (mach32_read_common(addr + 1, 0, mach) << 8); + ret = mach32_read_common(addr, 0, mach, &mach->svga); + ret |= (mach32_read_common(addr + 1, 0, mach, &mach->svga) << 8); return ret; } @@ -5180,10 +5006,10 @@ mach32_readl(uint32_t addr, void *priv) mach_t *mach = (mach_t *) priv; uint32_t ret; - ret = mach32_read_common(addr, 0, mach); - ret |= (mach32_read_common(addr + 1, 0, mach) << 8); - ret |= (mach32_read_common(addr + 2, 0, mach) << 16); - ret |= (mach32_read_common(addr + 3, 0, mach) << 24); + ret = mach32_read_common(addr, 0, mach, &mach->svga); + ret |= (mach32_read_common(addr + 1, 0, mach, &mach->svga) << 8); + ret |= (mach32_read_common(addr + 2, 0, mach, &mach->svga) << 16); + ret |= (mach32_read_common(addr + 3, 0, mach, &mach->svga) << 24); return ret; } @@ -5237,7 +5063,7 @@ mach32_ap_writeb(uint32_t addr, uint8_t val, void *priv) } else { mach_log("Linear WORDB Write=%08x, val=%02x.\n", addr, val); if (dev->on[0] || dev->on[1]) - mach32_write_common(addr, val, 1, mach); + mach32_write_common(addr, val, 1, mach, svga); else svga_write_linear(addr, val, svga); } @@ -5314,7 +5140,7 @@ mach32_ap_readb(uint32_t addr, void *priv) temp = mach_accel_inb(0x02e8 + (addr & 1) + (port_dword << 8), mach); } else { if (dev->on[0] || dev->on[1]) - temp = mach32_read_common(addr, 1, mach); + temp = mach32_read_common(addr, 1, mach, svga); else temp = svga_read_linear(addr, svga); @@ -5434,10 +5260,18 @@ mach32_updatemapping(mach_t *mach, svga_t *svga) mach->ap_size = 4; mem_mapping_disable(&mach->mmio_linear_mapping); } - if (((dev->local & 0xff) >= 0x02) && (dev->on[0] || dev->on[1]) && (mach->ext_on[0] || mach->ext_on[1]) && (dev->vendor_mode[0] || dev->vendor_mode[1])) { + if ((dev->on[0] || dev->on[1]) && (mach->ext_on[0] || mach->ext_on[1]) && (dev->vendor_mode[0] || dev->vendor_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); +#ifdef ATI_8514_ULTRA + if (svga->ext8514 != NULL) { + mem_mapping_set_handler(&svga->mapping, ati8514_read, ati8514_readw, ati8514_readl, ati8514_write, ati8514_writew, ati8514_writel); + mem_mapping_set_p(&svga->mapping, svga); + } else +#endif + { + 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); @@ -5534,6 +5368,7 @@ ati8514_io_set(svga_t *svga) io_sethandler(0x26e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); io_sethandler(0x2ee8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); io_sethandler(0x42e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0x46e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); io_sethandler(0x4ae8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); io_sethandler(0x52e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); io_sethandler(0x56e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); @@ -5650,6 +5485,7 @@ mach_io_set(mach_t *mach) io_sethandler(0x26e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0x2ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0x42e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x46e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0x4ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0x52e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0x56e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); @@ -5747,6 +5583,7 @@ mach_io_set(mach_t *mach) io_sethandler(0xeeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0xf2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0xf6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xfaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0xfeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); } @@ -5828,6 +5665,12 @@ ati8514_mca_write(int port, uint8_t val, void *priv) if (dev->pos_regs[2] & 0x01) mem_mapping_enable(&dev->bios_rom.mapping); } + +void +ati8514_pos_write(uint16_t port, uint8_t val, void *priv) +{ + ati8514_mca_write(port, val, priv); +} #endif static uint8_t @@ -6084,8 +5927,8 @@ mach8_init(const device_t *info) mach->config2 = 0x02; svga->clock_gen = device_add(&ati18810_device); } - dev->bpp = 0; - svga->getclock = ics2494_getclock; + dev->bpp = 0; + svga->getclock = ics2494_getclock; dev->on[0] = 0; dev->on[1] = 0; @@ -6107,7 +5950,6 @@ mach8_init(const device_t *info) mach->cursor_col_1 = 0xff; mach->ext_cur_col_1_r = 0xff; mach->ext_cur_col_1_g = 0xff; - io_sethandler(0xfaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); if (mach->vlb_bus) ati_eeprom_load(&mach->eeprom, "mach32_vlb.nvr", 1); else if (mach->mca_bus) { @@ -6134,8 +5976,6 @@ mach8_init(const device_t *info) } else ati_eeprom_load_mach8(&mach->eeprom, "mach8.nvr"); - timer_add(&svga->timer8514, ibm8514_poll, svga, 1); - return mach; } @@ -6143,8 +5983,8 @@ mach8_init(const device_t *info) void ati8514_init(svga_t *svga, void *ext8514, void *dev8514) { - mach_t *mach = (mach_t *)ext8514; - ibm8514_t *dev = (ibm8514_t *)dev8514; + mach_t *mach = (mach_t *) ext8514; + ibm8514_t *dev = (ibm8514_t *) dev8514; dev->on[0] = 0; dev->on[1] = 0; diff --git a/src/video/vid_ics2494.c b/src/video/vid_ics2494.c index 309d07966..e85b4539e 100644 --- a/src/video/vid_ics2494.c +++ b/src/video/vid_ics2494.c @@ -56,6 +56,7 @@ ics2494_getclock(int clock, void *priv) if (clock > 15) clock = 15; + ics2494_log("Clock=%d, freq=%f.\n", clock, ics2494->freq[clock]); return ics2494->freq[clock]; } @@ -68,60 +69,60 @@ ics2494_init(const device_t *info) switch (info->local) { case 10: /* ATI 18810 for ATI 28800 */ - ics2494->freq[0x0] = 30240000.0; - ics2494->freq[0x1] = 32000000.0; - ics2494->freq[0x2] = 37500000.0; - ics2494->freq[0x3] = 39000000.0; - ics2494->freq[0x4] = 42954000.0; - ics2494->freq[0x5] = 48771000.0; - ics2494->freq[0x6] = 16657000.0; - ics2494->freq[0x7] = 36000000.0; - ics2494->freq[0x8] = 40000000.0; - ics2494->freq[0x9] = 56644000.0; - ics2494->freq[0xa] = 75000000.0; - ics2494->freq[0xb] = 65000000.0; - ics2494->freq[0xc] = 50350000.0; - ics2494->freq[0xd] = 56640000.0; - ics2494->freq[0xe] = 28322000.0; - ics2494->freq[0xf] = 44900000.0; + ics2494->freq[0x0] = 42954000.0; + ics2494->freq[0x1] = 48771000.0; + ics2494->freq[0x2] = 0.0; + ics2494->freq[0x3] = 36000000.0; + ics2494->freq[0x4] = 50350000.0; + ics2494->freq[0x5] = 56640000.0; + ics2494->freq[0x6] = 0.0; + ics2494->freq[0x7] = 44900000.0; + ics2494->freq[0x8] = 30240000.0; + ics2494->freq[0x9] = 32000000.0; + ics2494->freq[0xa] = 37500000.0; + ics2494->freq[0xb] = 39000000.0; + ics2494->freq[0xc] = 40000000.0; + ics2494->freq[0xd] = 56644000.0; + ics2494->freq[0xe] = 75000000.0; + ics2494->freq[0xf] = 65000000.0; break; case 110: /* ATI 18811-0 for ATI Mach32 */ - ics2494->freq[0x0] = 30240000.0; - ics2494->freq[0x1] = 32000000.0; - ics2494->freq[0x2] = 110000000.0; - ics2494->freq[0x3] = 80000000.0; - ics2494->freq[0x4] = 42954000.0; - ics2494->freq[0x5] = 48771000.0; - ics2494->freq[0x6] = 92400000.0; - ics2494->freq[0x7] = 36000000.0; - ics2494->freq[0x8] = 39910000.0; - ics2494->freq[0x9] = 44900000.0; - ics2494->freq[0xa] = 75000000.0; - ics2494->freq[0xb] = 65000000.0; - ics2494->freq[0xc] = 50350000.0; - ics2494->freq[0xd] = 56640000.0; - ics2494->freq[0xe] = 0.0; - ics2494->freq[0xf] = 44900000.0; + ics2494->freq[0x0] = 42954000.0; + ics2494->freq[0x1] = 48771000.0; + ics2494->freq[0x2] = 92400000.0; + ics2494->freq[0x3] = 36000000.0; + ics2494->freq[0x4] = 50350000.0; + ics2494->freq[0x5] = 56640000.0; + ics2494->freq[0x6] = 0.0; + ics2494->freq[0x7] = 44900000.0; + ics2494->freq[0x8] = 30240000.0; + ics2494->freq[0x9] = 32000000.0; + ics2494->freq[0xa] = 110000000.0; + ics2494->freq[0xb] = 80000000.0; + ics2494->freq[0xc] = 39910000.0; + ics2494->freq[0xd] = 44900000.0; + ics2494->freq[0xe] = 75000000.0; + ics2494->freq[0xf] = 65000000.0; break; case 111: /* ATI 18811-1 for ATI Mach32 MCA */ - ics2494->freq[0x0] = 135000000.0; - ics2494->freq[0x1] = 32000000.0; - ics2494->freq[0x2] = 110000000.0; - ics2494->freq[0x3] = 80000000.0; - ics2494->freq[0x4] = 100000000.0; - ics2494->freq[0x5] = 126000000.0; - ics2494->freq[0x6] = 92400000.0; - ics2494->freq[0x7] = 36000000.0; - ics2494->freq[0x8] = 39910000.0; - ics2494->freq[0x9] = 44900000.0; - ics2494->freq[0xa] = 75000000.0; - ics2494->freq[0xb] = 65000000.0; - ics2494->freq[0xc] = 50350000.0; - ics2494->freq[0xd] = 56640000.0; - ics2494->freq[0xe] = 0.0; - ics2494->freq[0xf] = 44900000.0; + ics2494->freq[0x0] = 100000000.0; + ics2494->freq[0x1] = 126000000.0; + ics2494->freq[0x2] = 92400000.0; + ics2494->freq[0x3] = 36000000.0; + ics2494->freq[0x4] = 50350000.0; + ics2494->freq[0x5] = 56640000.0; + ics2494->freq[0x6] = 0.0; + ics2494->freq[0x7] = 44900000.0; + ics2494->freq[0x8] = 135000000.0; + ics2494->freq[0x9] = 32000000.0; + ics2494->freq[0xa] = 110000000.0; + ics2494->freq[0xb] = 80000000.0; + ics2494->freq[0xc] = 39910000.0; + ics2494->freq[0xd] = 44900000.0; + ics2494->freq[0xe] = 75000000.0; + ics2494->freq[0xf] = 65000000.0; break; case 305: /* ICS2494A(N)-205 for S3 86C924 */ diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 4632ab85e..307f455c3 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -46,6 +46,7 @@ #include <86box/vid_xga_device.h> void svga_doblit(int wx, int wy, svga_t *svga); +void svga_poll(void *priv); svga_t *svga_8514; @@ -121,6 +122,9 @@ svga_out(uint16_t addr, uint8_t val, void *priv) if (!dev && (addr >= 0x2ea) && (addr <= 0x2ed)) return; + if (addr >= 0x3c6 && addr <= 0x3c9) + svga_log("VGA OUT addr=%03x, val=%02x.\n", addr, val); + switch (addr) { case 0x2ea: dev->dac_mask = val; @@ -528,6 +532,9 @@ svga_in(uint16_t addr, void *priv) break; } + if ((addr >= 0x3c6) && (addr <= 0x3c9)) + svga_log("VGA IN addr=%03x, temp=%02x.\n", addr, ret); + return ret; } @@ -935,11 +942,11 @@ svga_recalctimings(svga_t *svga) if (dev->dispofftime < TIMER_USEC) dev->dispofftime = TIMER_USEC; - timer_disable(&svga->timer); - timer_set_delay_u64(&svga->timer8514, TIMER_USEC); + svga_log("IBM 8514/A poll.\n"); + timer_set_callback(&svga->timer, ibm8514_poll); } else { - timer_disable(&svga->timer8514); - timer_set_delay_u64(&svga->timer, TIMER_USEC); + svga_log("SVGA Poll.\n"); + timer_set_callback(&svga->timer, svga_poll); } }