From 2ac3d289e624c85dc08fd00b79acc6af06974146 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 29 May 2024 20:47:22 +0200 Subject: [PATCH 01/13] 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 | 38 +- src/video/vid_8514a.c | 388 +++++++------- src/video/vid_ati_mach8.c | 836 ++++++++++++------------------ src/video/vid_ics2494.c | 97 ++-- src/video/vid_svga.c | 15 +- 7 files changed, 632 insertions(+), 746 deletions(-) diff --git a/src/include/86box/vid_8514a.h b/src/include/86box/vid_8514a.h index ac4085089b..def3f0f2ba 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 7b5862f35e..a254329201 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 9eecebf2c3..3d68c1a34f 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 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 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 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 ff14701649..fc205dacfe 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 @@ ibm8514_accel_out_pixtrans(svga_t *svga, UNUSED(uint16_t port), uint32_t val, in } } -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,26 +1092,82 @@ 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); } - 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); - } + + default: + break; + } + 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; @@ -1176,16 +1181,29 @@ 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 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat WRITE(dev->accel.dest + dev->accel.cx, dest_dat); } } - mix_dat <<= 1; mix_dat |= 1; if (dev->bpp) @@ -2448,6 +2465,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } } } + mix_dat <<= 1; mix_dat |= 1; @@ -2525,6 +2543,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } } } + mix_dat <<= 1; mix_dat |= 1; if (dev->bpp) @@ -3385,6 +3404,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat WRITE(dev->accel.dest + dev->accel.dx, dest_dat); } } + mix_dat >>= 1; if (dev->bpp) cpu_dat >>= 16; @@ -3452,7 +3472,6 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } 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 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat WRITE(dev->accel.dest + dev->accel.dx, dest_dat); } } + mix_dat <<= 1; mix_dat |= 1; if (dev->bpp) @@ -3655,6 +3675,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat WRITE(dev->accel.dest + dev->accel.dx, dest_dat); } } + dev->accel.temp_cnt--; mix_dat >>= 1; @@ -3779,6 +3800,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } } } + 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->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) { + 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; } - svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0; + } else { + dev->h_disp = dev->hdisp; + dev->dispend = dev->vdisp; } - if (dev->interlace) { + 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; - dev->v_syncstart >>= 2; - dev->v_total >>= 2; - } else { - dev->v_syncstart >>= 1; - dev->v_total >>= 1; - } + if (dev->dispend == 766) + dev->dispend += 2; + + 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 be2c5d5472..83edb4355b 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 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 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 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 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 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } 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,55 +2446,56 @@ 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; - if (dev->dispend == 766) - dev->dispend += 2; - - 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; + 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; } - svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; } else { - svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; + dev->h_disp = dev->hdisp; + dev->dispend = dev->vdisp; } - if (dev->interlace) { - dev->dispend >>= 1; - dev->v_syncstart >>= 2; - dev->v_total >>= 2; + if (dev->accel.advfunc_cntl & 0x04) { + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0; } else { - dev->v_syncstart >>= 1; - dev->v_total >>= 1; + svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0; } + if (dev->dispend == 766) + dev->dispend += 2; + + if (dev->dispend == 598) + dev->dispend += 2; + + 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); - - 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.*/ - 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; + 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->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 = 640; - dev->dispend = 480; + dev->h_disp = dev->hdisp; + dev->dispend = dev->vdisp; } + } else { + dev->h_disp = dev->hdisp; + dev->dispend = dev->vdisp; } + 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); - 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: + 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)) { - 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 309d07966b..e85b4539ef 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 4632ab85e9..307f455c34 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); } } From 6d2ea183c221c480ed5f35a3cbe9d895513217ac Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 29 May 2024 23:18:43 +0200 Subject: [PATCH 02/13] PAS Plus: Fix ID. --- src/sound/snd_pas16.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 243332257b..d88a498d57 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -823,7 +823,7 @@ pas16_in(uint16_t port, void *priv) - 2 = FM (1 = stereo, 0 = mono); - 3 = Code (1 = 16-bit, 0 = 8-bit). */ - ret = pas16->type ? pas16->type : 0x06; + ret = pas16->type ? pas16->type : 0x07; break; case 0xf000: From ff5d5273ed3ea8d957e02c05d5605786181b47e5 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 29 May 2024 23:45:00 +0200 Subject: [PATCH 03/13] Video changes part 2 1. Added the Diamond Stealth 64 Video VRAM 968-based card. 2. Removed the useless VLB-based Phoenix 868 and 968 cards. 3. The Diamond Stealth 64 Video VRAM specific drivers apparently use 0x83ca-0x83cb as aliases of the RAMDAC ports 0x83c6-0x83c7 (New MMIO mode). This makes the hardware cursor visible in those drivers on win3.1 using the IBM RGB RAMDAC. 4. A few more logs and sanity checks around LFB access and MMIO as well. --- src/include/86box/video.h | 4 +- src/video/vid_s3.c | 149 +++++++++++++++++++++++++------------- src/video/vid_table.c | 4 +- 3 files changed, 104 insertions(+), 53 deletions(-) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 1c8b610153..e1a1a75025 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -507,15 +507,15 @@ extern const device_t s3_phoenix_vision864_pci_device; extern const device_t s3_phoenix_vision864_vlb_device; extern const device_t s3_9fx_531_pci_device; extern const device_t s3_phoenix_vision868_pci_device; -extern const device_t s3_phoenix_vision868_vlb_device; extern const device_t s3_diamond_stealth64_pci_device; extern const device_t s3_diamond_stealth64_vlb_device; extern const device_t s3_diamond_stealth64_964_pci_device; extern const device_t s3_diamond_stealth64_964_vlb_device; +extern const device_t s3_diamond_stealth64_968_pci_device; +extern const device_t s3_diamond_stealth64_968_vlb_device; extern const device_t s3_mirovideo_40sv_ergo_968_pci_device; extern const device_t s3_9fx_771_pci_device; extern const device_t s3_phoenix_vision968_pci_device; -extern const device_t s3_phoenix_vision968_vlb_device; extern const device_t s3_spea_mercury_p64v_pci_device; extern const device_t s3_elsa_winner2000_pro_x_964_pci_device; extern const device_t s3_elsa_winner2000_pro_x_pci_device; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 8fa86dfe00..e74ff8c06f 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -75,6 +75,7 @@ #define ROM_SPEA_MERCURY_P64V "roms/video/s3/S3_968PCI_TVP3026_SPEAMecuryP64V_ver1.01.BIN" #define ROM_NUMBER9_9FX_771 "roms/video/s3/no9motionfx771.BIN" #define ROM_PHOENIX_VISION968 "roms/video/s3/1-DSV3968P.BIN" +#define ROM_DIAMOND_STEALTH64_968 "roms/video/s3/vv_303.rom" enum { S3_NUMBER9_9FX, @@ -115,7 +116,8 @@ enum { S3_NUMBER9_9FX_531, S3_NUMBER9_9FX_771, S3_SPEA_MERCURY_LITE_PCI, - S3_86C805_ONBOARD + S3_86C805_ONBOARD, + S3_DIAMOND_STEALTH64_968 }; enum { @@ -2770,13 +2772,15 @@ s3_out(uint16_t addr, uint8_t val, void *priv) case 0x3C7: case 0x3C8: case 0x3C9: + case 0x3CA: /*0x3c6 alias*/ + case 0x3CB: /*0x3c7 alias*/ rs2 = (svga->crtc[0x55] & 0x01) || !!(svga->crtc[0x43] & 2); if (s3->chip >= S3_TRIO32) svga_out(addr, val, svga); else if ((s3->chip == S3_VISION964 && s3->card_type != S3_ELSAWIN2KPROX_964) || (s3->chip == S3_86C928)) { rs3 = !!(svga->crtc[0x55] & 0x02); bt48x_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); - } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_ELSAWIN2KPROX || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771))) + } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_DIAMOND_STEALTH64_968 || s3->card_type == S3_ELSAWIN2KPROX || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771))) ibm_rgb528_ramdac_out(addr, rs2, val, svga->ramdac, svga); else if (s3->chip == S3_VISION968 && (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968)) { rs3 = !!(svga->crtc[0x55] & 0x02); @@ -2957,10 +2961,12 @@ s3_out(uint16_t addr, uint8_t val, void *priv) case 0x58: case 0x59: case 0x5a: + s3_log("[%04X:%08X]: Write CRTC%02x=%02x.\n", CS, cpu_state.pc, svga->crtcreg, svga->crtc[svga->crtcreg]); s3_updatemapping(s3); break; case 0x55: + s3_log("[%04X:%08X]: Write CRTC%02x=%02x.\n", CS, cpu_state.pc, svga->crtcreg, svga->crtc[svga->crtcreg]); if (s3->chip == S3_86C928) { if (val & 0x28) { svga->hwcursor_draw = NULL; @@ -3093,6 +3099,8 @@ s3_in(uint16_t addr, void *priv) case 0x3c7: case 0x3c8: case 0x3c9: + case 0x3ca: /*0x3c6 alias*/ + case 0x3cb: /*0x3c7 alias*/ rs2 = (svga->crtc[0x55] & 0x01) || !!(svga->crtc[0x43] & 2); if (s3->chip >= S3_TRIO32) return svga_in(addr, svga); @@ -3103,7 +3111,7 @@ s3_in(uint16_t addr, void *priv) rs3 = !!(svga->crtc[0x55] & 0x02); temp = bt48x_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); return temp; - } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_ELSAWIN2KPROX || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771))) + } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_DIAMOND_STEALTH64_968 || s3->card_type == S3_ELSAWIN2KPROX || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771))) return ibm_rgb528_ramdac_in(addr, rs2, svga->ramdac, svga); else if (s3->chip == S3_VISION968 && (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968)) { rs3 = !!(svga->crtc[0x55] & 0x02); @@ -3138,6 +3146,7 @@ s3_in(uint16_t addr, void *priv) } break; case 0x30: + s3_log("[%04X:%08X]: Read CRTC30=%02x.\n", CS, cpu_state.pc, s3->id); return s3->id; /*Chip ID*/ case 0x31: return (svga->crtc[0x31] & 0xcf) | ((s3->ma_ext & 3) << 4); @@ -3168,6 +3177,7 @@ s3_in(uint16_t addr, void *priv) /* Phoenix S3 video BIOS'es seem to expect CRTC registers 6B and 6C to be mirrors of 59 and 5A. */ case 0x6b: + s3_log("[%04X:%08X]: Read CRTC6b=%02x.\n", CS, cpu_state.pc, svga->crtc[0x6b]); if (s3->chip != S3_TRIO64V2) { if (svga->crtc[0x53] & 0x08) { return (s3->chip == S3_TRIO64V) ? (svga->crtc[0x59] & 0xfc) : (svga->crtc[0x59] & 0xfe); @@ -3178,6 +3188,7 @@ s3_in(uint16_t addr, void *priv) return svga->crtc[0x6b]; break; case 0x6c: + s3_log("[%04X:%08X]: Read CRTC6c=%02x.\n", CS, cpu_state.pc, svga->crtc[0x6b]); if (s3->chip != S3_TRIO64V2) { if (svga->crtc[0x53] & 0x08) { return 0x00; @@ -3190,6 +3201,7 @@ s3_in(uint16_t addr, void *priv) default: break; } + s3_log("[%04X:%08X]: Read CRTC%02x=%02x.\n", CS, cpu_state.pc, svga->crtcreg, svga->crtc[svga->crtcreg]); return svga->crtc[svga->crtcreg]; default: @@ -3458,6 +3470,7 @@ s3_recalctimings(svga_t *svga) if (svga->hdisp == 832) svga->hdisp -= 32; break; + case S3_DIAMOND_STEALTH64_968: case S3_NUMBER9_9FX_771: case S3_PHOENIX_VISION968: case S3_SPEA_MERCURY_P64V: @@ -3640,6 +3653,7 @@ s3_recalctimings(svga_t *svga) if (svga->hdisp == 832) svga->hdisp -= 32; break; + case S3_DIAMOND_STEALTH64_968: case S3_NUMBER9_9FX_771: case S3_PHOENIX_VISION968: case S3_SPEA_MERCURY_P64V: @@ -3827,6 +3841,7 @@ s3_recalctimings(svga_t *svga) if (svga->hdisp == 832) svga->hdisp -= 32; break; + case S3_DIAMOND_STEALTH64_968: case S3_NUMBER9_9FX_771: case S3_PHOENIX_VISION968: case S3_SPEA_MERCURY_P64V: @@ -4039,6 +4054,7 @@ s3_recalctimings(svga_t *svga) if (svga->hdisp == 832) svga->hdisp -= 32; break; + case S3_DIAMOND_STEALTH64_968: case S3_NUMBER9_9FX_771: case S3_PHOENIX_VISION968: case S3_SPEA_MERCURY_P64V: @@ -4369,6 +4385,7 @@ s3_updatemapping(s3_t *s3) s3->linear_base &= 0x00ffffff; } + s3_log("LinearBase=%x, crtc58bits=%x.\n", s3->linear_base, svga->crtc[0x58] & 0x13); if ((svga->crtc[0x58] & 0x10) || (s3->accel.advfunc_cntl & 0x10)) { /*Linear framebuffer*/ mem_mapping_disable(&svga->mapping); @@ -4414,7 +4431,11 @@ s3_updatemapping(s3_t *s3) else if ((s3->chip == S3_VISION968) || (s3->chip == S3_VISION868)) s3->linear_base &= 0xfe000000; - mem_mapping_set_addr(&s3->linear_mapping, s3->linear_base, s3->linear_size); + s3_log("LinearBase update=%x, size=%x.\n", s3->linear_base, s3->linear_size); + if (s3->linear_base) + mem_mapping_set_addr(&s3->linear_mapping, s3->linear_base, s3->linear_size); + else + mem_mapping_disable(&s3->linear_mapping); } svga->fb_only = 1; } else { @@ -4437,8 +4458,12 @@ s3_updatemapping(s3_t *s3) } /* New MMIO. */ - if (svga->crtc[0x53] & 0x08) - mem_mapping_set_addr(&s3->new_mmio_mapping, s3->linear_base + 0x1000000, 0x20000); + if (svga->crtc[0x53] & 0x08) { + if (s3->linear_base) + mem_mapping_set_addr(&s3->new_mmio_mapping, s3->linear_base + 0x1000000, 0x20000); + else + mem_mapping_disable(&s3->new_mmio_mapping); + } else mem_mapping_disable(&s3->new_mmio_mapping); } @@ -9178,11 +9203,13 @@ s3_pci_read(UNUSED(int func), int addr, void *priv) return 0x00; /*Supports VGA interface*/ else return 0x01; + break; case 0x0b: if (s3->chip >= S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) return 0x03; else return 0x00; + break; case 0x0d: return (s3->chip == S3_TRIO64V2) ? (s3->pci_regs[0x0d] & 0xf8) : 0x00; @@ -9461,6 +9488,7 @@ s3_reset(void *priv) svga->crtc[0x5a] = 0x0a; break; + case S3_DIAMOND_STEALTH64_968: case S3_ELSAWIN2KPROX: case S3_SPEA_MERCURY_P64V: case S3_MIROVIDEO40SV_ERGO_968: @@ -9639,10 +9667,7 @@ s3_init(const device_t *info) case S3_PHOENIX_VISION868: bios_fn = ROM_PHOENIX_VISION868; chip = S3_VISION868; - if (info->flags & DEVICE_PCI) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision868_pci); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision868_vlb); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision868_pci); break; case S3_DIAMOND_STEALTH64_964: bios_fn = ROM_DIAMOND_STEALTH64_964; @@ -9662,6 +9687,14 @@ s3_init(const device_t *info) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision964_vlb); } break; + case S3_DIAMOND_STEALTH64_968: + bios_fn = ROM_DIAMOND_STEALTH64_968; + chip = S3_VISION968; + if (info->flags & DEVICE_PCI) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_pci); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_vlb); + break; case S3_MIROVIDEO40SV_ERGO_968: bios_fn = ROM_MIROVIDEO40SV_ERGO_968_PCI; chip = S3_VISION968; @@ -9675,10 +9708,7 @@ s3_init(const device_t *info) case S3_PHOENIX_VISION968: bios_fn = ROM_PHOENIX_VISION968; chip = S3_VISION968; - if (info->flags & DEVICE_PCI) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_pci); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_vlb); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_pci); break; case S3_ELSAWIN2KPROX_964: bios_fn = ROM_ELSAWIN2KPROX_964; @@ -9843,7 +9873,7 @@ s3_init(const device_t *info) mem_mapping_disable(&s3->mmio_mapping); mem_mapping_disable(&s3->new_mmio_mapping); - if (chip == S3_VISION964 || chip == S3_VISION968) + if ((chip == S3_VISION964) || (chip == S3_VISION968)) svga_init(info, &s3->svga, s3, vram_size, s3_recalctimings, s3_in, s3_out, @@ -9881,16 +9911,14 @@ s3_init(const device_t *info) case S3_VISION968: switch (info->local) { + case S3_DIAMOND_STEALTH64_968: case S3_ELSAWIN2KPROX: case S3_PHOENIX_VISION968: case S3_NUMBER9_9FX_771: svga->dac_hwcursor_draw = ibm_rgb528_hwcursor_draw; break; - case S3_SPEA_MERCURY_P64V: - case S3_MIROVIDEO40SV_ERGO_968: - svga->dac_hwcursor_draw = tvp3026_hwcursor_draw; - break; default: + svga->dac_hwcursor_draw = tvp3026_hwcursor_draw; break; } break; @@ -10125,6 +10153,7 @@ s3_init(const device_t *info) } break; + case S3_DIAMOND_STEALTH64_968: case S3_ELSAWIN2KPROX: case S3_SPEA_MERCURY_P64V: case S3_MIROVIDEO40SV_ERGO_968: @@ -10132,8 +10161,9 @@ s3_init(const device_t *info) case S3_PHOENIX_VISION968: svga->decode_mask = (8 << 20) - 1; s3->id = 0xe1; /*Vision968*/ - s3->id_ext = s3->id_ext_pci = 0xf0; - s3->packed_mmio = 1; + s3->id_ext = 0xf0; + s3->id_ext_pci = s3->id_ext; + s3->packed_mmio = 1; if (s3->pci) { svga->crtc[0x53] = 0x18; svga->crtc[0x58] = 0x10; @@ -10147,6 +10177,7 @@ s3_init(const device_t *info) } switch (info->local) { + case S3_DIAMOND_STEALTH64_968: case S3_ELSAWIN2KPROX: case S3_PHOENIX_VISION968: case S3_NUMBER9_9FX_771: @@ -10376,6 +10407,12 @@ s3_diamond_stealth64_964_available(void) return rom_present(ROM_DIAMOND_STEALTH64_964); } +static int +s3_diamond_stealth64_968_available(void) +{ + return rom_present(ROM_DIAMOND_STEALTH64_968); +} + static int s3_mirovideo_40sv_ergo_968_pci_available(void) { @@ -10593,6 +10630,20 @@ static const device_config_t s3_968_config[] = { { .type = CONFIG_END } }; +static const device_config_t s3_standard_config2[] = { + { .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_int = 4, + .selection = { + { .description = "2 MB", + .value = 2 }, + { .description = "4 MB", + .value = 4 }, + { .description = "" } } }, + { .type = CONFIG_END } +}; + const device_t s3_orchid_86c911_isa_device = { .name = "S3 86c911 ISA (Orchid Fahrenheit 1280)", .internal_name = "orchid_s3_911", @@ -10873,6 +10924,34 @@ const device_t s3_diamond_stealth64_964_pci_device = { .config = s3_standard_config }; +const device_t s3_diamond_stealth64_968_vlb_device = { + .name = "S3 Vision968 VLB (Diamond Stealth64 Video VRAM)", + .internal_name = "stealth64vv_vlb", + .flags = DEVICE_VLB, + .local = S3_DIAMOND_STEALTH64_968, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, + { .available = s3_diamond_stealth64_968_available }, + .speed_changed = s3_speed_changed, + .force_redraw = s3_force_redraw, + .config = s3_standard_config2 +}; + +const device_t s3_diamond_stealth64_968_pci_device = { + .name = "S3 Vision968 PCI (Diamond Stealth64 Video VRAM)", + .internal_name = "stealth64vv_pci", + .flags = DEVICE_PCI, + .local = S3_DIAMOND_STEALTH64_968, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, + { .available = s3_diamond_stealth64_968_available }, + .speed_changed = s3_speed_changed, + .force_redraw = s3_force_redraw, + .config = s3_standard_config2 +}; + const device_t s3_9fx_771_pci_device = { .name = "S3 Vision968 PCI (Number 9 9FX 771)", .internal_name = "n9_9fx_771_pci", @@ -10901,20 +10980,6 @@ const device_t s3_phoenix_vision968_pci_device = { .config = s3_standard_config }; -const device_t s3_phoenix_vision968_vlb_device = { - .name = "S3 Vision968 VLB (Phoenix)", - .internal_name = "px_vision968_vlb", - .flags = DEVICE_VLB, - .local = S3_PHOENIX_VISION968, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, - { .available = s3_phoenix_vision968_available }, - .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_standard_config -}; - const device_t s3_mirovideo_40sv_ergo_968_pci_device = { .name = "S3 Vision968 PCI (MiroVIDEO 40SV Ergo)", .internal_name = "mirovideo40sv_pci", @@ -11195,20 +11260,6 @@ const device_t s3_9fx_531_pci_device = { .config = s3_9fx_config }; -const device_t s3_phoenix_vision868_vlb_device = { - .name = "S3 Vision868 VLB (Phoenix)", - .internal_name = "px_vision868_vlb", - .flags = DEVICE_VLB, - .local = S3_PHOENIX_VISION868, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, - { .available = s3_phoenix_vision868_available }, - .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_standard_config -}; - const device_t s3_phoenix_vision868_pci_device = { .name = "S3 Vision868 PCI (Phoenix)", .internal_name = "px_vision868_pci", diff --git a/src/video/vid_table.c b/src/video/vid_table.c index b2686b2f31..c99a41544d 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -188,6 +188,7 @@ video_cards[] = { { &s3_diamond_stealth64_pci_device }, { &s3_9fx_pci_device }, { &s3_phoenix_trio64_pci_device }, + { &s3_diamond_stealth64_968_pci_device }, { &s3_elsa_winner2000_pro_x_pci_device }, { &s3_mirovideo_40sv_ergo_968_pci_device }, { &s3_9fx_771_pci_device }, @@ -252,8 +253,7 @@ video_cards[] = { { &s3_9fx_vlb_device }, { &s3_phoenix_trio64_vlb_device }, { &s3_spea_mirage_p64_vlb_device }, - { &s3_phoenix_vision968_vlb_device }, - { &s3_phoenix_vision868_vlb_device }, + { &s3_diamond_stealth64_968_vlb_device }, { &s3_stb_powergraph_64_video_vlb_device }, { &ht216_32_standalone_device }, { &tgui9400cxi_device }, From e9f19ec32b11a8d36ecb37af9b1b67200889dd98 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 29 May 2024 23:54:39 +0200 Subject: [PATCH 04/13] Fix compile warning. See above. --- src/video/vid_s3.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index e74ff8c06f..8ecd3711e4 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -145,7 +145,6 @@ static video_timings_t timing_s3_stealth64_vlb = { .type = VIDEO_BUS, .write_b = static video_timings_t timing_s3_stealth64_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 26, .read_w = 26, .read_l = 42 }; static video_timings_t timing_s3_vision864_vlb = { .type = VIDEO_BUS, .write_b = 4, .write_w = 4, .write_l = 5, .read_b = 20, .read_w = 20, .read_l = 35 }; static video_timings_t timing_s3_vision864_pci = { .type = VIDEO_PCI, .write_b = 4, .write_w = 4, .write_l = 5, .read_b = 20, .read_w = 20, .read_l = 35 }; -static video_timings_t timing_s3_vision868_vlb = { .type = VIDEO_BUS, .write_b = 4, .write_w = 4, .write_l = 5, .read_b = 20, .read_w = 20, .read_l = 35 }; static video_timings_t timing_s3_vision868_pci = { .type = VIDEO_PCI, .write_b = 4, .write_w = 4, .write_l = 5, .read_b = 20, .read_w = 20, .read_l = 35 }; static video_timings_t timing_s3_vision964_vlb = { .type = VIDEO_BUS, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 20, .read_w = 20, .read_l = 35 }; static video_timings_t timing_s3_vision964_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 20, .read_w = 20, .read_l = 35 }; From 11d7afd5780a5a7eb3fee560decc14934354bf63 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 30 May 2024 00:13:29 +0200 Subject: [PATCH 05/13] Video changes part 3 (minor though) 1. Added an on-board S3 ViRGE DX (375) video card to the Intel AP440FX socket 8-based machine alongside its on-board CS4236B audio. 2. Sanity check for on-board S3 ViRGE devices. --- src/include/86box/video.h | 1 + src/machine/m_at_socket8.c | 7 +++++ src/machine/machine_table.c | 14 +++++----- src/video/vid_s3_virge.c | 51 +++++++++++++++++++++++++++---------- 4 files changed, 52 insertions(+), 21 deletions(-) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index e1a1a75025..83930122ba 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -528,6 +528,7 @@ extern const device_t s3_diamond_stealth_2000_pci_device; extern const device_t s3_diamond_stealth_3000_pci_device; extern const device_t s3_stb_velocity_3d_pci_device; extern const device_t s3_virge_375_pci_device; +extern const device_t s3_virge_375_onboard_pci_device; extern const device_t s3_diamond_stealth_2000pro_pci_device; extern const device_t s3_virge_385_pci_device; extern const device_t s3_virge_357_pci_device; diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index e8262a6f4c..8c2688c1a3 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -33,6 +33,7 @@ #include <86box/timer.h> #include <86box/nvr.h> #include <86box/sio.h> +#include <86box/sound.h> #include <86box/hwm.h> #include <86box/spd.h> #include <86box/video.h> @@ -322,6 +323,12 @@ machine_at_ap440fx_init(const machine_t *model) device_add(&pc87307_device); device_add(&intel_flash_bxt_ami_device); + if (sound_card_current[0] == SOUND_INTERNAL) + device_add(&cs4236b_device); + + if (gfxcard[0] == VID_INTERNAL) + device_add(&s3_virge_375_onboard_pci_device); + return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 4b91f1668e..9d38686bda 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -5182,7 +5182,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* The board has a "ASII KB-100" which I was not able to find any information about, + /* The board has a "ASII KB-100" which I was not able to find any information about, but the BIOS sends commands C9 without a parameter and D5, both of which are Phoenix MultiKey commands. */ { @@ -10606,7 +10606,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* [TEST] The board doesn't seem to have a KBC at all, which probably means it's an on-chip one on the PC87306 SIO. + /* [TEST] The board doesn't seem to have a KBC at all, which probably means it's an on-chip one on the PC87306 SIO. A list on a Danish site shows the BIOS as having a -0 string, indicating non-AMI KBC firmware. */ { .name = "[i430HX] Supermicro P55T2S", @@ -12658,7 +12658,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - + /* ALi ALADDiN IV+ */ /* Has the ALi M1543 southbridge with on-chip KBC. */ { @@ -13051,7 +13051,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_A97 | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -13462,7 +13462,7 @@ const machine_t machines[] = { .max_multi = 3.5 }, .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, /* Machine has internal video: S3 ViRGE/DX and sound: Crystal CS4236B */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_SOUND | MACHINE_VIDEO | MACHINE_USB, /* Machine has internal video: S3 ViRGE/DX and sound: Crystal CS4236B */ .ram = { .min = 8192, .max = 131072, @@ -13476,8 +13476,8 @@ const machine_t machines[] = { .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, + .vid_device = &s3_virge_375_onboard_pci_device, + .snd_device = &cs4236b_device, .net_device = NULL }, /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 4d64dffbd4..26560c4984 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -295,6 +295,8 @@ typedef struct virge_t { void *i2c, *ddc; int waiting; + + int has_bios; } virge_t; static video_timings_t timing_diamond_stealth3d_2000_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 3, .read_b = 28, .read_w = 28, .read_l = 45 }; @@ -1070,14 +1072,13 @@ s3_virge_updatemapping(virge_t *virge) virge->linear_base &= ~(virge->linear_size - 1); s3_virge_log("Linear framebuffer at %08X size %08X, mask = %08x, CRTC58 sel = %02x\n", virge->linear_base, virge->linear_size, virge->vram_mask, svga->crtc[0x58] & 7); if (virge->linear_base == 0xa0000) { - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000, 0); mem_mapping_disable(&virge->linear_mapping); } else { - if (virge->chip == S3_VIRGEVX || virge->chip == S3_TRIO3D2X) { + if (virge->chip == S3_VIRGEVX || virge->chip == S3_TRIO3D2X) virge->linear_base &= 0xfe000000; - } else { + else virge->linear_base &= 0xfc000000; - } mem_mapping_set_addr(&virge->linear_mapping, virge->linear_base, virge->linear_size); } @@ -4069,16 +4070,16 @@ s3_virge_pci_read(UNUSED(int func), int addr, void *priv) break; case 0x30: - ret = virge->pci_regs[0x30] & 0x01; + ret = virge->has_bios ? (virge->pci_regs[0x30] & 0x01) : 0x00; break; /*BIOS ROM address*/ case 0x31: ret = 0x00; break; case 0x32: - ret = virge->pci_regs[0x32]; + ret = virge->has_bios ? virge->pci_regs[0x32] : 0x00; break; case 0x33: - ret = virge->pci_regs[0x33]; + ret = virge->has_bios ? virge->pci_regs[0x33] : 0x00; break; case 0x34: @@ -4202,6 +4203,8 @@ s3_virge_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) case 0x30: case 0x32: case 0x33: + if (!virge->has_bios) + return; virge->pci_regs[addr] = val; if (virge->pci_regs[0x30] & 0x01) { uint32_t biosaddr = (virge->pci_regs[0x32] << 16) | (virge->pci_regs[0x33] << 24); @@ -4337,7 +4340,8 @@ s3_virge_reset(void *priv) virge->svga.crtc[0x37] = 1 | (7 << 5); virge->svga.crtc[0x53] = 8; - mem_mapping_disable(&virge->bios_rom.mapping); + if (virge->has_bios) + mem_mapping_disable(&virge->bios_rom.mapping); s3_virge_updatemapping(virge); @@ -4360,6 +4364,8 @@ s3_virge_init(const device_t *info) else virge->memory_size = device_get_config_int("memory"); + virge->has_bios = !!(info->local & 0x100); + switch (info->local) { case S3_VIRGE_325: bios_fn = ROM_VIRGE_325; @@ -4374,7 +4380,7 @@ s3_virge_init(const device_t *info) bios_fn = ROM_STB_VELOCITY_3D; break; case S3_VIRGE_DX: - bios_fn = ROM_VIRGE_DX; + bios_fn = virge->has_bios ? ROM_VIRGE_DX : NULL; break; case S3_DIAMOND_STEALTH3D_2000PRO: bios_fn = ROM_DIAMOND_STEALTH3D_2000PRO; @@ -4408,11 +4414,12 @@ s3_virge_init(const device_t *info) rom_init(&virge->bios_rom, bios_fn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); else rom_init(&virge->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - } - mem_mapping_disable(&virge->bios_rom.mapping); + mem_mapping_disable(&virge->bios_rom.mapping); + } - mem_mapping_add(&virge->linear_mapping, 0, 0, svga_read_linear, + mem_mapping_add(&virge->linear_mapping, 0, 0, + svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, @@ -4421,7 +4428,8 @@ s3_virge_init(const device_t *info) NULL, MEM_MAPPING_EXTERNAL, &virge->svga); - mem_mapping_add(&virge->mmio_mapping, 0, 0, s3_virge_mmio_read, + mem_mapping_add(&virge->mmio_mapping, 0, 0, + s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, s3_virge_mmio_write, @@ -4430,7 +4438,8 @@ s3_virge_init(const device_t *info) NULL, MEM_MAPPING_EXTERNAL, virge); - mem_mapping_add(&virge->new_mmio_mapping, 0, 0, s3_virge_mmio_read, + mem_mapping_add(&virge->new_mmio_mapping, 0, 0, + s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, s3_virge_mmio_write, @@ -4896,6 +4905,20 @@ const device_t s3_virge_375_pci_device = { .config = s3_virge_config }; +const device_t s3_virge_375_onboard_pci_device = { + .name = "S3 ViRGE/DX (375) On-Board PCI", + .internal_name = "virge375_onboard_pci", + .flags = DEVICE_PCI, + .local = S3_VIRGE_DX | 0x100, + .init = s3_virge_init, + .close = s3_virge_close, + .reset = s3_virge_reset, + { .available = NULL }, + .speed_changed = s3_virge_speed_changed, + .force_redraw = s3_virge_force_redraw, + .config = s3_virge_config +}; + const device_t s3_diamond_stealth_2000pro_pci_device = { .name = "S3 ViRGE/DX (Diamond Stealth 3D 2000 Pro) PCI", .internal_name = "stealth3d_2000pro_pci", From 3d74f43b9557e13c1d7c18cb4d4a744417315b78 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 30 May 2024 00:25:29 +0200 Subject: [PATCH 06/13] NCR 53c400 timing fixes. See above (CD-ROM speeds too for said SCSI chips). --- src/scsi/scsi_ncr53c400.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/scsi/scsi_ncr53c400.c b/src/scsi/scsi_ncr53c400.c index ca4d28ffb9..0e772c16c0 100644 --- a/src/scsi/scsi_ncr53c400.c +++ b/src/scsi/scsi_ncr53c400.c @@ -146,8 +146,8 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) if (ncr400->buffer_host_pos == MIN(128, dev->buffer_length)) { ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; ncr400->busy = 1; - if (!(ncr->mode & MODE_MONITOR_BUSY)) - timer_on_auto(&ncr400->timer, ncr->period / 280.0); + if (!(ncr->mode & MODE_MONITOR_BUSY) && ((scsi_device_get_callback(dev) > 0.0))) + timer_on_auto(&ncr400->timer, ncr->period / 250.0); } } break; @@ -182,9 +182,12 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) memset(ncr400->buffer, 0, MIN(128, dev->buffer_length)); if (ncr->mode & MODE_MONITOR_BUSY) timer_on_auto(&ncr400->timer, ncr->period); - else + else if (scsi_device_get_callback(dev) > 0.0) timer_on_auto(&ncr400->timer, 40.0); - ncr53c400_log("DMA timer on, callback=%lf, scsi buflen=%d, waitdata=%d, waitcomplete=%d, clearreq=%d, datawait=%d, enabled=%d.\n", scsi_device_get_callback(dev), dev->buffer_length, ncr->wait_complete, ncr->wait_data, ncr->wait_complete, ncr->clear_req, ncr->data_wait, timer_is_enabled(&ncr400->timer)); + else + timer_on_auto(&ncr400->timer, ncr->period); + + ncr53c400_log("DMA timer on=%02x, callback=%lf, scsi buflen=%d, waitdata=%d, waitcomplete=%d, clearreq=%d, datawait=%d, enabled=%d.\n", ncr->mode & MODE_MONITOR_BUSY, scsi_device_get_callback(dev), dev->buffer_length, ncr->wait_complete, ncr->wait_data, ncr->wait_complete, ncr->clear_req, ncr->data_wait, timer_is_enabled(&ncr400->timer)); } break; @@ -239,8 +242,8 @@ ncr53c400_read(uint32_t addr, void *priv) if (ncr400->buffer_host_pos == MIN(128, dev->buffer_length)) { ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; ncr53c400_log("Transfer busy read, status = %02x.\n", ncr400->status_ctrl); - if (!(ncr->mode & MODE_MONITOR_BUSY)) - timer_on_auto(&ncr400->timer, ncr->period / 280.0); + if (!(ncr->mode & MODE_MONITOR_BUSY) && (scsi_device_get_callback(dev) > 0.0)) + timer_on_auto(&ncr400->timer, ncr->period / 250.0); } } break; From 0897eea7df06d51b7343e053e4e6060909c604f2 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 30 May 2024 00:43:00 +0200 Subject: [PATCH 07/13] Plus a compile fix. --- src/video/vid_s3_virge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 26560c4984..352fe2bd82 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -1072,7 +1072,7 @@ s3_virge_updatemapping(virge_t *virge) virge->linear_base &= ~(virge->linear_size - 1); s3_virge_log("Linear framebuffer at %08X size %08X, mask = %08x, CRTC58 sel = %02x\n", virge->linear_base, virge->linear_size, virge->vram_mask, svga->crtc[0x58] & 7); if (virge->linear_base == 0xa0000) { - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000, 0); + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); mem_mapping_disable(&virge->linear_mapping); } else { if (virge->chip == S3_VIRGEVX || virge->chip == S3_TRIO3D2X) From eff32906c5797a9a4a2ede39053ad94e20716e2e Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 30 May 2024 16:35:32 +0200 Subject: [PATCH 08/13] Fix onboard flag for actual onboard ViRGE BIOSes. So that ViRGE cards can work again without black screening. --- src/video/vid_s3_virge.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 352fe2bd82..7982f816e5 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -296,7 +296,7 @@ typedef struct virge_t { int waiting; - int has_bios; + int onboard; } virge_t; static video_timings_t timing_diamond_stealth3d_2000_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 3, .read_b = 28, .read_w = 28, .read_l = 45 }; @@ -4070,16 +4070,16 @@ s3_virge_pci_read(UNUSED(int func), int addr, void *priv) break; case 0x30: - ret = virge->has_bios ? (virge->pci_regs[0x30] & 0x01) : 0x00; + ret = (!virge->onboard) ? (virge->pci_regs[0x30] & 0x01) : 0x00; break; /*BIOS ROM address*/ case 0x31: ret = 0x00; break; case 0x32: - ret = virge->has_bios ? virge->pci_regs[0x32] : 0x00; + ret = (!virge->onboard) ? virge->pci_regs[0x32] : 0x00; break; case 0x33: - ret = virge->has_bios ? virge->pci_regs[0x33] : 0x00; + ret = (!virge->onboard) ? virge->pci_regs[0x33] : 0x00; break; case 0x34: @@ -4203,7 +4203,7 @@ s3_virge_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) case 0x30: case 0x32: case 0x33: - if (!virge->has_bios) + if (virge->onboard) return; virge->pci_regs[addr] = val; if (virge->pci_regs[0x30] & 0x01) { @@ -4340,7 +4340,7 @@ s3_virge_reset(void *priv) virge->svga.crtc[0x37] = 1 | (7 << 5); virge->svga.crtc[0x53] = 8; - if (virge->has_bios) + if (!virge->onboard) mem_mapping_disable(&virge->bios_rom.mapping); s3_virge_updatemapping(virge); @@ -4364,7 +4364,7 @@ s3_virge_init(const device_t *info) else virge->memory_size = device_get_config_int("memory"); - virge->has_bios = !!(info->local & 0x100); + virge->onboard = !!(info->local & 0x100); switch (info->local) { case S3_VIRGE_325: @@ -4380,7 +4380,7 @@ s3_virge_init(const device_t *info) bios_fn = ROM_STB_VELOCITY_3D; break; case S3_VIRGE_DX: - bios_fn = virge->has_bios ? ROM_VIRGE_DX : NULL; + bios_fn = virge->onboard ? NULL : ROM_VIRGE_DX; break; case S3_DIAMOND_STEALTH3D_2000PRO: bios_fn = ROM_DIAMOND_STEALTH3D_2000PRO; From c68a4445ae9dd8bcbe95c0338875c3df9adf9ccf Mon Sep 17 00:00:00 2001 From: Shelby Jueden Date: Thu, 30 May 2024 08:13:04 -0700 Subject: [PATCH 09/13] Add years to the Machine Type names --- src/machine/machine_table.c | 44 ++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 9d38686bda..69a87e3253 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -58,28 +58,28 @@ extern const device_t ps1_2011_device; const machine_filter_t machine_types[] = { { "None", MACHINE_TYPE_NONE }, - { "8088", MACHINE_TYPE_8088 }, - { "8086", MACHINE_TYPE_8086 }, - { "80286", MACHINE_TYPE_286 }, - { "i386SX", MACHINE_TYPE_386SX }, - { "486SLC", MACHINE_TYPE_486SLC }, - { "i386DX", MACHINE_TYPE_386DX }, - { "i386DX/i486", MACHINE_TYPE_386DX_486 }, - { "i486 (Socket 168 and 1)", MACHINE_TYPE_486 }, - { "i486 (Socket 2)", MACHINE_TYPE_486_S2 }, - { "i486 (Socket 3)", MACHINE_TYPE_486_S3 }, - { "i486 (Miscellaneous)", MACHINE_TYPE_486_MISC }, - { "Socket 4", MACHINE_TYPE_SOCKET4 }, - { "Socket 5", MACHINE_TYPE_SOCKET5 }, - { "Socket 7 (Single Voltage)", MACHINE_TYPE_SOCKET7_3V }, - { "Socket 7 (Dual Voltage)", MACHINE_TYPE_SOCKET7 }, - { "Super Socket 7", MACHINE_TYPE_SOCKETS7 }, - { "Socket 8", MACHINE_TYPE_SOCKET8 }, - { "Slot 1", MACHINE_TYPE_SLOT1 }, - { "Slot 1/2", MACHINE_TYPE_SLOT1_2 }, - { "Slot 1/Socket 370", MACHINE_TYPE_SLOT1_370 }, - { "Slot 2", MACHINE_TYPE_SLOT2 }, - { "Socket 370", MACHINE_TYPE_SOCKET370 }, + { "[1979] 8088", MACHINE_TYPE_8088 }, + { "[1978] 8086", MACHINE_TYPE_8086 }, + { "[1982] 80286", MACHINE_TYPE_286 }, + { "[1988] i386SX", MACHINE_TYPE_386SX }, + { "[1992] 486SLC", MACHINE_TYPE_486SLC }, + { "[1985] i386DX", MACHINE_TYPE_386DX }, + { "[1989] i386DX/i486", MACHINE_TYPE_386DX_486 }, + { "[1992] i486 (Socket 168 and 1)", MACHINE_TYPE_486 }, + { "[1992] i486 (Socket 2)", MACHINE_TYPE_486_S2 }, + { "[1994] i486 (Socket 3)", MACHINE_TYPE_486_S3 }, + { "[1992] i486 (Miscellaneous)", MACHINE_TYPE_486_MISC }, + { "[1993] Socket 4", MACHINE_TYPE_SOCKET4 }, + { "[1994] Socket 5", MACHINE_TYPE_SOCKET5 }, + { "[1995] Socket 7 (Single Voltage)", MACHINE_TYPE_SOCKET7_3V }, + { "[1995] Socket 7 (Dual Voltage)", MACHINE_TYPE_SOCKET7 }, + { "[1998] Super Socket 7", MACHINE_TYPE_SOCKETS7 }, + { "[1995] Socket 8", MACHINE_TYPE_SOCKET8 }, + { "[1996] Slot 1", MACHINE_TYPE_SLOT1 }, + { "[1998] Slot 1/2", MACHINE_TYPE_SLOT1_2 }, + { "[1998] Slot 1/Socket 370", MACHINE_TYPE_SLOT1_370 }, + { "[1998] Slot 2", MACHINE_TYPE_SLOT2 }, + { "[1998] Socket 370", MACHINE_TYPE_SOCKET370 }, { "Miscellaneous", MACHINE_TYPE_MISC } }; From 3f0e5ccf27c21c6d4ddfdf4ab3c9a5989321ca7e Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 31 May 2024 00:38:07 -0400 Subject: [PATCH 10/13] Add the lo-tech EMS Board --- src/device/isamem.c | 149 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 146 insertions(+), 3 deletions(-) diff --git a/src/device/isamem.c b/src/device/isamem.c index 70f51ce8d4..9ff61bc452 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -33,8 +33,10 @@ * * * Authors: Fred N. van Kempen, + * Jasmine Iwanek * - * Copyright 2018 Fred N. van Kempen. + * Copyright 2018 Fred N. van Kempen. + * Copyright 2022-2024 Jasmine Iwanek. * * Redistribution and use in source and binary forms, with * or without modification, are permitted provided that the @@ -98,6 +100,7 @@ #define ISAMEM_ABOVEBOARD_CARD 12 #define ISAMEM_BRAT_CARD 13 #define ISAMEM_EV165A_CARD 14 +#define ISAMEM_LOTECH_CARD 15 #define ISAMEM_DEBUG 0 @@ -318,6 +321,26 @@ ems_read(uint16_t port, void *priv) return ret; } +/* Handle a READ operation from one of our registers. */ +static uint8_t +consecutive_ems_read(uint16_t port, void *priv) +{ + const memdev_t *dev = (memdev_t *) priv; + uint8_t ret = 0xff; + int vpage; + + /* Get the viewport page number. */ + vpage = (port - dev->base_addr); + + isamem_log("ISAMEM: read(%04x) = %02x) page=%d\n", port, ret, vpage); + + ret = dev->ems[vpage].page; + if (dev->ems[vpage].enabled) + ret |= 0x80; + + return ret; +} + /* Handle a WRITE operation to one of our registers. */ static void ems_write(uint16_t port, uint8_t val, void *priv) @@ -393,6 +416,47 @@ ems_write(uint16_t port, uint8_t val, void *priv) } } +/* Handle a WRITE operation to one of our registers. */ +static void +consecutive_ems_write(uint16_t port, uint8_t val, void *priv) +{ + memdev_t *dev = (memdev_t *) priv; + int vpage; + + /* Get the viewport page number. */ + vpage = (port - dev->base_addr); + + isamem_log("ISAMEM: write(%04x, %02x) page=%d\n", port, val, vpage); + + isamem_log("EMS: write(%02x) to register 0! (%02x)\n", val); + /* Set the page number. */ + dev->ems[vpage].enabled = (val & 0xff); + dev->ems[vpage].page = (val & 0xff); + + /* Make sure we can do that.. */ + if (dev->flags & FLAG_CONFIG) { + if (dev->ems[vpage].page < dev->ems_pages) { + /* Pre-calculate the page address in EMS RAM. */ + dev->ems[vpage].addr = dev->ram + dev->ems_start + ((val & 0xff) * EMS_PGSIZE); + } else { + /* That page does not exist. */ + dev->ems[vpage].enabled = 0; + } + + if (dev->ems[vpage].enabled) { + /* Update the EMS RAM address for this page. */ + mem_mapping_set_exec(&dev->ems[vpage].mapping, + dev->ems[vpage].addr); + + /* Enable this page. */ + mem_mapping_enable(&dev->ems[vpage].mapping); + } else { + /* Disable this page. */ + mem_mapping_disable(&dev->ems[vpage].mapping); + } + } +} + /* Initialize the device for use. */ static void * isamem_init(const device_t *info) @@ -476,6 +540,13 @@ isamem_init(const device_t *info) dev->flags |= FLAG_FAST; break; + case ISAMEM_LOTECH_CARD: + dev->base_addr = device_get_config_hex16("base"); + dev->total_size = device_get_config_int("size"); + dev->start_addr = 0; + dev->frame_addr = device_get_config_hex20("frame"); + dev->flags |= (FLAG_EMS | FLAG_CONFIG); + default: break; } @@ -663,9 +734,14 @@ isamem_init(const device_t *info) mem_mapping_disable(&dev->ems[i].mapping); /* Set up an I/O port handler. */ - io_sethandler(dev->base_addr + (EMS_PGSIZE * i), 2, - ems_read, NULL, NULL, ems_write, NULL, NULL, dev); + if (dev->board != ISAMEM_LOTECH_CARD) + io_sethandler(dev->base_addr + (EMS_PGSIZE * i), 2, + ems_read, NULL, NULL, ems_write, NULL, NULL, dev); } + + if (dev->board == ISAMEM_LOTECH_CARD) + io_sethandler(dev->base_addr, 4, + consecutive_ems_read, NULL, NULL, consecutive_ems_write, NULL, NULL, dev); } /* Let them know our device instance. */ @@ -1439,6 +1515,72 @@ static const device_t brat_device = { }; #endif +static const device_config_t lotech_config[] = { +// clang-format off + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = "", + .default_int = 0x0260, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "260H", .value = 0x0260 }, + { .description = "264H", .value = 0x0264 }, + { .description = "268H", .value = 0x0268 }, + { .description = "26CH", .value = 0x026C }, + { .description = "" } + }, + }, + { + .name = "frame", + .description = "Frame Address", + .type = CONFIG_HEX20, + .default_string = "", + .default_int = 0xe0000, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = 0x00000 }, + { .description = "C000H", .value = 0xC0000 }, + { .description = "D000H", .value = 0xD0000 }, + { .description = "E000H", .value = 0xE0000 }, + { .description = "" } + }, + }, + { + .name = "size", + .description = "Memory Size", + .type = CONFIG_SPINNER, + .default_string = "", + .default_int = 2048, + .file_filter = "", + .spinner = { + .min = 512, + .max = 4096, + .step = 512 + }, + .selection = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +// clang-format on +}; + +static const device_t lotech_device = { + .name = "Lo-tech EMS Board", + .internal_name = "lotechems", + .flags = DEVICE_ISA, + .local = ISAMEM_LOTECH_CARD, + .init = isamem_init, + .close = isamem_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = lotech_config +}; + #if defined(DEV_BRANCH) && defined(USE_ISAMEM_RAMPAGE) static const device_config_t rampage_config[] = { // clang-format off @@ -1676,6 +1818,7 @@ static const struct { #if defined(DEV_BRANCH) && defined(USE_ISAMEM_IAB) { &iab_device }, #endif + { &lotech_device }, { NULL } // clang-format on }; From 028142136a4a031c0ead105b27b9cd0431ed8069 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 31 May 2024 00:44:04 -0400 Subject: [PATCH 11/13] Fix Max EMS per board --- src/device/isamem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/device/isamem.c b/src/device/isamem.c index 9ff61bc452..fea9c0d880 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -108,7 +108,7 @@ #define RAM_UMAMEM (384 << 10) /* upper memory block */ #define RAM_EXTMEM (1024 << 10) /* start of high memory */ -#define EMS_MAXSIZE (2048 << 10) /* max EMS memory size */ +#define EMS_MAXSIZE (4096 << 10) /* max EMS memory size */ #define EMS_PGSIZE (16 << 10) /* one page is this big */ #define EMS_MAXPAGE 4 /* number of viewport pages */ @@ -696,7 +696,7 @@ isamem_init(const device_t *info) /* If EMS is enabled, use the remainder for EMS. */ if (dev->flags & FLAG_EMS) { - /* EMS 3.2 cannot have more than 2048KB per board. */ + /* EMS 3.2 cannot have more than 4096KB per board. */ t = k; if (t > EMS_MAXSIZE) t = EMS_MAXSIZE; From bd28ad2fe44f70d75b00db38049e1db55acab032 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 31 May 2024 00:45:33 -0400 Subject: [PATCH 12/13] Fix trivial bug in EMS5150 --- src/device/isamem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/device/isamem.c b/src/device/isamem.c index fea9c0d880..09374f30dc 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -499,6 +499,7 @@ isamem_init(const device_t *info) case ISAMEM_EMS5150_CARD: /* Micro Mainframe EMS-5150(T) */ dev->base_addr = device_get_config_hex16("base"); dev->total_size = device_get_config_int("size"); + dev->start_addr = 0; dev->frame_addr = 0xD0000; dev->flags |= (FLAG_EMS | FLAG_CONFIG); break; From ab137e999e9339f660219c3df4186a99b7278f04 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 1 Jun 2024 02:00:22 +0200 Subject: [PATCH 13/13] VIA Apollo VPX: Fix SMRAM handling. --- src/chipset/via_apollo.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/chipset/via_apollo.c b/src/chipset/via_apollo.c index 7c1203c3ab..20e2c7f74f 100644 --- a/src/chipset/via_apollo.c +++ b/src/chipset/via_apollo.c @@ -444,7 +444,7 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) apollo_smram_map(dev, 0, 0x000a0000, 0x00020000, 0); break; } - else + else if (dev->id == VIA_595) switch (val & 0x03) { case 0x00: apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 0); @@ -468,6 +468,12 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) default: break; } + else { + smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x00020000, + (dev->pci_conf[0x6d] & 0x10) && (dev->pci_conf[0x63] & 0x01), + dev->pci_conf[0x63] & 0x01); + flushmmucache(); + } break; case 0x65: if (dev->id == VIA_585) @@ -532,6 +538,13 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) dev->pci_conf[0x6d] = (dev->pci_conf[0x6d] & ~0x7f) | (val & 0x7f); else dev->pci_conf[0x6d] = val; + if (dev->id == VIA_585) { + smram_disable_all(); + smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x00020000, + (dev->pci_conf[0x6d] & 0x10) && (dev->pci_conf[0x63] & 0x01), + dev->pci_conf[0x63] & 0x01); + flushmmucache(); + } break; case 0x6e: if ((dev->id == VIA_595) || (dev->id == VIA_694))