From 2aa741e597eaad61644d1c82cdc9dfbf5f4ac974 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 1 Oct 2020 21:05:53 +0200 Subject: [PATCH] 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