From 2aa741e597eaad61644d1c82cdc9dfbf5f4ac974 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 1 Oct 2020 21:05:53 +0200 Subject: [PATCH 01/12] Re-added the S3 928 to the video table (forgot in the previous commits). Marked the Trio3D/2X as incomplete/dev-branched due to bugs on win9x and no public datasheet of it. Added 8MB option to the supported video memory to the ViRGE/VX. --- src/include/86box/video.h | 2 + src/video/vid_s3_virge.c | 921 +++++++++++++++++++++----------------- src/video/vid_table.c | 6 +- src/win/Makefile.mingw | 10 + 4 files changed, 528 insertions(+), 411 deletions(-) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 597fcc5ea..ced613608 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -329,7 +329,9 @@ extern const device_t s3_virge_375_vlb_device; extern const device_t s3_virge_375_pci_device; extern const device_t s3_virge_375_4_vlb_device; extern const device_t s3_virge_375_4_pci_device; +#if defined(DEV_BRANCH) && defined(USE_S3TRIO3D2X) extern const device_t s3_trio3d_2x_pci_device; +#endif /* Sigma Color 400 */ extern const device_t sigma_device; diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index e9a7f0945..39a964933 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -68,23 +68,29 @@ static int dither[4][4] = #define ROM_DIAMOND_STEALTH3D_3000 L"roms/video/s3virge/diamondstealth3000.vbi" #define ROM_VIRGE_DX L"roms/video/s3virge/86c375_1.bin" #define ROM_VIRGE_DX_VBE20 L"roms/video/s3virge/86c375_4.bin" +#if defined(DEV_BRANCH) && defined(USE_S3TRIO3D2X) #define ROM_TRIO3D_2X L"roms/video/s3virge/TRIO3D2X_8mbsdr.VBI" +#endif enum { S3_DIAMOND_STEALTH3D_2000, S3_DIAMOND_STEALTH3D_3000, S3_VIRGE_DX, - S3_VIRGE_DX_VBE20, - S3_TRIO3D_2X + S3_VIRGE_DX_VBE20 +#if defined(DEV_BRANCH) && defined(USE_S3TRIO3D2X) + , S3_TRIO3D_2X +#endif }; enum { S3_VIRGE, S3_VIRGEVX, - S3_VIRGEDX, - S3_TRIO3D2X + S3_VIRGEDX +#if defined(DEV_BRANCH) && defined(USE_S3TRIO3D2X) + , S3_TRIO3D2X +#endif }; enum @@ -154,6 +160,7 @@ typedef struct virge_t uint8_t bank; uint8_t ma_ext; + uint8_t reg6b, lfb_bios; uint8_t virge_id, virge_id_high, virge_id_low, virge_rev; @@ -396,16 +403,12 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) switch (addr) { case 0x3c5: - if (svga->seqaddr >= 0x10 && svga->seqaddr < 0x20) - { - svga->seqregs[svga->seqaddr] = val; - switch (svga->seqaddr) - { - case 0x12: case 0x13: - svga_recalctimings(svga); - return; - } - } + if (svga->seqaddr >= 0x10) + { + svga->seqregs[svga->seqaddr & 0x1f]=val; + svga_recalctimings(svga); + return; + } if (svga->seqaddr == 4) /*Chain-4 - update banking*/ { if (val & 8) @@ -422,7 +425,7 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) return; if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); + val = (svga->crtc[7] & ~0x10) | (val & 0x10); if ((svga->crtcreg >= 0x20) && (svga->crtcreg < 0x40) && (svga->crtcreg != 0x36) && (svga->crtcreg != 0x38) && (svga->crtcreg != 0x39) && ((svga->crtc[0x38] & 0xcc) != 0x48)) @@ -552,52 +555,63 @@ static uint8_t s3_virge_in(uint16_t addr, void *p) { virge_t *virge = (virge_t *)p; svga_t *svga = &virge->svga; + uint8_t ret; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; switch (addr) { - case 0x3c1: - if (svga->attraddr > 0x14) - return 0xff; - break; + case 0x3c1: + if (svga->attraddr > 0x14) + ret = 0xff; + else + ret = svga_in(addr, svga); + break; - case 0x3c5: - if (svga->seqaddr >= 0x10 && svga->seqaddr < 0x20) - return svga->seqregs[svga->seqaddr]; - break; + case 0x3c5: + if (svga->seqaddr >= 8) + ret = svga->seqregs[svga->seqaddr & 0x1f]; + else if (svga->seqaddr <= 4) + ret = svga_in(addr, svga); + else + ret = 0xff; + break; case 0x3D4: - return svga->crtcreg; + ret = svga->crtcreg; + break; case 0x3D5: switch (svga->crtcreg) { - case 0x2d: return virge->virge_id_high; /*Extended chip ID*/ - case 0x2e: return virge->virge_id_low; /*New chip ID*/ - case 0x2f: return virge->virge_rev; - case 0x30: return virge->virge_id; /*Chip ID*/ - case 0x31: return (svga->crtc[0x31] & 0xcf) | ((virge->ma_ext & 3) << 4); - case 0x35: return (svga->crtc[0x35] & 0xf0) | (virge->bank & 0xf); - case 0x45: virge->hwc_col_stack_pos = 0; break; - case 0x51: return (svga->crtc[0x51] & 0xf0) | ((virge->bank >> 2) & 0xc) | ((virge->ma_ext >> 2) & 3); - case 0x69: return virge->ma_ext; - case 0x6a: return virge->bank; - case 0x6b: return svga->crtc[0x59] & 0xfc; - case 0x6c: return 0; + case 0x2d: ret = virge->virge_id_high; break; /*Extended chip ID*/ + case 0x2e: ret = virge->virge_id_low; break; /*New chip ID*/ + case 0x2f: ret = virge->virge_rev; break; + case 0x30: ret = virge->virge_id; break; /*Chip ID*/ + case 0x31: ret = (svga->crtc[0x31] & 0xcf) | ((virge->ma_ext & 3) << 4); break; + case 0x35: ret = (svga->crtc[0x35] & 0xf0) | (virge->bank & 0xf); break; + case 0x45: virge->hwc_col_stack_pos = 0; ret = svga->crtc[0x45]; break; + case 0x51: ret = (svga->crtc[0x51] & 0xf0) | ((virge->bank >> 2) & 0xc) | ((virge->ma_ext >> 2) & 3); break; + case 0x69: ret = virge->ma_ext; break; + case 0x6a: ret = virge->bank; break; + default: ret = svga->crtc[svga->crtcreg]; break; } - return svga->crtc[svga->crtcreg]; + break; + + default: + ret = svga_in(addr, svga); + break; } - return svga_in(addr, svga);; + return ret; } static void s3_virge_recalctimings(svga_t *svga) { virge_t *virge = (virge_t *)svga->p; - + svga->hdisp = svga->hdisp_old; - if (svga->crtc[0x5d] & 0x01) svga->htotal += 0x100; + if (svga->crtc[0x5d] & 0x01) svga->htotal += 0x100; if (svga->crtc[0x5d] & 0x02) { svga->hdisp_time += 0x100; svga->hdisp += 0x100 * ((svga->seqregs[1] & 8) ? 16 : 8); @@ -615,8 +629,10 @@ static void s3_virge_recalctimings(svga_t *svga) if (virge->chip == S3_VIRGEVX || virge->chip == S3_VIRGEDX) r &= 7; +#if defined(DEV_BRANCH) && defined(USE_S3TRIO3D2X) else if (virge->chip == S3_TRIO3D2X) r &= 10; +#endif else r &= 3; @@ -641,21 +657,35 @@ static void s3_virge_recalctimings(svga_t *svga) break; case 15: svga->render = svga_render_15bpp_highres; - if (virge->chip != S3_VIRGEVX && virge->chip != S3_TRIO3D2X) { +#if defined(DEV_BRANCH) && defined(USE_S3TRIO3D2X) + if (virge->chip != S3_VIRGEVX && virge->chip != S3_TRIO3D2X) +#else + if (virge->chip != S3_VIRGEVX) +#endif + { svga->htotal >>= 1; svga->hdisp >>= 1; } break; case 16: svga->render = svga_render_16bpp_highres; - if (virge->chip != S3_VIRGEVX && virge->chip != S3_TRIO3D2X) { +#if defined(DEV_BRANCH) && defined(USE_S3TRIO3D2X) + if (virge->chip != S3_VIRGEVX && virge->chip != S3_TRIO3D2X) +#else + if (virge->chip != S3_VIRGEVX) +#endif + { svga->htotal >>= 1; svga->hdisp >>= 1; } break; - case 24: + case 24: svga->render = svga_render_24bpp_highres; +#if defined(DEV_BRANCH) && defined(USE_S3TRIO3D2X) if (virge->chip != S3_VIRGEVX && virge->chip != S3_TRIO3D2X) +#else + if (virge->chip != S3_VIRGEVX) +#endif svga->rowoffset = (svga->rowoffset * 3) / 4; /*Hack*/ break; case 32: @@ -728,8 +758,7 @@ static void s3_virge_updatemapping(virge_t *virge) s3_virge_log("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc); /*Banked framebuffer*/ - switch (svga->gdcreg[6] & 0xc) /*VGA mapping*/ - { + switch (svga->gdcreg[6] & 0xc) { /*VGA mapping*/ case 0x0: /*128k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); svga->banked_mask = 0xffff; @@ -748,11 +777,10 @@ static void s3_virge_updatemapping(virge_t *virge) break; } - virge->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); + virge->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); - s3_virge_log("Linear framebuffer %02X ", svga->crtc[0x58] & 0x10); - if ((svga->crtc[0x58] & 0x10) || (virge->advfunc_cntl & 0x10)) /*Linear framebuffer*/ - { + s3_virge_log("Linear framebuffer %02X, linear base = %08x\n", svga->crtc[0x58] & 0x10, virge->linear_base); + if ((svga->crtc[0x58] & 0x10) || (virge->advfunc_cntl & 0x10)) { /*Linear framebuffer*/ switch (svga->crtc[0x58] & 3) { case 0: /*64k*/ virge->linear_size = 0x10000; @@ -764,7 +792,11 @@ static void s3_virge_updatemapping(virge_t *virge) virge->linear_size = 0x200000; break; case 3: /*4mb*/ - if (virge->chip == S3_TRIO3D2X) +#if defined(DEV_BRANCH) && defined(USE_S3TRIO3D2X) + if (virge->chip == S3_VIRGEVX || virge->chip == S3_TRIO3D2X) +#else + if (virge->chip == S3_VIRGEVX) +#endif virge->linear_size = 0x800000; else virge->linear_size = 0x400000; @@ -773,25 +805,19 @@ static void s3_virge_updatemapping(virge_t *virge) virge->linear_base &= ~(virge->linear_size - 1); s3_virge_log("Linear framebuffer at %08X size %08X\n", virge->linear_base, virge->linear_size); if (virge->linear_base == 0xa0000) { + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); mem_mapping_disable(&virge->linear_mapping); - if (!(svga->crtc[0x53] & 0x10)) { - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - } } else mem_mapping_set_addr(&virge->linear_mapping, virge->linear_base, virge->linear_size); svga->fb_only = 1; - } - else - { + } else { mem_mapping_disable(&virge->linear_mapping); svga->fb_only = 0; } - s3_virge_log("Memory mapped IO %02X\n", svga->crtc[0x53] & 0x18); + s3_virge_log("Memory mapped IO %02X\n", svga->crtc[0x53] & 0x28); /* Memory mapped I/O. */ - /* Old MMIO. */ if ((svga->crtc[0x53] & 0x10) || (virge->advfunc_cntl & 0x20)) { if (svga->crtc[0x53] & 0x20) @@ -829,23 +855,18 @@ static uint8_t s3_virge_mmio_read(uint32_t addr, void *p) { virge_t *virge = (virge_t *)p; - uint8_t ret = 0x00; + uint8_t ret; switch (addr & 0xffff) { - case 0x8504: - ret = virge->subsys_cntl; - break; - case 0x8505: if (virge->s3d_busy || virge->virge_busy || !FIFO_EMPTY) ret = 0x10; else - ret = 0x30; - ret |= virge->subsys_stat; + ret = 0x10 | (1 << 5); if (!virge->virge_busy) wake_fifo_thread(virge); - break; + return ret; case 0x83b0: case 0x83b1: case 0x83b2: case 0x83b3: case 0x83b4: case 0x83b5: case 0x83b6: case 0x83b7: @@ -859,177 +880,269 @@ s3_virge_mmio_read(uint32_t addr, void *p) case 0x83d4: case 0x83d5: case 0x83d6: case 0x83d7: case 0x83d8: case 0x83d9: case 0x83da: case 0x83db: case 0x83dc: case 0x83dd: case 0x83de: case 0x83df: - ret = s3_virge_in(addr & 0x3ff, virge); - break; + return s3_virge_in(addr & 0x3ff, virge); } - return ret; + return 0xff; } static uint16_t s3_virge_mmio_read_w(uint32_t addr, void *p) { virge_t *virge = (virge_t *)p; - uint16_t ret = 0x0000; - - if (addr & 0x8000) - ret = s3_virge_mmio_read(addr & 0xfffe, virge) | - (s3_virge_mmio_read((addr & 0xfffe) + 1, virge) << 8); - return ret; + switch (addr & 0xfffe) { + default: + return s3_virge_mmio_read(addr, virge) | + (s3_virge_mmio_read(addr + 1, virge) << 8); + } + + return 0xffff; } + static uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p) { virge_t *virge = (virge_t *)p; - uint32_t ret = 0x00000000; - - if (addr & 0x8000) { - switch (addr & 0xfffc) { - case 0x8180: - ret = virge->streams.pri_ctrl; - break; - case 0x8184: - ret = virge->streams.chroma_ctrl; - break; - case 0x8190: - ret = virge->streams.sec_ctrl; - break; - case 0x8194: - ret = virge->streams.chroma_upper_bound; - break; - case 0x8198: - ret = virge->streams.sec_filter; - break; - case 0x81a0: - ret = virge->streams.blend_ctrl; - break; - case 0x81c0: - ret = virge->streams.pri_fb0; - break; - case 0x81c4: - ret = virge->streams.pri_fb1; - break; - case 0x81c8: - ret = virge->streams.pri_stride; - break; - case 0x81cc: - ret = virge->streams.buffer_ctrl; - break; - case 0x81d0: - ret = virge->streams.sec_fb0; - break; - case 0x81d4: - ret = virge->streams.sec_fb1; - break; - case 0x81d8: - ret = virge->streams.sec_stride; - break; - case 0x81dc: - ret = virge->streams.overlay_ctrl; - break; - case 0x81e0: - ret = virge->streams.k1_vert_scale; - break; - case 0x81e4: - ret = virge->streams.k2_vert_scale; - break; - case 0x81e8: - ret = virge->streams.dda_vert_accumulator; - break; - case 0x81ec: - ret = virge->streams.fifo_ctrl; - break; - case 0x81f0: - ret = virge->streams.pri_start; - break; - case 0x81f4: - ret = virge->streams.pri_size; - break; - case 0x81f8: - ret = virge->streams.sec_start; - break; - case 0x81fc: - ret = virge->streams.sec_size; - break; - - default: - ret = s3_virge_mmio_read(addr & 0xfffc, virge) | - (s3_virge_mmio_read((addr & 0xfffc) + 1, virge) << 8) | - (s3_virge_mmio_read((addr & 0xfffc) + 2, virge) << 16) | - (s3_virge_mmio_read((addr & 0xfffc) + 3, virge) << 24); - break; - } - } else if ((addr & 0xfffc) >= 0xa000) { - switch (addr & 0xfffc) { - case 0xa4d4: - s3_virge_wait_fifo_idle(virge); - ret = virge->s3d.src_base; - break; - case 0xa4d8: - s3_virge_wait_fifo_idle(virge); - ret = virge->s3d.dest_base; - break; - case 0xa4dc: - s3_virge_wait_fifo_idle(virge); - ret = (virge->s3d.clip_l << 16) | virge->s3d.clip_r; - break; - case 0xa4e0: - s3_virge_wait_fifo_idle(virge); - ret = (virge->s3d.clip_t << 16) | virge->s3d.clip_b; - break; - case 0xa4e4: - s3_virge_wait_fifo_idle(virge); - ret = (virge->s3d.dest_str << 16) | virge->s3d.src_str; - break; - case 0xa4e8: case 0xace8: - s3_virge_wait_fifo_idle(virge); - ret = virge->s3d.mono_pat_0; - break; - case 0xa4ec: case 0xacec: - s3_virge_wait_fifo_idle(virge); - ret = virge->s3d.mono_pat_1; - break; - case 0xa4f0: - s3_virge_wait_fifo_idle(virge); - ret = virge->s3d.pat_bg_clr; - break; - case 0xa4f4: - s3_virge_wait_fifo_idle(virge); - ret = virge->s3d.pat_fg_clr; - break; - case 0xa4f8: - s3_virge_wait_fifo_idle(virge); - ret = virge->s3d.src_bg_clr; - break; - case 0xa4fc: - s3_virge_wait_fifo_idle(virge); - ret = virge->s3d.src_fg_clr; - break; - case 0xa500: - s3_virge_wait_fifo_idle(virge); - ret = virge->s3d.cmd_set; - break; - case 0xa504: - s3_virge_wait_fifo_idle(virge); - ret = (virge->s3d.r_width << 16) | virge->s3d.r_height; - break; - case 0xa508: - s3_virge_wait_fifo_idle(virge); - ret = (virge->s3d.rsrc_x << 16) | virge->s3d.rsrc_y; - break; - case 0xa50c: - s3_virge_wait_fifo_idle(virge); - ret = (virge->s3d.rdest_x << 16) | virge->s3d.rdest_y; - break; - } + uint32_t ret = 0xffffffff; + + switch (addr & 0xfffc) { + case 0x8180: + ret = virge->streams.pri_ctrl; + break; + case 0x8184: + ret = virge->streams.chroma_ctrl; + break; + case 0x8190: + ret = virge->streams.sec_ctrl; + break; + case 0x8194: + ret = virge->streams.chroma_upper_bound; + break; + case 0x8198: + ret = virge->streams.sec_filter; + break; + case 0x81a0: + ret = virge->streams.blend_ctrl; + break; + case 0x81c0: + ret = virge->streams.pri_fb0; + break; + case 0x81c4: + ret = virge->streams.pri_fb1; + break; + case 0x81c8: + ret = virge->streams.pri_stride; + break; + case 0x81cc: + ret = virge->streams.buffer_ctrl; + break; + case 0x81d0: + ret = virge->streams.sec_fb0; + break; + case 0x81d4: + ret = virge->streams.sec_fb1; + break; + case 0x81d8: + ret = virge->streams.sec_stride; + break; + case 0x81dc: + ret = virge->streams.overlay_ctrl; + break; + case 0x81e0: + ret = virge->streams.k1_vert_scale; + break; + case 0x81e4: + ret = virge->streams.k2_vert_scale; + break; + case 0x81e8: + ret = virge->streams.dda_vert_accumulator; + break; + case 0x81ec: + ret = virge->streams.fifo_ctrl; + break; + case 0x81f0: + ret = virge->streams.pri_start; + break; + case 0x81f4: + ret = virge->streams.pri_size; + break; + case 0x81f8: + ret = virge->streams.sec_start; + break; + case 0x81fc: + ret = virge->streams.sec_size; + break; + + case 0x8504: + if (virge->s3d_busy || virge->virge_busy || !FIFO_EMPTY) + ret = (0x10 << 8); + else + ret = (0x10 << 8) | (1 << 13); + ret |= virge->subsys_stat; + if (!virge->virge_busy) + wake_fifo_thread(virge); + break; + + case 0xa4d4: + s3_virge_wait_fifo_idle(virge); + ret = virge->s3d.src_base; + break; + case 0xa4d8: + s3_virge_wait_fifo_idle(virge); + ret = virge->s3d.dest_base; + break; + case 0xa4dc: + s3_virge_wait_fifo_idle(virge); + ret = (virge->s3d.clip_l << 16) | virge->s3d.clip_r; + break; + case 0xa4e0: + s3_virge_wait_fifo_idle(virge); + ret = (virge->s3d.clip_t << 16) | virge->s3d.clip_b; + break; + case 0xa4e4: + s3_virge_wait_fifo_idle(virge); + ret = (virge->s3d.dest_str << 16) | virge->s3d.src_str; + break; + case 0xa4e8: case 0xace8: + s3_virge_wait_fifo_idle(virge); + ret = virge->s3d.mono_pat_0; + break; + case 0xa4ec: case 0xacec: + s3_virge_wait_fifo_idle(virge); + ret = virge->s3d.mono_pat_1; + break; + case 0xa4f0: + s3_virge_wait_fifo_idle(virge); + ret = virge->s3d.pat_bg_clr; + break; + case 0xa4f4: + s3_virge_wait_fifo_idle(virge); + ret = virge->s3d.pat_fg_clr; + break; + case 0xa4f8: + s3_virge_wait_fifo_idle(virge); + ret = virge->s3d.src_bg_clr; + break; + case 0xa4fc: + s3_virge_wait_fifo_idle(virge); + ret = virge->s3d.src_fg_clr; + break; + case 0xa500: + s3_virge_wait_fifo_idle(virge); + ret = virge->s3d.cmd_set; + break; + case 0xa504: + s3_virge_wait_fifo_idle(virge); + ret = (virge->s3d.r_width << 16) | virge->s3d.r_height; + break; + case 0xa508: + s3_virge_wait_fifo_idle(virge); + ret = (virge->s3d.rsrc_x << 16) | virge->s3d.rsrc_y; + break; + case 0xa50c: + s3_virge_wait_fifo_idle(virge); + ret = (virge->s3d.rdest_x << 16) | virge->s3d.rdest_y; + break; + + default: + ret = s3_virge_mmio_read_w(addr, virge) | + (s3_virge_mmio_read_w(addr + 2, virge) << 16); + break; } + + s3_virge_log("MMIO ReadL addr = %04x, val = %08x\n", addr & 0xfffc, ret); return ret; } -static void -s3_virge_write_fifo(virge_t *virge, uint32_t addr, uint8_t val) + +static void fifo_thread(void *param) { - if ((addr & 0xffff) < 0x8000) { - s3_virge_bitblt(virge, 8, val); + virge_t *virge = (virge_t *)param; + + while (1) + { + thread_set_event(virge->fifo_not_full_event); + thread_wait_event(virge->wake_fifo_thread, -1); + thread_reset_event(virge->wake_fifo_thread); + virge->virge_busy = 1; + while (!FIFO_EMPTY) + { + uint64_t start_time = plat_timer_read(); + uint64_t end_time; + uint32_t addr, val; + fifo_entry_t *fifo = &virge->fifo[virge->fifo_read_idx & FIFO_MASK]; + addr = fifo->addr_type & FIFO_ADDR; + val = fifo->val; + + switch (fifo->addr_type & FIFO_TYPE) + { + case FIFO_WRITE_BYTE: + if ((addr & 0xfffc) < 0x8000) + s3_virge_bitblt(virge, 8, val); + break; + case FIFO_WRITE_WORD: + if ((addr & 0xfffc) < 0x8000) + { + if (virge->s3d.cmd_set & CMD_SET_MS) + s3_virge_bitblt(virge, 16, ((val >> 8) | (val << 8)) << 16); + else + s3_virge_bitblt(virge, 16, val); + } + break; + case FIFO_WRITE_DWORD: + if ((addr & 0xfffc) < 0x8000) + { + if (virge->s3d.cmd_set & CMD_SET_MS) + s3_virge_bitblt(virge, 32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); + else + s3_virge_bitblt(virge, 32, val); + } + break; + } + + virge->fifo_read_idx++; + fifo->addr_type = FIFO_INVALID; + + if (FIFO_ENTRIES > 0xe000) + thread_set_event(virge->fifo_not_full_event); + + end_time = plat_timer_read(); + virge_time += end_time - start_time; + } + virge->virge_busy = 0; + virge->subsys_stat |= INT_FIFO_EMP | INT_3DF_EMP; + s3_virge_update_irqs(virge); + } +} + +static void s3_virge_queue(virge_t *virge, uint32_t addr, uint32_t val, uint32_t type) +{ + fifo_entry_t *fifo = &virge->fifo[virge->fifo_write_idx & FIFO_MASK]; + + if (FIFO_FULL) + { + thread_reset_event(virge->fifo_not_full_event); + if (FIFO_FULL) + { + thread_wait_event(virge->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ + } + } + + fifo->val = val; + fifo->addr_type = (addr & FIFO_ADDR) | type; + + virge->fifo_write_idx++; + + if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) + wake_fifo_thread(virge); +} + +static void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p) +{ + virge_t *virge = (virge_t *)p; + s3_virge_log("MMIO WriteB addr = %04x, val = %02x\n", addr & 0xffff, val); + + if ((addr & 0xfffc) < 0x8000) { + s3_virge_queue(virge, addr, val, FIFO_WRITE_BYTE); } else { switch (addr & 0xffff) { case 0x83b0: case 0x83b1: case 0x83b2: case 0x83b3: @@ -1046,44 +1159,43 @@ s3_virge_write_fifo(virge_t *virge, uint32_t addr, uint8_t val) case 0x83dc: case 0x83dd: case 0x83de: case 0x83df: s3_virge_out(addr & 0x3ff, val, virge); break; - case 0x8504: - virge->subsys_stat &= ~val; - s3_virge_update_irqs(virge); - break; - case 0x8505: - virge->subsys_cntl = val; - s3_virge_update_irqs(virge); - break; - case 0x850c: - virge->advfunc_cntl = val; - s3_virge_updatemapping(virge); - break; } } } static void -s3_virge_write_fifo_w(virge_t *virge, uint32_t addr, uint16_t val) +s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p) { - if ((addr & 0xfffe) < 0x8000) { - if (virge->s3d.cmd_set & CMD_SET_MS) { - s3_virge_bitblt(virge, 16, ((val >> 8) | (val << 8)) << 16); - } else { - s3_virge_bitblt(virge, 16, val); - } + virge_t *virge = (virge_t *)p; + s3_virge_log("MMIO WriteW addr = %04x, val = %04x\n", addr & 0xfffe, val); + if ((addr & 0xfffc) < 0x8000) { + s3_virge_queue(virge, addr, val, FIFO_WRITE_WORD); } else { - s3_virge_mmio_write(addr & 0xfffe, val, virge); - s3_virge_mmio_write((addr & 0xfffe) + 1, val >> 8, virge); + if ((addr & 0xfffe) == 0x83d4) { + s3_virge_mmio_write(addr, val, virge); + s3_virge_mmio_write(addr + 1, val >> 8, virge); + } } } static void -s3_virge_write_fifo_l(virge_t *virge, uint32_t addr, uint32_t val) +s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) { + virge_t *virge = (virge_t *)p; svga_t *svga = &virge->svga; - if ((addr & 0xfffc) >= 0x8000 && (addr & 0xfffc) < 0xa000) { - switch (addr & 0xfffc) { + s3_virge_log("MMIO WriteL addr = %04x, val = %08x\n", addr & 0xfffc, val); + if ((addr & 0xfffc) < 0x8000) { + if ((addr & 0xe000) == 0) { + if (virge->s3d.cmd_set & CMD_SET_MS) + s3_virge_bitblt(virge, 32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); + else + s3_virge_bitblt(virge, 32, val); + } else { + s3_virge_queue(virge, addr, val, FIFO_WRITE_DWORD); + } + } else { + switch (addr & 0xfffc) { case 0x8180: virge->streams.pri_ctrl = val; svga_recalctimings(svga); @@ -1199,22 +1311,17 @@ s3_virge_write_fifo_l(virge_t *virge, uint32_t addr, uint32_t val) svga->fullchange = changeframecount; break; - default: - s3_virge_mmio_write(addr & 0xfffc, val, virge); - s3_virge_mmio_write((addr & 0xfffc) + 1, val >> 8, virge); - s3_virge_mmio_write((addr & 0xfffc) + 2, val >> 16, virge); - s3_virge_mmio_write((addr & 0xfffc) + 3, val >> 24, virge); + case 0x8504: + virge->subsys_stat &= ~(val & 0xff); + virge->subsys_cntl = (val >> 8); + s3_virge_update_irqs(virge); break; - } - } else if ((addr & 0xfffc) < 0x8000) { - if (virge->s3d.cmd_set & CMD_SET_MS) { - s3_virge_bitblt(virge, 32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); - } else { - s3_virge_bitblt(virge, 32, val); - } - } else if ((addr & 0xfffc) >= 0xa000) { - switch (addr & 0xfffc) - { + + case 0x850c: + virge->advfunc_cntl = val & 0xff; + s3_virge_updatemapping(virge); + break; + case 0xa000: case 0xa004: case 0xa008: case 0xa00c: case 0xa010: case 0xa014: case 0xa018: case 0xa01c: case 0xa020: case 0xa024: case 0xa028: case 0xa02c: @@ -1517,94 +1624,10 @@ s3_virge_write_fifo_l(virge_t *virge, uint32_t addr, uint32_t val) if (virge->s3d_tri.cmd_set & CMD_SET_AE) queue_triangle(virge); break; - } + } } } -static void fifo_thread(void *param) -{ - virge_t *virge = (virge_t *)param; - - while (1) - { - thread_set_event(virge->fifo_not_full_event); - thread_wait_event(virge->wake_fifo_thread, -1); - thread_reset_event(virge->wake_fifo_thread); - virge->virge_busy = 1; - while (!FIFO_EMPTY) - { - uint64_t start_time = plat_timer_read(); - uint64_t end_time; - fifo_entry_t *fifo = &virge->fifo[virge->fifo_read_idx & FIFO_MASK]; - - switch (fifo->addr_type & FIFO_TYPE) - { - case FIFO_WRITE_BYTE: - s3_virge_write_fifo(virge, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_WRITE_WORD: - s3_virge_write_fifo_w(virge, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_WRITE_DWORD: - s3_virge_write_fifo_l(virge, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - } - - virge->fifo_read_idx++; - fifo->addr_type = FIFO_INVALID; - - if (FIFO_ENTRIES > 0xe000) - thread_set_event(virge->fifo_not_full_event); - - end_time = plat_timer_read(); - virge_time += end_time - start_time; - } - virge->virge_busy = 0; - virge->subsys_stat |= INT_FIFO_EMP; - s3_virge_update_irqs(virge); - } -} - -static void s3_virge_queue(virge_t *virge, uint32_t addr, uint32_t val, uint32_t type) -{ - fifo_entry_t *fifo = &virge->fifo[virge->fifo_write_idx & FIFO_MASK]; - - if (FIFO_FULL) - { - thread_reset_event(virge->fifo_not_full_event); - if (FIFO_FULL) - { - thread_wait_event(virge->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ - } - } - - fifo->val = val; - fifo->addr_type = (addr & FIFO_ADDR) | type; - - virge->fifo_write_idx++; - - if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) - wake_fifo_thread(virge); -} - -static void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p) -{ - virge_t *virge = (virge_t *)p; - s3_virge_queue(virge, addr & 0xffff, val, FIFO_WRITE_BYTE); -} -static void -s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p) -{ - virge_t *virge = (virge_t *)p; - s3_virge_queue(virge, addr & 0xffff, val, FIFO_WRITE_WORD); -} -static void -s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) -{ - virge_t *virge = (virge_t *)p; - s3_virge_queue(virge, addr & 0xffff, val, FIFO_WRITE_DWORD); -} - #define READ(addr, val) \ { \ switch (bpp) \ @@ -1698,14 +1721,14 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) svga_t *svga = &virge->svga; uint8_t *vram = virge->svga.vram; uint32_t mono_pattern[64]; - int count_mask = -1; + int count_mask; int x_inc = (virge->s3d.cmd_set & CMD_SET_XP) ? 1 : -1; int y_inc = (virge->s3d.cmd_set & CMD_SET_YP) ? 1 : -1; - int bpp = -1; - int x_mul = -1; - int cpu_dat_shift = 0; - uint32_t *pattern_data = NULL; - uint32_t src_fg_clr = 0, src_bg_clr = 0; + int bpp; + int x_mul; + int cpu_dat_shift; + uint32_t *pattern_data; + uint32_t src_fg_clr, src_bg_clr; uint32_t src_addr; uint32_t dest_addr; uint32_t source = 0, dest = 0, pattern; @@ -1731,6 +1754,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) src_bg_clr = virge->s3d.src_bg_clr & 0xffff; break; case CMD_SET_FORMAT_24: + default: bpp = 2; x_mul = 3; cpu_dat_shift = 24; @@ -1751,6 +1775,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) count_mask = ~0xf; break; case CMD_SET_ITA_DWORD: + default: count_mask = ~0x1f; break; } @@ -1816,7 +1841,6 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) READ(src_addr, source); if ((virge->s3d.cmd_set & CMD_SET_TP) && source == src_fg_clr) update = 0; - count--; break; case CMD_SET_IDS: if (virge->s3d.data_left_count) @@ -1880,9 +1904,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) virge->s3d.w = virge->s3d.r_width; virge->s3d.src_y += y_inc; - virge->s3d.src_y &= 0x7ff; virge->s3d.dest_y += y_inc; - virge->s3d.dest_y &= 0x7ff; virge->s3d.h--; switch (virge->s3d.cmd_set & (CMD_SET_MS | CMD_SET_IDS)) @@ -3050,25 +3072,41 @@ static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) tex_sample = virge->bilinear_enabled ? tex_sample_normal_filter : tex_sample_normal; break; case (0 | 8): case (1 | 8): - if (virge->chip == S3_VIRGEDX || virge->chip == S3_TRIO3D2X) +#if defined(DEV_BRANCH) && defined(USE_S3TRIO3D2X) + if (virge->chip == S3_VIRGEDX || virge->chip == S3_TRIO3D2X) +#else + if (virge->chip == S3_VIRGEDX) +#endif tex_sample = tex_sample_persp_mipmap_375; else tex_sample = tex_sample_persp_mipmap; break; case (2 | 8): case (3 | 8): - if (virge->chip == S3_VIRGEDX || virge->chip == S3_TRIO3D2X) +#if defined(DEV_BRANCH) && defined(USE_S3TRIO3D2X) + if (virge->chip == S3_VIRGEDX || virge->chip == S3_TRIO3D2X) +#else + if (virge->chip == S3_VIRGEDX) +#endif tex_sample = virge->bilinear_enabled ? tex_sample_persp_mipmap_filter_375 : tex_sample_persp_mipmap_375; else tex_sample = virge->bilinear_enabled ? tex_sample_persp_mipmap_filter : tex_sample_persp_mipmap; break; case (4 | 8): case (5 | 8): - if (virge->chip == S3_VIRGEDX || virge->chip == S3_TRIO3D2X) +#if defined(DEV_BRANCH) && defined(USE_S3TRIO3D2X) + if (virge->chip == S3_VIRGEDX || virge->chip == S3_TRIO3D2X) +#else + if (virge->chip == S3_VIRGEDX) +#endif tex_sample = tex_sample_persp_normal_375; else tex_sample = tex_sample_persp_normal; break; case (6 | 8): case (7 | 8): - if (virge->chip == S3_VIRGEDX || virge->chip == S3_TRIO3D2X) +#if defined(DEV_BRANCH) && defined(USE_S3TRIO3D2X) + if (virge->chip == S3_VIRGEDX || virge->chip == S3_TRIO3D2X) +#else + if (virge->chip == S3_VIRGEDX) +#endif tex_sample = virge->bilinear_enabled ? tex_sample_persp_normal_filter_375 : tex_sample_persp_normal_375; else tex_sample = virge->bilinear_enabled ? tex_sample_persp_normal_filter : tex_sample_persp_normal; @@ -3496,45 +3534,46 @@ static uint8_t s3_virge_pci_read(int func, int addr, void *p) { virge_t *virge = (virge_t *)p; svga_t *svga = &virge->svga; - switch (addr) - { - case 0x00: return 0x33; /*'S3'*/ - case 0x01: return 0x53; - - case 0x02: return virge->virge_id_low; - case 0x03: return virge->virge_id_high; + uint8_t ret = 0; - case PCI_REG_COMMAND: - return virge->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ + switch (addr) { + case 0x00: ret = 0x33; break; /*'S3'*/ + case 0x01: ret = 0x53; break; - case 0x07: return 1 << 1; /*Medium DEVSEL timing*/ + case 0x02: ret = virge->virge_id_low; break; + case 0x03: ret = virge->virge_id_high; break; + + case PCI_REG_COMMAND: ret = virge->pci_regs[PCI_REG_COMMAND] & 0x27; break; + + case 0x07: ret = virge->pci_regs[0x07] & 0x36; break; - case 0x08: return 0; /*Revision ID*/ - case 0x09: return 0; /*Programming interface*/ + case 0x08: ret = 0; break; /*Revision ID*/ + case 0x09: ret = 0; break; /*Programming interface*/ - case 0x0a: return 0x00; /*Supports VGA interface*/ - case 0x0b: return 0x03; + case 0x0a: ret = 0x00; break; /*Supports VGA interface*/ + case 0x0b: ret = 0x03; break; - case 0x0d: return virge->pci_regs[0x0d] & 0xf8; + case 0x0d: ret = virge->pci_regs[0x0d] & 0xf8; break; - case 0x10: return 0x00; /*Linear frame buffer address*/ - case 0x11: return 0x00; - case 0x12: return 0x00; - case 0x13: return svga->crtc[0x59] & 0xfc; + case 0x10: ret = 0x00; break;/*Linear frame buffer address*/ + case 0x11: ret = 0x00; break; + case 0x12: ret = 0x00; break; + case 0x13: ret = svga->crtc[0x59] & 0xfc; break; - case 0x30: return virge->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ - case 0x31: return 0x00; - case 0x32: return virge->pci_regs[0x32]; - case 0x33: return virge->pci_regs[0x33]; + case 0x30: ret = virge->pci_regs[0x30] & 0x01; break; /*BIOS ROM address*/ + case 0x31: ret = 0x00; break; + case 0x32: ret = virge->pci_regs[0x32]; break; + case 0x33: ret = virge->pci_regs[0x33]; break; - case 0x3c: return virge->int_line; - case 0x3d: return PCI_INTA; + case 0x3c: ret = virge->pci_regs[0x3c]; break; + + case 0x3d: ret = PCI_INTA; break; /*INTA*/ - case 0x3e: return 0x04; - case 0x3f: return 0xff; + case 0x3e: ret = 0x04; break; + case 0x3f: ret = 0xff; break; } - return 0; + return ret; } static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) @@ -3543,8 +3582,12 @@ static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) svga_t *svga = &virge->svga; switch (addr) { + case 0x00: case 0x01: case 0x02: case 0x03: + case 0x08: case 0x09: case 0x0a: case 0x0b: + case 0x3d: case 0x3e: case 0x3f: + return; + case PCI_REG_COMMAND: - virge->pci_regs[PCI_REG_COMMAND] = val & 0x27; if (val & PCI_COMMAND_IO) { io_removehandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); @@ -3552,19 +3595,20 @@ static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) } else io_removehandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); - s3_virge_updatemapping(virge); - break; + virge->pci_regs[PCI_REG_COMMAND] = val & 0x27; + s3_virge_updatemapping(virge); + return; case 0x07: virge->pci_regs[0x07] = val & 0x3e; - break; - case 0x0d: + return; + case 0x0d: virge->pci_regs[0x0d] = val & 0xf8; - break; + return; - case 0x13: - svga->crtc[0x59] = val & 0xfc; - s3_virge_updatemapping(virge); - break; + case 0x13: + svga->crtc[0x59] = val & 0xfc; + s3_virge_updatemapping(virge); + return; case 0x30: case 0x32: case 0x33: virge->pci_regs[addr] = val; @@ -3579,7 +3623,7 @@ static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) } return; case 0x3c: - virge->int_line = val; + virge->pci_regs[0x3c] = val; return; } } @@ -3608,9 +3652,11 @@ static void *s3_virge_init(const device_t *info) case S3_VIRGE_DX_VBE20: bios_fn = ROM_VIRGE_DX_VBE20; break; +#if defined(DEV_BRANCH) && defined(USE_S3TRIO3D2X) case S3_TRIO3D_2X: bios_fn = ROM_TRIO3D_2X; break; +#endif default: free(virge); return NULL; @@ -3621,7 +3667,6 @@ static void *s3_virge_init(const device_t *info) s3_virge_in, s3_virge_out, s3_virge_hwcursor_draw, s3_virge_overlay_draw); - virge->svga.vblank_start = s3_virge_vblank_start; virge->pci = !!(info->flags & DEVICE_PCI); @@ -3659,49 +3704,56 @@ static void *s3_virge_init(const device_t *info) io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); - virge->pci_regs[0x04] = 7; + virge->pci_regs[PCI_REG_COMMAND] = 3; virge->pci_regs[0x05] = 0; virge->pci_regs[0x06] = 0; virge->pci_regs[0x07] = 2; - virge->pci_regs[0x30] = 0x00; virge->pci_regs[0x32] = 0x0c; - virge->pci_regs[0x33] = 0x00; virge->pci_regs[0x3d] = 1; virge->pci_regs[0x3e] = 4; virge->pci_regs[0x3f] = 0xff; virge->virge_rev = 0; virge->virge_id = 0xe1; - - virge->int_line = 0; switch (virge->memory_size) { case 2: + virge->svga.vram_mask = (2 << 20) - 1; + virge->svga.vram_max = 2 << 20; if (virge->pci) virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (4 << 5); else virge->svga.crtc[0x36] = 1 | (0 << 2) | (1 << 4) | (4 << 5); break; + case 8: + virge->svga.vram_mask = (8 << 20) - 1; + virge->svga.vram_max = 8 << 20; + if (virge->pci) + virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (3 << 5); + else + virge->svga.crtc[0x36] = 1 | (0 << 2) | (1 << 4) | (3 << 5); + break; case 4: default: + virge->svga.vram_mask = (4 << 20) - 1; + virge->svga.vram_max = 4 << 20; if (virge->pci) virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); else virge->svga.crtc[0x36] = 1 | (0 << 2) | (1 << 4) | (0 << 5); break; - case 8: - virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (3 << 5); - break; } - virge->svga.crtc[0x37] = 1 | (7 << 5); - virge->svga.crtc[0x59] = virge->pci ? 0x70 : 0x0a; + virge->svga.crtc[0x37] = 1; + virge->svga.crtc[0x53] = 8; switch(info->local) { case S3_DIAMOND_STEALTH3D_2000: + virge->svga.decode_mask = (4 << 20) - 1; virge->virge_id_high = 0x56; virge->virge_id_low = 0x31; + virge->svga.crtc[0x59] = virge->pci ? 0x70 : 0x0a; virge->chip = S3_VIRGE; if (info->flags & DEVICE_PCI) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_diamond_stealth3d_2000_pci); @@ -3709,23 +3761,36 @@ static void *s3_virge_init(const device_t *info) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_diamond_stealth3d_2000_vlb); break; case S3_DIAMOND_STEALTH3D_3000: + virge->svga.decode_mask = (8 << 20) - 1; virge->virge_id_high = 0x88; virge->virge_id_low = 0x3d; + virge->svga.crtc[0x59] = virge->pci ? 0x70 : 0x0a; virge->chip = S3_VIRGEVX; if (info->flags & DEVICE_PCI) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_diamond_stealth3d_3000_pci); else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_diamond_stealth3d_3000_vlb); break; +#if defined(DEV_BRANCH) && defined(USE_S3TRIO3D2X) case S3_TRIO3D_2X: + virge->svga.decode_mask = (8 << 20) - 1; virge->virge_id_high = 0x8a; virge->virge_id_low = 0x13; + virge->svga.crtc[0x6c] = 1; + virge->svga.crtc[0x59] = 0x70; + virge->svga.vblank_start = s3_virge_vblank_start; virge->chip = S3_TRIO3D2X; video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_virge_dx_pci); break; +#endif + default: + virge->svga.decode_mask = (4 << 20) - 1; virge->virge_id_high = 0x8a; virge->virge_id_low = 0x01; + virge->svga.crtc[0x6c] = 1; + virge->svga.crtc[0x59] = virge->pci ? 0x70 : 0x0a; + virge->svga.vblank_start = s3_virge_vblank_start; virge->chip = S3_VIRGEDX; if (info->flags & DEVICE_PCI) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_virge_dx_pci); @@ -3787,10 +3852,12 @@ static int s3_virge_375_4_available(void) return rom_present(ROM_VIRGE_DX_VBE20); } +#if defined(DEV_BRANCH) && defined(USE_S3TRIO3D2X) static int s3_trio3d_2x_available(void) { return rom_present(ROM_TRIO3D_2X); } +#endif static void s3_virge_speed_changed(void *p) { @@ -3833,6 +3900,37 @@ static const device_config_t s3_virge_config[] = } }; +static const device_config_t s3_virge_vx_config[] = +{ + { + "memory", "Memory size", CONFIG_SELECTION, "", 4, + { + { + "2 MB", 2 + }, + { + "4 MB", 4 + }, + { + "8 MB", 8 + }, + { + "" + } + } + }, + { + "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 + }, + { + "dithering", "Dithering", CONFIG_BINARY, "", 1 + }, + { + "", "", -1 + } +}; + +#if defined(DEV_BRANCH) && defined(USE_S3TRIO3D2X) static const device_config_t s3_trio3d_2x_config[] = { { @@ -3859,6 +3957,7 @@ static const device_config_t s3_trio3d_2x_config[] = "", "", -1 } }; +#endif const device_t s3_virge_vlb_device = { @@ -3899,7 +3998,7 @@ const device_t s3_virge_988_vlb_device = s3_virge_988_available, s3_virge_speed_changed, s3_virge_force_redraw, - s3_virge_config + s3_virge_vx_config }; const device_t s3_virge_988_pci_device = @@ -3913,7 +4012,7 @@ const device_t s3_virge_988_pci_device = s3_virge_988_available, s3_virge_speed_changed, s3_virge_force_redraw, - s3_virge_config + s3_virge_vx_config }; const device_t s3_virge_375_vlb_device = @@ -3972,6 +4071,7 @@ const device_t s3_virge_375_4_pci_device = s3_virge_config }; +#if defined(DEV_BRANCH) && defined(USE_S3TRIO3D2X) const device_t s3_trio3d_2x_pci_device = { "S3 Trio3D/2X PCI", @@ -3985,3 +4085,4 @@ const device_t s3_trio3d_2x_pci_device = s3_virge_force_redraw, s3_trio3d_2x_config }; +#endif diff --git a/src/video/vid_table.c b/src/video/vid_table.c index ef3c5942e..ce00f5b05 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -88,10 +88,11 @@ video_cards[] = { { "[ISA] Hercules Plus", "hercules_plus", &herculesplus_device }, { "[ISA] Hercules InColor", "incolor", &incolor_device }, { "[ISA] Image Manager 1024", "im1024", &im1024_device }, - { "[ISA] Schetmash Iskra EGA (Cyrillic ROM)", "iskra_ega", &iskra_ega_device }, + { "[ISA] Schetmash Iskra EGA (Cyrillic ROM)", "iskra_ega", &iskra_ega_device }, { "[ISA] Kasan Hangulmadang-16 VGA (ET4000AX)", "kasan16vga", &et4000_kasan_isa_device }, { "[ISA] MDA", "mda", &mda_device }, { "[ISA] MDSI Genius", "genius", &genius_device }, + { "[ISA] Metheus Premier 928 (S3 86c928)", "metheus928_isa", &s3_metheus_86c928_isa_device }, { "[ISA] OAK OTI-037C", "oti037c", &oti037c_device }, { "[ISA] OAK OTI-067", "oti067", &oti067_device }, { "[ISA] OAK OTI-077", "oti077", &oti077_device }, @@ -135,7 +136,9 @@ video_cards[] = { { "[PCI] Phoenix S3 Vision864", "px_vision864_pci", &s3_phoenix_vision864_pci_device }, { "[PCI] Phoenix S3 Trio32", "px_trio32_pci", &s3_phoenix_trio32_pci_device }, { "[PCI] Phoenix S3 Trio64", "px_trio64_pci", &s3_phoenix_trio64_pci_device }, +#if defined(DEV_BRANCH) && defined(USE_S3TRIO3D2X) { "[PCI] S3 Trio3D/2X", "trio3d2x", &s3_trio3d_2x_pci_device }, +#endif { "[PCI] S3 Trio64V2/DX", "trio64v2dx_pci", &s3_trio64v2_dx_pci_device }, { "[PCI] S3 ViRGE/DX", "virge375_pci", &s3_virge_375_pci_device }, { "[PCI] S3 ViRGE/DX (VBE 2.0)", "virge375_vbe20_pci", &s3_virge_375_4_pci_device }, @@ -156,6 +159,7 @@ video_cards[] = { { "[VLB] Diamond Stealth 3D 3000 (S3 ViRGE/VX)", "stealth3d_3000_vlb", &s3_virge_988_vlb_device }, { "[VLB] Diamond Stealth 64 DRAM (S3 Trio64)", "stealth64d_vlb", &s3_diamond_stealth64_vlb_device }, { "[VLB] Diamond Stealth 64 VRAM (S3 Vision964)", "stealth64v_vlb", &s3_diamond_stealth64_964_vlb_device }, + { "[VLB] Metheus Premier 928 (S3 86c928)", "metheus928_vlb", &s3_metheus_86c928_vlb_device }, { "[VLB] Number Nine 9FX (S3 Trio64)", "n9_9fx_vlb", &s3_9fx_vlb_device }, { "[VLB] Paradise Bahamas 64 (S3 Vision864)", "bahamas64_vlb", &s3_bahamas64_vlb_device }, { "[VLB] Phoenix S3 86c805", "px_86c805_vlb", &s3_phoenix_86c805_vlb_device }, diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index fcd35a524..67669f3bd 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -72,6 +72,9 @@ ifeq ($(DEV_BUILD), y) ifndef VECTRA54 VECTRA54 := y endif + ifndef S3TRIO3D2X + S3TRIO3D2X := y + endif ifndef SIEMENS SIEMENS := y endif @@ -151,6 +154,9 @@ else ifndef VECTRA54 VECTRA54 := n endif + ifndef S3TRIO3D2X + S3TRIO3D2X := n + endif ifndef SIEMENS SIEMENS := n endif @@ -550,6 +556,10 @@ ifeq ($(VECTRA54), y) OPTS += -DUSE_VECTRA54 endif +ifeq ($(S3TRIO3D2X), y) +OPTS += -DUSE_S3TRIO3D2X +endif + ifeq ($(SIEMENS), y) OPTS += -DUSE_SIEMENS endif From 64fa9a9526d1030599f332d8ec72509dd605bde7 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 4 Oct 2020 19:56:03 +0200 Subject: [PATCH 02/12] Added the Phoenix S3 Trio64V+ card. --- src/include/86box/video.h | 2 + src/video/vid_s3.c | 635 ++++++++++++++++++++++++++------------ src/video/vid_table.c | 4 +- 3 files changed, 441 insertions(+), 200 deletions(-) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index ced613608..42fae633b 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -312,6 +312,8 @@ extern const device_t s3_phoenix_trio32_pci_device; extern const device_t s3_phoenix_trio64_vlb_device; extern const device_t s3_phoenix_trio64_onboard_pci_device; extern const device_t s3_phoenix_trio64_pci_device; +extern const device_t s3_phoenix_trio64vplus_vlb_device; +extern const device_t s3_phoenix_trio64vplus_pci_device; extern const device_t s3_phoenix_vision864_pci_device; extern const device_t s3_phoenix_vision864_vlb_device; extern const device_t s3_diamond_stealth64_pci_device; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 1bdbeff18..718b2717d 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -47,6 +47,7 @@ #define ROM_PHOENIX_TRIO64 L"roms/video/s3/86c764x1.bin" #define ROM_DIAMOND_STEALTH64_764 L"roms/video/s3/stealt64.bin" #define ROM_TRIO64V2_DX_VBE20 L"roms/video/s3/86c775_2.bin" +#define ROM_PHOENIX_TRIO64VPLUS L"roms/video/s3/octekmirage64.vbi" enum { @@ -64,6 +65,7 @@ enum S3_METHEUS_86C928, S3_AMI_86C924, S3_TRIO64V2_DX, + S3_PHOENIX_TRIO64VPLUS }; @@ -78,6 +80,7 @@ enum S3_VISION864, S3_TRIO32 = 0x18, S3_TRIO64, + S3_TRIO64V, S3_TRIO64V2 }; @@ -403,6 +406,7 @@ s3_data_len(s3_t *s3) static uint16_t s3_accel_pix_trans_w(s3_t *s3, uint16_t port, uint16_t val) { + svga_t *svga = &s3->svga; int i, word = 0; int s3dl, bswap; @@ -456,6 +460,8 @@ s3_accel_pix_trans_w(s3_t *s3, uint16_t port, uint16_t val) /* Normal dword mode, do 1 dword blit if (port & 2). */ if (port & 2) s3_accel_start(32, 1, s3->accel.pix_trans.dw, 0, s3); + else if (svga->crtc[0x53] & 0x08) + s3_accel_start(32, 1, val | (val << 16), 0, s3); break; } } else { @@ -472,6 +478,8 @@ s3_accel_pix_trans_w(s3_t *s3, uint16_t port, uint16_t val) /* Normal dword mode, do 1 dword blit if (port & 2). */ if (port & 2) s3_accel_start(4, 1, 0xffffffff, s3->accel.pix_trans.dw, s3); + else if (svga->crtc[0x53] & 0x08) + s3_accel_start(4, 1, 0xffffffff, val | (val << 16), s3); break; } } @@ -998,6 +1006,8 @@ s3_accel_out_fifo_l(s3_t *s3, uint16_t port, uint32_t val) static void s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) { + svga_t *svga = &s3->svga; + if (s3->packed_mmio) { int addr_lo = addr & 1; switch (addr & 0xfffe) { @@ -1082,8 +1092,15 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) addr |= addr_lo; } - if (addr & 0x8000) { - if (s3->chip == S3_TRIO64V2) { + if (svga->crtc[0x53] & 0x08) { + if ((addr & 0xffff) < 0x8000) { + if (s3_cpu_src(s3)) { + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) + s3_accel_start(8, 1, val | (val << 8) | (val << 16) | (val << 24), 0, s3); + else + s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); + } + } else { switch (addr & 0xffff) { case 0x83b0: case 0x83b1: case 0x83b2: case 0x83b3: case 0x83b4: case 0x83b5: case 0x83b6: case 0x83b7: @@ -1106,7 +1123,7 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) case 0x8505: s3->subsys_cntl = val; s3_update_irqs(s3); - break; + break; case 0x850c: s3->accel.advfunc_cntl = val; s3_updatemapping(s3); @@ -1115,26 +1132,47 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) s3_accel_out_fifo(s3, addr & 0xffff, val); break; } - } else - s3_accel_out_fifo(s3, addr & 0xffff, val); - } else { - if (s3_cpu_src(s3)) { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) - s3_accel_start(8, 1, val | (val << 8) | (val << 16) | (val << 24), 0, s3); - else - s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); } + } else { + if (addr & 0x8000) { + s3_accel_out_fifo(s3, addr & 0xffff, val); + } else { + if (s3_cpu_src(s3)) { + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) + s3_accel_start(8, 1, val | (val << 8) | (val << 16) | (val << 24), 0, s3); + else + s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); + } + } } } static void s3_accel_write_fifo_w(s3_t *s3, uint32_t addr, uint16_t val) -{ - if (addr & 0x8000) { - s3_accel_write_fifo(s3, addr, val); - s3_accel_write_fifo(s3, addr + 1, val >> 8); - } else if (s3_cpu_src(s3)) - (void) s3_accel_pix_trans_w(s3, addr & 0xfffe, val); +{ + svga_t *svga = &s3->svga; + + if (svga->crtc[0x53] & 0x08) { + if ((addr & 0xfffe) < 0x8000) { + if (s3_cpu_src(s3)) { + (void) s3_accel_pix_trans_w(s3, addr & 0xfffe, val); + } + } else { + switch (addr & 0xfffe) { + case 0x83d4: + default: + s3_accel_write_fifo(s3, addr, val); + s3_accel_write_fifo(s3, addr + 1, val >> 8); + break; + } + } + } else { + if (addr & 0x8000) { + s3_accel_write_fifo(s3, addr, val); + s3_accel_write_fifo(s3, addr + 1, val >> 8); + } else if (s3_cpu_src(s3)) + (void) s3_accel_pix_trans_w(s3, addr & 0xfffe, val); + } } @@ -1143,8 +1181,12 @@ s3_accel_write_fifo_l(s3_t *s3, uint32_t addr, uint32_t val) { svga_t *svga = &s3->svga; - if (addr & 0x8000) { - if (s3->chip == S3_TRIO64V2) { + if (svga->crtc[0x53] & 0x08) { + if ((addr & 0xfffc) < 0x8000) { + if (s3_cpu_src(s3)) { + (void) s3_accel_pix_trans_l(s3, addr & 0xfffc, val); + } + } else { switch (addr & 0xfffc) { case 0x8180: s3->streams.pri_ctrl = val; @@ -1261,21 +1303,34 @@ s3_accel_write_fifo_l(s3_t *s3, uint32_t addr, uint32_t val) svga->fullchange = changeframecount; break; + case 0x8504: + s3->subsys_stat &= ~(val & 0xff); + s3->subsys_cntl = (val >> 8); + s3_update_irqs(s3); + break; + + case 0x850c: + s3->accel.advfunc_cntl = val & 0xff; + s3_updatemapping(s3); + break; + default: s3_accel_write_fifo(s3, addr, val); s3_accel_write_fifo(s3, addr + 1, val >> 8); s3_accel_write_fifo(s3, addr + 2, val >> 16); s3_accel_write_fifo(s3, addr + 3, val >> 24); break; - } - } else { + } + } + } else { + if (addr & 0x8000) { s3_accel_write_fifo(s3, addr, val); s3_accel_write_fifo(s3, addr + 1, val >> 8); s3_accel_write_fifo(s3, addr + 2, val >> 16); s3_accel_write_fifo(s3, addr + 3, val >> 24); - } - } else if (s3_cpu_src(s3)) - (void) s3_accel_pix_trans_l(s3, addr & 0xfffc, val); + } else if (s3_cpu_src(s3)) + (void) s3_accel_pix_trans_l(s3, addr & 0xfffc, val); + } } static void @@ -1798,7 +1853,7 @@ s3_io_set_alt(s3_t *s3) io_sethandler(0x4148, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0x4548, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0x4948, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - if (s3->chip == S3_TRIO64 || s3->chip == S3_TRIO64V2) + if (s3->chip == S3_TRIO64 || s3->chip == S3_TRIO64V) { io_sethandler(0x8148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0x8548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); @@ -1844,7 +1899,7 @@ s3_io_set(s3_t *s3) io_sethandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - if (s3->chip == S3_TRIO64 || s3->chip == S3_TRIO64V2) + if (s3->chip == S3_TRIO64 || s3->chip == S3_TRIO64V) { io_sethandler(0x82e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0x86e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); @@ -1903,15 +1958,24 @@ s3_out(uint16_t addr, uint8_t val, void *p) break; case 0x3c5: - if (svga->seqaddr >= 0x10 && svga->seqaddr < 0x20) - { - svga->seqregs[svga->seqaddr] = val; - switch (svga->seqaddr) + if (s3->chip >= S3_TRIO64V) { + if (svga->seqaddr >= 0x10) { - case 0x12: case 0x13: + svga->seqregs[svga->seqaddr & 0x1f]=val; svga_recalctimings(svga); return; } + } else { + if (svga->seqaddr >= 0x10 && svga->seqaddr < 0x20) + { + svga->seqregs[svga->seqaddr] = val; + switch (svga->seqaddr) + { + case 0x12: case 0x13: + svga_recalctimings(svga); + return; + } + } } if (svga->seqaddr == 4) /*Chain-4 - update banking*/ { @@ -2170,8 +2234,17 @@ s3_in(uint16_t addr, void *p) break; case 0x3c5: - if (svga->seqaddr >= 0x10 && svga->seqaddr < 0x20) - return svga->seqregs[svga->seqaddr]; + if (s3->chip >= S3_TRIO64V) { + if (svga->seqaddr >= 8) + return svga->seqregs[svga->seqaddr & 0x1f]; + else if (svga->seqaddr <= 4) + return svga_in(addr, svga); + else + return 0xff; + } else { + if (svga->seqaddr >= 0x10 && svga->seqaddr < 0x20) + return svga->seqregs[svga->seqaddr]; + } break; case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: @@ -2196,7 +2269,7 @@ s3_in(uint16_t addr, void *p) { case 0x2d: return (s3->chip == S3_TRIO64V2) ? 0x89 : 0x88; /*Extended chip ID*/ case 0x2e: return s3->id_ext; /*New chip ID*/ - case 0x2f: return 0; /*Revision level*/ + case 0x2f: return (s3->chip == S3_TRIO64V) ? 0x40 : 0; /*Revision level*/ case 0x30: return s3->id; /*Chip ID*/ case 0x31: return (svga->crtc[0x31] & 0xcf) | ((s3->ma_ext & 3) << 4); case 0x35: return (svga->crtc[0x35] & 0xf0) | (s3->bank & 0xf); @@ -2213,8 +2286,8 @@ s3_in(uint16_t addr, void *p) case 0x6a: return s3->bank; /* Phoenix S3 video BIOS'es seem to expect CRTC registers 6B and 6C to be mirrors of 59 and 5A. */ - case 0x6b: return svga->crtc[0x59]; - case 0x6c: return svga->crtc[0x5a] & 0x80; + case 0x6b: return (s3->chip >= S3_TRIO64V) ? (svga->crtc[0x59] & 0xfc) : svga->crtc[0x59]; + case 0x6c: return (s3->chip >= S3_TRIO64V) ? 0 : (svga->crtc[0x5a] & 0x80); } return svga->crtc[svga->crtcreg]; } @@ -2319,6 +2392,14 @@ static void s3_trio64v_recalctimings(svga_t *svga) svga->interlace = svga->crtc[0x42] & 0x20; svga->clock = (cpuclock * (double)(1ull << 32)) / svga->getclock(clk_sel, svga->clock_gen); + + if (s3->chip == S3_TRIO64V) { + switch (svga->crtc[0x67] >> 4) { + case 3: case 5: case 7: + svga->clock /= 2; + break; + } + } if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/ { @@ -2349,7 +2430,8 @@ static void s3_trio64v_recalctimings(svga_t *svga) break; } } - svga->vram_display_mask = (!(svga->crtc[0x31] & 0x08) && (svga->crtc[0x32] & 0x40)) ? 0x3ffff : s3->vram_mask; + if (s3->chip == S3_TRIO64V2) + svga->vram_display_mask = (!(svga->crtc[0x31] & 0x08) && (svga->crtc[0x32] & 0x40)) ? 0x3ffff : s3->vram_mask; } else /*Streams mode*/ { @@ -2395,7 +2477,9 @@ static void s3_trio64v_recalctimings(svga_t *svga) svga->render = svga_render_32bpp_highres; break; } - svga->vram_display_mask = s3->vram_mask; + + if (s3->chip == S3_TRIO64V2) + svga->vram_display_mask = s3->vram_mask; } } @@ -2453,8 +2537,7 @@ s3_updatemapping(s3_t *s3) if ((svga->crtc[0x58] & 0x10) || (s3->accel.advfunc_cntl & 0x10)) { /*Linear framebuffer*/ - if (s3->chip != S3_TRIO64V2) - mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&svga->mapping); switch (svga->crtc[0x58] & 3) { @@ -2470,6 +2553,7 @@ s3_updatemapping(s3_t *s3) case 3: /*8mb*/ switch (s3->chip) { /* Not on video cards that don't support 4MB*/ case S3_TRIO64: + case S3_TRIO64V: case S3_TRIO64V2: case S3_86C928: s3->linear_size = 0x400000; @@ -2484,12 +2568,10 @@ s3_updatemapping(s3_t *s3) s3->linear_base &= ~(s3->linear_size - 1); if (s3->linear_base == 0xa0000) { mem_mapping_disable(&s3->linear_mapping); - if (!(svga->crtc[0x53] & 0x10) && (s3->chip != S3_TRIO64V2)) + if (!(svga->crtc[0x53] & 0x10)) { mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; - } else if (s3->chip == S3_TRIO64V2) { - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); } } else { mem_mapping_set_addr(&s3->linear_mapping, s3->linear_base, s3->linear_size); @@ -2500,23 +2582,20 @@ s3_updatemapping(s3_t *s3) /* Memory mapped I/O. */ if ((svga->crtc[0x53] & 0x10) || (s3->accel.advfunc_cntl & 0x20)) { - if (s3->chip != S3_TRIO64V2) { - mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&svga->mapping); + if (svga->crtc[0x53] & 0x20) + mem_mapping_set_addr(&s3->mmio_mapping, 0xb8000, 0x8000); + else mem_mapping_set_addr(&s3->mmio_mapping, 0xa0000, 0x10000); - } else { - if (svga->crtc[0x53] & 0x20) - mem_mapping_set_addr(&s3->mmio_mapping, 0xb8000, 0x8000); - else - mem_mapping_set_addr(&s3->mmio_mapping, 0xa0000, 0x10000); - } } else { mem_mapping_disable(&s3->mmio_mapping); } /* New MMIO. */ - if (svga->crtc[0x53] & 0x08) + if (svga->crtc[0x53] & 0x08) { + mem_mapping_disable(&svga->mapping); mem_mapping_set_addr(&s3->new_mmio_mapping, s3->linear_base + 0x1000000, 0x10000); - else + } else mem_mapping_disable(&s3->new_mmio_mapping); } } @@ -2543,7 +2622,8 @@ s3_enable_fifo(s3_t *s3) { svga_t *svga = &s3->svga; - if ((s3->chip == S3_TRIO32) || (s3->chip == S3_TRIO64) || (s3->chip == S3_TRIO64V2) || + if ((s3->chip == S3_TRIO32) || (s3->chip == S3_TRIO64) || + (s3->chip == S3_TRIO64V) || (s3->chip == S3_TRIO64V2) || (s3->chip == S3_VISION864) || (s3->chip == S3_VISION964)) return 1; /* FIFO always enabled on these chips. */ @@ -2681,7 +2761,7 @@ s3_accel_in(uint16_t port, void *p) temp = 0; /* FIFO empty */ if (!s3->blitter_busy) wake_fifo_thread(s3); - if (FIFO_FULL && (s3->chip >= S3_VISION864)) + if (FIFO_FULL && (s3->chip >= S3_VISION964)) temp = 0xff; /*FIFO full*/ return temp; /*FIFO empty*/ case 0x9949: case 0x9ae9: @@ -2698,7 +2778,7 @@ s3_accel_in(uint16_t port, void *p) temp |= 0x01; /*Read Data available*/ s3->data_available = 0; } - if (FIFO_FULL && s3->chip >= S3_VISION864) + if (FIFO_FULL && s3->chip >= S3_VISION964) temp |= 0xf8; /*FIFO full*/ } else { if (s3->busy || s3->force_busy) { @@ -2966,49 +3046,47 @@ static uint8_t s3_accel_read(uint32_t addr, void *p) { s3_t *s3 = (s3_t *)p; + svga_t *svga = &s3->svga; uint8_t temp = 0x00; if (!s3->enable_8514) return 0xff; - if (addr & 0x8000) { - if (s3->chip == S3_TRIO64V2) { - switch (addr & 0xffff) { - case 0x83b0: case 0x83b1: case 0x83b2: case 0x83b3: - case 0x83b4: case 0x83b5: case 0x83b6: case 0x83b7: - case 0x83b8: case 0x83b9: case 0x83ba: case 0x83bb: - case 0x83bc: case 0x83bd: case 0x83be: case 0x83bf: - case 0x83c0: case 0x83c1: case 0x83c2: case 0x83c3: - case 0x83c4: case 0x83c5: case 0x83c6: case 0x83c7: - case 0x83c8: case 0x83c9: case 0x83ca: case 0x83cb: - case 0x83cc: case 0x83cd: case 0x83ce: case 0x83cf: - case 0x83d0: case 0x83d1: case 0x83d2: case 0x83d3: - case 0x83d4: case 0x83d5: case 0x83d6: case 0x83d7: - case 0x83d8: case 0x83d9: case 0x83da: case 0x83db: - case 0x83dc: case 0x83dd: case 0x83de: case 0x83df: - temp = s3_in(addr & 0x3ff, s3); - break; - case 0x8504: - temp = s3->subsys_stat; - break; - case 0x8505: - temp = s3->subsys_cntl; - break; - default: - temp = s3_accel_in(addr & 0xffff, s3); - break; - } - } else { - temp = s3_accel_in(addr & 0xffff, s3); + if (svga->crtc[0x53] & 0x08) { + switch (addr & 0xffff) { + case 0x83b0: case 0x83b1: case 0x83b2: case 0x83b3: + case 0x83b4: case 0x83b5: case 0x83b6: case 0x83b7: + case 0x83b8: case 0x83b9: case 0x83ba: case 0x83bb: + case 0x83bc: case 0x83bd: case 0x83be: case 0x83bf: + case 0x83c0: case 0x83c1: case 0x83c2: case 0x83c3: + case 0x83c4: case 0x83c5: case 0x83c6: case 0x83c7: + case 0x83c8: case 0x83c9: case 0x83ca: case 0x83cb: + case 0x83cc: case 0x83cd: case 0x83ce: case 0x83cf: + case 0x83d0: case 0x83d1: case 0x83d2: case 0x83d3: + case 0x83d4: case 0x83d5: case 0x83d6: case 0x83d7: + case 0x83d8: case 0x83d9: case 0x83da: case 0x83db: + case 0x83dc: case 0x83dd: case 0x83de: case 0x83df: + return s3_in(addr & 0x3ff, s3); + case 0x8504: + return s3->subsys_stat; + case 0x8505: + return s3->subsys_cntl;; + default: + return s3_accel_in(addr & 0xffff, s3); } - } else if (s3_cpu_dest(s3)) { - temp = s3->accel.pix_trans.b[addr & 3]; + return 0xff; + } else { + if (addr & 0x8000) { + temp = s3_accel_in(addr & 0xffff, s3); + } else if (s3_cpu_dest(s3)) { + temp = s3->accel.pix_trans.b[addr & 3]; - if (s3->accel.cmd & 0x100) { + if (s3->accel.cmd & 0x100) { if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) - s3_accel_start(8, 1, 0xffffffff, 0, s3); + s3_accel_start(8, 1, 0xffffffff, 0, s3); else - s3_accel_start(1, 1, 0xffffffff, 0xffffffff, s3); + s3_accel_start(1, 1, 0xffffffff, 0xffffffff, s3); + } } } @@ -3019,16 +3097,26 @@ static uint16_t s3_accel_read_w(uint32_t addr, void *p) { s3_t *s3 = (s3_t *)p; + svga_t *svga = &s3->svga; uint16_t temp = 0x0000; if (!s3->enable_8514) return 0xffff; - - if (addr & 0x8000) { - temp = s3_accel_read((addr & 0xfffe), p); - temp |= s3_accel_read((addr & 0xfffe) + 1, p) << 8; - } else if (s3_cpu_dest(s3)) - temp = s3_accel_pix_trans_w(s3, (addr & 0xfffe), 0xffff); + + if (svga->crtc[0x53] & 0x08) { + switch (addr & 0xfffe) { + default: + return s3_accel_read(addr, p) | + s3_accel_read(addr + 1, p) << 8; + } + return 0xffff; + } else { + if (addr & 0x8000) { + temp = s3_accel_read((addr & 0xfffe), p); + temp |= s3_accel_read((addr & 0xfffe) + 1, p) << 8; + } else if (s3_cpu_dest(s3)) + temp = s3_accel_pix_trans_w(s3, (addr & 0xfffe), 0xffff); + } return temp; } @@ -3038,96 +3126,94 @@ static uint32_t s3_accel_read_l(uint32_t addr, void *p) { s3_t *s3 = (s3_t *)p; + svga_t *svga = &s3->svga; uint32_t temp = 0x00000000; if (!s3->enable_8514) return 0xffffffff; - if (addr & 0x8000) { - if (s3->chip == S3_TRIO64V2) { - switch (addr & 0xfffc) { - case 0x8180: - temp = s3->streams.pri_ctrl; - break; - case 0x8184: - temp = s3->streams.chroma_ctrl; - break; - case 0x8190: - temp = s3->streams.sec_ctrl; - break; - case 0x8194: - temp = s3->streams.chroma_upper_bound; - break; - case 0x8198: - temp = s3->streams.sec_filter; - break; - case 0x81a0: - temp = s3->streams.blend_ctrl; - break; - case 0x81c0: - temp = s3->streams.pri_fb0; - break; - case 0x81c4: - temp = s3->streams.pri_fb1; - break; - case 0x81c8: - temp = s3->streams.pri_stride; - break; - case 0x81cc: - temp = s3->streams.buffer_ctrl; - break; - case 0x81d0: - temp = s3->streams.sec_fb0; - break; - case 0x81d4: - temp = s3->streams.sec_fb1; - break; - case 0x81d8: - temp = s3->streams.sec_stride; - break; - case 0x81dc: - temp = s3->streams.overlay_ctrl; - break; - case 0x81e0: - temp = s3->streams.k1_vert_scale; - break; - case 0x81e4: - temp = s3->streams.k2_vert_scale; - break; - case 0x81e8: - temp = s3->streams.dda_vert_accumulator; - break; - case 0x81ec: - temp = s3->streams.fifo_ctrl; - break; - case 0x81f0: - temp = s3->streams.pri_start; - break; - case 0x81f4: - temp = s3->streams.pri_size; - break; - case 0x81f8: - temp = s3->streams.sec_start; - break; - case 0x81fc: - temp = s3->streams.sec_size; - break; - - default: - temp = s3_accel_read((addr & 0xfffc), p); - temp |= s3_accel_read((addr & 0xfffc) + 1, p) << 8; - temp |= s3_accel_read((addr & 0xfffc) + 2, p) << 16; - temp |= s3_accel_read((addr & 0xfffc) + 3, p) << 24; - break; - } - } else { - temp = s3_accel_read((addr & 0xfffc), p); - temp |= s3_accel_read((addr & 0xfffc) + 1, p) << 8; - temp |= s3_accel_read((addr & 0xfffc) + 2, p) << 16; - temp |= s3_accel_read((addr & 0xfffc) + 3, p) << 24; + if (svga->crtc[0x53] & 0x08) { + switch (addr & 0xfffc) { + case 0x8180: + temp = s3->streams.pri_ctrl; + break; + case 0x8184: + temp = s3->streams.chroma_ctrl; + break; + case 0x8190: + temp = s3->streams.sec_ctrl; + break; + case 0x8194: + temp = s3->streams.chroma_upper_bound; + break; + case 0x8198: + temp = s3->streams.sec_filter; + break; + case 0x81a0: + temp = s3->streams.blend_ctrl; + break; + case 0x81c0: + temp = s3->streams.pri_fb0; + break; + case 0x81c4: + temp = s3->streams.pri_fb1; + break; + case 0x81c8: + temp = s3->streams.pri_stride; + break; + case 0x81cc: + temp = s3->streams.buffer_ctrl; + break; + case 0x81d0: + temp = s3->streams.sec_fb0; + break; + case 0x81d4: + temp = s3->streams.sec_fb1; + break; + case 0x81d8: + temp = s3->streams.sec_stride; + break; + case 0x81dc: + temp = s3->streams.overlay_ctrl; + break; + case 0x81e0: + temp = s3->streams.k1_vert_scale; + break; + case 0x81e4: + temp = s3->streams.k2_vert_scale; + break; + case 0x81e8: + temp = s3->streams.dda_vert_accumulator; + break; + case 0x81ec: + temp = s3->streams.fifo_ctrl; + break; + case 0x81f0: + temp = s3->streams.pri_start; + break; + case 0x81f4: + temp = s3->streams.pri_size; + break; + case 0x81f8: + temp = s3->streams.sec_start; + break; + case 0x81fc: + temp = s3->streams.sec_size; + break; + + default: + temp = s3_accel_read_w(addr, p) | (s3_accel_read_w(addr + 2, p) << 16); + break; } - } else if (s3_cpu_dest(s3)) - temp = s3_accel_pix_trans_l(s3, (addr & 0xfffc), 0xffffffff); + } else { + if (addr & 0x8000) { + temp = s3_accel_read((addr & 0xfffc), p); + temp |= s3_accel_read((addr & 0xfffc) + 1, p) << 8; + temp |= s3_accel_read((addr & 0xfffc) + 2, p) << 16; + temp |= s3_accel_read((addr & 0xfffc) + 3, p) << 24; + } else if (s3_cpu_dest(s3)) + temp = s3_accel_pix_trans_l(s3, (addr & 0xfffc), 0xffffffff); + } return temp; } @@ -3246,11 +3332,11 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ int cmd = s3->accel.cmd >> 13; int read = 0, byte_cnt = 0, i; - if ((s3->chip == S3_TRIO64 || s3->chip == S3_TRIO64V2) && (s3->accel.cmd & (1 << 11))) + if ((s3->chip >= S3_TRIO64) && (s3->accel.cmd & (1 << 11))) cmd |= 8; if ((s3_cpu_src(s3) || s3_cpu_dest(s3))) { - if (s3->accel.pixtrans_failed) { + if (s3->accel.pixtrans_failed) { /*Some hack for some 911/924 driver*/ if (s3->busy) s3->busy = 0; if (cpu_input) @@ -3374,7 +3460,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ } else /*Bresenham*/ { - if (s3->accel.sy < 0 && cpu_input) { + if (s3->accel.sy < 0 && cpu_input && !(svga->crtc[0x53] & 0x08)) { s3->busy = 0; s3->accel.cur_x = s3->accel.cx; s3->accel.cur_y = s3->accel.cy; @@ -3476,14 +3562,14 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ } frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - + bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; + s3->accel.pix_trans.b[0] = 0xff; s3->accel.pix_trans.b[1] = 0xff; s3->accel.pix_trans.b[2] = 0xff; s3->accel.pix_trans.b[3] = 0xff; - - if ((s3->accel.sy < 0 && cpu_input)) { + + if ((s3->accel.sy < 0 && cpu_input) && !(svga->crtc[0x53] & 0x08)) { s3->busy = 0; s3->accel.cur_x = s3->accel.cx; s3->accel.cur_y = s3->accel.cy; @@ -3626,7 +3712,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if (!cpu_input && frgd_mix == 3 && !vram_mask && !compare_mode && (s3->accel.cmd & 0xa0) == 0xa0 && (s3->accel.frgd_mix & 0xf) == 7) - { while (1) { @@ -3886,7 +3971,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ { int end_y1, end_y2; - if (s3->chip != S3_TRIO64 && s3->chip != S3_TRIO64V2) + if (s3->chip != S3_TRIO64) break; polygon_setup(s3); @@ -3961,7 +4046,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ { int end_y1, end_y2; - if (s3->chip != S3_TRIO64 && s3->chip != S3_TRIO64V2) + if (s3->chip != S3_TRIO64) break; polygon_setup(s3); @@ -4059,7 +4144,7 @@ s3_pci_read(int func, int addr, void *p) case 0x01: return 0x53; case 0x02: return s3->id_ext_pci; - case 0x03: return (s3->chip == S3_TRIO64V2) ? 0x89 : 0x88; + case 0x03: return 0x88; case PCI_REG_COMMAND: return s3->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ @@ -4086,7 +4171,7 @@ s3_pci_read(int func, int addr, void *p) case 0x11: return 0x00; case 0x12: return svga->crtc[0x5a] & 0x80; case 0x13: return svga->crtc[0x59]; - + case 0x30: return s3->has_bios ? (s3->pci_regs[0x30] & 0x01) : 0x00; /*BIOS ROM address*/ case 0x31: return 0x00; case 0x32: return s3->has_bios ? s3->pci_regs[0x32] : 0x00; @@ -4118,6 +4203,7 @@ s3_pci_write(int func, int addr, uint8_t val, void *p) svga->crtc[0x5a] = (svga->crtc[0x5a] & 0x7f) | (val & 0x80); s3_updatemapping(s3); break; + case 0x13: svga->crtc[0x59] = val; s3_updatemapping(s3); @@ -4144,6 +4230,103 @@ s3_pci_write(int func, int addr, uint8_t val, void *p) } } +static uint8_t s3_trio64v_pci_read(int func, int addr, void *p) +{ + s3_t *s3 = (s3_t *)p; + svga_t *svga = &s3->svga; + uint8_t ret = 0; + + switch (addr) { + case 0x00: ret = 0x33; break; /*'S3'*/ + case 0x01: ret = 0x53; break; + + case 0x02: ret = s3->id_ext_pci; break; + case 0x03: ret = s3->chip == S3_TRIO64V ? 0x88 : 0x89; break; + + case PCI_REG_COMMAND: ret = s3->pci_regs[PCI_REG_COMMAND] & 0x27; break; + + case 0x07: ret = s3->pci_regs[0x07] & 0x36; break; + + case 0x08: ret = (s3->chip == S3_TRIO64V) ? 0x40 : 0; break; /*Revision ID*/ + case 0x09: ret = 0; break; /*Programming interface*/ + + case 0x0a: ret = 0x00; break; /*Supports VGA interface*/ + case 0x0b: ret = 0x03; break; + + case 0x0d: ret = s3->pci_regs[0x0d] & 0xf8; break; + + case 0x10: ret = 0x00; break;/*Linear frame buffer address*/ + case 0x11: ret = 0x00; break; + case 0x12: ret = 0x00; break; + case 0x13: ret = svga->crtc[0x59] & 0xfc; break; + + case 0x30: ret = s3->has_bios ? (s3->pci_regs[0x30] & 0x01) : 0x00; break; /*BIOS ROM address*/ + case 0x31: ret = 0x00; break; + case 0x32: ret = s3->has_bios ? s3->pci_regs[0x32] : 0x00; break; + case 0x33: ret = s3->has_bios ? s3->pci_regs[0x33] : 0x00; break; + + case 0x3c: ret = s3->int_line; break; + + case 0x3d: ret = PCI_INTA; break; /*INTA*/ + + case 0x3e: ret = 0x04; break; + case 0x3f: ret = 0xff; break; + + } + return ret; +} + +static void s3_trio64v_pci_write(int func, int addr, uint8_t val, void *p) +{ + s3_t *s3 = (s3_t *)p; + svga_t *svga = &s3->svga; + switch (addr) + { + case 0x00: case 0x01: case 0x02: case 0x03: + case 0x08: case 0x09: case 0x0a: case 0x0b: + case 0x3d: case 0x3e: case 0x3f: + return; + + case PCI_REG_COMMAND: + if (val & PCI_COMMAND_IO) + s3_io_set(s3); + else + s3_io_remove(s3); + s3->pci_regs[PCI_REG_COMMAND] = val & 0x27; + s3_updatemapping(s3); + return; + case 0x07: + s3->pci_regs[0x07] = val & 0x3e; + return; + case 0x0d: + s3->pci_regs[0x0d] = val & 0xf8; + return; + + case 0x13: + svga->crtc[0x59] = val & 0xfc; + s3_updatemapping(s3); + return; + + case 0x30: case 0x32: case 0x33: + if (!s3->has_bios) + return; + s3->pci_regs[addr] = val; + if (s3->pci_regs[0x30] & 0x01) + { + uint32_t biosaddr = (s3->pci_regs[0x32] << 16) | (s3->pci_regs[0x33] << 24); + mem_mapping_set_addr(&s3->bios_rom.mapping, biosaddr, 0x8000); + } + else + { + mem_mapping_disable(&s3->bios_rom.mapping); + } + return; + case 0x3c: + s3->int_line = val; + return; + } +} + static int vram_sizes[] = { 7, /*512 kB*/ @@ -4243,6 +4426,14 @@ static void *s3_init(const device_t *info) else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_vlb); break; + case S3_PHOENIX_TRIO64VPLUS: + bios_fn = ROM_PHOENIX_TRIO64VPLUS; + chip = S3_TRIO64V; + if (info->flags & DEVICE_PCI) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_pci); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_vlb); + break; case S3_DIAMOND_STEALTH64_764: bios_fn = ROM_DIAMOND_STEALTH64_764; chip = S3_TRIO64; @@ -4292,7 +4483,7 @@ static void *s3_init(const device_t *info) mem_mapping_add(&s3->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, - NULL, 0, &s3->svga); + NULL, MEM_MAPPING_EXTERNAL, &s3->svga); mem_mapping_add(&s3->mmio_mapping, 0, 0, s3_accel_read, s3_accel_read_w, s3_accel_read_l, s3_accel_write, s3_accel_write_w, s3_accel_write_l, @@ -4310,7 +4501,7 @@ static void *s3_init(const device_t *info) NULL, NULL); else { - if (chip == S3_TRIO64V2) { + if (chip == S3_TRIO64V2 || chip == S3_TRIO64V) { svga_init(info, &s3->svga, s3, vram_size, s3_trio64v_recalctimings, s3_in, s3_out, @@ -4377,10 +4568,22 @@ static void *s3_init(const device_t *info) s3_io_set(s3); - if (s3->pci) - s3->card = pci_add_card(PCI_ADD_VIDEO, s3_pci_read, s3_pci_write, s3); - - s3->pci_regs[0x04] = 7; + if (s3->pci) { + if (chip >= S3_TRIO64V) + s3->card = pci_add_card(PCI_ADD_VIDEO, s3_trio64v_pci_read, s3_trio64v_pci_write, s3); + else + s3->card = pci_add_card(PCI_ADD_VIDEO, s3_pci_read, s3_pci_write, s3); + } + if (chip >= S3_TRIO64V) { + s3->pci_regs[PCI_REG_COMMAND] = 3; + s3->pci_regs[0x05] = 0; + s3->pci_regs[0x06] = 0; + s3->pci_regs[0x3d] = 1; + s3->pci_regs[0x3e] = 4; + s3->pci_regs[0x3f] = 0xff; + } else { + s3->pci_regs[PCI_REG_COMMAND] = 7; + } s3->pci_regs[0x30] = 0x00; s3->pci_regs[0x32] = 0x0c; @@ -4483,7 +4686,7 @@ static void *s3_init(const device_t *info) case S3_DIAMOND_STEALTH64_964: svga->decode_mask = (8 << 20) - 1; - stepping = 0xd0; /*Vision964P*/ + stepping = 0xd0; /*Vision964*/ s3->id = stepping; s3->id_ext = s3->id_ext_pci = stepping; s3->packed_mmio = 1; @@ -4507,6 +4710,7 @@ static void *s3_init(const device_t *info) case S3_PHOENIX_TRIO64: case S3_PHOENIX_TRIO64_ONBOARD: + case S3_PHOENIX_TRIO64VPLUS: case S3_DIAMOND_STEALTH64_764: if (device_get_config_int("memory") == 1) s3->svga.vram_max = 1 << 20; /* Phoenix BIOS does not expect VRAM to be mirrored. */ @@ -4595,6 +4799,11 @@ static int s3_phoenix_trio64_available(void) return rom_present(ROM_PHOENIX_TRIO64); } +static int s3_phoenix_trio64vplus_available(void) +{ + return rom_present(ROM_PHOENIX_TRIO64VPLUS); +} + static int s3_diamond_stealth64_764_available(void) { return rom_present(ROM_DIAMOND_STEALTH64_764); @@ -4999,6 +5208,34 @@ const device_t s3_phoenix_trio64_pci_device = s3_config }; +const device_t s3_phoenix_trio64vplus_vlb_device = +{ + "Phoenix S3 Trio64V+ VLB", + DEVICE_VLB, + S3_PHOENIX_TRIO64VPLUS, + s3_init, + s3_close, + NULL, + s3_phoenix_trio64vplus_available, + s3_speed_changed, + s3_force_redraw, + s3_config +}; + +const device_t s3_phoenix_trio64vplus_pci_device = +{ + "Phoenix S3 Trio64V+ PCI", + DEVICE_PCI, + S3_PHOENIX_TRIO64VPLUS, + s3_init, + s3_close, + NULL, + s3_phoenix_trio64vplus_available, + s3_speed_changed, + s3_force_redraw, + s3_config +}; + const device_t s3_phoenix_vision864_vlb_device = { "Phoenix S3 Vision864 VLB", diff --git a/src/video/vid_table.c b/src/video/vid_table.c index ce00f5b05..922ccf5d1 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -136,10 +136,11 @@ video_cards[] = { { "[PCI] Phoenix S3 Vision864", "px_vision864_pci", &s3_phoenix_vision864_pci_device }, { "[PCI] Phoenix S3 Trio32", "px_trio32_pci", &s3_phoenix_trio32_pci_device }, { "[PCI] Phoenix S3 Trio64", "px_trio64_pci", &s3_phoenix_trio64_pci_device }, + { "[PCI] Phoenix S3 Trio64V+", "px_trio64vplus_pci", &s3_phoenix_trio64vplus_pci_device }, #if defined(DEV_BRANCH) && defined(USE_S3TRIO3D2X) { "[PCI] S3 Trio3D/2X", "trio3d2x", &s3_trio3d_2x_pci_device }, #endif - { "[PCI] S3 Trio64V2/DX", "trio64v2dx_pci", &s3_trio64v2_dx_pci_device }, + { "[PCI] S3 Trio64V2/DX", "trio64v2dx_pci", &s3_trio64v2_dx_pci_device }, { "[PCI] S3 ViRGE/DX", "virge375_pci", &s3_virge_375_pci_device }, { "[PCI] S3 ViRGE/DX (VBE 2.0)", "virge375_vbe20_pci", &s3_virge_375_4_pci_device }, { "[PCI] STB Nitro 64V (CL-GD 5446)", "cl_gd5446_stb_pci", &gd5446_stb_pci_device }, @@ -166,6 +167,7 @@ video_cards[] = { { "[VLB] Phoenix S3 Vision864", "px_vision864_vlb", &s3_phoenix_vision864_vlb_device }, { "[VLB] Phoenix S3 Trio32", "px_trio32_vlb", &s3_phoenix_trio32_vlb_device }, { "[VLB] Phoenix S3 Trio64", "px_trio64_vlb", &s3_phoenix_trio64_vlb_device }, + { "[VLB] Phoenix S3 Trio64V+", "px_trio64vplus_vlb", &s3_phoenix_trio64vplus_vlb_device }, { "[VLB] S3 ViRGE/DX", "virge375_vlb", &s3_virge_375_vlb_device }, { "[VLB] S3 ViRGE/DX (VBE 2.0)", "virge375_vbe20_vlb", &s3_virge_375_4_vlb_device }, { "[VLB] Trident TGUI9400CXi", "tgui9400cxi_vlb", &tgui9400cxi_device }, From 945ec153505d18c1294d7db5b0096a445cbd0237 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 6 Oct 2020 18:06:08 +0200 Subject: [PATCH 03/12] Built-in video card device fixes from selected machines, such as Tandy and Olivetti. Added the Compaq Deskpro BIOS from 1987 (8086, not 386). Added the Trident TVGA9000B video card and fixed some anomalies with the TVGA8900B. --- src/include/86box/machine.h | 8 ++- src/include/86box/video.h | 1 + src/machine/m_olivetti_m24.c | 6 ++ src/machine/m_tandy.c | 6 ++ src/machine/m_xt_compaq.c | 30 ++++++++- src/machine/machine_table.c | 9 +-- src/video/vid_table.c | 1 + src/video/vid_tvga.c | 125 +++++++++++++++++++++++++++-------- 8 files changed, 152 insertions(+), 34 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index c0bc68eaa..ce290780c 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -387,6 +387,7 @@ extern int machine_at_ficva502_init(const machine_t *); extern int machine_at_ficpa2012_init(const machine_t *); #ifdef EMU_DEVICE_H +extern const device_t *at_thor_get_device(void); extern const device_t *at_pb640_get_device(void); #endif @@ -458,6 +459,9 @@ extern const device_t europc_device; /* m_oivetti_m24.c */ extern int machine_olim24_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t *m24_get_device(void); +#endif /* m_pcjr.c */ extern int machine_pcjr_init(const machine_t *); @@ -502,6 +506,7 @@ extern int machine_tandy1000sl2_init(const machine_t *); #ifdef EMU_DEVICE_H extern const device_t *tandy1k_get_device(void); extern const device_t *tandy1k_hx_get_device(void); +extern const device_t *tandy1k_sl_get_device(void); #endif /* m_xt.c */ @@ -527,7 +532,8 @@ extern int machine_xt_hed919_init(const machine_t *); #endif /* m_xt_compaq.c */ -extern int machine_xt_compaq_init(const machine_t *); +extern int machine_xt_compaq_deskpro_init(const machine_t *); +extern int machine_xt_compaq_portable_init(const machine_t *); /* m_xt_laserxt.c */ #if defined(DEV_BRANCH) && defined(USE_LASERXT) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 42fae633b..9499823a6 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -349,6 +349,7 @@ extern const device_t ibm_ps1_2121_device; /* Trident TVGA 8900 */ extern const device_t tvga8900b_device; extern const device_t tvga8900d_device; +extern const device_t tvga9000b_device; /* IBM VGA */ extern const device_t vga_device; diff --git a/src/machine/m_olivetti_m24.c b/src/machine/m_olivetti_m24.c index 8d8c94229..c01363167 100644 --- a/src/machine/m_olivetti_m24.c +++ b/src/machine/m_olivetti_m24.c @@ -818,6 +818,12 @@ const device_t m24_device = { NULL }; +const device_t * +m24_get_device(void) +{ + return &m24_device; +} + static void kbd_reset(void *priv) diff --git a/src/machine/m_tandy.c b/src/machine/m_tandy.c index 26777dc77..44fc7f533 100644 --- a/src/machine/m_tandy.c +++ b/src/machine/m_tandy.c @@ -1192,6 +1192,12 @@ tandy1k_hx_get_device(void) return &vid_device_hx; } +const device_t * +tandy1k_sl_get_device(void) +{ + return &vid_device_sl; +} + static void eep_write(uint16_t addr, uint8_t val, void *priv) diff --git a/src/machine/m_xt_compaq.c b/src/machine/m_xt_compaq.c index 1b84a10de..da41a4a41 100644 --- a/src/machine/m_xt_compaq.c +++ b/src/machine/m_xt_compaq.c @@ -37,9 +37,37 @@ #include <86box/lpt.h> #include <86box/machine.h> +int +machine_xt_compaq_deskpro_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/deskpro/Compaq - BIOS - Revision J - 106265-002.bin", + 0x000fe000, 8192, 0); + + if (bios_only || !ret) + return ret; + + machine_common_init(model); + + pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_xt); + + device_add(&keyboard_xt_compaq_device); + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_xt_device); + nmi_init(); + if (joystick_type != JOYSTICK_TYPE_NONE) + device_add(&gameport_device); + + lpt1_remove(); + lpt1_init(0x03bc); + + return ret; +} + int -machine_xt_compaq_init(const machine_t *model) +machine_xt_compaq_portable_init(const machine_t *model) { int ret; diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index f04a925f3..5ad457624 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -97,7 +97,7 @@ const machine_t machines[] = { { "[8088] AMI XT clone", "amixt", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_amixt_init, NULL }, { "[8088] Tandy 1000", "tandy", MACHINE_TYPE_8088, {{"Intel", cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 128, 640, 128, 0, machine_tandy_init, tandy1k_get_device }, { "[8088] Tandy 1000 HX", "tandy1000hx", MACHINE_TYPE_8088, {{"Intel", cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 256, 640, 128, 0, machine_tandy1000hx_init, tandy1k_hx_get_device }, - { "[8088] Compaq Portable", "portable", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO, 128, 640, 128, 0, machine_xt_compaq_init, NULL }, + { "[8088] Compaq Portable", "portable", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 128, 640, 128, 0, machine_xt_compaq_portable_init, NULL }, { "[8088] Generic XT clone", "genxt", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_genxt_init, NULL }, { "[8088] DTK XT clone", "dtk", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_dtk_init, NULL }, { "[8088] Juko XT clone", "jukopc", MACHINE_TYPE_8088, {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_jukopc_init, NULL }, @@ -118,9 +118,10 @@ const machine_t machines[] = { { "[8086] Amstrad PC3086", "pc3086", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 640, 640, 0, 63, machine_pc3086_init, pc3086_get_device }, { "[8086] Amstrad PC20(0)", "pc200", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE | MACHINE_NONMI, 512, 640, 128, 63, machine_pc200_init, pc200_get_device }, { "[8086] Amstrad PPC512/640", "ppc512", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE | MACHINE_NONMI, 512, 640, 128, 63, machine_ppc512_init, ppc512_get_device }, - { "[8086] Olivetti M24", "olivetti_m24", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 128, 640, 128, 0, machine_olim24_init, NULL }, + { "[8086] Compaq Deskpro", "deskpro", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 128, 640, 128, 0, machine_xt_compaq_deskpro_init, NULL }, + { "[8086] Olivetti M24", "olivetti_m24", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 128, 640, 128, 0, machine_olim24_init, m24_get_device }, { "[8086] Schetmash Iskra-3104", "iskra3104", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 128, 640, 128, 0, machine_xt_iskra3104_init, NULL }, - { "[8086] Tandy 1000 SL/2", "tandy1000sl2", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 512, 768, 128, 0, machine_tandy1000sl2_init, NULL }, + { "[8086] Tandy 1000 SL/2", "tandy1000sl2", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 512, 768, 128, 0, machine_tandy1000sl2_init, tandy1k_sl_get_device }, { "[8086] Toshiba T1200", "t1200", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO, 1024, 2048,1024, 63, machine_xt_t1200_init, t1200_get_device }, #if defined(DEV_BRANCH) && defined(USE_LASERXT) { "[8086] VTech Laser XT3", "lxt3", MACHINE_TYPE_8086, {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 256, 640, 256, 0, machine_xt_lxt3_init, NULL }, @@ -285,7 +286,7 @@ const machine_t machines[] = { { "[i430FX] ASUS P/I-P54TP4XE", "p54tp4xe", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p54tp4xe_init, NULL }, { "[i430FX] ASUS P/I-P54TP4XE (MR BIOS)", "mr586", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_PS2, 8, 128, 8, 127, machine_at_mr586_init, NULL }, { "[i430FX] Gateway 2000 P5-xxx", "gw2katx", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_gw2katx_init, NULL }, - { "[i430FX] Intel Advanced/ATX", "thor", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_thor_init, NULL }, + { "[i430FX] Intel Advanced/ATX", "thor", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_thor_init, at_thor_get_device }, { "[i430FX] Intel Advanced/ATX (MR BIOS)", "mrthor", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_mrthor_init, NULL }, { "[i430FX] Intel Advanced/EV", "endeavor", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_endeavor_init, at_endeavor_get_device }, { "[i430FX] Packard Bell PB640", "pb640", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_pb640_init, at_pb640_get_device }, diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 922ccf5d1..a95720077 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -106,6 +106,7 @@ video_cards[] = { { "[ISA] SPEA V7 Mirage (S3 86c801)", "px_s3_v7_801_isa", &s3_v7mirage_86c801_isa_device }, { "[ISA] Trident TVGA8900B", "tvga8900b", &tvga8900b_device }, { "[ISA] Trident TVGA8900D", "tvga8900d", &tvga8900d_device }, + { "[ISA] Trident TVGA9000B", "tvga9000b", &tvga9000b_device }, { "[ISA] Trigem Korean VGA (ET4000AX)", "tgkorvga", &et4000k_isa_device }, { "[ISA] Tseng ET4000AX", "et4000ax", &et4000_isa_device }, { "[ISA] VGA", "vga", &vga_device }, diff --git a/src/video/vid_tvga.c b/src/video/vid_tvga.c index 3c149a145..32ee53fb0 100644 --- a/src/video/vid_tvga.c +++ b/src/video/vid_tvga.c @@ -32,10 +32,12 @@ #include <86box/vid_svga_render.h> #define TVGA8900B_ID 0x03 +#define TVGA9000B_ID 0x23 #define TVGA8900CLD_ID 0x33 #define ROM_TVGA_8900B L"roms/video/tvga/tvga8900B.VBI" #define ROM_TVGA_8900CLD L"roms/video/tvga/trident.bin" +#define ROM_TVGA_9000B L"roms/video/tvga/tvga9000b/BIOS.BIN" typedef struct tvga_t { @@ -56,7 +58,8 @@ typedef struct tvga_t uint32_t vram_mask; } tvga_t; -video_timings_t timing_tvga = {VIDEO_ISA, 3, 3, 6, 8, 8, 12}; +video_timings_t timing_tvga8900 = {VIDEO_ISA, 3, 3, 6, 8, 8, 12}; +video_timings_t timing_tvga9000 = {VIDEO_ISA, 7, 7, 12, 7, 7, 12}; static uint8_t crtc_mask[0x40] = { @@ -115,8 +118,11 @@ void tvga_out(uint16_t addr, uint8_t val, void *p) break; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - tkd8001_ramdac_out(addr, val, svga->ramdac, svga); - return; + if (tvga->card_id != TVGA9000B_ID) { + tkd8001_ramdac_out(addr, val, svga->ramdac, svga); + return; + } + break; case 0x3CF: switch (svga->gdcaddr & 15) @@ -143,35 +149,39 @@ void tvga_out(uint16_t addr, uint8_t val, void *p) old = svga->crtc[svga->crtcreg]; val &= crtc_mask[svga->crtcreg]; svga->crtc[svga->crtcreg] = val; - if (old != val) - { - if (svga->crtcreg < 0xE || svga->crtcreg > 0x10) - { + if (old != val) { + if (svga->crtcreg < 0xE || svga->crtcreg > 0x10) { svga->fullchange = changeframecount; svga_recalctimings(svga); } } - switch (svga->crtcreg) - { + switch (svga->crtcreg) { case 0x1e: svga->vram_display_mask = (val & 0x80) ? tvga->vram_mask : 0x3ffff; break; } return; case 0x3D8: - if (svga->gdcreg[0xf] & 4) - { + if (svga->gdcreg[0xf] & 4) { tvga->tvga_3d8 = val; tvga_recalcbanking(tvga); } return; case 0x3D9: - if (svga->gdcreg[0xf] & 4) - { + if (svga->gdcreg[0xf] & 4) { tvga->tvga_3d9 = val; tvga_recalcbanking(tvga); } return; + case 0x3DB: + if (tvga->card_id != TVGA9000B_ID) { + /*3db appears to be a 4 bit clock select register on 8900D*/ + svga->miscout = (svga->miscout & ~0x0c) | ((val & 3) << 2); + tvga->newctrl2 = (tvga->newctrl2 & ~0x01) | ((val & 4) >> 2); + tvga->oldctrl1 = (tvga->oldctrl1 & ~0x10) | ((val & 8) << 1); + svga_recalctimings(svga); + } + break; } svga_out(addr, val, svga); } @@ -203,7 +213,10 @@ uint8_t tvga_in(uint16_t addr, void *p) } break; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - return tkd8001_ramdac_in(addr, svga->ramdac, svga); + if (tvga->card_id != TVGA9000B_ID) { + return tkd8001_ramdac_in(addr, svga->ramdac, svga); + } + break; case 0x3D4: return svga->crtcreg; case 0x3D5: @@ -233,6 +246,9 @@ static void tvga_recalcbanking(tvga_t *tvga) void tvga_recalctimings(svga_t *svga) { tvga_t *tvga = (tvga_t *)svga->p; + int clksel; + int high_res_256 = 0; + if (!svga->rowoffset) svga->rowoffset = 0x100; /*This is the only sensible way I can see this being handled, given that TVGA8900D has no overflow bits. Some sort of overflow is required for 320x200x24 and 1024x768x16*/ @@ -264,18 +280,43 @@ void tvga_recalctimings(svga_t *svga) if (svga->interlace) svga->rowoffset >>= 1; - switch (((svga->miscout >> 2) & 3) | ((tvga->newctrl2 << 2) & 4)) - { - case 2: svga->clock = (cpuclock * (double)(1ull << 32))/44900000.0; break; - case 3: svga->clock = (cpuclock * (double)(1ull << 32))/36000000.0; break; - case 4: svga->clock = (cpuclock * (double)(1ull << 32))/57272000.0; break; - case 5: svga->clock = (cpuclock * (double)(1ull << 32))/65000000.0; break; - case 6: svga->clock = (cpuclock * (double)(1ull << 32))/50350000.0; break; - case 7: svga->clock = (cpuclock * (double)(1ull << 32))/40000000.0; break; + if (tvga->card_id == TVGA8900CLD_ID) + clksel = ((svga->miscout >> 2) & 3) | ((tvga->newctrl2 & 0x01) << 2) | ((tvga->oldctrl1 & 0x10) >> 1); + else + clksel = ((svga->miscout >> 2) & 3) | ((tvga->newctrl2 & 0x01) << 2) | ((tvga->newctrl2 & 0x40) >> 3); + + switch (clksel) { + case 0x2: svga->clock = (cpuclock * (double)(1ull << 32)) / 44900000.0; break; + case 0x3: svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; break; + case 0x4: svga->clock = (cpuclock * (double)(1ull << 32)) / 57272000.0; break; + case 0x5: svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; break; + case 0x6: svga->clock = (cpuclock * (double)(1ull << 32)) / 50350000.0; break; + case 0x7: svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; break; + case 0x8: svga->clock = (cpuclock * (double)(1ull << 32)) / 88000000.0; break; + case 0x9: svga->clock = (cpuclock * (double)(1ull << 32)) / 98000000.0; break; + case 0xa: svga->clock = (cpuclock * (double)(1ull << 32)) / 118800000.0; break; + case 0xb: svga->clock = (cpuclock * (double)(1ull << 32)) / 108000000.0; break; + case 0xc: svga->clock = (cpuclock * (double)(1ull << 32)) / 72000000.0; break; + case 0xd: svga->clock = (cpuclock * (double)(1ull << 32)) / 77000000.0; break; + case 0xe: svga->clock = (cpuclock * (double)(1ull << 32)) / 80000000.0; break; + case 0xf: svga->clock = (cpuclock * (double)(1ull << 32)) / 75000000.0; break; } - if (tvga->oldctrl2 & 0x10) + if (tvga->card_id != TVGA8900CLD_ID) { + /*TVGA9000 doesn't seem to have support for a 'high res' 256 colour mode + (without the VGA pixel doubling). Instead it implements these modes by + doubling the horizontal pixel count and pixel clock. Hence we use a + basic heuristic to detect this*/ + if (svga->interlace) + high_res_256 = (svga->htotal * 8) > (svga->vtotal * 4); + else + high_res_256 = (svga->htotal * 8) > (svga->vtotal * 2); + } + + if ((tvga->oldctrl2 & 0x10) || high_res_256) { + if (high_res_256) + svga->hdisp /= 2; switch (svga->bpp) { case 8: @@ -304,11 +345,16 @@ static void *tvga_init(const device_t *info) const wchar_t *bios_fn; tvga_t *tvga = malloc(sizeof(tvga_t)); memset(tvga, 0, sizeof(tvga_t)); - - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tvga); - tvga->vram_size = device_get_config_int("memory") << 10; - tvga->vram_mask = tvga->vram_size - 1; + if (info->local == TVGA9000B_ID) { + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tvga9000); + tvga->vram_size = 512 << 10; + } else { + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tvga8900); + tvga->vram_size = device_get_config_int("memory") << 10; + } + + tvga->vram_mask = tvga->vram_size - 1; tvga->card_id = info->local; @@ -320,6 +366,9 @@ static void *tvga_init(const device_t *info) case TVGA8900CLD_ID: bios_fn = ROM_TVGA_8900CLD; break; + case TVGA9000B_ID: + bios_fn = ROM_TVGA_9000B; + break; default: free(tvga); return NULL; @@ -333,7 +382,8 @@ static void *tvga_init(const device_t *info) NULL, NULL); - tvga->svga.ramdac = device_add(&tkd8001_ramdac_device); + if (info->local != TVGA9000B_ID) + tvga->svga.ramdac = device_add(&tkd8001_ramdac_device); io_sethandler(0x03c0, 0x0020, tvga_in, NULL, NULL, tvga_out, NULL, NULL, tvga); @@ -350,6 +400,11 @@ static int tvga8900d_available(void) return rom_present(ROM_TVGA_8900CLD); } +static int tvga9000b_available(void) +{ + return rom_present(ROM_TVGA_9000B); +} + void tvga_close(void *p) { tvga_t *tvga = (tvga_t *)p; @@ -425,3 +480,17 @@ const device_t tvga8900d_device = tvga_force_redraw, tvga_config }; + +const device_t tvga9000b_device = +{ + "Trident TVGA 9000B", + DEVICE_ISA, + TVGA9000B_ID, + tvga_init, + tvga_close, + NULL, + tvga9000b_available, + tvga_speed_changed, + tvga_force_redraw, + NULL +}; From 5afe206cf97a92384aa8f76a36c844a67d9d58a4 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 6 Oct 2020 18:26:19 +0200 Subject: [PATCH 04/12] Fixed compile issue. --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 5ad457624..c00da7858 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -286,7 +286,7 @@ const machine_t machines[] = { { "[i430FX] ASUS P/I-P54TP4XE", "p54tp4xe", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p54tp4xe_init, NULL }, { "[i430FX] ASUS P/I-P54TP4XE (MR BIOS)", "mr586", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_PS2, 8, 128, 8, 127, machine_at_mr586_init, NULL }, { "[i430FX] Gateway 2000 P5-xxx", "gw2katx", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_gw2katx_init, NULL }, - { "[i430FX] Intel Advanced/ATX", "thor", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_thor_init, at_thor_get_device }, + { "[i430FX] Intel Advanced/ATX", "thor", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_thor_init, NULL }, { "[i430FX] Intel Advanced/ATX (MR BIOS)", "mrthor", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_mrthor_init, NULL }, { "[i430FX] Intel Advanced/EV", "endeavor", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_endeavor_init, at_endeavor_get_device }, { "[i430FX] Packard Bell PB640", "pb640", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_pb640_init, at_pb640_get_device }, From b22e447c2d1d26432c6da08a0ab712b4bfe1a713 Mon Sep 17 00:00:00 2001 From: Daniel Gurney Date: Tue, 6 Oct 2020 19:33:28 +0300 Subject: [PATCH 05/12] Fix tvga9000b path --- src/video/vid_tvga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_tvga.c b/src/video/vid_tvga.c index 32ee53fb0..2bcab6696 100644 --- a/src/video/vid_tvga.c +++ b/src/video/vid_tvga.c @@ -37,7 +37,7 @@ #define ROM_TVGA_8900B L"roms/video/tvga/tvga8900B.VBI" #define ROM_TVGA_8900CLD L"roms/video/tvga/trident.bin" -#define ROM_TVGA_9000B L"roms/video/tvga/tvga9000b/BIOS.BIN" +#define ROM_TVGA_9000B L"roms/video/tvga/tvga9000b.bin" typedef struct tvga_t { From 1be1e2c7234c77f4e06c82e41e94acaee67f1268 Mon Sep 17 00:00:00 2001 From: anabate123 <62159176+anabate123@users.noreply.github.com> Date: Tue, 6 Oct 2020 21:05:49 -0400 Subject: [PATCH 06/12] Update m_at_socket7_s7.c --- src/machine/m_at_socket7_s7.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/machine/m_at_socket7_s7.c b/src/machine/m_at_socket7_s7.c index 3ab2d8649..16144bc75 100644 --- a/src/machine/m_at_socket7_s7.c +++ b/src/machine/m_at_socket7_s7.c @@ -753,6 +753,40 @@ machine_at_pb680_init(const machine_t *model) } +int +machine_at_gw2kte_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined2(L"roms/machines/gw2kte/1008CY1T.BIO", + L"roms/machines/gw2kte/1008CY1T.BI1", + L"roms/machines/gw2kte/1008CY1T.BI2", + L"roms/machines/gw2kte/1008CY1T.BI3", + L"roms/machines/gw2kte/1008CY1T.RCV", + 0x3a000, 128); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x08, PCI_CARD_ONBOARD, 4, 0, 0, 0); + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&i430vx_device); + device_add(&piix3_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&pc87306_device); + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + + int machine_at_nupro592_init(const machine_t *model) { From cbf6555fab8799f64f24c7a7479756c09398f971 Mon Sep 17 00:00:00 2001 From: anabate123 <62159176+anabate123@users.noreply.github.com> Date: Tue, 6 Oct 2020 21:07:56 -0400 Subject: [PATCH 07/12] Update machine_table.c --- src/machine/machine_table.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index c00da7858..aa39e46da 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -285,7 +285,7 @@ const machine_t machines[] = { /* 430FX */ { "[i430FX] ASUS P/I-P54TP4XE", "p54tp4xe", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p54tp4xe_init, NULL }, { "[i430FX] ASUS P/I-P54TP4XE (MR BIOS)", "mr586", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_PS2, 8, 128, 8, 127, machine_at_mr586_init, NULL }, - { "[i430FX] Gateway 2000 P5-xxx", "gw2katx", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_gw2katx_init, NULL }, + { "[i430FX] Gateway 2000 Thor", "gw2katx", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_gw2katx_init, NULL }, { "[i430FX] Intel Advanced/ATX", "thor", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_thor_init, NULL }, { "[i430FX] Intel Advanced/ATX (MR BIOS)", "mrthor", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_mrthor_init, NULL }, { "[i430FX] Intel Advanced/EV", "endeavor", MACHINE_TYPE_SOCKET7_3V, MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_endeavor_init, at_endeavor_get_device }, @@ -313,6 +313,7 @@ const machine_t machines[] = { { "[i430VX] HP Brio 80xx", "brio80xx", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_brio80xx_init, NULL }, { "[i430VX] Biostar MB-8500TVX-A", "8500tvxa", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_8500tvxa_init, NULL }, { "[i430VX] Compaq Presario 4500", "presario4500", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_presario4500_init, NULL }, + { "[i430VX] Gateway 2000 Tigereye", "gw2kte", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_gw2kte_init, NULL }, { "[i430VX] Packard Bell PB680", "pb680", MACHINE_TYPE_SOCKET7, MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_pb680_init, NULL }, /* 430TX */ From c71e999f86813ac6fd8d56e760ba8893a198daf0 Mon Sep 17 00:00:00 2001 From: anabate123 <62159176+anabate123@users.noreply.github.com> Date: Tue, 6 Oct 2020 21:09:18 -0400 Subject: [PATCH 08/12] Update machine.h --- src/include/86box/machine.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index ce290780c..f5b027f41 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -374,6 +374,7 @@ extern int machine_at_i430vx_init(const machine_t *); extern int machine_at_brio80xx_init(const machine_t *); extern int machine_at_8500tvxa_init(const machine_t *); extern int machine_at_presario4500_init(const machine_t *); +extern int machine_at_gw2kte_init(const machine_t *); extern int machine_at_pb680_init(const machine_t *); extern int machine_at_nupro592_init(const machine_t *); From 1556bc7442ed146e48fc8b750afbb613bbe3d0cc Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 9 Oct 2020 13:41:20 +0200 Subject: [PATCH 09/12] (S)VGA split screen now takes interlace, odd/even line, and skew into account, fixes the E-Ten Traditional Chinese DOS display driver on Trident graphics cards. --- src/video/vid_svga.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 3bec9dd24..915328c81 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -741,7 +741,12 @@ svga_poll(void *p) ret = svga->line_compare(svga); if (ret) { - svga->ma = svga->maback = 0; + if (svga->interlace && svga->oddeven) + svga->ma = svga->maback = (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5); + else + svga->ma = svga->maback = ((svga->crtc[5] & 0x60) >> 5); + svga->ma = (svga->ma << 2); + svga->maback = (svga->maback << 2); svga->sc = 0; if (svga->attrregs[0x10] & 0x20) { svga->scrollcache = 0; @@ -805,7 +810,7 @@ svga_poll(void *p) changeframecount = svga->interlace ? 3 : 2; svga->vslines = 0; - if (svga->interlace && svga->oddeven) + if (svga->interlace && svga->oddeven) svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5); else svga->ma = svga->maback = svga->ma_latch + ((svga->crtc[5] & 0x60) >> 5); From b350c86237993efaddf830cc4672176b0e830695 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 9 Oct 2020 13:50:31 +0200 Subject: [PATCH 10/12] Applies the split screen fix to EGA as well. --- src/video/vid_ega.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index 74222d5c8..780d1559d 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -537,7 +537,12 @@ ega_poll(void *p) ega->vc++; ega->vc &= 1023; if (ega->vc == ega->split) { - ega->ma = ega->maback = 0; + if (ega->interlace && ega->oddeven) + ega->ma = ega->maback = ega->ma_latch + (ega->rowoffset << 1); + else + ega->ma = ega->maback = ega->ma_latch; + ega->ma <<= 2; + ega->maback <<= 2; ega->sc = 0; if (ega->attrregs[0x10] & 0x20) { ega->scrollcache = 0; From 6ed78ae5d8c5cb3f501d4e834447f4e33ca844e0 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 10 Oct 2020 15:14:19 +0200 Subject: [PATCH 11/12] Ported twilen's S3 ViRGE and Trio/Vision fixes to 86box. --- src/video/vid_s3.c | 85 +++++++++++++++++++++++++--------------- src/video/vid_s3_virge.c | 45 ++++----------------- 2 files changed, 61 insertions(+), 69 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 718b2717d..f328361fb 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -3331,10 +3331,31 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ uint32_t rd_mask = s3->accel.rd_mask; int cmd = s3->accel.cmd >> 13; int read = 0, byte_cnt = 0, i; + uint32_t srcbase, dstbase; if ((s3->chip >= S3_TRIO64) && (s3->accel.cmd & (1 << 11))) cmd |= 8; + // SRC-BASE/DST-BASE + if ((s3->accel.multifunc[0xd] >> 4) & 7) { + srcbase = 0x100000 * ((s3->accel.multifunc[0xd] >> 4) & 3); + } else { + srcbase = 0x100000 * ((s3->accel.multifunc[0xe] >> 2) & 3); + } + if ((s3->accel.multifunc[0xd] >> 0) & 7) { + dstbase = 0x100000 * ((s3->accel.multifunc[0xd] >> 0) & 3); + } else { + dstbase = 0x100000 * ((s3->accel.multifunc[0xe] >> 0) & 3); + } + if (s3->bpp == 1) { + srcbase >>= 1; + dstbase >>= 1; + } else if (s3->bpp == 3) { + srcbase >>= 2; + dstbase >>= 2; + } + + if ((s3_cpu_src(s3) || s3_cpu_dest(s3))) { if (s3->accel.pixtrans_failed) { /*Some hack for some 911/924 driver*/ if (s3->busy) @@ -3410,8 +3431,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ { while (count-- && s3->accel.sy >= 0) { - if (s3->accel.cx >= clip_l && s3->accel.cx <= clip_r && - s3->accel.cy >= clip_t && s3->accel.cy <= clip_b) + if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && + (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { @@ -3469,8 +3490,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ while (count-- && s3->accel.sy >= 0) { - if (s3->accel.cx >= clip_l && s3->accel.cx <= clip_r && - s3->accel.cy >= clip_t && s3->accel.cy <= clip_b) + if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && + (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { @@ -3552,7 +3573,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.cy = s3->accel.cur_y; if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff; - s3->accel.dest = s3->accel.cy * s3->width; + s3->accel.dest = dstbase + s3->accel.cy * s3->width; if (s3_cpu_src(s3)) { return; /*Wait for data from CPU*/ @@ -3580,8 +3601,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ while (count-- && s3->accel.sy >= 0) { - if (s3->accel.cx >= clip_l && s3->accel.cx <= clip_r && - s3->accel.cy >= clip_t && s3->accel.cy <= clip_b) + if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && + (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { if (s3_cpu_dest(s3) && ((s3->accel.multifunc[0xa] & 0xc0) == 0x00)) mix_dat = mix_mask; /* Mix data = forced to foreground register. */ @@ -3656,7 +3677,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if (s3->accel.cmd & 0x80) s3->accel.cy++; else s3->accel.cy--; - s3->accel.dest = s3->accel.cy * s3->width; + s3->accel.dest = dstbase + s3->accel.cy * s3->width; s3->accel.sy--; if (s3->accel.sy < 0) { @@ -3699,8 +3720,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.cy = s3->accel.cur_y & 0xfff; if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff; - s3->accel.src = s3->accel.cy * s3->width; - s3->accel.dest = s3->accel.dy * s3->width; + s3->accel.src = srcbase + s3->accel.cy * s3->width; + s3->accel.dest = dstbase + s3->accel.dy * s3->width; } if ((s3->accel.cmd & 0x100) && !cpu_input) { @@ -3715,8 +3736,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ { while (1) { - if (s3->accel.dx >= clip_l && s3->accel.dx <= clip_r && - s3->accel.dy >= clip_t && s3->accel.dy <= clip_b) + if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && + (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b) { READ(s3->accel.src + s3->accel.cx, src_dat); READ(s3->accel.dest + s3->accel.dx, dest_dat); @@ -3738,8 +3759,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.cy++; s3->accel.dy++; - s3->accel.src = s3->accel.cy * s3->width; - s3->accel.dest = s3->accel.dy * s3->width; + s3->accel.src = srcbase + s3->accel.cy * s3->width; + s3->accel.dest = dstbase + s3->accel.dy * s3->width; s3->accel.sy--; @@ -3754,8 +3775,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ { while (count-- && s3->accel.sy >= 0) { - if (s3->accel.dx >= clip_l && s3->accel.dx <= clip_r && - s3->accel.dy >= clip_t && s3->accel.dy <= clip_b) + if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && + (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b) { if (vram_mask) { @@ -3827,8 +3848,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.dy--; } - s3->accel.src = s3->accel.cy * s3->width; - s3->accel.dest = s3->accel.dy * s3->width; + s3->accel.src = srcbase + s3->accel.cy * s3->width; + s3->accel.dest = dstbase + s3->accel.dy * s3->width; s3->accel.sy--; @@ -3864,12 +3885,12 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ /*Align source with destination*/ s3->accel.pattern = (s3->accel.cy * s3->width) + s3->accel.cx; - s3->accel.dest = s3->accel.dy * s3->width; + s3->accel.dest = dstbase + s3->accel.dy * s3->width; s3->accel.cx = s3->accel.dx & 7; s3->accel.cy = s3->accel.dy & 7; - s3->accel.src = s3->accel.pattern + (s3->accel.cy * s3->width); + s3->accel.src = srcbase + s3->accel.pattern + (s3->accel.cy * s3->width); } if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ @@ -3879,8 +3900,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ while (count-- && s3->accel.sy >= 0) { - if (s3->accel.dx >= clip_l && s3->accel.dx <= clip_r && - s3->accel.dy >= clip_t && s3->accel.dy <= clip_b) + if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && + (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b) { if (vram_mask) { @@ -3952,8 +3973,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.dy--; } - s3->accel.src = s3->accel.pattern + (s3->accel.cy * s3->width); - s3->accel.dest = s3->accel.dy * s3->width; + s3->accel.src = srcbase + s3->accel.pattern + (s3->accel.cy * s3->width); + s3->accel.dest = dstbase + s3->accel.dy * s3->width; s3->accel.sy--; @@ -3988,12 +4009,12 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ int y = s3->accel.poly_cy; int x_count = ABS((s3->accel.poly_cx2 >> 20) - s3->accel.poly_x) + 1; - s3->accel.dest = y * s3->width; + s3->accel.dest = dstbase + y * s3->width; while (x_count-- && count--) { - if (s3->accel.poly_x >= clip_l && s3->accel.poly_x <= clip_r && - s3->accel.poly_cy >= clip_t && s3->accel.poly_cy <= clip_b) + if ((s3->accel.poly_x & 0xfff) >= clip_l && (s3->accel.poly_x & 0xfff) <= clip_r && + (s3->accel.poly_cy & 0xfff) >= clip_t && (s3->accel.poly_cy & 0xfff) <= clip_b) { switch (frgd_mix) { @@ -4064,15 +4085,15 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ int y = s3->accel.poly_cy; int x_count = ABS((s3->accel.poly_cx2 >> 20) - s3->accel.poly_x) + 1; - s3->accel.src = s3->accel.pattern + ((y & 7) * s3->width); - s3->accel.dest = y * s3->width; + s3->accel.src = srcbase + s3->accel.pattern + ((y & 7) * s3->width); + s3->accel.dest = dstbase + y * s3->width; while (x_count-- && count--) { int pat_x = s3->accel.poly_x & 7; - if (s3->accel.poly_x >= clip_l && s3->accel.poly_x <= clip_r && - s3->accel.poly_cy >= clip_t && s3->accel.poly_cy <= clip_b) + if ((s3->accel.poly_x & 0xfff) >= clip_l && (s3->accel.poly_x & 0xfff) <= clip_r && + (s3->accel.poly_cy & 0xfff) >= clip_t && (s3->accel.poly_cy & 0xfff) <= clip_b) { if (vram_mask) { READ(s3->accel.src + pat_x, mix_dat); @@ -4433,7 +4454,7 @@ static void *s3_init(const device_t *info) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_pci); else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_vlb); - break; + break; case S3_DIAMOND_STEALTH64_764: bios_fn = ROM_DIAMOND_STEALTH64_764; chip = S3_TRIO64; diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 39a964933..b01d2e710 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -1787,13 +1787,13 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) for (x = 0; x < 8; x++) { if (virge->s3d.mono_pat_0 & (1 << (x + y*8))) - mono_pattern[y*8 + x] = virge->s3d.pat_fg_clr; + mono_pattern[y*8 + (7 - x)] = virge->s3d.pat_fg_clr; else - mono_pattern[y*8 + x] = virge->s3d.pat_bg_clr; + mono_pattern[y*8 + (7 - x)] = virge->s3d.pat_bg_clr; if (virge->s3d.mono_pat_1 & (1 << (x + y*8))) - mono_pattern[(y+4)*8 + x] = virge->s3d.pat_fg_clr; + mono_pattern[(y+4)*8 + (7 - x)] = virge->s3d.pat_fg_clr; else - mono_pattern[(y+4)*8 + x] = virge->s3d.pat_bg_clr; + mono_pattern[(y+4)*8 + (7 - x)] = virge->s3d.pat_bg_clr; } } } @@ -1951,7 +1951,8 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) while (count && virge->s3d.h) { - dest_addr = virge->s3d.dest_base + (virge->s3d.dest_x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str); + source = virge->s3d.pat_fg_clr; + dest_addr = virge->s3d.dest_base + (virge->s3d.dest_x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str); pattern = virge->s3d.pat_fg_clr; out = 0; update = 1; @@ -3900,36 +3901,6 @@ static const device_config_t s3_virge_config[] = } }; -static const device_config_t s3_virge_vx_config[] = -{ - { - "memory", "Memory size", CONFIG_SELECTION, "", 4, - { - { - "2 MB", 2 - }, - { - "4 MB", 4 - }, - { - "8 MB", 8 - }, - { - "" - } - } - }, - { - "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 - }, - { - "dithering", "Dithering", CONFIG_BINARY, "", 1 - }, - { - "", "", -1 - } -}; - #if defined(DEV_BRANCH) && defined(USE_S3TRIO3D2X) static const device_config_t s3_trio3d_2x_config[] = { @@ -3998,7 +3969,7 @@ const device_t s3_virge_988_vlb_device = s3_virge_988_available, s3_virge_speed_changed, s3_virge_force_redraw, - s3_virge_vx_config + s3_virge_config }; const device_t s3_virge_988_pci_device = @@ -4012,7 +3983,7 @@ const device_t s3_virge_988_pci_device = s3_virge_988_available, s3_virge_speed_changed, s3_virge_force_redraw, - s3_virge_vx_config + s3_virge_config }; const device_t s3_virge_375_vlb_device = From 71b26b0a09d2c79879bb917ea65fbf6b3145bc62 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 10 Oct 2020 21:57:46 +0200 Subject: [PATCH 12/12] Added the VIA 596B ACPI device and fixed the ACPI I/O port size on the VIA 586B ACPI device. --- src/acpi.c | 160 +++++++++++++++++++++++++++++++++++---- src/include/86box/acpi.h | 15 ++-- 2 files changed, 155 insertions(+), 20 deletions(-) diff --git a/src/acpi.c b/src/acpi.c index 87bc58924..43529701c 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -216,7 +216,7 @@ acpi_reg_read_intel(int size, uint16_t addr, void *p) static uint32_t -acpi_reg_read_via(int size, uint16_t addr, void *p) +acpi_reg_read_via_common(int size, uint16_t addr, void *p) { acpi_t *dev = (acpi_t *) p; uint32_t ret = 0x00000000; @@ -279,6 +279,27 @@ acpi_reg_read_via(int size, uint16_t addr, void *p) /* GP Timer Reload Enable */ ret = (dev->regs.gptren >> shift32) & 0xff; break; + default: + ret = acpi_reg_read_common_regs(size, addr, p); + break; + } + + acpi_log("(%i) ACPI Read (%i) %02X: %02X\n", in_smm, size, addr, ret); + return ret; +} + + +static uint32_t +acpi_reg_read_via(int size, uint16_t addr, void *p) +{ + acpi_t *dev = (acpi_t *) p; + uint32_t ret = 0x00000000; + int shift16; + + addr &= 0xff; + shift16 = (addr & 1) << 3; + + switch (addr) { case 0x40: /* GPIO Direction Control */ if (size == 1) @@ -303,7 +324,41 @@ acpi_reg_read_via(int size, uint16_t addr, void *p) ret = (dev->regs.gpi_val >> shift16) & 0xff; break; default: - ret = acpi_reg_read_common_regs(size, addr, p); + ret = acpi_reg_read_via_common(size, addr, p); + break; + } + + acpi_log("(%i) ACPI Read (%i) %02X: %02X\n", in_smm, size, addr, ret); + return ret; +} + + +static uint32_t +acpi_reg_read_via_596b(int size, uint16_t addr, void *p) +{ + acpi_t *dev = (acpi_t *) p; + uint32_t ret = 0x00000000; + int shift16, shift32; + + addr &= 0x7f; + shift16 = (addr & 1) << 3; + shift32 = (addr & 3) << 3; + + switch (addr) { + case 0x44: case 0x45: + /* External SMI Input Value */ + ret = (dev->regs.extsmi_val >> shift16) & 0xff; + break; + case 0x48: case 0x49: case 0x4a: case 0x4b: + /* GPI Port Input Value */ + ret = (dev->regs.gpi_val >> shift32) & 0xff; + break; + case 0x4c: case 0x4d: case 0x4e: case 0x4f: + /* GPO Port Output Value */ + ret = (dev->regs.gpi_val >> shift32) & 0xff; + break; + default: + ret = acpi_reg_read_via_common(size, addr, p); break; } @@ -492,7 +547,7 @@ acpi_reg_write_intel(int size, uint16_t addr, uint8_t val, void *p) static void -acpi_reg_write_via(int size, uint16_t addr, uint8_t val, void *p) +acpi_reg_write_via_common(int size, uint16_t addr, uint8_t val, void *p) { acpi_t *dev = (acpi_t *) p; int shift16, shift32; @@ -569,6 +624,32 @@ acpi_reg_write_via(int size, uint16_t addr, uint8_t val, void *p) /* GP Timer Reload Enable */ dev->regs.gptren = ((dev->regs.gptren & ~(0xff << shift32)) | (val << shift32)) & 0x000000d9; break; + default: + acpi_reg_write_common_regs(size, addr, val, p); + /* Setting GBL_RLS also sets BIOS_STS and generates SMI. */ + if ((addr == 0x00) && !(dev->regs.pmsts & 0x20)) + dev->regs.glbctl &= ~0x0002; + else if ((addr == 0x04) && (dev->regs.pmcntrl & 0x0004)) { + dev->regs.glbsts |= 0x20; + if (dev->regs.glben & 0x20) + acpi_raise_smi(dev); + } + break; + } +} + + +static void +acpi_reg_write_via(int size, uint16_t addr, uint8_t val, void *p) +{ + acpi_t *dev = (acpi_t *) p; + int shift16; + + addr &= 0xff; + acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val); + shift16 = (addr & 1) << 3; + + switch (addr) { case 0x40: /* GPIO Direction Control */ if (size == 1) @@ -584,15 +665,29 @@ acpi_reg_write_via(int size, uint16_t addr, uint8_t val, void *p) dev->regs.gpo_val = ((dev->regs.gpo_val & ~(0xff << shift16)) | (val << shift16)) & 0xffff; break; default: - acpi_reg_write_common_regs(size, addr, val, p); - /* Setting GBL_RLS also sets BIOS_STS and generates SMI. */ - if ((addr == 0x00) && !(dev->regs.pmsts & 0x20)) - dev->regs.glbctl &= ~0x0002; - else if ((addr == 0x04) && (dev->regs.pmcntrl & 0x0004)) { - dev->regs.glbsts |= 0x20; - if (dev->regs.glben & 0x20) - acpi_raise_smi(dev); - } + acpi_reg_write_via_common(size, addr, val, p); + break; + } +} + + +static void +acpi_reg_write_via_596b(int size, uint16_t addr, uint8_t val, void *p) +{ + acpi_t *dev = (acpi_t *) p; + int shift32; + + addr &= 0x7f; + acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val); + shift32 = (addr & 3) << 3; + + switch (addr) { + case 0x4c: case 0x4d: case 0x4e: case 0x4f: + /* GPO Port Output Value */ + dev->regs.gpo_val = ((dev->regs.gpo_val & ~(0xff << shift32)) | (val << shift32)) & 0x7fffffff; + break; + default: + acpi_reg_write_via_common(size, addr, val, p); break; } } @@ -672,6 +767,8 @@ acpi_reg_read_common(int size, uint16_t addr, void *p) if (dev->vendor == VEN_VIA) ret = acpi_reg_read_via(size, addr, p); + else if (dev->vendor == VEN_VIA_596B) + ret = acpi_reg_read_via_596b(size, addr, p); else if (dev->vendor == VEN_INTEL) ret = acpi_reg_read_intel(size, addr, p); else if (dev->vendor == VEN_SMC) @@ -688,6 +785,8 @@ acpi_reg_write_common(int size, uint16_t addr, uint8_t val, void *p) if (dev->vendor == VEN_VIA) acpi_reg_write_via(size, addr, val, p); + else if (dev->vendor == VEN_VIA_596B) + acpi_reg_write_via_596b(size, addr, val, p); else if (dev->vendor == VEN_INTEL) acpi_reg_write_intel(size, addr, val, p); else if (dev->vendor == VEN_SMC) @@ -853,7 +952,23 @@ acpi_aux_reg_write(uint16_t addr, uint8_t val, void *p) void acpi_update_io_mapping(acpi_t *dev, uint32_t base, int chipset_en) { - int size = (dev->vendor == VEN_SMC) ? 0x10 : 0x40; + int size; + + switch (dev->vendor) { + case VEN_INTEL: + default: + size = 0x040; + break; + case VEN_SMC: + size = 0x010; + break; + case VEN_VIA: + size = 0x100; + break; + case VEN_VIA_596B: + size = 0x080; + break; + } if (dev->io_base != 0x0000) { io_removehandler(dev->io_base, size, @@ -1022,6 +1137,8 @@ acpi_reset(void *priv) dev->regs.gpireg[0] = dev->regs.gpireg[1] = dev->regs.gpireg[2] = 0xff; for (i = 0; i < 4; i++) dev->regs.gporeg[i] = dev->gporeg_default[i]; + if (dev->vendor == VEN_VIA_596B) + dev->regs.gpo_val = 0x7fffffff; } @@ -1067,7 +1184,7 @@ acpi_init(const device_t *info) timer_add(&dev->timer, acpi_timer_count, dev, 0); timer_set_delay_u64(&dev->timer, ACPICONST); - dev->regs.gpireg[0] = dev->regs.gpireg[1] = dev->regs.gpireg[2] = 0xff; + acpi_reset(dev); return dev; } @@ -1103,6 +1220,21 @@ const device_t acpi_via_device = }; +const device_t acpi_via_596b_device = +{ + "VIA ACPI (VT82C596B)", + DEVICE_PCI, + VEN_VIA_596B, + acpi_init, + acpi_close, + acpi_reset, + NULL, + acpi_speed_changed, + NULL, + NULL +}; + + const device_t acpi_smc_device = { "SMC FDC73C931APM ACPI", diff --git a/src/include/86box/acpi.h b/src/include/86box/acpi.h index 3f9ea76e3..affc34264 100644 --- a/src/include/86box/acpi.h +++ b/src/include/86box/acpi.h @@ -42,30 +42,32 @@ extern "C" { #define ACPI_ENABLE 0xf1 #define ACPI_DISABLE 0xf0 -#define VEN_INTEL 0x8086 -#define VEN_SMC 0x1055 -#define VEN_VIA 0x1106 +#define VEN_INTEL 0x08086 +#define VEN_SMC 0x01055 +#define VEN_VIA 0x01106 +#define VEN_VIA_596B 0x11106 typedef struct { uint8_t plvl2, plvl3, smicmd, gpio_dir, - gpio_val, extsmi_val, + gpio_val, pad, timer32, gpireg[3], gporeg[4]; uint16_t pmsts, pmen, pmcntrl, gpsts, gpen, gpscien, gpsmien, pscntrl, - gpo_val, gpi_val, gpscists; int smi_lock, smi_active; uint32_t pcntrl, glbsts, devsts, glben, glbctl, devctl, padsts, paden, - gptren, timer_val; + gptren, timer_val, + gpo_val, gpi_val, + extsmi_val, pad0; uint64_t tmr_overflow_time; } acpi_regs_t; @@ -88,6 +90,7 @@ typedef struct extern const device_t acpi_intel_device; extern const device_t acpi_smc_device; extern const device_t acpi_via_device; +extern const device_t acpi_via_596b_device; /* Functions. */