From fba5ef3e1bec2257a0b0daab9c7427791fc29217 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Wed, 1 Sep 2021 15:37:32 +0200 Subject: [PATCH 01/24] cmake: strip release builds --- .github/workflows/cmake.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 7ff2216da..294442bf4 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -37,10 +37,13 @@ jobs: build: - name: Regular preset: regular + target: install/strip - name: Debug preset: debug + target: install - name: Dev preset: experimental + target: install environment: - msystem: MINGW32 prefix: mingw-w64-i686 @@ -74,7 +77,7 @@ jobs: -D CMAKE_INSTALL_PREFIX=./build/artifacts -D VNC=OFF - name: Build - run: cmake --build build --target install + run: cmake --build build --target ${{ matrix.build.target }} - uses: actions/upload-artifact@v2 with: name: '86Box-${{ matrix.build.name }}-MSYS2-${{ matrix.environment.msystem }}-${{ github.sha }}' From 320c867ea3a7b1e44f5756cd4b57d12f0cf3c305 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 2 Sep 2021 14:36:35 +0200 Subject: [PATCH 02/24] Fix T128 timer initialization on reads for faster cpu's. --- src/scsi/scsi_ncr5380.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index d22b5fbf5..c48af0ae5 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -692,7 +692,7 @@ ncr_write(uint16_t port, uint8_t val, void *priv) ncr_dev->t128.host_pos = MIN(512, dev->buffer_length); ncr_dev->t128.status |= 0x04; - timer_on_auto(&ncr_dev->timer, 0.2); + timer_on_auto(&ncr_dev->timer, 0.02); } else { if ((ncr->mode & MODE_DMA) && !timer_is_enabled(&ncr_dev->timer)) { memset(ncr_dev->buffer, 0, MIN(128, dev->buffer_length)); From 87abf37e2f796ec6f5866c365d806cadc11f3bf8 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 2 Sep 2021 15:21:20 +0200 Subject: [PATCH 03/24] Added Short Vector accel command to the TGUI cards and some cleanups and fixes. --- src/video/vid_tgui9440.c | 425 +++++++++++++++++++++++++-------------- 1 file changed, 275 insertions(+), 150 deletions(-) diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index 90872027f..b961fbf78 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -115,6 +115,7 @@ typedef struct tgui_t int16_t dst_x, dst_y; int16_t dst_y_clip, dst_x_clip; int16_t size_x, size_y; + uint16_t sv_size_y; uint16_t patloc; uint32_t fg_col, bg_col; uint32_t style, ckey; @@ -131,7 +132,7 @@ typedef struct tgui_t int pat_x, pat_y; int use_src; - int src_pitch, dst_pitch, bpp; + int pitch, bpp; uint32_t fill_pattern[8*8]; uint32_t mono_pattern[8*8]; uint32_t pattern_8[8*8]; @@ -144,8 +145,9 @@ typedef struct tgui_t uint8_t tgui_3d8, tgui_3d9; int oldmode; - uint8_t oldctrl1; - uint8_t oldctrl2,newctrl2; + uint8_t oldctrl1, newctrl1; + uint8_t oldctrl2, newctrl2; + uint8_t oldgr0e, newgr0e; uint32_t linear_base, linear_size, ge_base, mmio_base; @@ -292,23 +294,21 @@ tgui_out(uint16_t addr, uint8_t val, void *p) { tgui_t *tgui = (tgui_t *)p; svga_t *svga = &tgui->svga; - uint8_t old, mask; - - mask = (tgui->type >= TGUI_9660) ? 0x3f : 0x1f; + uint8_t old; if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60; switch (addr) { case 0x3C5: - switch (svga->seqaddr & 0xf) + switch (svga->seqaddr) { case 0xB: - tgui->oldmode=1; + tgui->oldmode = 1; break; case 0xC: - if (svga->seqregs[0xe] & 0x80) - svga->seqregs[0xc] = val; + if (svga->seqregs[0x0e] & 0x80) + svga->seqregs[0x0c] = val; break; case 0xd: if (tgui->oldmode) @@ -320,12 +320,13 @@ tgui_out(uint16_t addr, uint8_t val, void *p) if (tgui->oldmode) { tgui->oldctrl1 = val; tgui_update_irqs(tgui); - } else { - svga->seqregs[0xe] = (val ^ 2); - svga->write_bank = (svga->seqregs[0xe] & 0xf) * 65536; - if (!(svga->gdcreg[0xf] & 1)) - svga->read_bank = svga->write_bank; + svga->write_bank = (tgui->oldctrl1) * 65536; + } else { + svga->seqregs[0xe] = val ^ 2; + svga->write_bank = (svga->seqregs[0xe]) * 65536; } + if (!(svga->gdcreg[0xf] & 1)) + svga->read_bank = svga->write_bank; return; } break; @@ -340,16 +341,16 @@ tgui_out(uint16_t addr, uint8_t val, void *p) { tgui->ramdac_state = 0; tgui->ramdac_ctrl = val; - switch (tgui->ramdac_ctrl & 0xf0) + switch ((tgui->ramdac_ctrl >> 4) & 0x0f) { - case 0x10: + case 1: svga->bpp = 15; break; - case 0x30: + case 3: svga->bpp = 16; break; - case 0xd0: - svga->bpp = ((svga->crtc[0x38] & 0x08) == 0x08 && (tgui->type == TGUI_9440)) ? 24 : 32; + case 0x0d: + svga->bpp = (tgui->type >= TGUI_9660) ? 32 : 24; break; default: svga->bpp = 8; @@ -366,7 +367,7 @@ tgui_out(uint16_t addr, uint8_t val, void *p) tkd8001_ramdac_out(addr, val, svga->ramdac, svga); return; } - tgui->ramdac_state = 0; + tgui->ramdac_state = 0; break; case 0x3CF: @@ -383,26 +384,45 @@ tgui_out(uint16_t addr, uint8_t val, void *p) tgui_recalcmapping(tgui); return; } - switch (svga->gdcaddr & 15) + switch (svga->gdcaddr) { - case 0x6: - if (svga->gdcreg[6] != val) - { - svga->gdcreg[6] = val; - tgui_recalcmapping(tgui); - } - return; + case 0x6: + if (svga->gdcreg[6] != val) + { + svga->gdcreg[6] = val; + tgui_recalcmapping(tgui); + } + return; - case 0xE: + case 0x0e: svga->gdcreg[0xe] = val ^ 2; if ((svga->gdcreg[0xf] & 1) == 1) - svga->read_bank = (svga->gdcreg[0xe] & 0xf) * 65536; + svga->read_bank = (svga->gdcreg[0xe]) * 65536; break; - case 0xF: - if (val & 1) svga->read_bank = (svga->gdcreg[0xe] & 0xf) *65536; - else svga->read_bank = (svga->seqregs[0xe] & 0xf) *65536; - svga->write_bank = (svga->seqregs[0xe] & 0xf) * 65536; + case 0x0f: + if (val & 1) + svga->read_bank = (svga->gdcreg[0xe]) * 65536; + else { + if (tgui->oldmode) + svga->read_bank = (tgui->oldctrl1) * 65536; + else + svga->read_bank = (svga->seqregs[0xe]) * 65536; + } + + if (tgui->oldmode) + svga->write_bank = (tgui->oldctrl1) * 65536; + else + svga->write_bank = (svga->seqregs[0xe]) * 65536; break; + + case 0x5a: + case 0x5b: + case 0x5c: + case 0x5d: + case 0x5e: + case 0x5f: + svga->gdcreg[svga->gdcaddr] = val; + break; } break; case 0x3D4: @@ -430,7 +450,7 @@ tgui_out(uint16_t addr, uint8_t val, void *p) } } switch (svga->crtcreg) { - case 0x1e: + case 0x1e: svga->vram_display_mask = (val & 0x80) ? tgui->vram_mask : 0x3ffff; break; @@ -441,6 +461,7 @@ tgui_out(uint16_t addr, uint8_t val, void *p) tgui->linear_size = (val & 0x10) ? 0x200000 : 0x100000; svga->decode_mask = (val & 0x10) ? 0x1fffff : 0xfffff; } + pclog("Linear base = %08x, size = %08x, mask = %08x\n", tgui->linear_base, tgui->linear_size, svga->decode_mask); tgui_recalcmapping(tgui); } break; @@ -457,11 +478,6 @@ tgui_out(uint16_t addr, uint8_t val, void *p) case 0x39: tgui_recalcmapping(tgui); break; - - case 0x37: - if (tgui->type >= TGUI_9660) - i2c_gpio_set(tgui->i2c, !!(val & 0x02), (val & 0x01)); - break; case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: @@ -486,19 +502,20 @@ tgui_out(uint16_t addr, uint8_t val, void *p) } return; - case 0x3D8: - tgui->tgui_3d8 = val; - if (svga->gdcreg[0xf] & 4) { - svga->write_bank = (val & mask) * 65536; - if (!(svga->gdcreg[0xf] & 1)) - svga->read_bank = (val & mask) * 65536; - } - return; + case 0x3D8: + tgui->tgui_3d8 = val; + if (svga->gdcreg[0xf] & 4) { + svga->write_bank = (val & 0x3f) * 65536; + if (!(svga->gdcreg[0xf] & 1)) { + svga->read_bank = (val & 0x3f) * 65536; + } + } + return; case 0x3D9: - tgui->tgui_3d9 = val; - if ((svga->gdcreg[0xf] & 5) == 5) - svga->read_bank = (val & mask) * 65536; - return; + tgui->tgui_3d9 = val; + if ((svga->gdcreg[0xf] & 5) == 5) + svga->read_bank = (val & 0x3f) * 65536; + return; case 0x43c8: tgui->clock_n = val & 0x7f; @@ -524,11 +541,11 @@ tgui_in(uint16_t addr, void *p) switch (addr) { case 0x3C5: - if ((svga->seqaddr & 0xf) == 9) { + if (svga->seqaddr == 9) { if (tgui->type == TGUI_9680) return 0x01; /*TGUI9680XGi*/ } - if ((svga->seqaddr & 0xf) == 0xb) + if (svga->seqaddr == 0x0b) { tgui->oldmode = 0; switch (tgui->type) @@ -542,16 +559,22 @@ tgui_in(uint16_t addr, void *p) return 0xd3; /*TGUI9660XGi*/ } } - if ((svga->seqaddr & 0xf) == 0xd) + if (svga->seqaddr == 0x0d) { if (tgui->oldmode) return tgui->oldctrl2; return tgui->newctrl2; } - if ((svga->seqaddr & 0xf) == 0xe) + if (svga->seqaddr == 0x0c) + { + if (svga->seqregs[0x0e] & 0x80) + return svga->seqregs[0x0c]; + } + if (svga->seqaddr == 0x0e) { if (tgui->oldmode) - return tgui->oldctrl1; + return tgui->oldctrl1 | 0x88; + return svga->seqregs[0x0e]; } break; @@ -572,19 +595,13 @@ tgui_in(uint16_t addr, void *p) case 0x3CF: if (tgui->type == TGUI_9400CXI && svga->gdcaddr >= 16 && svga->gdcaddr < 32) return tgui->ext_gdc_regs[svga->gdcaddr & 15]; - break; + if (svga->gdcaddr >= 0x5a && svga->gdcaddr <= 0x5f) + return svga->gdcreg[svga->gdcaddr]; + break; case 0x3D4: return svga->crtcreg; case 0x3D5: temp = svga->crtc[svga->crtcreg]; - if (svga->crtcreg == 0x37) { - if (tgui->type >= TGUI_9660) { - if ((svga->crtc[0x37] & 0x02) && i2c_gpio_get_scl(tgui->i2c)) - temp |= 0x02; - if ((svga->crtc[0x37] & 0x01) && i2c_gpio_get_sda(tgui->i2c)) - temp |= 0x01; - } - } return temp; case 0x3d8: return tgui->tgui_3d8; @@ -611,14 +628,17 @@ void tgui_recalctimings(svga_t *svga) svga->rowoffset <<= 1; } - if ((svga->crtc[0x1e] & 0xa0) == 0xa0) + + + if ((svga->crtc[0x1e] & 0xA0) == 0xA0) svga->ma_latch |= 0x10000; - if (svga->crtc[0x27] & 0x01) + if ((svga->crtc[0x27] & 0x01) == 0x01) svga->ma_latch |= 0x20000; - if (svga->crtc[0x27] & 0x02) + if ((svga->crtc[0x27] & 0x02) == 0x02) svga->ma_latch |= 0x40000; - if (svga->crtc[0x27] & 0x04) + if ((svga->crtc[0x27] & 0x04) == 0x04) svga->ma_latch |= 0x80000; + if (svga->crtc[0x27] & 0x08) svga->split |= 0x400; if (svga->crtc[0x27] & 0x10) @@ -635,7 +655,7 @@ void tgui_recalctimings(svga_t *svga) svga->lowres = 0; } - if (((tgui->oldctrl2 & 0x10) && (svga->crtc[0x1e] & 0x20) && (tgui->oldctrl1 & 1)) || (svga->crtc[0x2a] & 0x40)) /*According to vgadoc*/ + if ((tgui->oldctrl2 & 0x10) || (svga->crtc[0x2a] & 0x40)) svga->ma_latch <<= 1; svga->lowres = !(svga->crtc[0x2a] & 0x40); @@ -711,6 +731,11 @@ void tgui_recalctimings(svga_t *svga) break; case 32: svga->render = svga_render_32bpp_highres; + if (tgui->type >= TGUI_9660) { + if (svga->hdisp == 1024) { + svga->rowoffset <<= 1; + } + } break; } } @@ -888,7 +913,7 @@ uint8_t tgui_pci_read(int func, int addr, void *p) case 0x02: return (tgui->type == TGUI_9440) ? 0x40 : 0x60; /*TGUI9440AGi or TGUI9660XGi*/ case 0x03: return (tgui->type == TGUI_9440) ? 0x94 : 0x96; - case PCI_REG_COMMAND: return tgui->pci_regs[PCI_REG_COMMAND] & 0x23; /*Respond to IO and memory accesses*/ + case PCI_REG_COMMAND: return tgui->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ case 0x07: return 1 << 1; /*Medium DEVSEL timing*/ @@ -942,7 +967,6 @@ void tgui_pci_write(int func, int addr, uint8_t val, void *p) tgui->linear_base = (tgui->linear_base & 0xff000000) | ((val & 0xe0) << 16); tgui->linear_size = tgui->vram_size; svga->decode_mask = tgui->vram_mask; - svga->crtc[0x21] = (svga->crtc[0x21] & ~0xf) | (val >> 4); tgui_recalcmapping(tgui); break; case 0x13: @@ -952,7 +976,6 @@ void tgui_pci_write(int func, int addr, uint8_t val, void *p) tgui->linear_base = (tgui->linear_base & 0xe00000) | (val << 24); tgui->linear_size = tgui->vram_size; svga->decode_mask = tgui->vram_mask; - svga->crtc[0x21] = (svga->crtc[0x21] & ~0xc0) | (val >> 6); tgui_recalcmapping(tgui); break; @@ -1204,7 +1227,8 @@ enum { TGUI_BITBLT = 1, TGUI_SCANLINE = 3, - TGUI_BRESENHAMLINE = 4 + TGUI_BRESENHAMLINE = 4, + TGUI_SHORTVECTOR = 5 }; enum @@ -1333,62 +1357,88 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) } /*Other than mode stuff, this bit is undocumented*/ + pclog("TGUI ger22 = %04x, cmd = %i, hdisp = %i, svga = %i, bpp = %i\n", tgui->accel.ger22, tgui->accel.command, svga->hdisp, svga->bpp, tgui->accel.bpp); switch (tgui->accel.ger22 & 0xff) { + case 0: + switch (tgui->accel.ger22 >> 8) { + case 0x41: + tgui->accel.pitch = 640; + break; + } + break; + case 4: - tgui->accel.src_pitch = 1024; - tgui->accel.dst_pitch = 1024; - if (svga->hdisp == 800) { - if ((tgui->accel.ger22 >> 8) > 0) { - tgui->accel.src_pitch = 832; - tgui->accel.dst_pitch = 832; - } - } - break; - - case 8: - tgui->accel.src_pitch = 2048; - tgui->accel.dst_pitch = 2048; - if (tgui->type >= TGUI_9660) { - tgui->accel.src_pitch = 1280; - tgui->accel.dst_pitch = 1280; - } - break; - - case 9: - tgui->accel.src_pitch = 1024; - tgui->accel.dst_pitch = 1024; - if (tgui->type >= TGUI_9660) { - tgui->accel.src_pitch = svga->hdisp; - tgui->accel.dst_pitch = svga->hdisp; - if (svga->hdisp == 800) { - tgui->accel.src_pitch = 832; - tgui->accel.dst_pitch = 832; - } - } - break; - - case 14: - tgui->accel.src_pitch = svga->hdisp; - tgui->accel.dst_pitch = svga->hdisp; - switch (tgui->svga.bpp) { - case 32: - if (svga->hdisp == 800) { - tgui->accel.src_pitch = 832; - tgui->accel.dst_pitch = 832; + switch (tgui->accel.ger22 >> 8) { + case 0: + tgui->accel.pitch = 1024; + break; + case 0x40: + tgui->accel.pitch = 640; + break; + case 0x50: + tgui->accel.pitch = 832; + break; + } + break; + case 8: + switch (tgui->accel.ger22 >> 8) { + case 0: + tgui->accel.pitch = 2048; + break; + case 0x60: + tgui->accel.pitch = 1280; + break; + } + break; + case 9: + switch (tgui->accel.ger22 >> 8) { + case 0: + tgui->accel.pitch = svga->hdisp; + if (tgui->type == TGUI_9440) + tgui->accel.pitch = 1024; + break; + case 0x40: + tgui->accel.pitch = 640; + break; + case 0x50: + tgui->accel.pitch = 832; + break; + } + break; + case 13: + switch (tgui->accel.ger22 >> 8) { + case 0x60: + tgui->accel.pitch = 2048; + if (tgui->type >= TGUI_9660) { + if (svga->hdisp == 1280) + tgui->accel.pitch = svga->hdisp; + } + break; + } + break; + case 14: + switch (tgui->accel.ger22 >> 8) { + case 0: + tgui->accel.pitch = 1024; + break; + case 0x40: + tgui->accel.pitch = 640; + break; + case 0x50: + tgui->accel.pitch = 832; + break; } break; - } - break; } switch (tgui->accel.command) { case TGUI_BITBLT: if (count == -1) { - tgui->accel.src_old = tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.src_pitch); + tgui->accel.src_old = tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch); tgui->accel.src = tgui->accel.src_old; - tgui->accel.dst_old = tgui->accel.dst_x + (tgui->accel.dst_y * tgui->accel.dst_pitch); + tgui->accel.dst_old = tgui->accel.dst_x + (tgui->accel.dst_y * tgui->accel.pitch); tgui->accel.dst = tgui->accel.dst_old; tgui->accel.pat_x = tgui->accel.dst_x; @@ -1473,8 +1523,8 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) tgui->accel.dy += ydir; } - tgui->accel.src_old += (ydir * tgui->accel.src_pitch); - tgui->accel.dst_old += (ydir * tgui->accel.dst_pitch); + tgui->accel.src_old += (ydir * tgui->accel.pitch); + tgui->accel.dst_old += (ydir * tgui->accel.pitch); tgui->accel.src = tgui->accel.src_old; tgui->accel.dst = tgui->accel.dst_old; @@ -1535,8 +1585,8 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) tgui->accel.pat_x = tgui->accel.dst_x; tgui->accel.pat_y += ydir; - tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.src_pitch); - tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.dst_pitch); + tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.pitch); + tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.pitch); tgui->accel.y++; @@ -1582,8 +1632,8 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) tgui->accel.pat_x = tgui->accel.dst_x; tgui->accel.pat_y += ydir; - tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.src_pitch); - tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.dst_pitch); + tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.pitch); + tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.pitch); if (tgui->accel.y > tgui->accel.size_y) return; @@ -1596,10 +1646,10 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) case TGUI_SCANLINE: { if (count == -1) { - tgui->accel.src_old = tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.src_pitch); + tgui->accel.src_old = tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch); tgui->accel.src = tgui->accel.src_old; - tgui->accel.dst_old = tgui->accel.dst_x + (tgui->accel.dst_y * tgui->accel.dst_pitch); + tgui->accel.dst_old = tgui->accel.dst_x + (tgui->accel.dst_y * tgui->accel.pitch); tgui->accel.dst = tgui->accel.dst_old; tgui->accel.pat_x = tgui->accel.dst_x; @@ -1633,8 +1683,8 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) tgui->accel.x = 0; tgui->accel.pat_x = tgui->accel.dst_x; - tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.src_pitch); - tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.dst_pitch); + tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.pitch); + tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.pitch); tgui->accel.pat_y += ydir; return; } @@ -1691,13 +1741,13 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) } while (count--) { - READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.src_pitch), src_dat); + READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); /*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/ if (steep) { if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && dx >= tgui->accel.left && dx <= tgui->accel.right && dy >= tgui->accel.top && dy <= tgui->accel.bottom)) { - READ(dx + (dy * tgui->accel.dst_pitch), dst_dat); + READ(dx + (dy * tgui->accel.pitch), dst_dat); pat_dat = tgui->accel.fg_col; @@ -1708,12 +1758,12 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) MIX(); - WRITE(dx + (dy * tgui->accel.dst_pitch), out); + WRITE(dx + (dy * tgui->accel.pitch), out); } } else { if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && dy >= tgui->accel.left && dy <= tgui->accel.right && - dx >= tgui->accel.top && dx <= tgui->accel.bottom)) { - READ(dy + (dx * tgui->accel.dst_pitch), dst_dat); + dx >= tgui->accel.top && dx <= tgui->accel.bottom)) { + READ(dy + (dx * tgui->accel.pitch), dst_dat); pat_dat = tgui->accel.fg_col; @@ -1724,7 +1774,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) MIX(); - WRITE(dy + (dx * tgui->accel.dst_pitch), out); + WRITE(dy + (dx * tgui->accel.pitch), out); } } @@ -1742,13 +1792,92 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) } } break; + + case TGUI_SHORTVECTOR: + { + int16_t dx, dy; + + dx = tgui->accel.dst_x & 0xfff; + dy = tgui->accel.dst_y & 0xfff; + + tgui->accel.left = tgui->accel.src_x_clip & 0xfff; + tgui->accel.right = tgui->accel.dst_x_clip & 0xfff; + tgui->accel.top = tgui->accel.src_y_clip & 0xfff; + tgui->accel.bottom = tgui->accel.dst_y_clip & 0xfff; + + if (tgui->accel.bpp == 1) { + tgui->accel.left >>= 1; + tgui->accel.right >>= 1; + } else if (tgui->accel.bpp == 3) { + tgui->accel.left >>= 2; + tgui->accel.right >>= 2; + } + + while (count--) { + READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); + + /*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/ + if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && dx >= tgui->accel.left && dx <= tgui->accel.right && + dy >= tgui->accel.top && dy <= tgui->accel.bottom)) { + READ(dx + (dy * tgui->accel.pitch), dst_dat); + + pat_dat = tgui->accel.fg_col; + + if (tgui->accel.bpp == 0) + pat_dat &= 0xff; + else if (tgui->accel.bpp == 1) + pat_dat &= 0xffff; + + MIX(); + + WRITE(dx + (dy * tgui->accel.pitch), out); + } + + if (tgui->accel.y == (tgui->accel.sv_size_y & 0xfff)) + break; + + switch ((tgui->accel.sv_size_y >> 8) & 0xe0) { + case 0x00: + dx++; + break; + case 0x20: + dx++; + dy--; + break; + case 0x40: + dy--; + break; + case 0x60: + dx--; + dy--; + break; + case 0x80: + dx--; + break; + case 0xa0: + dx--; + dy++; + break; + case 0xc0: + dy++; + break; + case 0xe0: + dx++; + dy++; + break; + } + + tgui->accel.y++; + } + } + break; } } static void tgui_accel_out(uint16_t addr, uint8_t val, void *p) { - tgui_t *tgui = (tgui_t *)p; + tgui_t *tgui = (tgui_t *)p; switch (addr) { @@ -1764,6 +1893,7 @@ tgui_accel_out(uint16_t addr, uint8_t val, void *p) tgui->accel.bpp = 1; break; + case 13: case 14: switch (tgui->svga.bpp) { case 15: @@ -1885,9 +2015,11 @@ tgui_accel_out(uint16_t addr, uint8_t val, void *p) break; case 0x2142: /*Size Y*/ tgui->accel.size_y = (tgui->accel.size_y & 0xff00) | val; + tgui->accel.sv_size_y = (tgui->accel.sv_size_y & 0xff00) | val; break; case 0x2143: /*Size Y*/ tgui->accel.size_y = (tgui->accel.size_y & 0xff) | (val << 8); + tgui->accel.sv_size_y = (tgui->accel.sv_size_y & 0xff) | (val << 8); break; case 0x2144: /*Style*/ @@ -2186,8 +2318,8 @@ tgui_accel_in_l(uint16_t addr, void *p) static void tgui_accel_write(uint32_t addr, uint8_t val, void *p) { - tgui_t *tgui = (tgui_t *)p; - svga_t *svga = &tgui->svga; + tgui_t *tgui = (tgui_t *)p; + svga_t *svga = &tgui->svga; if ((svga->crtc[0x36] & 0x03) == 0x02) { if ((addr & ~0xff) != 0xbff00) @@ -2211,6 +2343,7 @@ tgui_accel_write(uint32_t addr, uint8_t val, void *p) tgui->accel.bpp = 1; break; + case 13: case 14: switch (tgui->svga.bpp) { case 15: @@ -2332,9 +2465,11 @@ tgui_accel_write(uint32_t addr, uint8_t val, void *p) break; case 0x42: /*Size Y*/ tgui->accel.size_y = (tgui->accel.size_y & 0xff00) | val; + tgui->accel.sv_size_y = (tgui->accel.sv_size_y & 0xff00) | val; break; case 0x43: /*Size Y*/ tgui->accel.size_y = (tgui->accel.size_y & 0xff) | (val << 8); + tgui->accel.sv_size_y = (tgui->accel.sv_size_y & 0xff) | (val << 8); break; case 0x44: /*Style*/ @@ -2858,7 +2993,7 @@ static void *tgui_init(const device_t *info) if (tgui->pci && (tgui->type >= TGUI_9440)) tgui->card = pci_add_card(PCI_ADD_VIDEO, tgui_pci_read, tgui_pci_write, tgui); - tgui->pci_regs[PCI_REG_COMMAND] = 3; + tgui->pci_regs[PCI_REG_COMMAND] = 7; tgui->pci_regs[0x30] = 0x00; tgui->pci_regs[0x32] = 0x0c; @@ -2866,11 +3001,6 @@ static void *tgui_init(const device_t *info) if (tgui->type >= TGUI_9440) svga->packed_chain4 = 1; - - if (tgui->type >= TGUI_9660) { - tgui->i2c = i2c_gpio_init("ddc_tgui"); - tgui->ddc = ddc_init(i2c_gpio_get_bus(tgui->i2c)); - } return tgui; } @@ -2896,11 +3026,6 @@ void tgui_close(void *p) svga_close(&tgui->svga); - if (tgui->type >= TGUI_9660) { - ddc_close(tgui->ddc); - i2c_gpio_close(tgui->i2c); - } - free(tgui); } From 586066d891669e9534e2eab7418a4b66276ee8bb Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 2 Sep 2021 15:24:17 +0200 Subject: [PATCH 04/24] Made NMI's always auto-clear, will revert if it makes things worse. --- src/cpu/386.c | 4 ++++ src/cpu/386_dynarec.c | 4 ++++ src/cpu/808x.c | 3 +++ 3 files changed, 11 insertions(+) diff --git a/src/cpu/386.c b/src/cpu/386.c index 743989e47..86327e5de 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -195,10 +195,14 @@ exec386(int cycs) cpu_state.oldpc = cpu_state.pc; x86_int(2); nmi_enable = 0; +#ifdef OLD_NMI_BEHAVIOR if (nmi_auto_clear) { nmi_auto_clear = 0; nmi = 0; } +#else + nmi = 0; +#endif } else if ((cpu_state.flags & I_FLAG) && pic.int_pending && !cpu_end_block_after_ins) { vector = picinterrupt(); if (vector != -1) { diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index a15e7a291..d396d122a 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -797,10 +797,14 @@ exec386_dynarec(int cycs) cpu_state.oldpc = cpu_state.pc; x86_int(2); nmi_enable = 0; +#ifdef OLD_NMI_BEHAVIOR if (nmi_auto_clear) { nmi_auto_clear = 0; nmi = 0; } +#else + nmi = 0; +#endif } else if ((cpu_state.flags & I_FLAG) && pic.int_pending) { vector = picinterrupt(); if (vector != -1) { diff --git a/src/cpu/808x.c b/src/cpu/808x.c index 329ebe25f..3fbcfb0ed 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -968,6 +968,9 @@ check_interrupts(void) if (nmi && nmi_enable && nmi_mask) { nmi_enable = 0; interrupt(2); +#ifndef OLD_NMI_BEHAVIOR + nmi = 0; +#endif return; } if ((cpu_state.flags & I_FLAG) && pic.int_pending && !noint) { From 448aec5d405d70c19ab69ef4656e4cc758130715 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 2 Sep 2021 15:33:17 +0200 Subject: [PATCH 05/24] SDL now makes sure the mutex is not NULL before attempting to lock it. --- src/win/win_sdl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/win/win_sdl.c b/src/win/win_sdl.c index bebad43dd..8a748fb2b 100644 --- a/src/win/win_sdl.c +++ b/src/win/win_sdl.c @@ -288,7 +288,8 @@ sdl_destroy_texture(void) void sdl_close(void) { - SDL_LockMutex(sdl_mutex); + if (sdl_mutex != NULL) + SDL_LockMutex(sdl_mutex); /* Unregister our renderer! */ video_setblit(NULL); From 6c26a99841bb1c30fb8b382e85ae78cd6aa71017 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Thu, 2 Sep 2021 15:33:51 +0200 Subject: [PATCH 06/24] cmake: full static linking on mingw builds --- CMakeLists.txt | 2 +- src/CMakeLists.txt | 41 +++++++++++++++++++++++------------------ 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9e6552571..68b9e760e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,7 +39,7 @@ include(CPack) include(CMakeDependentOption) add_compile_definitions(CMAKE) -add_compile_definitions("$<$:DEBUG>") +add_compile_definitions("$<$:DEBUG>") if(WIN32) # Disables *_s function warnings diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1ba30edb4..f997ae439 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -47,22 +47,7 @@ endif() target_link_libraries(86Box cpu chipset mch dev mem fdd game cdrom zip mo hdd net print scsi sio snd vid voodoo plat ui) -find_package(Freetype REQUIRED) -include_directories(${FREETYPE_INCLUDE_DIRS}) - -find_package(OpenAL REQUIRED) -include_directories(${OPENAL_INCLUDE_DIR}) -target_link_libraries(86Box ${OPENAL_LIBRARY}) - -find_package(SDL2 CONFIG REQUIRED) -include_directories(${SDL2_INCLUDE_DIRS}) -target_link_libraries(86Box SDL2::SDL2) - -find_package(PNG REQUIRED) -include_directories(${PNG_INCLUDE_DIRS}) -target_link_libraries(86Box PNG::PNG) - -if(ARCH STREQUAL "i386") +if(WIN32 AND ARCH STREQUAL "i386") if(MSVC) target_link_options(86Box PRIVATE "/LARGEADDRESSAWARE") else() @@ -70,10 +55,30 @@ if(ARCH STREQUAL "i386") endif() endif() -if(NOT MSVC AND NOT UNIX AND NOT APPLE) +if(MINGW) target_link_options(86Box PRIVATE "-static") + set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" ".dll.a") endif() +find_package(Freetype REQUIRED) +include_directories(${FREETYPE_INCLUDE_DIRS}) + +find_package(OpenAL REQUIRED) +include_directories(${OPENAL_INCLUDE_DIR}) +target_link_libraries(86Box ${OPENAL_LIBRARY}) + +find_package(SDL2 REQUIRED) +include_directories(${SDL2_INCLUDE_DIRS}) +if(MINGW) + target_link_libraries(86Box SDL2::SDL2-static) +else() + target_link_libraries(86Box SDL2::SDL2) +endif() + +find_package(PNG REQUIRED) +include_directories(${PNG_INCLUDE_DIRS}) +target_link_libraries(86Box PNG::PNG) + configure_file(include/86box/version.h.in include/86box/version.h @ONLY) include_directories(${CMAKE_CURRENT_BINARY_DIR}/include) @@ -123,7 +128,7 @@ add_subdirectory(sio) add_subdirectory(scsi) add_subdirectory(sound) add_subdirectory(video) -if (${CMAKE_SYSTEM_NAME} MATCHES "Windows") +if (WIN32) add_subdirectory(win) else() add_subdirectory(unix) From 296df745ed80c07e6f9bc6b14149a019f5f9231a Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 2 Sep 2021 16:04:58 +0200 Subject: [PATCH 07/24] S3 & TVP3026: Part 1. Initial implementation of the tvp3026 ramdac, (clock still missing, will be added later). --- src/video/CMakeLists.txt | 2 +- src/video/vid_tvp3026_ramdac.c | 472 +++++++++++++++++++++++++++++++++ src/win/Makefile.mingw | 3 +- 3 files changed, 475 insertions(+), 2 deletions(-) create mode 100644 src/video/vid_tvp3026_ramdac.c diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index 78be96495..4cbc18535 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -24,7 +24,7 @@ add_library(vid OBJECT video.c vid_table.c vid_cga.c vid_cga_comp.c vid_stg_ramdac.c vid_ht216.c vid_oak_oti.c vid_paradise.c vid_rtg310x.c vid_ti_cf62011.c vid_tvga.c vid_tgui9440.c vid_tkd8001_ramdac.c vid_att20c49x_ramdac.c vid_s3.c vid_s3_virge.c vid_ibm_rgb528_ramdac.c - vid_sdac_ramdac.c vid_ogc.c vid_nga.c) + vid_sdac_ramdac.c vid_ogc.c vid_nga.c vid_tvp3026_ramdac.c) if(MGA) target_compile_definitions(vid PRIVATE USE_MGA) diff --git a/src/video/vid_tvp3026_ramdac.c b/src/video/vid_tvp3026_ramdac.c new file mode 100644 index 000000000..926921946 --- /dev/null +++ b/src/video/vid_tvp3026_ramdac.c @@ -0,0 +1,472 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the Texas Instruments TVP3026 true colour RAMDAC + * family. + * + * + * TODO: Clock and other parts. + * + * Authors: TheCollector1995, + * + * Copyright 2021 TheCollector1995. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/mem.h> +#include <86box/timer.h> +#include <86box/video.h> +#include <86box/vid_svga.h> + + +typedef struct +{ + PALETTE extpal; + uint32_t extpallook[256]; + uint8_t cursor64_data[1024]; + int hwc_y, hwc_x; + uint8_t ind_idx; + uint8_t dcc, dc_init; + uint8_t ccr; + uint8_t true_color; + uint8_t latch_cntl; + uint8_t mcr; + uint8_t ppr; + uint8_t general_cntl; + uint8_t mclk; + uint8_t misc; + uint8_t type; + uint8_t mode; +} tvp3026_ramdac_t; + +static void +tvp3026_set_bpp(tvp3026_ramdac_t *ramdac, svga_t *svga) +{ + if ((ramdac->true_color & 0x80) == 0x80) { + if (ramdac->mcr & 0x08) + svga->bpp = 8; + else + svga->bpp = 4; + } else { + switch (ramdac->true_color & 0x0f) { + case 0x01: + case 0x03: + case 0x05: + svga->bpp = 16; + break; + case 0x04: + svga->bpp = 15; + break; + case 0x06: + case 0x07: + if (ramdac->true_color & 0x10) + svga->bpp = 24; + else + svga->bpp = 32; + break; + case 0x0e: + case 0x0f: + svga->bpp = 24; + break; + } + } + svga_recalctimings(svga); +} + + +void +tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t *svga) +{ + tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) p; + uint32_t o32; + uint8_t *cd; + uint16_t index; + uint8_t rs = (addr & 0x03); + uint16_t da_mask = 0x03ff; + rs |= (!!rs2 << 2); + rs |= (!!rs3 << 3); + + + switch (rs) { + case 0x00: /* Palette Write Index Register (RS value = 0000) */ + ramdac->ind_idx = val; + case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */ + case 0x03: + case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */ + svga->dac_pos = 0; + svga->dac_status = addr & 0x03; + svga->dac_addr = val; + if (svga->dac_status) + svga->dac_addr = (svga->dac_addr + 1) & da_mask; + break; + case 0x01: /* Palette Data Register (RS value = 0001) */ + case 0x02: /* Pixel Read Mask Register (RS value = 0010) */ + svga_out(addr, val, svga); + break; + case 0x05: /* Ext Palette Data Register (RS value = 0101) */ + svga->dac_status = 0; + svga->fullchange = changeframecount; + switch (svga->dac_pos) { + case 0: + svga->dac_r = val; + svga->dac_pos++; + break; + case 1: + svga->dac_g = val; + svga->dac_pos++; + break; + case 2: + index = svga->dac_addr & 3; + ramdac->extpal[index].r = svga->dac_r; + ramdac->extpal[index].g = svga->dac_g; + ramdac->extpal[index].b = val; + if (svga->ramdac_type == RAMDAC_8BIT) + ramdac->extpallook[index] = makecol32(ramdac->extpal[index].r, ramdac->extpal[index].g, ramdac->extpal[index].b); + else + ramdac->extpallook[index] = makecol32(video_6to8[ramdac->extpal[index].r & 0x3f], video_6to8[ramdac->extpal[index].g & 0x3f], video_6to8[ramdac->extpal[index].b & 0x3f]); + + if (svga->ext_overscan && !index) { + o32 = svga->overscan_color; + svga->overscan_color = ramdac->extpallook[0]; + if (o32 != svga->overscan_color) + svga_recalctimings(svga); + } + svga->dac_addr = (svga->dac_addr + 1) & 0xff; + svga->dac_pos = 0; + break; + } + break; + case 0x09: /* Direct Cursor Control (RS value = 1001) */ + ramdac->dcc = val; + if (ramdac->ccr & 0x80) { + svga->dac_hwcursor.xsize = svga->dac_hwcursor.ysize = 64; + svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.xsize; + svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.ysize; + svga->dac_hwcursor.ena = ((val & 0x03) != 0); + ramdac->mode = val & 0x03; + } + break; + case 0x0a: /* Indexed Data (RS value = 1010) */ + switch (ramdac->ind_idx) { + case 0x06: /* Indirect Cursor Control */ + ramdac->ccr = val; + svga->dac_hwcursor.xsize = svga->dac_hwcursor.ysize = 64; + svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.xsize; + svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.ysize; + svga->dac_hwcursor.ena = ((val & 0x03) != 0); + ramdac->mode = val & 0x03; + break; + case 0x0f: /* Latch Control */ + ramdac->latch_cntl = val; + break; + case 0x18: /* True Color Control */ + ramdac->true_color = val; + tvp3026_set_bpp(ramdac, svga); + break; + case 0x19: /* Multiplex Control */ + ramdac->mcr = val; + tvp3026_set_bpp(ramdac, svga); + break; + case 0x1c: /* Palette-Page Register */ + ramdac->ppr = val; + break; + case 0x1d: /* General Control Register */ + ramdac->general_cntl = val; + break; + case 0x1e: /* Miscellaneous Control */ + ramdac->misc = val; + svga->ramdac_type = (val & 0x08) ? RAMDAC_8BIT : RAMDAC_6BIT; + break; + case 0x39: /* MCLK/Loop Clock Control */ + ramdac->mclk = val; + break; + + } + break; + case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */ + index = svga->dac_addr & da_mask; + cd = (uint8_t *) ramdac->cursor64_data; + cd[index] = val; + svga->dac_addr = (svga->dac_addr + 1) & da_mask; + break; + case 0x0c: /* Cursor X Low Register (RS value = 1100) */ + ramdac->hwc_x = (ramdac->hwc_x & 0x0f00) | val; + svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.xsize; + break; + case 0x0d: /* Cursor X High Register (RS value = 1101) */ + ramdac->hwc_x = (ramdac->hwc_x & 0x00ff) | ((val & 0x0f) << 8); + svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.xsize; + break; + case 0x0e: /* Cursor Y Low Register (RS value = 1110) */ + ramdac->hwc_y = (ramdac->hwc_y & 0x0f00) | val; + svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.ysize; + break; + case 0x0f: /* Cursor Y High Register (RS value = 1111) */ + ramdac->hwc_y = (ramdac->hwc_y & 0x00ff) | ((val & 0x0f) << 8); + svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.ysize; + break; + } + + return; +} + + +uint8_t +tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) +{ + tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) p; + uint8_t temp = 0xff; + uint8_t *cd; + uint16_t index; + uint8_t rs = (addr & 0x03); + uint16_t da_mask = 0x03ff; + rs |= (!!rs2 << 2); + rs |= (!!rs3 << 3); + + switch (rs) { + case 0x00: /* Palette Write Index Register (RS value = 0000) */ + case 0x01: /* Palette Data Register (RS value = 0001) */ + case 0x02: /* Pixel Read Mask Register (RS value = 0010) */ + case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */ + temp = svga_in(addr, svga); + break; + case 0x03: /* Palette Read Index Register (RS value = 0011) */ + case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */ + temp = svga->dac_addr & 0xff; + break; + case 0x05: /* Ext Palette Data Register (RS value = 0101) */ + index = (svga->dac_addr - 1) & 3; + svga->dac_status = 3; + switch (svga->dac_pos) { + case 0: + svga->dac_pos++; + if (svga->ramdac_type == RAMDAC_8BIT) + temp = ramdac->extpal[index].r; + else + temp = ramdac->extpal[index].r & 0x3f; + break; + case 1: + svga->dac_pos++; + if (svga->ramdac_type == RAMDAC_8BIT) + temp = ramdac->extpal[index].g; + else + temp = ramdac->extpal[index].g & 0x3f; + break; + case 2: + svga->dac_pos=0; + svga->dac_addr = svga->dac_addr + 1; + if (svga->ramdac_type == RAMDAC_8BIT) + temp = ramdac->extpal[index].b; + else + temp = ramdac->extpal[index].b & 0x3f; + break; + } + break; + case 0x09: /* Direct Cursor Control (RS value = 1001) */ + temp = ramdac->dcc; + break; + case 0x0a: /* Indexed Data (RS value = 1010) */ + switch (ramdac->ind_idx) { + case 0x01: /* Silicon Revision */ + temp = 0x00; + break; + case 0x06: /* Indirect Cursor Control */ + temp = ramdac->ccr; + break; + case 0x0f: /* Latch Control */ + temp = ramdac->latch_cntl; + break; + case 0x18: /* True Color Control */ + temp = ramdac->true_color; + break; + case 0x19: /* Multiplex Control */ + temp = ramdac->mcr; + break; + case 0x1c: /* Palette-Page Register */ + temp = ramdac->ppr; + break; + case 0x1d: /* General Control Register */ + temp = ramdac->general_cntl; + break; + case 0x1e: /* Miscellaneous Control */ + temp = ramdac->misc; + break; + case 0x39: /* MCLK/Loop Clock Control */ + temp = ramdac->mclk; + break; + case 0x3f: /* ID */ + temp = 0x26; + break; + } + break; + case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */ + index = (svga->dac_addr - 1) & da_mask; + cd = (uint8_t *) ramdac->cursor64_data; + temp = cd[index]; + + svga->dac_addr = (svga->dac_addr + 1) & da_mask; + break; + case 0x0c: /* Cursor X Low Register (RS value = 1100) */ + temp = ramdac->hwc_x & 0xff; + break; + case 0x0d: /* Cursor X High Register (RS value = 1101) */ + temp = (ramdac->hwc_x >> 8) & 0xff; + break; + case 0x0e: /* Cursor Y Low Register (RS value = 1110) */ + temp = ramdac->hwc_y & 0xff; + break; + case 0x0f: /* Cursor Y High Register (RS value = 1111) */ + temp = (ramdac->hwc_y >> 8) & 0xff; + break; + } + + return temp; +} + +void +tvp3026_recalctimings(void *p, svga_t *svga) +{ + tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) p; + + svga->interlace = (ramdac->ccr & 0x40); +} + + +void +tvp3026_hwcursor_draw(svga_t *svga, int displine) +{ + int x, xx, comb, b0, b1; + uint16_t dat[2]; + int offset = svga->dac_hwcursor_latch.x + svga->dac_hwcursor_latch.xoff; + int pitch, bppl, mode, x_pos, y_pos; + uint32_t clr1, clr2, clr3, *p; + uint8_t *cd; + tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) svga->ramdac; + + clr1 = ramdac->extpallook[1]; + clr2 = ramdac->extpallook[2]; + clr3 = ramdac->extpallook[3]; + + /* The planes come in two parts, and each plane is 1bpp, + so a 32x32 cursor has 4 bytes per line, and a 64x64 + cursor has 8 bytes per line. */ + pitch = (svga->dac_hwcursor_latch.xsize >> 3); /* Bytes per line. */ + /* A 32x32 cursor has 128 bytes per line, and a 64x64 + cursor has 512 bytes per line. */ + bppl = (pitch * svga->dac_hwcursor_latch.ysize); /* Bytes per plane. */ + mode = ramdac->mode; + + if (svga->interlace && svga->dac_hwcursor_oddeven) + svga->dac_hwcursor_latch.addr += pitch; + + cd = (uint8_t *) ramdac->cursor64_data; + + for (x = 0; x < svga->dac_hwcursor_latch.xsize; x += 16) { + dat[0] = (cd[svga->dac_hwcursor_latch.addr] << 8) | + cd[svga->dac_hwcursor_latch.addr + 1]; + dat[1] = (cd[svga->dac_hwcursor_latch.addr + bppl] << 8) | + cd[svga->dac_hwcursor_latch.addr + bppl + 1]; + + for (xx = 0; xx < 16; xx++) { + b0 = (dat[0] >> (15 - xx)) & 1; + b1 = (dat[1] >> (15 - xx)) & 1; + comb = (b0 | (b1 << 1)); + + y_pos = displine; + x_pos = offset + svga->x_add; + p = buffer32->line[y_pos]; + + if (offset >= svga->dac_hwcursor_latch.x) { + switch (mode) { + case 1: /* Three Color */ + switch (comb) { + case 1: + p[x_pos] = clr1; + break; + case 2: + p[x_pos] = clr2; + break; + case 3: + p[x_pos] = clr3; + break; + } + break; + case 2: /* XGA */ + switch (comb) { + case 0: + p[x_pos] = clr1; + break; + case 1: + p[x_pos] = clr2; + break; + case 3: + p[x_pos] ^= 0xffffff; + break; + } + break; + case 3: /* X-Windows */ + switch (comb) { + case 2: + p[x_pos] = clr1; + break; + case 3: + p[x_pos] = clr2; + break; + } + break; + } + } + offset++; + } + svga->dac_hwcursor_latch.addr += 2; + } + + if (svga->interlace && !svga->dac_hwcursor_oddeven) + svga->dac_hwcursor_latch.addr += pitch; +} + + +void * +tvp3026_ramdac_init(const device_t *info) +{ + tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) malloc(sizeof(tvp3026_ramdac_t)); + memset(ramdac, 0, sizeof(tvp3026_ramdac_t)); + + ramdac->type = info->local; + + ramdac->latch_cntl = 0x06; + ramdac->true_color = 0x80; + ramdac->mcr = 0x98; + ramdac->mclk = 0x18; + + return ramdac; +} + + +static void +tvp3026_ramdac_close(void *priv) +{ + tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) priv; + + if (ramdac) + free(ramdac); +} + + +const device_t tvp3026_ramdac_device = +{ + "TI TVP3026 RAMDAC", + 0, 0, + tvp3026_ramdac_init, tvp3026_ramdac_close, + NULL, { NULL }, NULL, NULL +}; diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 5fe5790b0..02e3f7ac1 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -779,7 +779,8 @@ VIDOBJ := video.o \ vid_s3.o vid_s3_virge.o \ vid_ibm_rgb528_ramdac.o vid_sdac_ramdac.o \ vid_ogc.o \ - vid_nga.o + vid_nga.o \ + vid_tvp3026_ramdac.o VOODOOOBJ := vid_voodoo.o vid_voodoo_banshee.o \ vid_voodoo_banshee_blitter.o \ From 603bf1fdfd5c4474f1e338a1e48df3f21a9a48c8 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 2 Sep 2021 23:08:24 +0600 Subject: [PATCH 08/24] Port close fix to unix_sdl.c --- src/unix/unix_sdl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/unix/unix_sdl.c b/src/unix/unix_sdl.c index db3b6e591..e5abdcd32 100644 --- a/src/unix/unix_sdl.c +++ b/src/unix/unix_sdl.c @@ -198,7 +198,8 @@ sdl_destroy_texture(void) void sdl_close(void) { - SDL_LockMutex(sdl_mutex); + if (sdl_mutex != NULL) + SDL_LockMutex(sdl_mutex); /* Unregister our renderer! */ video_setblit(NULL); From aa58c637f5e7dcb88bc43cbbcebe306e0570f4b0 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 2 Sep 2021 23:59:14 +0600 Subject: [PATCH 09/24] Default to "build" binary directory for presets --- CMakePresets.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CMakePresets.json b/CMakePresets.json index 8fc5f21a1..843727936 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -19,7 +19,8 @@ "CMAKE_C_FLAGS_OPTIMIZED": "-march=native -mtune=native -O3 -ffp-contract=last -flto", "CMAKE_CXX_FLAGS_OPTIMIZED": "-march=native -mtune=native -O3 -ffp-contract=last -flto" }, - "hidden": true + "hidden": true, + "binaryDir": "build" }, { "name": "regular", @@ -70,4 +71,4 @@ } } ] -} \ No newline at end of file +} From 84f4b8cac7ddbc51e02adbefb55371b46b57a095 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 2 Sep 2021 20:15:46 +0200 Subject: [PATCH 10/24] Added a bunch of parameters (including one to specify custom ROM path), fixed a warnings, removed excess commented out code from video/vid_voodoo.c, and made Makefile.mingw quiet again. --- src/86box.c | 100 +++++++++++++++++++++++++++++++------- src/config.c | 4 +- src/include/86box/86box.h | 1 + src/mem/rom.c | 29 ++++++++++- src/video/vid_voodoo.c | 16 ------ src/win/Makefile.mingw | 2 +- 6 files changed, 114 insertions(+), 38 deletions(-) diff --git a/src/86box.c b/src/86box.c index 3264a2959..4ad02ff1a 100644 --- a/src/86box.c +++ b/src/86box.c @@ -109,6 +109,7 @@ int confirm_exit_cmdl = 1; /* (O) do not ask for confirmation on quit if set t uint64_t unique_id = 0; uint64_t source_hwnd = 0; #endif +char rom_path[1024] = { '\0'}; /* (O) full path to ROMs */ char log_path[1024] = { '\0'}; /* (O) full path of logfile */ char vm_name[1024] = { '\0'}; /* (O) display name of the VM */ @@ -379,12 +380,13 @@ pc_log(const char *fmt, ...) int pc_init(int argc, char *argv[]) { - char path[2048]; + char path[2048], path2[2048]; char *cfg = NULL, *p; char temp[128]; struct tm *info; time_t now; - int c; + int c, ng; + int lvmp; uint32_t *uid, *shwnd; /* Grab the executable's full path. */ @@ -401,7 +403,10 @@ pc_init(int argc, char *argv[]) * could have been set to something else. */ plat_getcwd(usr_path, sizeof(usr_path) - 1); + plat_getcwd(rom_path, sizeof(rom_path) - 1); + memset(path, 0x00, sizeof(path)); + memset(path2, 0x00, sizeof(path)); for (c=1; ctex_mem[0], voodoo->texture_size*1024*1024, 1, f); - fclose(f); - if (voodoo->dual_tmus) - { - f = rom_fopen("texram2.dmp", "wb"); - fwrite(voodoo->tex_mem[1], voodoo->texture_size*1024*1024, 1, f); - fclose(f); - } -#endif */ - voodoo->fifo_thread_run = 0; thread_set_event(voodoo->wake_fifo_thread); diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 5fe5790b0..56c7c26ba 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -838,7 +838,7 @@ LIBS += -static ifeq ($(AUTODEP), y) %.o: %.c @echo $< - $(CC) $(CFLAGS) $(DEPS) -c $< + @$(CC) $(CFLAGS) $(DEPS) -c $< %.o: %.cc @echo $< From 5b972fc4770d2d30900c6380c306f655c815aa8b Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 2 Sep 2021 20:52:30 +0200 Subject: [PATCH 11/24] Implemented CD Audio de-emphasizing for pre-emphasized tracks, closes #1623. --- src/cdrom/cdrom.c | 10 +++++++ src/cdrom/cdrom_image.c | 19 ++++++++++++- src/cdrom/cdrom_image_backend.c | 37 ++++++++++++++++++++++++- src/include/86box/cdrom.h | 2 ++ src/include/86box/cdrom_image_backend.h | 3 +- src/sound/sound.c | 11 +++++++- 6 files changed, 78 insertions(+), 4 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 223e1411c..37615a32e 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -238,6 +238,16 @@ cdrom_seek(cdrom_t *dev, uint32_t pos) } +int +cdrom_is_pre(cdrom_t *dev, uint32_t lba) +{ + if (dev->ops && dev->ops->is_track_pre) + return dev->ops->is_track_pre(dev, lba); + + return 0; +} + + int cdrom_audio_callback(cdrom_t *dev, int16_t *output, int len) { diff --git a/src/cdrom/cdrom_image.c b/src/cdrom/cdrom_image.c index 2df0801c3..91e4992b4 100644 --- a/src/cdrom/cdrom_image.c +++ b/src/cdrom/cdrom_image.c @@ -155,12 +155,28 @@ image_is_track_audio(cdrom_t *dev, uint32_t pos, int ismsf) if (track == -1) return 0; else { - cdi_get_audio_track_info(img, 0, cdi_get_track(img, pos), &number, &tmsf, &attr); + cdi_get_audio_track_info(img, 0, track, &number, &tmsf, &attr); return attr == AUDIO_TRACK; } } +static int +image_is_track_pre(cdrom_t *dev, uint32_t lba) +{ + cd_img_t *img = (cd_img_t *)dev->image; + int track; + + /* GetTrack requires LBA. */ + track = cdi_get_track(img, lba); + + if (track != -1) + return cdi_get_audio_track_pre(img, track); + + return 0; +} + + static int image_sector_size(struct cdrom *dev, uint32_t lba) { @@ -231,6 +247,7 @@ static const cdrom_ops_t cdrom_image_ops = { image_get_tracks, image_get_track_info, image_get_subchannel, + image_is_track_pre, image_sector_size, image_read_sector, image_track_type, diff --git a/src/cdrom/cdrom_image_backend.c b/src/cdrom/cdrom_image_backend.c index cf4cb0005..ae6e4bb39 100644 --- a/src/cdrom/cdrom_image_backend.c +++ b/src/cdrom/cdrom_image_backend.c @@ -272,6 +272,18 @@ cdi_get_audio_tracks_lba(cd_img_t *cdi, int *st_track, int *end, uint32_t *lead_ } +int +cdi_get_audio_track_pre(cd_img_t *cdi, int track) +{ + track_t *trk = &cdi->tracks[track - 1]; + + if ((track < 1) || (track > cdi->tracks_num)) + return 0; + + return trk->pre; +} + + /* This replaces both Info and EndInfo, they are specified by a variable. */ int cdi_get_audio_track_info(cd_img_t *cdi, int end, int track, int *track_num, TMSF *start, uint8_t *attr) @@ -709,6 +721,25 @@ cdi_cue_get_frame(uint64_t *frames, char **line) } +static int +cdi_cue_get_flags(track_t *cur, char **line) +{ + char temp[128], temp2[128]; + int success; + + success = cdi_cue_get_buffer(temp, line, 0); + if (! success) return 0; + + memset(temp2, 0x00, sizeof(temp2)); + success = sscanf(temp, "%s", temp2) == 1; + if (! success) return 0; + + cur->pre = (strstr(temp2, "PRE") != NULL); + + return 1; +} + + static int cdi_add_track(cd_img_t *cdi, track_t *cur, uint64_t *shift, uint64_t prestart, uint64_t *total_pregap, uint64_t cur_pregap) { @@ -850,6 +881,8 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile) trk.form = 0; trk.mode2 = 0; + trk.pre = 0; + if (!strcmp(type, "AUDIO")) { trk.sector_size = RAW_SECTOR_SIZE; trk.attr = AUDIO_TRACK; @@ -964,7 +997,9 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile) } } else if (!strcmp(command, "PREGAP")) success = cdi_cue_get_frame(&cur_pregap, &line); - else if (!strcmp(command, "CATALOG") || !strcmp(command, "CDTEXTFILE") || !strcmp(command, "FLAGS") || !strcmp(command, "ISRC") || + else if (!strcmp(command, "FLAGS")) + success = cdi_cue_get_flags(&trk, &line); + else if (!strcmp(command, "CATALOG") || !strcmp(command, "CDTEXTFILE") || !strcmp(command, "ISRC") || !strcmp(command, "PERFORMER") || !strcmp(command, "POSTGAP") || !strcmp(command, "REM") || !strcmp(command, "SONGWRITER") || !strcmp(command, "TITLE") || !strcmp(command, "")) { /* Ignored commands. */ diff --git a/src/include/86box/cdrom.h b/src/include/86box/cdrom.h index 759932198..95b806d30 100644 --- a/src/include/86box/cdrom.h +++ b/src/include/86box/cdrom.h @@ -83,6 +83,7 @@ typedef struct { void (*get_tracks)(struct cdrom *dev, int *first, int *last); void (*get_track_info)(struct cdrom *dev, uint32_t track, int end, track_info_t *ti); void (*get_subchannel)(struct cdrom *dev, uint32_t lba, subchannel_t *subc); + int (*is_track_pre)(struct cdrom *dev, uint32_t lba); int (*sector_size)(struct cdrom *dev, uint32_t lba); int (*read_sector)(struct cdrom *dev, int type, uint8_t *b, uint32_t lba); int (*track_type)(struct cdrom *dev, uint32_t lba); @@ -136,6 +137,7 @@ extern cdrom_t cdrom[CDROM_NUM]; extern int cdrom_lba_to_msf_accurate(int lba); extern double cdrom_seek_time(cdrom_t *dev); extern void cdrom_stop(cdrom_t *dev); +extern int cdrom_is_pre(cdrom_t *dev, uint32_t lba); extern int cdrom_audio_callback(cdrom_t *dev, int16_t *output, int len); extern uint8_t cdrom_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf); extern uint8_t cdrom_audio_track_search(cdrom_t *dev, uint32_t pos, int type, uint8_t playbit); diff --git a/src/include/86box/cdrom_image_backend.h b/src/include/86box/cdrom_image_backend.h index 5d5901320..74be1df69 100644 --- a/src/include/86box/cdrom_image_backend.h +++ b/src/include/86box/cdrom_image_backend.h @@ -58,7 +58,7 @@ typedef struct { typedef struct { int number, track_number, attr, sector_size, - mode2, form; + mode2, form, pre, pad; uint64_t start, length, skip; track_file_t *file; @@ -75,6 +75,7 @@ extern void cdi_close(cd_img_t *cdi); extern int cdi_set_device(cd_img_t *cdi, const char *path); extern int cdi_get_audio_tracks(cd_img_t *cdi, int *st_track, int *end, TMSF *lead_out); extern int cdi_get_audio_tracks_lba(cd_img_t *cdi, int *st_track, int *end, uint32_t *lead_out); +extern int cdi_get_audio_track_pre(cd_img_t *cdi, int track); extern int cdi_get_audio_track_info(cd_img_t *cdi, int end, int track, int *track_num, TMSF *start, uint8_t *attr); extern int cdi_get_audio_track_info_lba(cd_img_t *cdi, int end, int track, int *track_num, uint32_t *start, uint8_t *attr); extern int cdi_get_track(cd_img_t *cdi, uint32_t sector); diff --git a/src/sound/sound.c b/src/sound/sound.c index fa5d180ac..663983738 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -212,7 +212,8 @@ sound_cd_clean_buffers(void) static void sound_cd_thread(void *param) { - int c, r, i, channel_select[2]; + uint32_t lba; + int c, r, i, pre, channel_select[2]; double audio_vol_l, audio_vol_r; double cd_buffer_temp[2] = {0.0, 0.0}; @@ -231,9 +232,11 @@ sound_cd_thread(void *param) if ((cdrom[i].bus_type == CDROM_BUS_DISABLED) || (cdrom[i].cd_status == CD_STATUS_EMPTY)) continue; + lba = cdrom[i].seek_pos; r = cdrom_audio_callback(&(cdrom[i]), cd_buffer[i], CD_BUFLEN * 2); if (!cdrom[i].bus_type || !cdrom[i].sound_on || !r) continue; + pre = cdrom_is_pre(&(cdrom[i]), lba); if (cdrom[i].get_volume) { audio_vol_l = (float) (cdrom[i].get_volume(cdrom[i].priv, 0)); @@ -277,6 +280,9 @@ sound_cd_thread(void *param) cd_buffer_temp[0] += ((double) cd_buffer[i][c + 1]); /* Channel 1 => Port 0 */ cd_buffer_temp[0] *= audio_vol_l; /* Multiply Port 0 by Port 0 volume */ + + if (pre) + cd_buffer_temp[0] = deemph_iir(0, cd_buffer_temp[0]); /* De-emphasize if necessary */ } if ((audio_vol_r != 0.0) && (channel_select[1] != 0)) { @@ -286,6 +292,9 @@ sound_cd_thread(void *param) cd_buffer_temp[1] += ((double) cd_buffer[i][c + 1]); /* Channel 1 => Port 1 */ cd_buffer_temp[1] *= audio_vol_r; /* Multiply Port 1 by Port 1 volume */ + + if (pre) + cd_buffer_temp[1] = deemph_iir(1, cd_buffer_temp[1]); /* De-emphasize if necessary */ } /* Apply sound card CD volume and filters */ From ef03d2c4b9e1ed04fd79430b6e70694a417e2756 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 2 Sep 2021 21:23:46 +0200 Subject: [PATCH 12/24] A fix to 86box.c. --- src/86box.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/86box.c b/src/86box.c index 4ad02ff1a..7916db29f 100644 --- a/src/86box.c +++ b/src/86box.c @@ -385,8 +385,8 @@ pc_init(int argc, char *argv[]) char temp[128]; struct tm *info; time_t now; - int c, ng; - int lvmp; + int c; + int ng = 0, lvmp = 0; uint32_t *uid, *shwnd; /* Grab the executable's full path. */ From e74cd24c171bc457f2df6934553069eb6af93ea5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 2 Sep 2021 21:28:47 +0200 Subject: [PATCH 13/24] Increased the size of the gdcreg array. --- src/include/86box/vid_svga.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 73c176742..a850d4b9e 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -126,7 +126,7 @@ typedef struct svga_t int override; void *p; - uint8_t crtc[256], gdcreg[64], attrregs[32], seqregs[256], + uint8_t crtc[256], gdcreg[256], attrregs[32], seqregs[256], egapal[16], *vram, *changedvram; From 3268c0299de187f701899b1ff388d633af00ea1f Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 2 Sep 2021 22:56:51 +0200 Subject: [PATCH 14/24] Implemented DDMA for the VIA southbridges that support it, closes #1613. --- src/chipset/via_pipc.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/chipset/via_pipc.c b/src/chipset/via_pipc.c index 5b86c8d59..41667edfd 100644 --- a/src/chipset/via_pipc.c +++ b/src/chipset/via_pipc.c @@ -37,6 +37,7 @@ #include <86box/timer.h> #include <86box/nvr.h> #include <86box/acpi.h> +#include <86box/ddma.h> #include <86box/pci.h> #include <86box/pic.h> #include <86box/port_92.h> @@ -79,6 +80,7 @@ typedef struct sff8038i_t *bm[2]; nvr_t *nvr; int nvr_enabled, slot; + ddma_t *ddma; smbus_piix4_t *smbus; usb_t *usb[2]; acpi_t *acpi; @@ -708,6 +710,19 @@ usb_update_io_mapping(pipc_t *dev, int func) } +static void +pipc_ddma_update(pipc_t *dev, int addr) +{ + uint32_t base; + + if (dev->local >= VIA_PIPC_8231) + return; + + base = (dev->pci_isa_regs[addr] & 0xf0) | (((uint32_t) dev->pci_isa_regs[addr | 0x01]) << 8); + ddma_update_io_mapping(dev->ddma, (addr & 0x0e) >> 1, (dev->pci_isa_regs[addr] & 0xf0), dev->pci_isa_regs[addr | 0x01], (dev->pci_isa_regs[addr] & 0x08) && (base != 0x0000)); +} + + static void pipc_write(int func, int addr, uint8_t val, void *priv) { @@ -854,19 +869,13 @@ pipc_write(int func, int addr, uint8_t val, void *priv) case 0x60: case 0x62: case 0x64: case 0x66: case 0x6a: case 0x6c: case 0x6e: - c = (addr & 0x0e) >> 1; - dma[c].ab = (dma[c].ab & 0xffffff0f) | (val & 0xf0); - dma[c].ac = (dma[c].ac & 0xffffff0f) | (val & 0xf0); - if (val & 0x08) - dma_e |= (1 << c); - else - dma_e &= ~(1 << c); + dev->pci_isa_regs[addr] = val & 0xf8; + pipc_ddma_update(dev, addr); break; case 0x61: case 0x63: case 0x65: case 0x67: case 0x6b: case 0x6d: case 0x6f: - c = (addr & 0x0e) >> 1; - dma[c].ab = (dma[c].ab & 0xffff00ff) | (val << 8); - dma[c].ac = (dma[c].ac & 0xffff00ff) | (val << 8); + dev->pci_isa_regs[addr] = val; + pipc_ddma_update(dev, addr & 0xfe); break; case 0x70: case 0x71: case 0x72: case 0x73: @@ -1353,6 +1362,9 @@ pipc_init(const device_t *info) pci_enable_mirq(2); } + if (dev->local < VIA_PIPC_8231) + dev->ddma = device_add(&ddma_device); + if (dev->acpi) { acpi_set_slot(dev->acpi, dev->slot); acpi_set_nvr(dev->acpi, dev->nvr); From 3b3d863ed0d0e764c196fcc5f4d9846e2a05586c Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 2 Sep 2021 23:16:54 +0200 Subject: [PATCH 15/24] Fixed more bugs in 86box.c - the paths are now displayed, and also made it display the ROM path. --- src/86box.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/86box.c b/src/86box.c index 7916db29f..02843b48e 100644 --- a/src/86box.c +++ b/src/86box.c @@ -620,6 +620,7 @@ usage: /* Make sure we have a trailing backslash. */ plat_path_slash(usr_path); + plat_path_slash(rom_path); /* At this point, we can safely create the full path name. */ plat_append_filename(cfg_path, usr_path, p); @@ -647,15 +648,13 @@ usage: strftime(temp, sizeof(temp), "%Y/%m/%d %H:%M:%S", info); pclog("#\n# %ls v%ls logfile, created %s\n#\n", EMU_NAME_W, EMU_VERSION_W, temp); -#ifdef _WIN32 - pclog("# Emulator path: %ls\n", exe_path); - pclog("# Userfiles path: %ls\n", usr_path); - pclog("# Configuration file: %ls\n#\n\n", cfg_path); -#else pclog("# Emulator path: %s\n", exe_path); pclog("# Userfiles path: %s\n", usr_path); + if (rom_path[0] != '\0') + pclog("# ROM path: %s\n", rom_path); + else + pclog("# ROM path: %sroms\\\n", usr_path); pclog("# Configuration file: %s\n#\n\n", cfg_path); -#endif /* * We are about to read the configuration file, which MAY * put data into global variables (the hard- and floppy From 024083fd998cc51fa54f2befe9528f23ace8077e Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 2 Sep 2021 23:20:57 +0200 Subject: [PATCH 16/24] And even more bug fixes in 86box.c, to fix the mess I accidentally created in the previous commit. --- src/86box.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/86box.c b/src/86box.c index 02843b48e..4f3cfe5b4 100644 --- a/src/86box.c +++ b/src/86box.c @@ -620,7 +620,8 @@ usage: /* Make sure we have a trailing backslash. */ plat_path_slash(usr_path); - plat_path_slash(rom_path); + if (rom_path[0] != '\0') + plat_path_slash(rom_path); /* At this point, we can safely create the full path name. */ plat_append_filename(cfg_path, usr_path, p); @@ -653,7 +654,7 @@ usage: if (rom_path[0] != '\0') pclog("# ROM path: %s\n", rom_path); else - pclog("# ROM path: %sroms\\\n", usr_path); + pclog("# ROM path: %sroms\\\n", exe_path); pclog("# Configuration file: %s\n#\n\n", cfg_path); /* * We are about to read the configuration file, which MAY From 833971d8e3af76ac3087c4fb3593b82aa9333952 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 2 Sep 2021 23:26:24 +0200 Subject: [PATCH 17/24] Added -M / --vmrompath option for per-emulated-machine ROM path. --- src/86box.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/86box.c b/src/86box.c index 4f3cfe5b4..099a57903 100644 --- a/src/86box.c +++ b/src/86box.c @@ -385,7 +385,7 @@ pc_init(int argc, char *argv[]) char temp[128]; struct tm *info; time_t now; - int c; + int c, vmrp = 0; int ng = 0, lvmp = 0; uint32_t *uid, *shwnd; @@ -429,6 +429,7 @@ usage: printf("-H or --hwnd id,hwnd - sends back the main dialog's hwnd\n"); #endif printf("-L or --logfile path - set 'path' to be the logfile\n"); + printf("-M or --vmrompath - ROM path is roms subdirectory inside the userfiles path\n"); printf("-N or --noconfirm - do not ask for confirmation on quit\n"); printf("-O or --dumpcfg - dump config file after loading\n"); printf("-P or --vmpath path - set 'path' to be root for vm\n"); @@ -438,6 +439,9 @@ usage: printf("-Z or --lastvmpath - the last parameter is VM path rather than config\n"); printf("\nA config file can be specified. If none is, the default file will be used.\n"); return(0); + } else if (!strcasecmp(argv[c], "--vmrompath") || + !strcasecmp(argv[c], "-M")) { + vmrp = 1; } else if (!strcasecmp(argv[c], "--lastvmpath") || !strcasecmp(argv[c], "-Z")) { lvmp = 1; @@ -555,6 +559,12 @@ usage: plat_dir_create(usr_path); } + if (vmrp && (path2[0] == '\0')) { + strcpy(path2, usr_path); + plat_path_slash(path2); + strcat(path2, "roms/"); + } + /* * If the user provided a path for ROMs, use that * instead of the current working directory. We do From 3644329bb60a18eb410f6341b0086d9aaeb93467 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 2 Sep 2021 23:26:54 +0200 Subject: [PATCH 18/24] An a fix to that. --- src/86box.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/86box.c b/src/86box.c index 099a57903..e89dc4723 100644 --- a/src/86box.c +++ b/src/86box.c @@ -562,7 +562,8 @@ usage: if (vmrp && (path2[0] == '\0')) { strcpy(path2, usr_path); plat_path_slash(path2); - strcat(path2, "roms/"); + strcat(path2, "roms"); + plat_path_slash(path2); } /* From d17e53fc4bff00c3a1d68215c608b5fa10e43266 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 2 Sep 2021 23:34:15 +0200 Subject: [PATCH 19/24] Added VM name display. --- src/86box.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/86box.c b/src/86box.c index e89dc4723..82c847eaa 100644 --- a/src/86box.c +++ b/src/86box.c @@ -638,14 +638,13 @@ usage: plat_append_filename(cfg_path, usr_path, p); /* - * Get the current directory's name + * Get the current directory's name * * At this point usr_path is perfectly initialized. * If no --vmname parameter specified we'll use the * working directory name as the VM's name. */ - if (strlen(vm_name) == 0) - { + if (strlen(vm_name) == 0) { char ltemp[1024] = { '\0'}; plat_get_dirname(ltemp, usr_path); strcpy(vm_name, plat_get_filename(ltemp)); @@ -660,6 +659,7 @@ usage: strftime(temp, sizeof(temp), "%Y/%m/%d %H:%M:%S", info); pclog("#\n# %ls v%ls logfile, created %s\n#\n", EMU_NAME_W, EMU_VERSION_W, temp); + pclog("# VM: %s\n#\n", vm_name); pclog("# Emulator path: %s\n", exe_path); pclog("# Userfiles path: %s\n", usr_path); if (rom_path[0] != '\0') From 391c6a357163d942be7f7b4079e7ed78cfe69c0f Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 3 Sep 2021 00:05:43 +0200 Subject: [PATCH 20/24] S3 & TVP3026: Part 2. Reworked the pix tranfer register to allow a word in a byte transfer. Added an alternative bios selection for the SPEA Mirage 801 card (3.05I and 4.01, the latter being the default now. Added the MiroCrystal 10SD 805 VLB, Phoenix 801 ISA, MiroVideo 40SV 968 VLB/PCI, SPEA Mercury P64V 968 PCI , SPEA Mirage P64 Trio64 VLB cards. Removed some non-working S3 cards like the Trio64V+ VLB and Elsa Winner 2000 Pro X VLB (only PCI variants of these cards are now in) --- src/include/86box/vid_svga.h | 7 +- src/include/86box/video.h | 12 +- src/video/vid_s3.c | 1234 +++++++++++++++++++++++++--------- src/video/vid_table.c | 58 +- 4 files changed, 950 insertions(+), 361 deletions(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 73c176742..eed2d2ad2 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -126,7 +126,7 @@ typedef struct svga_t int override; void *p; - uint8_t crtc[256], gdcreg[64], attrregs[32], seqregs[256], + uint8_t crtc[256], gdcreg[256], attrregs[32], seqregs[256], egapal[16], *vram, *changedvram; @@ -264,6 +264,10 @@ extern float stg_getclock(int clock, void *p); extern void tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga); extern uint8_t tkd8001_ramdac_in(uint16_t addr, void *p, svga_t *svga); +extern void tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t *svga); +extern uint8_t tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga); +extern void tvp3026_recalctimings(void *p, svga_t *svga); +extern void tvp3026_hwcursor_draw(svga_t *svga, int displine); #ifdef EMU_DEVICE_H extern const device_t ati68860_ramdac_device; @@ -292,4 +296,5 @@ extern const device_t stg_ramdac_device; extern const device_t tkd8001_ramdac_device; extern const device_t tseng_ics5301_ramdac_device; extern const device_t tseng_ics5341_ramdac_device; +extern const device_t tvp3026_ramdac_device; #endif diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 311c707df..8b9ddab84 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -325,7 +325,10 @@ extern const device_t s3_diamond_stealth_vram_isa_device; extern const device_t s3_ami_86c924_isa_device; extern const device_t s3_metheus_86c928_isa_device; extern const device_t s3_metheus_86c928_vlb_device; -extern const device_t s3_v7mirage_86c801_isa_device; +extern const device_t s3_spea_mirage_86c801_isa_device; +extern const device_t s3_spea_mirage_86c805_vlb_device; +extern const device_t s3_mirocrystal_10sd_805_vlb_device; +extern const device_t s3_phoenix_86c801_isa_device; extern const device_t s3_phoenix_86c805_vlb_device; extern const device_t s3_bahamas64_vlb_device; extern const device_t s3_bahamas64_pci_device; @@ -335,10 +338,10 @@ extern const device_t s3_phoenix_trio32_vlb_device; extern const device_t s3_phoenix_trio32_pci_device; extern const device_t s3_diamond_stealth_se_vlb_device; extern const device_t s3_diamond_stealth_se_pci_device; +extern const device_t s3_spea_mirage_p64_vlb_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_trio64vplus_onboard_pci_device; extern const device_t s3_phoenix_vision864_pci_device; @@ -349,10 +352,11 @@ extern const device_t s3_diamond_stealth64_pci_device; extern const device_t s3_diamond_stealth64_vlb_device; extern const device_t s3_diamond_stealth64_964_pci_device; extern const device_t s3_diamond_stealth64_964_vlb_device; +extern const device_t s3_mirovideo_40sv_968_pci_device; +extern const device_t s3_mirovideo_40sv_968_vlb_device; +extern const device_t s3_spea_mercury_p64v_pci_device; extern const device_t s3_elsa_winner2000_pro_x_964_pci_device; -extern const device_t s3_elsa_winner2000_pro_x_964_vlb_device; extern const device_t s3_elsa_winner2000_pro_x_pci_device; -extern const device_t s3_elsa_winner2000_pro_x_vlb_device; extern const device_t s3_trio64v2_dx_pci_device; /* S3 ViRGE */ diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 8d24ac201..36220e8f0 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -41,12 +41,15 @@ #define ROM_DIAMOND_STEALTH_VRAM "roms/video/s3/Diamond Stealth VRAM BIOS v2.31 U14.BIN" #define ROM_AMI_86C924 "roms/video/s3/S3924AMI.BIN" #define ROM_METHEUS_86C928 "roms/video/s3/928.vbi" -#define ROM_V7MIRAGE_86C801 "roms/video/s3/v7mirage.vbi" -#define ROM_PHOENIX_86C805 "roms/video/s3/805.vbi" +#define ROM_SPEA_MIRAGE_86C801_V305I "roms/video/s3/V7MIRAGE.VBI" +#define ROM_SPEA_MIRAGE_86C801_V401 "roms/video/s3/S3_805VL_ATT20C491_SPEAmirage_VL_4.01.BIN" +#define ROM_MIROCRYSTAL10SD_805 "roms/video/s3/MIROcrystal10SD_VLB.VBI" +#define ROM_PHOENIX_86C80X "roms/video/s3/805.vbi" #define ROM_PARADISE_BAHAMAS64 "roms/video/s3/bahamas64.bin" #define ROM_PHOENIX_VISION864 "roms/video/s3/86c864p.bin" #define ROM_DIAMOND_STEALTH64_964 "roms/video/s3/964_107h.rom" #define ROM_PHOENIX_TRIO32 "roms/video/s3/86c732p.bin" +#define ROM_SPEA_MIRAGE_P64 "roms/video/s3/S3_764VL_SPEAMirageP64VL_ver5_03.BIN" #define ROM_NUMBER9_9FX "roms/video/s3/s3_764.bin" #define ROM_PHOENIX_TRIO64 "roms/video/s3/86c764x1.bin" #define ROM_DIAMOND_STEALTH64_764 "roms/video/s3/stealt64.bin" @@ -56,6 +59,8 @@ #define ROM_ELSAWIN2KPROX_964 "roms/video/s3/elsaw20004m.BIN" #define ROM_ELSAWIN2KPROX "roms/video/s3/elsaw20008m.BIN" #define ROM_PHOENIX_VISION868 "roms/video/s3/1-DSV3868.BIN" +#define ROM_MIROVIDEO40SV_968 "roms/video/s3/S3_968PCI_TVP3026_miroVideo40SV_PCI_1.04.BIN" +#define ROM_SPEA_MERCURY_P64V "roms/video/s3/S3_968PCI_TVP3026_SPEAMecuryP64V_ver1.01.BIN" enum { @@ -67,7 +72,9 @@ enum S3_PHOENIX_TRIO64_ONBOARD, S3_PHOENIX_VISION864, S3_DIAMOND_STEALTH64_764, - S3_V7MIRAGE_86C801, + S3_SPEA_MIRAGE_86C801, + S3_SPEA_MIRAGE_86C805, + S3_PHOENIX_86C801, S3_PHOENIX_86C805, S3_ORCHID_86C911, S3_METHEUS_86C928, @@ -79,7 +86,11 @@ enum S3_DIAMOND_STEALTH_VRAM, S3_ELSAWIN2KPROX_964, S3_ELSAWIN2KPROX, - S3_PHOENIX_VISION868 + S3_PHOENIX_VISION868, + S3_MIROVIDEO40SV_968, + S3_MIROCRYSTAL10SD_805, + S3_SPEA_MIRAGE_P64, + S3_SPEA_MERCURY_P64V }; @@ -217,10 +228,11 @@ typedef struct s3_t uint16_t multifunc_cntl; uint16_t multifunc[16]; uint8_t pix_trans[4]; + int ssv_state; int cx, cy; int px, py; - int sx, sy; + int sx, sy, sx_backup; int dx, dy; uint32_t src, dest, pattern; @@ -235,6 +247,9 @@ typedef struct s3_t int dat_count; int b2e8_pix, temp_cnt; uint8_t cur_x_bit12, cur_y_bit12; + int ssv_len1, ssv_len2; + uint8_t ssv_dir1, ssv_dir2; + uint8_t ssv_draw1, ssv_draw2; } accel; struct { @@ -350,6 +365,8 @@ static void s3_accel_out(uint16_t port, uint8_t val, void *p); static void s3_accel_out_w(uint16_t port, uint16_t val, void *p); static void s3_accel_out_l(uint16_t port, uint32_t val, void *p); static uint8_t s3_accel_in(uint16_t port, void *p); +static uint16_t s3_accel_in_w(uint16_t port, void *p); +static uint32_t s3_accel_in_l(uint16_t port, void *p); static uint8_t s3_pci_read(int func, int addr, void *p); static void s3_pci_write(int func, int addr, uint8_t val, void *p); @@ -392,6 +409,53 @@ static void s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3); case 3: var = (var & 0x00ffffff) | ((val) << 24); break; \ } + +#define READ_PIXTRANS_BYTE_IO(n) \ + if (s3->bpp == 0) \ + s3->accel.pix_trans[n] = svga->vram[(s3->accel.dest + s3->accel.cx + n) & s3->vram_mask]; \ + else if (s3->bpp == 1) \ + s3->accel.pix_trans[n] = svga->vram[(s3->accel.dest + s3->accel.cx + n) & (s3->vram_mask >> 1)]; \ + else \ + s3->accel.pix_trans[n] = svga->vram[(s3->accel.dest + s3->accel.cx + n) & (s3->vram_mask >> 2)]; + +#define READ_PIXTRANS_BYTE_MM \ + if (s3->bpp == 0) \ + temp = svga->vram[(s3->accel.dest + s3->accel.cx) & s3->vram_mask]; \ + else if (s3->bpp == 1) \ + temp = svga->vram[(s3->accel.dest + s3->accel.cx) & (s3->vram_mask >> 1)]; \ + else \ + temp = svga->vram[(s3->accel.dest + s3->accel.cx) & (s3->vram_mask >> 2)]; + +#define READ_PIXTRANS_WORD \ + if (s3->bpp == 0) { \ + temp = svga->vram[(s3->accel.dest + s3->accel.cx) & s3->vram_mask]; \ + temp |= (svga->vram[(s3->accel.dest + s3->accel.cx + 1) & s3->vram_mask] << 8); \ + } else if (s3->bpp == 1) { \ + temp = svga->vram[(s3->accel.dest + s3->accel.cx) & (s3->vram_mask >> 1)]; \ + temp |= (svga->vram[(s3->accel.dest + s3->accel.cx + 1) & (s3->vram_mask >> 1)] << 8); \ + } else { \ + temp = svga->vram[(s3->accel.dest + s3->accel.cx) & (s3->vram_mask >> 2)]; \ + temp |= (svga->vram[(s3->accel.dest + s3->accel.cx + 1) & (s3->vram_mask >> 2)] << 8); \ + } + +#define READ_PIXTRANS_LONG \ + if (s3->bpp == 0) { \ + temp = svga->vram[(s3->accel.dest + s3->accel.cx) & s3->vram_mask]; \ + temp |= (svga->vram[(s3->accel.dest + s3->accel.cx + 1) & s3->vram_mask] << 8); \ + temp |= (svga->vram[(s3->accel.dest + s3->accel.cx + 2) & s3->vram_mask] << 16); \ + temp |= (svga->vram[(s3->accel.dest + s3->accel.cx + 3) & s3->vram_mask] << 24); \ + } else if (s3->bpp == 1) { \ + temp = svga->vram[(s3->accel.dest + s3->accel.cx) & (s3->vram_mask >> 1)]; \ + temp |= (svga->vram[(s3->accel.dest + s3->accel.cx + 1) & (s3->vram_mask >> 1)] << 8); \ + temp |= (svga->vram[(s3->accel.dest + s3->accel.cx + 2) & (s3->vram_mask >> 1)] << 16); \ + temp |= (svga->vram[(s3->accel.dest + s3->accel.cx + 3) & (s3->vram_mask >> 1)] << 24); \ + } else { \ + temp = svga->vram[(s3->accel.dest + s3->accel.cx) & (s3->vram_mask >> 2)]; \ + temp |= (svga->vram[(s3->accel.dest + s3->accel.cx + 1) & (s3->vram_mask >> 2)] << 8); \ + temp |= (svga->vram[(s3->accel.dest + s3->accel.cx + 2) & (s3->vram_mask >> 2)] << 16); \ + temp |= (svga->vram[(s3->accel.dest + s3->accel.cx + 3) & (s3->vram_mask >> 2)] << 24); \ + } + static int s3_cpu_src(s3_t *s3) { @@ -425,18 +489,14 @@ s3_cpu_dest(s3_t *s3) static int s3_accel_count(s3_t *s3) { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && !(s3->accel.cmd & 0x600) && (s3->accel.cmd & 0x100) && (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && !(s3->accel.cmd & 0x200) && (s3->accel.cmd & 0x100) && ((s3->accel.cmd & 2) || ((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) return 8; - else if (!(s3->accel.cmd & 0x600) && (s3->accel.cmd & 0x100)) + else if (!(s3->accel.cmd & 0x200) && (s3->accel.cmd & 0x100)) return 1; - else if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && ((s3->accel.cmd & 0x600) == 0x200) && (s3->accel.cmd & 0x100) && (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) + else if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && ((s3->accel.cmd & 0x600) == 0x200) && (s3->accel.cmd & 0x100) && ((s3->accel.cmd & 2) || ((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) return 16; - else if (((s3->accel.cmd & 0x600) == 0x200) && (s3->accel.cmd & 0x100)) + else if (((s3->accel.cmd & 0x200) == 0x200) && (s3->accel.cmd & 0x100)) return 2; - else if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (s3->accel.cmd & 0x100) && (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) - return 32; - else if (s3->accel.cmd & 0x100) - return 4; else return -1; } @@ -445,13 +505,24 @@ s3_accel_count(s3_t *s3) static int s3_data_len(s3_t *s3) { - if (!(s3->accel.cmd & 0x600)) + if (!(s3->accel.cmd & 0x200)) return 1; - if ((s3->accel.cmd & 0x600) == 0x200) - return 2; + return 2; +} - return 4; + +static int +s3_enable_fifo(s3_t *s3) +{ + 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) || + (s3->chip == S3_VISION968) || (s3->chip == S3_VISION868)) + return 1; /* FIFO always enabled on these chips. */ + + //return !!((svga->crtc[0x40] & 0x08) || (s3->accel.advfunc_cntl & 0x40)); + return 0; /*Disable FIFO on pre-964 cards due to glitches going around*/ } static void @@ -460,8 +531,7 @@ s3_accel_out_pixtrans_w(s3_t *s3, uint16_t val) svga_t *svga = &s3->svga; if (s3->accel.cmd & 0x100) { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && - (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) { + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && ((s3->accel.cmd & 2) || ((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) { if (s3->accel.cmd & 0x1000) val = (val >> 8) | (val << 8); if ((s3->accel.cmd & 0x600) == 0x600 && (s3->chip == S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868 || s3->chip >= S3_TRIO64V)) { @@ -476,7 +546,7 @@ s3_accel_out_pixtrans_w(s3_t *s3, uint16_t val) } } else { if ((s3->accel.cmd & 0x600) == 0x000) - s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); + s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); else if (s3->accel.cmd & 0x400) s3_accel_start(4, 1, 0xffffffff, val | (val << 16), s3); else { @@ -490,8 +560,7 @@ static void s3_accel_out_pixtrans_l(s3_t *s3, uint32_t val) { if (s3->accel.cmd & 0x100) { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && - (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) { + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && ((s3->accel.cmd & 2) || ((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) { if ((s3->accel.cmd & 0x600) == 0x600 && (s3->chip == S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868 || s3->chip >= S3_TRIO64V)) { if (s3->accel.cmd & 0x1000) val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); @@ -500,7 +569,7 @@ s3_accel_out_pixtrans_l(s3_t *s3, uint32_t val) s3_accel_start(8, 1, (val >> 8) & 0xff, 0, s3); s3_accel_start(8, 1, val & 0xff, 0, s3); } else if (s3->accel.cmd & 0x400) { - if (s3->accel.cmd & 0x1000) + if (s3->accel.cmd & 0x1000) val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); s3_accel_start(32, 1, val, 0, s3); } else if ((s3->accel.cmd & 0x600) == 0x200) { @@ -657,6 +726,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0x9949: case 0x9ae9: s3->accel.cmd = (s3->accel.cmd & 0xff) | (val << 8); + s3->accel.ssv_state = 0; s3_accel_start(-1, 0, 0xffffffff, 0, s3); s3->accel.multifunc[0xe] &= ~0x10; /*hack*/ break; @@ -673,6 +743,9 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0x9d49: case 0x9ee9: s3->accel.short_stroke = (s3->accel.short_stroke & 0xff) | (val << 8); + s3->accel.ssv_state = 1; + s3_accel_start(-1, 0, 0xffffffff, 0, s3); + s3->accel.multifunc[0xe] &= ~0x10; /*hack*/ break; case 0xa148: case 0xa2e8: @@ -966,7 +1039,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; s3->accel.pix_trans[0] = val; if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && !(s3->accel.cmd & 0x600) && (s3->accel.cmd & 0x100) && - (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) { + (s3->accel.cmd & 2)) { s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); } else if (!(s3->accel.cmd & 0x600) && (s3->accel.cmd & 0x100)) s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); @@ -976,7 +1049,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) if (s3_cpu_dest(s3)) break; s3->accel.pix_trans[1] = val; - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) { + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (s3->accel.cmd & 2)) { if (s3->accel.cmd & 0x100) { switch (s3->accel.cmd & 0x600) { case 0x000: @@ -1033,7 +1106,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) if (s3_cpu_dest(s3)) break; s3->accel.pix_trans[3] = val; - if ((s3->accel.multifunc[0xa]& 0xc0) == 0x80 && (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) { + if ((s3->accel.multifunc[0xa]& 0xc0) == 0x80 && (s3->accel.cmd & 2)) { if (s3->accel.cmd & 0x100) { switch (s3->accel.cmd & 0x600) { case 0x000: @@ -1212,7 +1285,7 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) if (svga->crtc[0x53] & 0x08) { if ((addr & 0x1ffff) < 0x8000) { if (s3->accel.cmd & 0x100) { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (s3->accel.cmd & 2)) 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); @@ -1259,10 +1332,11 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) s3_accel_out_fifo(s3, addr & 0xffff, val); } else { if (s3->accel.cmd & 0x100) { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && ((s3->accel.cmd & 2) || ((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 + else { s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); + } } } } @@ -1292,8 +1366,9 @@ 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 - s3_accel_out_pixtrans_w(s3, val); + } else { + s3_accel_out_pixtrans_w(s3, val); + } } } @@ -1499,8 +1574,9 @@ s3_accel_write_fifo_l(s3_t *s3, uint32_t addr, uint32_t 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 + } else { s3_accel_out_pixtrans_l(s3, val); + } } } @@ -1594,7 +1670,8 @@ static void s3_hwcursor_draw(svga_t *svga, int displine) { s3_t *s3 = (s3_t *)svga->p; - int x; + int x, shift = 1; + int width = 16; uint16_t dat[2]; int xx; int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; @@ -1605,14 +1682,31 @@ s3_hwcursor_draw(svga_t *svga, int displine) case 15: fg = video_15to32[s3->hwc_fg_col & 0xffff]; bg = video_15to32[s3->hwc_bg_col & 0xffff]; + if (s3->chip >= S3_86C928 && s3->chip <= S3_86C805) { + if (!(svga->crtc[0x45] & 0x04)) { + shift = 2; + width = 8; + } + } break; case 16: fg = video_16to32[s3->hwc_fg_col & 0xffff]; bg = video_16to32[s3->hwc_bg_col & 0xffff]; + if (s3->chip >= S3_86C928 && s3->chip <= S3_86C805) { + if (!(svga->crtc[0x45] & 0x04)) { + shift = 2; + width = 8; + } + } break; - case 24: case 32: + case 24: + fg = s3->hwc_fg_col; + bg = s3->hwc_bg_col; + break; + + case 32: fg = s3->hwc_fg_col; bg = s3->hwc_bg_col; break; @@ -1636,8 +1730,8 @@ s3_hwcursor_draw(svga_t *svga, int displine) for (x = 0; x < 64; x += 16) { - dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 8) | svga->vram[svga->hwcursor_latch.addr + 1]; - dat[1] = (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3]; + dat[0] = (svga->vram[svga->hwcursor_latch.addr & svga->vram_display_mask] << 8) | svga->vram[(svga->hwcursor_latch.addr + 1) & svga->vram_display_mask]; + dat[1] = (svga->vram[(svga->hwcursor_latch.addr + 2) & svga->vram_display_mask] << 8) | svga->vram[(svga->hwcursor_latch.addr + 3) & svga->vram_display_mask]; if (svga->crtc[0x55] & 0x10) { /*X11*/ for (xx = 0; xx < 16; xx++) { @@ -1647,12 +1741,12 @@ s3_hwcursor_draw(svga_t *svga, int displine) } offset++; - dat[0] <<= 1; - dat[1] <<= 1; + dat[0] <<= shift; + dat[1] <<= shift; } } else { /*Windows*/ - for (xx = 0; xx < 16; xx++) { + for (xx = 0; xx < width; xx++) { if (offset >= svga->hwcursor_latch.x) { if (!(dat[0] & 0x8000)) buffer32->line[displine][offset + svga->x_add] = (dat[1] & 0x8000) ? fg : bg; @@ -1661,8 +1755,8 @@ s3_hwcursor_draw(svga_t *svga, int displine) } offset++; - dat[0] <<= 1; - dat[1] <<= 1; + dat[0] <<= shift; + dat[1] <<= shift; } } svga->hwcursor_latch.addr += 4; @@ -1973,12 +2067,12 @@ s3_io_remove_alt(s3_t *s3) if (s3->chip >= S3_86C928) io_removehandler(0xb148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); else - io_removehandler(0xb148, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); + io_removehandler(0xb148, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); io_removehandler(0xb548, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0xb948, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0xbd48, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0xd148, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xe148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xe148, 0x0004, s3_accel_in, s3_accel_in_w, s3_accel_in_l, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); io_removehandler(0xe548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0xe948, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0xed48, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); @@ -2007,12 +2101,12 @@ s3_io_remove(s3_t *s3) if (s3->chip >= S3_86C928) io_removehandler(0xb2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); else - io_removehandler(0xb2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); + io_removehandler(0xb2e8, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); io_removehandler(0xb6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0xbee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0xd2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xe2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); + io_removehandler(0xe2e8, 0x0004, s3_accel_in, s3_accel_in_w, s3_accel_in_l, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); io_removehandler(0xe6e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0xeae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0xeee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); @@ -2064,11 +2158,11 @@ s3_io_set_alt(s3_t *s3) if (s3->chip >= S3_86C928) io_sethandler(0xb148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); else - io_sethandler(0xb148, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); + io_sethandler(0xb148, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); io_sethandler(0xb548, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0xb948, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0xbd48, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xe148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); + io_sethandler(0xe148, 0x0004, s3_accel_in, s3_accel_in_w, s3_accel_in_l, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); if (s3->chip == S3_VISION968 || s3->chip == S3_VISION868) { io_sethandler(0xd148, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0xe548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); @@ -2122,11 +2216,11 @@ s3_io_set(s3_t *s3) if (s3->chip >= S3_86C928) io_sethandler(0xb2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); else - io_sethandler(0xb2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); + io_sethandler(0xb2e8, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); io_sethandler(0xb6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0xbee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xe2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); + io_sethandler(0xe2e8, 0x0004, s3_accel_in, s3_accel_in_w, s3_accel_in_l, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); if (s3->chip == S3_VISION968 || s3->chip == S3_VISION868) { io_sethandler(0xd2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0xe6e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); @@ -2205,11 +2299,14 @@ s3_out(uint16_t addr, uint8_t val, void *p) if (!(svga->crtc[0x45] & 0x20) || (s3->chip == S3_86C928)) rs3 = !!(svga->crtc[0x55] & 0x02); else - rs3 = 0; + rs3 = 0; bt48x_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); - } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || s3->chip == S3_VISION968) + } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && s3->card_type == S3_ELSAWIN2KPROX)) ibm_rgb528_ramdac_out(addr, rs2, val, svga->ramdac, svga); - else if ((s3->chip == S3_86C801) || (s3->chip == S3_86C805)) + else if ((s3->chip == S3_VISION968 && (s3->card_type == S3_MIROVIDEO40SV_968 || s3->card_type == S3_SPEA_MERCURY_P64V))) { + rs3 = !!(svga->crtc[0x55] & 0x02); + tvp3026_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); + } else if (((s3->chip == S3_86C801) || (s3->chip == S3_86C805)) && (s3->card_type != S3_MIROCRYSTAL10SD_805)) att49x_ramdac_out(addr, rs2, val, svga->ramdac, svga); else if (s3->chip <= S3_86C924) sc1148x_ramdac_out(addr, 0, val, svga->ramdac, svga); @@ -2328,6 +2425,8 @@ s3_out(uint16_t addr, uint8_t val, void *p) svga->hwcursor.x <<= 1; else if ((s3->chip >= S3_86C928 && s3->chip <= S3_86C805) && (svga->bpp == 15 || svga->bpp == 16)) svga->hwcursor.x >>= 1; + else if ((s3->chip >= S3_86C928 && s3->chip <= S3_86C805) && (svga->bpp == 24)) + svga->hwcursor.x /= 3; break; case 0x4a: @@ -2368,7 +2467,7 @@ s3_out(uint16_t addr, uint8_t val, void *p) case 0x55: if (s3->chip == S3_86C928) { - if (val & 0x08 || ((val & 0x20) == 0x20)) { + if ((val & 0x08) || ((val & 0x20) == 0x20)) { svga->hwcursor_draw = NULL; svga->dac_hwcursor_draw = bt48x_hwcursor_draw; } else { @@ -2471,9 +2570,12 @@ s3_in(uint16_t addr, void *p) else if ((s3->chip == S3_VISION964 && s3->card_type != S3_ELSAWIN2KPROX_964) || (s3->chip == S3_86C928)) { rs3 = !!(svga->crtc[0x55] & 0x02); return bt48x_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); - } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || s3->chip == S3_VISION968) + } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && s3->card_type == S3_ELSAWIN2KPROX)) return ibm_rgb528_ramdac_in(addr, rs2, svga->ramdac, svga); - else if ((s3->chip == S3_86C801) || (s3->chip == S3_86C805)) + else if ((s3->chip == S3_VISION968 && (s3->card_type == S3_MIROVIDEO40SV_968 || s3->card_type == S3_SPEA_MERCURY_P64V))) { + rs3 = !!(svga->crtc[0x55] & 0x02); + return tvp3026_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); + } else if (((s3->chip == S3_86C801) || (s3->chip == S3_86C805)) && (s3->card_type != S3_MIROCRYSTAL10SD_805)) return att49x_ramdac_in(addr, rs2, svga->ramdac, svga); else if (s3->chip <= S3_86C924) return sc1148x_ramdac_in(addr, 0, svga->ramdac, svga); @@ -2512,7 +2614,7 @@ s3_in(uint16_t addr, void *p) /* Phoenix S3 video BIOS'es seem to expect CRTC registers 6B and 6C to be mirrors of 59 and 5A. */ case 0x6b: - if (s3->chip != S3_TRIO64V2) { + if (s3->chip != S3_TRIO64V2 && s3->card_type != S3_MIROVIDEO40SV_968) { if (svga->crtc[0x53] & 0x08) { return (s3->chip == S3_TRIO64V) ? (svga->crtc[0x59] & 0xfc) : (svga->crtc[0x59] & 0xfe); } else { @@ -2522,7 +2624,7 @@ s3_in(uint16_t addr, void *p) return svga->crtc[0x6b]; break; case 0x6c: - if (s3->chip != S3_TRIO64V2) { + if (s3->chip != S3_TRIO64V2 && s3->card_type != S3_MIROVIDEO40SV_968) { if (svga->crtc[0x53] & 0x08) return 0x00; else @@ -2565,9 +2667,12 @@ static void s3_recalctimings(svga_t *svga) ibm_rgb528_recalctimings(svga->ramdac, svga); else bt48x_recalctimings(svga->ramdac, svga); - } else if (s3->chip == S3_VISION968) - ibm_rgb528_recalctimings(svga->ramdac, svga); - else + } else if (s3->chip == S3_VISION968) { + if (s3->card_type == S3_MIROVIDEO40SV_968 || s3->card_type == S3_SPEA_MERCURY_P64V) + tvp3026_recalctimings(svga->ramdac, svga); + else + ibm_rgb528_recalctimings(svga->ramdac, svga); + } else svga->interlace = svga->crtc[0x42] & 0x20; if ((((svga->miscout >> 2) & 3) == 3) && s3->chip < S3_TRIO32) @@ -2582,6 +2687,7 @@ static void s3_recalctimings(svga_t *svga) } svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)); + if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { if (!(svga->crtc[0x14] & 0x40)) /*There are still accel issues with dword mode enabled, so disable dword mode for now.*/ @@ -2598,6 +2704,18 @@ static void s3_recalctimings(svga_t *svga) (s3->chip != S3_TRIO64) && (s3->chip != S3_VISION964) && (s3->chip != S3_VISION968)) { if (s3->width == 1280 || s3->width == 1600) svga->hdisp *= 2; + } else if (s3->card_type == S3_SPEA_MERCURY_P64V) { + if (s3->width == 1280 || s3->width == 1600) + svga->hdisp *= 2; + } + + if (s3->card_type == S3_MIROVIDEO40SV_968) { + if (svga->hdisp != 1408) + svga->hdisp = s3->width; + } + if (s3->card_type == S3_MIROCRYSTAL10SD_805) { + if (svga->rowoffset == 256 && ((svga->crtc[0x51] & 0x30) == 0x00 && !(svga->crtc[0x43] & 0x04))) + svga->rowoffset >>= 1; } } break; @@ -2605,7 +2723,8 @@ static void s3_recalctimings(svga_t *svga) svga->render = svga_render_15bpp_highres; if (s3->chip <= S3_86C924) svga->rowoffset >>= 1; - if ((s3->chip != S3_VISION964) && (s3->chip != S3_86C801)) { + if ((s3->chip != S3_VISION964) && (s3->card_type != S3_SPEA_MIRAGE_86C801 || + (s3->card_type != S3_SPEA_MIRAGE_86C805))) { if (s3->chip == S3_86C928) svga->hdisp *= 2; else if (s3->chip != S3_VISION968) @@ -2621,24 +2740,41 @@ static void s3_recalctimings(svga_t *svga) svga->render = svga_render_16bpp_highres; if (s3->chip <= S3_86C924) svga->rowoffset >>= 1; - if ((s3->chip != S3_VISION964) && (s3->chip != S3_86C801)) { + if ((s3->chip != S3_VISION964) && (s3->card_type != S3_SPEA_MIRAGE_86C801 || + (s3->card_type != S3_SPEA_MIRAGE_86C805))) { if (s3->chip == S3_86C928) svga->hdisp *= 2; else if (s3->chip != S3_VISION968) svga->hdisp /= 2; + } else if (s3->card_type == S3_SPEA_MIRAGE_86C801 || s3->card_type == S3_SPEA_MIRAGE_86C805) { + svga->hdisp /= 2; } if ((s3->chip != S3_VISION868) && (s3->chip != S3_TRIO32) && (s3->chip != S3_TRIO64) && (s3->chip != S3_VISION964)) { if (s3->width == 1280 || s3->width == 1600) svga->hdisp *= 2; } + if (s3->card_type == S3_MIROVIDEO40SV_968) { + if (svga->hdisp == (1408*2)) + svga->hdisp /= 2; + else + svga->hdisp = s3->width; + } + + if (s3->card_type == S3_SPEA_MIRAGE_86C801 || s3->card_type == S3_SPEA_MIRAGE_86C805) + svga->hdisp = s3->width; break; case 24: svga->render = svga_render_24bpp_highres; - if (s3->chip != S3_86C928 && s3->chip != S3_86C801 && s3->chip != S3_86C805 && s3->chip != S3_VISION968) - svga->hdisp /= 3; - else - svga->hdisp = (svga->hdisp * 2) / 3; + if (s3->chip != S3_VISION968) { + if (s3->chip != S3_86C928 && s3->chip != S3_86C801 && s3->chip != S3_86C805) + svga->hdisp /= 3; + else + svga->hdisp = (svga->hdisp * 2) / 3; + } else { + if (s3->card_type == S3_MIROVIDEO40SV_968) + svga->hdisp = s3->width; + } break; case 32: svga->render = svga_render_32bpp_highres; @@ -2646,11 +2782,13 @@ static void s3_recalctimings(svga_t *svga) (s3->chip != S3_VISION968) && (s3->chip != S3_86C928)) { if (s3->chip == S3_VISION868) svga->hdisp /= 2; - else + else svga->hdisp /= 4; } - if (s3->width == 1280 || s3->width == 1600) + if (s3->width == 1280 || s3->width == 1600 || (s3->card_type == S3_SPEA_MERCURY_P64V)) svga->hdisp *= 2; + if (s3->card_type == S3_MIROVIDEO40SV_968) + svga->hdisp = s3->width; break; } } else { @@ -2863,7 +3001,7 @@ s3_updatemapping(s3_t *s3) } else { mem_mapping_disable(&s3->linear_mapping); } - + /* Memory mapped I/O. */ if ((svga->crtc[0x53] & 0x10) || (s3->accel.advfunc_cntl & 0x20)) { mem_mapping_disable(&svga->mapping); @@ -2901,22 +3039,6 @@ s3_trio64_getclock(int clock, void *p) return t; } - -static int -s3_enable_fifo(s3_t *s3) -{ - svga_t *svga = &s3->svga; - - 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) || - (s3->chip == S3_VISION968) || (s3->chip == S3_VISION868)) - return 1; /* FIFO always enabled on these chips. */ - - return !!((svga->crtc[0x40] & 0x08) || (s3->accel.advfunc_cntl & 0x40)); -} - - static void s3_accel_out(uint16_t port, uint8_t val, void *p) { @@ -2956,6 +3078,11 @@ s3_accel_out(uint16_t port, uint8_t val, void *p) svga->fullchange = changeframecount; svga_recalctimings(svga); } + if (s3->chip <= S3_86C924) { + s3->width = (val & 4) ? 1024 : 640; + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } s3_updatemapping(s3); break; } @@ -3065,6 +3192,7 @@ s3_accel_in(uint16_t port, void *p) } break; + case 0x8118: case 0x9948: case 0x9ae8: temp = 0; /* FIFO empty */ if (!s3->blitter_busy) @@ -3072,6 +3200,7 @@ s3_accel_in(uint16_t port, void *p) if (FIFO_FULL && (s3->chip >= S3_VISION964)) temp = 0xff; /*FIFO full*/ return temp; /*FIFO empty*/ + case 0x8119: case 0x9949: case 0x9ae9: if (!s3->blitter_busy) wake_fifo_thread(s3); @@ -3322,53 +3451,118 @@ s3_accel_in(uint16_t port, void *p) case 0xe148: case 0xe2e8: if (!s3_cpu_dest(s3)) - break; + break; temp = s3->accel.pix_trans[0]; - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && !(s3->accel.cmd & 0x600) && (s3->accel.cmd & 0x100) && - (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) - s3_accel_start(8, 1, 0xffffffff, 0, s3); - else if (!(s3->accel.cmd & 0x600) && (s3->accel.cmd & 0x100)) - s3_accel_start(1, 1, 0xffffffff, 0xff, s3); + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && ((s3->accel.cmd & 2) || ((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) { + if (s3->accel.cmd & 0x100) { + switch (s3->accel.cmd & 0x200) { + case 0x000: + s3_accel_start(8, 1, 0xffffffff, 0, s3); + break; + case 0x200: + s3_accel_start(16, 1, 0xffffffff, 0, s3); + break; + } + } + } else { + if (s3->accel.cmd & 0x100) { + switch (s3->accel.cmd & 0x200) { + case 0x000: + s3_accel_start(1, 1, 0xffffffff, 0xffffffff, s3); + break; + case 0x200: + s3_accel_start(2, 1, 0xffffffff, 0xffffffff, s3); + break; + } + } + } return temp; + case 0xe149: case 0xe2e9: if (!s3_cpu_dest(s3)) break; temp = s3->accel.pix_trans[1]; - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (s3->accel.cmd & 0x600) == 0x200 && (s3->accel.cmd & 0x100) && - (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) - s3_accel_start(16, 1, 0xffffffff, 0, s3); - else if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (s3->accel.cmd & 0x600) == 0x000 && (s3->accel.cmd & 0x100) && - (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) - s3_accel_start(8, 1, 0xffffffff, 0, s3); - else if ((s3->accel.cmd & 0x600) == 0x200 && (s3->accel.cmd & 0x100)) - s3_accel_start(2, 1, 0xffffffff, 0xffff, s3); - else if ((s3->accel.cmd & 0x600) == 0x000 && (s3->accel.cmd & 0x100)) - s3_accel_start(1, 1, 0xffffffff, 0xff, s3); + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && ((s3->accel.cmd & 2) || ((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) { + if (s3->accel.cmd & 0x100) { + switch (s3->accel.cmd & 0x200) { + case 0x000: + s3_accel_start(8, 1, 0xffffffff, 0, s3); + break; + case 0x200: + s3_accel_start(16, 1, 0xffffffff, 0, s3); + break; + } + } + } else { + if (s3->accel.cmd & 0x100) { + switch (s3->accel.cmd & 0x200) { + case 0x000: + s3_accel_start(1, 1, 0xffffffff, 0xffffffff, s3); + break; + case 0x200: + s3_accel_start(2, 1, 0xffffffff, 0xffffffff, s3); + break; + } + } + } return temp; + case 0xe14a: case 0xe2ea: if (!s3_cpu_dest(s3)) break; temp = s3->accel.pix_trans[2]; + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && ((s3->accel.cmd & 2) || ((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) { + if (s3->accel.cmd & 0x100) { + switch (s3->accel.cmd & 0x200) { + case 0x000: + s3_accel_start(8, 1, 0xffffffff, 0, s3); + break; + case 0x200: + s3_accel_start(16, 1, 0xffffffff, 0, s3); + break; + } + } + } else { + if (s3->accel.cmd & 0x100) { + switch (s3->accel.cmd & 0x200) { + case 0x000: + s3_accel_start(1, 1, 0xffffffff, 0xffffffff, s3); + break; + case 0x200: + s3_accel_start(2, 1, 0xffffffff, 0xffffffff, s3); + break; + } + } + } return temp; + case 0xe14b: case 0xe2eb: if (!s3_cpu_dest(s3)) break; temp = s3->accel.pix_trans[3]; - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (s3->accel.cmd & 0x400) && (s3->accel.cmd & 0x100) && - (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) - s3_accel_start(32, 1, 0xffffffff, 0, s3); - else if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (s3->accel.cmd & 0x600) == 0x200 && (s3->accel.cmd & 0x100) && - (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) - s3_accel_start(16, 1, 0xffffffff, 0, s3); - else if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (s3->accel.cmd & 0x600) == 0x000 && (s3->accel.cmd & 0x100) && - (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) - s3_accel_start(8, 1, 0xffffffff, 0, s3); - else if ((s3->accel.cmd & 0x400) && (s3->accel.cmd & 0x100)) - s3_accel_start(4, 1, 0xffffffff, 0xffffffff, s3); - else if ((s3->accel.cmd & 0x600) == 0x200 && (s3->accel.cmd & 0x100)) - s3_accel_start(2, 1, 0xffffffff, 0xffff, s3); - else if ((s3->accel.cmd & 0x600) == 0x000 && (s3->accel.cmd & 0x100)) - s3_accel_start(1, 1, 0xffffffff, 0xff, s3); + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && ((s3->accel.cmd & 2) || ((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) { + if (s3->accel.cmd & 0x100) { + switch (s3->accel.cmd & 0x200) { + case 0x000: + s3_accel_start(8, 1, 0xffffffff, 0, s3); + break; + case 0x200: + s3_accel_start(16, 1, 0xffffffff, 0, s3); + break; + } + } + } else { + if (s3->accel.cmd & 0x100) { + switch (s3->accel.cmd & 0x200) { + case 0x000: + s3_accel_start(1, 1, 0xffffffff, 0xffffffff, s3); + break; + case 0x200: + s3_accel_start(2, 1, 0xffffffff, 0xffffffff, s3); + break; + } + } + } return temp; case 0xff20: case 0xff21: @@ -3383,6 +3577,72 @@ s3_accel_in(uint16_t port, void *p) return 0xff; } +static uint16_t +s3_accel_in_w(uint16_t port, void *p) +{ + s3_t *s3 = (s3_t *)p; + uint16_t temp = 0x0000; + + if (!s3->enable_8514) + return 0xffff; + + if (s3_cpu_dest(s3)) { + temp = s3->accel.pix_trans[port & 2]; + temp |= s3->accel.pix_trans[(port & 2) + 1] << 8; + + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && ((s3->accel.cmd & 2) || ((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) { + if ((s3->accel.cmd & 0x200) == 0x000) + s3_accel_start(8, 1, 0xffffffff, 0, s3); + else + s3_accel_start(16, 1, 0xffffffff, 0, s3); + } else { + if ((s3->accel.cmd & 0x200) == 0x000) + s3_accel_start(1, 1, 0xffffffff, 0xffffffff, s3); + else + s3_accel_start(2, 1, 0xffffffff, 0xffffffff, s3); + } + } + + return temp; +} + +static uint32_t +s3_accel_in_l(uint16_t port, void *p) +{ + s3_t *s3 = (s3_t *)p; + uint32_t temp = 0x00000000; + + if (!s3->enable_8514) + return 0xffffffff; + + if (s3_cpu_dest(s3)) { + temp = s3->accel.pix_trans[0]; + temp |= s3->accel.pix_trans[1] << 8; + temp |= s3->accel.pix_trans[2] << 16; + temp |= s3->accel.pix_trans[3] << 24; + + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && ((s3->accel.cmd & 2) || ((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) { + if ((s3->accel.cmd & 0x200) == 0x000) { + s3_accel_start(8, 1, 0xffffffff, 0, s3); + s3_accel_start(8, 1, 0xffffffff, 0, s3); + } else { + s3_accel_start(16, 1, 0xffffffff, 0, s3); + s3_accel_start(16, 1, 0xffffffff, 0, s3); + } + } else { + if ((s3->accel.cmd & 0x200) == 0x000) { + s3_accel_start(1, 1, 0xffffffff, 0xffffffff, s3); + s3_accel_start(1, 1, 0xffffffff, 0xffffffff, s3); + } else { + s3_accel_start(2, 1, 0xffffffff, 0xffffffff, s3); + s3_accel_start(2, 1, 0xffffffff, 0xffffffff, s3); + } + } + } + + return temp; +} + static void s3_accel_write(uint32_t addr, uint8_t val, void *p) @@ -3391,7 +3651,7 @@ s3_accel_write(uint32_t addr, uint8_t val, void *p) svga_t *svga = &s3->svga; if (!s3->enable_8514) - return; + return; if (s3_enable_fifo(s3)) { if (svga->crtc[0x53] & 0x08) @@ -3409,7 +3669,7 @@ s3_accel_write_w(uint32_t addr, uint16_t val, void *p) svga_t *svga = &s3->svga; if (!s3->enable_8514) - return; + return; if (s3_enable_fifo(s3)) { if (svga->crtc[0x53] & 0x08) @@ -3427,7 +3687,7 @@ s3_accel_write_l(uint32_t addr, uint32_t val, void *p) svga_t *svga = &s3->svga; if (!s3->enable_8514) - return; + return; if (s3_enable_fifo(s3)) { if (svga->crtc[0x53] & 0x08) @@ -3478,14 +3738,19 @@ s3_accel_read(uint32_t addr, void *p) if (addr & 0x8000) { temp = s3_accel_in(addr & 0xffff, p); } else if (s3_cpu_dest(s3)) { - temp = s3->accel.pix_trans[addr & 3]; + temp = s3->accel.pix_trans[addr & 3]; - 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); - else - s3_accel_start(1, 1, 0xffffffff, 0xffffffff, s3); - } + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && ((s3->accel.cmd & 2) || ((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) { + if ((s3->accel.cmd & 0x200) == 0x000) + s3_accel_start(8, 1, 0xffffffff, 0, s3); + else + s3_accel_start(16, 1, 0xffffffff, 0, s3); + } else { + if ((s3->accel.cmd & 0x200) == 0x000) + s3_accel_start(1, 1, 0xffffffff, 0xffffffff, s3); + else + s3_accel_start(2, 1, 0xffffffff, 0xffffffff, s3); + } } } @@ -3517,20 +3782,17 @@ s3_accel_read_w(uint32_t addr, void *p) temp = s3->accel.pix_trans[addr & 2]; temp |= s3->accel.pix_trans[(addr & 2) + 1] << 8; - if (s3->accel.cmd & 0x100) { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && - (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) { - if ((s3->accel.cmd & 0x600) == 0x000) + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && ((s3->accel.cmd & 2) || ((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) { + if ((s3->accel.cmd & 0x200) == 0x000) s3_accel_start(8, 1, 0xffff, 0, s3); else s3_accel_start(16, 1, 0xffff, 0, s3); } else { - if ((s3->accel.cmd & 0x600) == 0x000) + if ((s3->accel.cmd & 0x200) == 0x000) s3_accel_start(1, 1, 0xffffffff, 0xffff, s3); else s3_accel_start(2, 1, 0xffffffff, 0xffff, s3); } - } } } @@ -3666,35 +3928,28 @@ s3_accel_read_l(uint32_t addr, void *p) 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[0]; + temp = s3->accel.pix_trans[0]; temp |= s3->accel.pix_trans[1] << 8; - temp |= s3->accel.pix_trans[2] << 16; + temp |= s3->accel.pix_trans[2] << 16; temp |= s3->accel.pix_trans[3] << 24; - if (s3->accel.cmd & 0x100) { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && - (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) { - if (s3->accel.cmd & 0x400) { - s3_accel_start(32, 1, 0xffffffff, 0, s3); - } else if ((s3->accel.cmd & 0x600) == 0x200) { - s3_accel_start(16, 1, 0xffff, 0, s3); - s3_accel_start(16, 1, 0xffff, 0, s3); - } else { - s3_accel_start(8, 1, 0xffff, 0, s3); - s3_accel_start(8, 1, 0xffff, 0, s3); - } - } else { - if (s3->accel.cmd & 0x400) - s3_accel_start(4, 1, 0xffffffff, 0xffffffff, s3); - else if ((s3->accel.cmd & 0x600) == 0x200) { - s3_accel_start(2, 1, 0xffffffff, 0xffff, s3); - s3_accel_start(2, 1, 0xffffffff, 0xffff, s3); - } else { - s3_accel_start(1, 1, 0xffffffff, 0xffff, s3); - s3_accel_start(1, 1, 0xffffffff, 0xffff, s3); - } - } - } + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (s3->accel.cmd & 2)) { + if ((s3->accel.cmd & 0x200) == 0x000) { + s3_accel_start(8, 1, 0xffffffff, 0, s3); + s3_accel_start(8, 1, 0xffffffff, 0, s3); + } else { + s3_accel_start(16, 1, 0xffffffff, 0, s3); + s3_accel_start(16, 1, 0xffffffff, 0, s3); + } + } else { + if ((s3->accel.cmd & 0x200) == 0x000) { + s3_accel_start(1, 1, 0xffffffff, 0xffffffff, s3); + s3_accel_start(1, 1, 0xffffffff, 0xffffffff, s3); + } else { + s3_accel_start(2, 1, 0xffffffff, 0xffffffff, s3); + s3_accel_start(2, 1, 0xffffffff, 0xffffffff, s3); + } + } } } @@ -3743,10 +3998,10 @@ polygon_setup(s3_t *s3) } } - #define READ(addr, dat) if (s3->bpp == 0) dat = svga->vram[(addr) & s3->vram_mask]; \ else if (s3->bpp == 1) dat = vram_w[(addr) & (s3->vram_mask >> 1)]; \ - else dat = vram_l[(addr) & (s3->vram_mask >> 2)]; + else if (s3->bpp == 2) dat = svga->vram[(addr) & s3->vram_mask]; \ + else dat = vram_l[(addr) & (s3->vram_mask >> 2)]; #define MIX_READ { \ switch ((mix_dat & mix_mask) ? (s3->accel.frgd_mix & 0xf) : (s3->accel.bkgd_mix & 0xf)) \ @@ -4059,6 +4314,11 @@ polygon_setup(s3_t *s3) vram_w[(addr) & (s3->vram_mask >> 1)] = dat; \ svga->changedvram[((addr) & (s3->vram_mask >> 1)) >> 11] = changeframecount; \ } \ + else if (s3->bpp == 2) \ + { \ + svga->vram[(addr) & s3->vram_mask] = dat; \ + svga->changedvram[((addr) & s3->vram_mask) >> 12] = changeframecount; \ + } \ else \ { \ vram_l[(addr) & (s3->vram_mask >> 2)] = dat; \ @@ -4466,20 +4726,20 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if (s3->bpp == 1) { srcbase >>= 1; dstbase >>= 1; - } else if (s3->bpp == 3) { - srcbase >>= 2; - dstbase >>= 2; + } else if (s3->bpp == 3) { + srcbase >>= 2; + dstbase >>= 2; } - if ((s3->accel.cmd & 0x100) && (s3_cpu_src(s3) || s3_cpu_dest(s3)) && !cpu_input) { + if ((s3->accel.cmd & 0x100) && ((s3_cpu_src(s3) || (s3_cpu_dest(s3))) && !cpu_input)) { s3->force_busy = 1; } if (!cpu_input) s3->accel.dat_count = 0; - if (cpu_input && (s3->accel.multifunc[0xa] & 0xc0) != 0x80) { - if (s3->bpp == 3 && count == 2) { + if (cpu_input && (((s3->accel.multifunc[0xa] & 0xc0) != 0x80) || (!(s3->accel.cmd & 2)))) { + if ((s3->bpp == 3) && count == 2) { if (s3->accel.dat_count) { cpu_dat = ((cpu_dat & 0xffff) << 16) | s3->accel.dat_buf; count = 4; @@ -4508,11 +4768,147 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ case 0x600: mix_mask = (s3->chip == S3_TRIO32 || s3->chip >= S3_TRIO64V || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) ? 0x80 : 0x80000000; break; } - if (s3->bpp == 0) compare &= 0xff; + if (s3->bpp == 0) compare &= 0xff; if (s3->bpp == 1) compare &= 0xffff; switch (cmd) { + case 0: /*NOP (Short Stroke Vectors)*/ + if (s3->accel.ssv_state == 0) + break; + + if (!cpu_input) { + s3->accel.cx = s3->accel.cur_x; + if (s3->accel.cur_x_bit12) s3->accel.cx |= ~0xfff; + s3->accel.cy = s3->accel.cur_y; + if (s3->accel.cur_y_bit12) s3->accel.cy |= ~0xfff; + + if (s3->accel.cmd & 0x1000) { + s3->accel.ssv_len1 = (s3->accel.short_stroke >> 8) & 0x0f; + s3->accel.ssv_dir1 = (s3->accel.short_stroke >> 8) & 0xe0; + s3->accel.ssv_draw1 = (s3->accel.short_stroke >> 8) & 0x10; + s3->accel.ssv_len2 = s3->accel.short_stroke & 0x0f; + s3->accel.ssv_dir2 = s3->accel.short_stroke & 0xe0; + s3->accel.ssv_draw2 = s3->accel.short_stroke & 0x10; + } else { + s3->accel.ssv_len2 = (s3->accel.short_stroke >> 8) & 0x0f; + s3->accel.ssv_dir2 = (s3->accel.short_stroke >> 8) & 0xe0; + s3->accel.ssv_draw2 = (s3->accel.short_stroke >> 8) & 0x10; + s3->accel.ssv_len1 = s3->accel.short_stroke & 0x0f; + s3->accel.ssv_dir1 = s3->accel.short_stroke & 0xe0; + s3->accel.ssv_draw1 = s3->accel.short_stroke & 0x10; + } + + if (s3_cpu_src(s3)) { + return; /*Wait for data from CPU*/ + } + } + + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; + + if (s3->accel.cmd & 8) /*Radial*/ + { + while (count-- && s3->accel.ssv_len1 >= 0) + { + 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) + { + case 0: src_dat = s3->accel.bkgd_color; break; + case 1: src_dat = s3->accel.frgd_color; break; + case 2: src_dat = cpu_dat; break; + case 3: src_dat = 0; break; + } + + if ((compare_mode == 2 && src_dat != compare) || + (compare_mode == 3 && src_dat == compare) || + compare_mode < 2) + { + READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + + MIX + + if (s3->accel.ssv_draw1) { + WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + } + } + } + + mix_dat <<= 1; + mix_dat |= 1; + if (s3->bpp == 0) cpu_dat >>= 8; + else cpu_dat >>= 16; + if (!s3->accel.ssv_len1) + break; + + switch (s3->accel.ssv_dir1 & 0xe0) + { + case 0x00: s3->accel.cx++; break; + case 0x20: s3->accel.cx++; s3->accel.cy--; break; + case 0x40: s3->accel.cy--; break; + case 0x60: s3->accel.cx--; s3->accel.cy--; break; + case 0x80: s3->accel.cx--; break; + case 0xa0: s3->accel.cx--; s3->accel.cy++; break; + case 0xc0: s3->accel.cy++; break; + case 0xe0: s3->accel.cx++; s3->accel.cy++; break; + } + s3->accel.ssv_len1--; + } + + while (count-- && s3->accel.ssv_len2 >= 0) + { + 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) + { + case 0: src_dat = s3->accel.bkgd_color; break; + case 1: src_dat = s3->accel.frgd_color; break; + case 2: src_dat = cpu_dat; break; + case 3: src_dat = 0; break; + } + + if ((compare_mode == 2 && src_dat != compare) || + (compare_mode == 3 && src_dat == compare) || + compare_mode < 2) + { + READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + + MIX + + if (s3->accel.ssv_draw2) { + WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + } + } + } + + mix_dat <<= 1; + mix_dat |= 1; + if (s3->bpp == 0) cpu_dat >>= 8; + else cpu_dat >>= 16; + if (!s3->accel.ssv_len2) + break; + + switch (s3->accel.ssv_dir2 & 0xe0) + { + case 0x00: s3->accel.cx++; break; + case 0x20: s3->accel.cx++; s3->accel.cy--; break; + case 0x40: s3->accel.cy--; break; + case 0x60: s3->accel.cx--; s3->accel.cy--; break; + case 0x80: s3->accel.cx--; break; + case 0xa0: s3->accel.cx--; s3->accel.cy++; break; + case 0xc0: s3->accel.cy++; break; + case 0xe0: s3->accel.cx++; s3->accel.cy++; break; + } + s3->accel.ssv_len2--; + } + s3->accel.cur_x = s3->accel.cx; + s3->accel.cur_y = s3->accel.cy; + } + break; + case 1: /*Draw line*/ if (!cpu_input) { s3->accel.cx = s3->accel.cur_x; @@ -4526,6 +4922,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ return; /*Wait for data from CPU*/ } } + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; @@ -4549,10 +4946,12 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ compare_mode < 2) { READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); - + MIX - WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + if (s3->accel.cmd & 0x10) { + WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + } } } @@ -4575,6 +4974,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ case 0xc0: s3->accel.cy++; break; case 0xe0: s3->accel.cx++; s3->accel.cy++; break; } + s3->accel.sy--; } s3->accel.cur_x = s3->accel.cx; @@ -4613,7 +5013,9 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ MIX - WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + if (s3->accel.cmd & 0x10) { + WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + } } } @@ -4633,7 +5035,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if (!s3->accel.sy) { break; } - + if (s3->accel.err_term >= s3->accel.maj_axis_pcnt) { s3->accel.err_term += s3->accel.destx_distp; /*Step minor axis*/ @@ -4664,6 +5066,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ case 0xc0: s3->accel.cy++; break; case 0xe0: s3->accel.cy++; break; } + s3->accel.sy--; } s3->accel.cur_x = s3->accel.cx; @@ -4673,15 +5076,15 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ case 2: /*Rectangle fill*/ byte_cnt = s3_data_len(s3); - s3->data_available = 0; - + s3->data_available = 0; + if (!cpu_input) /*!cpu_input is trigger to start operation*/ { s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; s3->accel.sy = s3->accel.multifunc[0] & 0xfff; s3->accel.cx = s3->accel.cur_x; s3->accel.cy = s3->accel.cur_y; - + if (s3->accel.cur_x_bit12) { if (s3->accel.cx <= 0x7ff) { s3->accel.cx = s3->accel.cur_x_bitres & 0xfff; @@ -4695,7 +5098,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ } else { s3->accel.cy |= ~0xfff; } - } + } s3->accel.dest = dstbase + s3->accel.cy * s3->width; @@ -4708,7 +5111,7 @@ 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; - + s3->accel.pix_trans[0] = 0xff; s3->accel.pix_trans[1] = 0xff; s3->accel.pix_trans[2] = 0xff; @@ -4724,11 +5127,12 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if (s3->accel.b2e8_pix && s3_cpu_src(s3) && s3->accel.temp_cnt == 0) { mix_dat >>= 16; s3->accel.temp_cnt = 16; - } + } - 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->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && + (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) || ((s3_cpu_dest(s3) && + (s3->accel.cy & 0xfff) >= clip_b))) /*For some reason, the SPEA v7 drivers want to draw the pixels beyond the clipping in read mode*/ + { if (s3_cpu_dest(s3) && ((s3->accel.multifunc[0xa] & 0xc0) == 0x00)) { mix_dat = mix_mask; /* Mix data = forced to foreground register. */ } else if (s3_cpu_dest(s3) && vram_mask) { @@ -4754,27 +5158,32 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { - if (s3_cpu_dest(s3)) + if (s3_cpu_dest(s3)) { dest_dat = 0xffffffff; - else { + } else { READ(s3->accel.dest + s3->accel.cx, dest_dat); } MIX - + if (s3_cpu_dest(s3)) { - for (i = 0; i <= s3->bpp; i++) - s3->accel.pix_trans[read + i] = (src_dat >> (i << 3)) & 0xff; - /* Yes, src_dat is correct, there is no mixing/ROP's done on PIX_TRANS reads. */ - } else - WRITE(s3->accel.dest + s3->accel.cx, dest_dat); + if (s3->accel.cmd & 0x10) { + for (i = 0; i <= s3->bpp; i++) { + s3->accel.pix_trans[read + i] = (src_dat >> (i << 3)) & 0xff; + /* Yes, src_dat is correct, there is no mixing/ROP's done on PIX_TRANS reads. */ + } + } + } else { + if (s3->accel.cmd & 0x10) { + WRITE(s3->accel.dest + s3->accel.cx, dest_dat); + } + } } } if (s3_cpu_dest(s3)) { - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) && - (((s3->accel.frgd_mix & 0x60) != 0x40) || - ((s3->accel.bkgd_mix & 0x60) != 0x40))) { + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) && ((s3->accel.cmd & 2) || + ((s3->accel.frgd_mix & 0x60) != 0x40 || (s3->accel.bkgd_mix != 0x40)))) { read++; if (read >= (byte_cnt << 3)) s3->data_available = 1; /* Read data available. */ @@ -4796,20 +5205,33 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ mix_dat |= 1; } - if (s3->bpp == 0) cpu_dat >>= 8; - else cpu_dat >>= 16; + if (s3->bpp == 0) + cpu_dat >>= 8; + else + cpu_dat >>= 16; - if (s3->accel.cmd & 0x20) s3->accel.cx++; - else s3->accel.cx--; + if (s3->accel.cmd & 0x20) + s3->accel.cx++; + else + s3->accel.cx--; + s3->accel.sx--; if (s3->accel.sx < 0) { - if (s3->accel.cmd & 0x20) s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - else s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + if (s3->accel.cmd & 0x20) + { + s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + } + else + { + s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; + } + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - if (s3->accel.cmd & 0x80) s3->accel.cy++; - else s3->accel.cy--; + if (s3->accel.cmd & 0x80) + s3->accel.cy++; + else + s3->accel.cy--; s3->accel.dest = dstbase + s3->accel.cy * s3->width; s3->accel.sy--; @@ -4827,7 +5249,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ return; } } - + if (s3_cpu_dest(s3) && s3->data_available) return; } @@ -4878,7 +5300,9 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ MIX - WRITE(s3->accel.dest + s3->accel.poly_x, dest_dat); + if (s3->accel.cmd & 0x10) { + WRITE(s3->accel.dest + s3->accel.poly_x, dest_dat); + } } } if (s3->bpp == 0) cpu_dat >>= 8; @@ -4976,7 +5400,9 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ dest_dat = (src_dat & s3->accel.wrt_mask) | (dest_dat & ~s3->accel.wrt_mask); - WRITE(s3->accel.dest + s3->accel.dx, dest_dat); + if (s3->accel.cmd & 0x10) { + WRITE(s3->accel.dest + s3->accel.dx, dest_dat); + } } s3->accel.cx++; @@ -5034,7 +5460,9 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ MIX - WRITE(s3->accel.dest + s3->accel.dx, dest_dat); + if (s3->accel.cmd & 0x10) { + WRITE(s3->accel.dest + s3->accel.dx, dest_dat); + } } } @@ -5156,7 +5584,9 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ MIX - WRITE(s3->accel.dest + s3->accel.dx, dest_dat); + if (s3->accel.cmd & 0x10) { + WRITE(s3->accel.dest + s3->accel.dx, dest_dat); + } } } @@ -5254,7 +5684,9 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ MIX - WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + if (s3->accel.cmd & 0x10) { + WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + } } } @@ -5288,7 +5720,9 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ MIX - WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + if (s3->accel.cmd & 0x10) { + WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + } } } @@ -5369,7 +5803,10 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ MIX - WRITE(s3->accel.dest + s3->accel.poly_x, dest_dat); } + if (s3->accel.cmd & 0x10) { + WRITE(s3->accel.dest + s3->accel.poly_x, dest_dat); + } + } } if (s3->bpp == 0) cpu_dat >>= 8; else cpu_dat >>= 16; @@ -5474,7 +5911,9 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ ROPMIX - WRITE(s3->accel.dest + s3->accel.dx, out); + if (s3->accel.cmd & 0x10) { + WRITE(s3->accel.dest + s3->accel.dx, out); + } } } @@ -5708,7 +6147,7 @@ static void *s3_init(const device_t *info) int chip, stepping; s3_t *s3 = malloc(sizeof(s3_t)); svga_t *svga = &s3->svga; - int vram; + int vram, spea_bios_ver; uint32_t vram_size; switch(info->local) { @@ -5727,13 +6166,27 @@ static void *s3_init(const device_t *info) chip = S3_86C924; video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c911); break; - case S3_V7MIRAGE_86C801: - bios_fn = ROM_V7MIRAGE_86C801; + case S3_SPEA_MIRAGE_86C801: + spea_bios_ver = device_get_config_int("bios_ver"); + if (spea_bios_ver) + bios_fn = ROM_SPEA_MIRAGE_86C801_V401; + else + bios_fn = ROM_SPEA_MIRAGE_86C801_V305I; + chip = S3_86C801; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c801); + break; + case S3_MIROCRYSTAL10SD_805: + bios_fn = ROM_MIROCRYSTAL10SD_805; + chip = S3_86C805; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c805); + break; + case S3_PHOENIX_86C801: + bios_fn = ROM_PHOENIX_86C80X; chip = S3_86C801; video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c801); break; case S3_PHOENIX_86C805: - bios_fn = ROM_PHOENIX_86C805; + bios_fn = ROM_PHOENIX_86C80X; chip = S3_86C805; video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c805); break; @@ -5777,22 +6230,29 @@ static void *s3_init(const device_t *info) else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision964_vlb); break; - case S3_ELSAWIN2KPROX_964: - bios_fn = ROM_ELSAWIN2KPROX_964; - chip = S3_VISION964; - if (info->flags & DEVICE_PCI) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision964_pci); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision964_vlb); - break; - case S3_ELSAWIN2KPROX: - bios_fn = ROM_ELSAWIN2KPROX; + case S3_MIROVIDEO40SV_968: + bios_fn = ROM_MIROVIDEO40SV_968; chip = S3_VISION968; if (info->flags & DEVICE_PCI) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_pci); else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_vlb); break; + case S3_ELSAWIN2KPROX_964: + bios_fn = ROM_ELSAWIN2KPROX_964; + chip = S3_VISION964; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision964_pci); + break; + case S3_ELSAWIN2KPROX: + bios_fn = ROM_ELSAWIN2KPROX; + chip = S3_VISION968; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_pci); + break; + case S3_SPEA_MERCURY_P64V: + bios_fn = ROM_SPEA_MERCURY_P64V; + chip = S3_VISION968; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_pci); + break; case S3_PHOENIX_TRIO32: bios_fn = ROM_PHOENIX_TRIO32; chip = S3_TRIO32; @@ -5817,6 +6277,11 @@ static void *s3_init(const device_t *info) else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_vlb); break; + case S3_SPEA_MIRAGE_P64: + bios_fn = ROM_SPEA_MIRAGE_P64; + chip = S3_TRIO64; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_vlb); + break; case S3_PHOENIX_TRIO64_ONBOARD: bios_fn = NULL; chip = S3_TRIO64; @@ -5869,7 +6334,10 @@ static void *s3_init(const device_t *info) memset(s3, 0, sizeof(s3_t)); - vram = device_get_config_int("memory"); + if (info->local == S3_MIROCRYSTAL10SD_805) + vram = 1; + else + vram = device_get_config_int("memory"); if (vram) vram_size = vram << 20; @@ -5935,8 +6403,10 @@ static void *s3_init(const device_t *info) if (chip == S3_VISION964 && info->local != S3_ELSAWIN2KPROX_964) svga->dac_hwcursor_draw = bt48x_hwcursor_draw; - else if ((chip == S3_VISION964 && info->local == S3_ELSAWIN2KPROX_964) || chip == S3_VISION968) + else if ((chip == S3_VISION964 && info->local == S3_ELSAWIN2KPROX_964) || (chip == S3_VISION968 && info->local == S3_ELSAWIN2KPROX)) svga->dac_hwcursor_draw = ibm_rgb528_hwcursor_draw; + else if (chip == S3_VISION968 && (info->local == S3_MIROVIDEO40SV_968 || info->local == S3_SPEA_MERCURY_P64V)) + svga->dac_hwcursor_draw = tvp3026_hwcursor_draw; if (chip >= S3_VISION964) { switch (vram) { @@ -5974,7 +6444,7 @@ static void *s3_init(const device_t *info) else if (s3->vlb) svga->crtc[0x36] = 1 | (3 << 2) | (1 << 4); else - svga->crtc[0x36] = 3; + svga->crtc[0x36] = 3 | (1 << 4); if (chip >= S3_86C928) svga->crtc[0x36] |= (vram_sizes[vram] << 5); @@ -5982,6 +6452,9 @@ static void *s3_init(const device_t *info) svga->crtc[0x36] |= ((vram == 1) ? 0x00 : 0x20) | 0x80; svga->crtc[0x37] = 1 | (7 << 5); + + if (chip >= S3_86C928) + svga->crtc[0x37] |= 0x04; svga->vblank_start = s3_vblank_start; @@ -6008,7 +6481,6 @@ static void *s3_init(const device_t *info) s3->id_ext = stepping; s3->id_ext_pci = 0; s3->packed_mmio = 0; - s3->width = 1024; svga->ramdac = device_add(&sc11483_ramdac_device); svga->clock_gen = device_add(&av9194_device); @@ -6029,7 +6501,7 @@ static void *s3_init(const device_t *info) svga->getclock = ics2494_getclock; break; - case S3_V7MIRAGE_86C801: + case S3_MIROCRYSTAL10SD_805: svga->decode_mask = (2 << 20) - 1; stepping = 0xa0; /*86C801/86C805*/ s3->id = stepping; @@ -6038,11 +6510,27 @@ static void *s3_init(const device_t *info) s3->packed_mmio = 0; svga->crtc[0x5a] = 0x0a; - svga->ramdac = device_add(&att491_ramdac_device); + svga->ramdac = device_add(&gendac_ramdac_device); + svga->clock_gen = svga->ramdac; + svga->getclock = sdac_getclock; + break; + + case S3_SPEA_MIRAGE_86C801: + case S3_SPEA_MIRAGE_86C805: + svga->decode_mask = (2 << 20) - 1; + stepping = 0xa0; /*86C801/86C805*/ + s3->id = stepping; + s3->id_ext = stepping; + s3->id_ext_pci = 0; + s3->packed_mmio = 0; + svga->crtc[0x5a] = 0x0a; + + svga->ramdac = device_add(&att490_ramdac_device); svga->clock_gen = device_add(&av9194_device); svga->getclock = av9194_getclock; break; + case S3_PHOENIX_86C801: case S3_PHOENIX_86C805: svga->decode_mask = (2 << 20) - 1; stepping = 0xa0; /*86C801/86C805*/ @@ -6099,9 +6587,12 @@ static void *s3_init(const device_t *info) svga->ramdac = (info->local == S3_ELSAWIN2KPROX_964) ? device_add(&ibm_rgb528_ramdac_device) : device_add(&bt485_ramdac_device); svga->clock_gen = device_add(&icd2061_device); svga->getclock = icd2061_getclock; - break; + break; + case S3_ELSAWIN2KPROX: + case S3_MIROVIDEO40SV_968: + case S3_SPEA_MERCURY_P64V: svga->decode_mask = (8 << 20) - 1; s3->id = 0xe1; /*Vision968*/ s3->id_ext = s3->id_ext_pci = 0xf0; @@ -6117,8 +6608,12 @@ static void *s3_init(const device_t *info) svga->crtc[0x59] = 0x00; svga->crtc[0x5a] = 0x0a; } + + if (info->local == S3_ELSAWIN2KPROX) + svga->ramdac = device_add(&ibm_rgb528_ramdac_device); + else + svga->ramdac = device_add(&tvp3026_ramdac_device); - svga->ramdac = device_add(&ibm_rgb528_ramdac_device); svga->clock_gen = device_add(&icd2061_device); svga->getclock = icd2061_getclock; break; @@ -6163,6 +6658,7 @@ static void *s3_init(const device_t *info) case S3_PHOENIX_TRIO64VPLUS: case S3_PHOENIX_TRIO64VPLUS_ONBOARD: case S3_DIAMOND_STEALTH64_764: + case S3_SPEA_MIRAGE_P64: if (device_get_config_int("memory") == 1) svga->vram_max = 1 << 20; /* Phoenix BIOS does not expect VRAM to be mirrored. */ /* Fall over. */ @@ -6174,8 +6670,7 @@ static void *s3_init(const device_t *info) s3->packed_mmio = 1; if (info->local == S3_PHOENIX_TRIO64VPLUS || info->local == S3_PHOENIX_TRIO64VPLUS_ONBOARD) { - if (s3->pci) - svga->crtc[0x53] = 0x08; + svga->crtc[0x53] = 0x08; } svga->clock_gen = s3; @@ -6213,7 +6708,7 @@ static void *s3_init(const device_t *info) s3->ddc = ddc_init(i2c_gpio_get_bus(s3->i2c)); svga->packed_chain4 = 1; - + s3->wake_fifo_thread = thread_create_event(); s3->fifo_not_full_event = thread_create_event(); s3->thread_run = 1; @@ -6237,14 +6732,19 @@ static int s3_ami_86c924_available(void) return rom_present(ROM_AMI_86C924); } -static int s3_v7mirage_86c801_available(void) +static int s3_spea_mirage_86c801_available(void) { - return rom_present(ROM_V7MIRAGE_86C801); + return rom_present(ROM_SPEA_MIRAGE_86C801_V305I) && rom_present(ROM_SPEA_MIRAGE_86C801_V401); } -static int s3_phoenix_86c805_available(void) +static int s3_phoenix_86c80x_available(void) { - return rom_present(ROM_PHOENIX_86C805); + return rom_present(ROM_PHOENIX_86C80X); +} + +static int s3_mirocrystal_10sd_805_available(void) +{ + return rom_present(ROM_MIROCRYSTAL10SD_805); } static int s3_metheus_86c928_available(void) @@ -6272,6 +6772,16 @@ static int s3_diamond_stealth64_964_available(void) return rom_present(ROM_DIAMOND_STEALTH64_964); } +static int s3_mirovideo_40sv_968_available(void) +{ + return rom_present(ROM_MIROVIDEO40SV_968); +} + +static int s3_spea_mercury_p64v_pci_available(void) +{ + return rom_present(ROM_SPEA_MERCURY_P64V); +} + static int s3_elsa_winner2000_pro_x_964_available(void) { return rom_present(ROM_ELSAWIN2KPROX_964); @@ -6297,6 +6807,11 @@ static int s3_9fx_available(void) return rom_present(ROM_NUMBER9_9FX); } +static int s3_spea_mirage_p64_vlb_available(void) +{ + return rom_present(ROM_SPEA_MIRAGE_P64); +} + static int s3_phoenix_trio64_available(void) { return rom_present(ROM_PHOENIX_TRIO64); @@ -6322,7 +6837,7 @@ static void s3_close(void *p) s3_t *s3 = (s3_t *)p; svga_close(&s3->svga); - + s3->thread_run = 0; thread_set_event(s3->wake_fifo_thread); thread_wait(s3->fifo_thread, -1); @@ -6392,6 +6907,42 @@ static const device_config_t s3_9fx_config[] = } }; + +static const device_config_t s3_spea_mirage_config[] = +{ + { + "memory", "Memory size", CONFIG_SELECTION, "", 2, "", { 0 }, + { + { + "1 MB", 1 + }, + { + "2 MB", 2 + }, + { + "" + } + } + }, + { + "bios_ver", "BIOS version", CONFIG_SELECTION, "", 1, "", { 0 }, + { + { + "3.05I", 0 + }, + { + "4.01", 1 + }, + { + "" + } + } + }, + { + "", "", -1 + } +}; + static const device_config_t s3_phoenix_trio32_config[] = { { @@ -6469,7 +7020,7 @@ static const device_config_t s3_968_config[] = const device_t s3_orchid_86c911_isa_device = { - "Orchid Fahrenheit 1280 (S3 86c911) ISA", + "S3 86c911 ISA (Orchid Fahrenheit 1280)", DEVICE_AT | DEVICE_ISA, S3_ORCHID_86C911, s3_init, @@ -6483,7 +7034,7 @@ const device_t s3_orchid_86c911_isa_device = const device_t s3_diamond_stealth_vram_isa_device = { - "Diamond Stealth VRAM (S3 86c911) ISA", + "S3 86c911 ISA (Diamond Stealth VRAM)", DEVICE_AT | DEVICE_ISA, S3_DIAMOND_STEALTH_VRAM, s3_init, @@ -6497,7 +7048,7 @@ const device_t s3_diamond_stealth_vram_isa_device = const device_t s3_ami_86c924_isa_device = { - "AMI S3 86c924 ISA", + "S3 86c924 ISA (AMI)", DEVICE_AT | DEVICE_ISA, S3_AMI_86C924, s3_init, @@ -6509,15 +7060,43 @@ const device_t s3_ami_86c924_isa_device = s3_orchid_86c911_config }; -const device_t s3_v7mirage_86c801_isa_device = +const device_t s3_spea_mirage_86c801_isa_device = { - "SPEA V7 Mirage (S3 86c801) ISA", + "S3 86c801 ISA (SPEA Mirage ISA)", DEVICE_AT | DEVICE_ISA, - S3_V7MIRAGE_86C801, + S3_SPEA_MIRAGE_86C801, s3_init, s3_close, NULL, - { s3_v7mirage_86c801_available }, + { s3_spea_mirage_86c801_available }, + s3_speed_changed, + s3_force_redraw, + s3_spea_mirage_config +}; + +const device_t s3_mirocrystal_10sd_805_vlb_device = +{ + "S3 86c805 VLB (MiroCrystal 10SD)", + DEVICE_VLB, + S3_MIROCRYSTAL10SD_805, + s3_init, + s3_close, + NULL, + { s3_mirocrystal_10sd_805_available }, + s3_speed_changed, + s3_force_redraw, + NULL +}; + +const device_t s3_phoenix_86c801_isa_device = +{ + "S3 86c801 ISA (Phoenix)", + DEVICE_AT | DEVICE_ISA, + S3_PHOENIX_86C801, + s3_init, + s3_close, + NULL, + { s3_phoenix_86c80x_available }, s3_speed_changed, s3_force_redraw, s3_9fx_config @@ -6525,13 +7104,13 @@ const device_t s3_v7mirage_86c801_isa_device = const device_t s3_phoenix_86c805_vlb_device = { - "Phoenix S3 86c805 VLB", + "S3 86c805 VLB (Phoenix)", DEVICE_VLB, S3_PHOENIX_86C805, s3_init, s3_close, NULL, - { s3_phoenix_86c805_available }, + { s3_phoenix_86c80x_available }, s3_speed_changed, s3_force_redraw, s3_9fx_config @@ -6539,7 +7118,7 @@ const device_t s3_phoenix_86c805_vlb_device = const device_t s3_metheus_86c928_isa_device = { - "Metheus Premier 928 (S3 86c928) ISA", + "S3 86c928 ISA (Metheus Premier 928)", DEVICE_AT | DEVICE_ISA, S3_METHEUS_86C928, s3_init, @@ -6553,7 +7132,7 @@ const device_t s3_metheus_86c928_isa_device = const device_t s3_metheus_86c928_vlb_device = { - "Metheus Premier 928 (S3 86c928) VLB", + "S3 86c928 VLB (Metheus Premier 928)", DEVICE_VLB, S3_METHEUS_86C928, s3_init, @@ -6565,23 +7144,9 @@ const device_t s3_metheus_86c928_vlb_device = s3_standard_config }; -const device_t s3_metheus_86c928_pci_device = -{ - "Metheus Premier 928 (S3 86c928) PCI", - DEVICE_PCI, - S3_METHEUS_86C928, - s3_init, - s3_close, - NULL, - { s3_metheus_86c928_available }, - s3_speed_changed, - s3_force_redraw, - s3_standard_config -}; - const device_t s3_bahamas64_vlb_device = { - "Paradise Bahamas 64 (S3 Vision864) VLB", + "S3 Vision864 VLB (Paradise Bahamas 64)", DEVICE_VLB, S3_PARADISE_BAHAMAS64, s3_init, @@ -6595,7 +7160,7 @@ const device_t s3_bahamas64_vlb_device = const device_t s3_bahamas64_pci_device = { - "Paradise Bahamas 64 (S3 Vision864) PCI", + "S3 Vision864 PCI (Paradise Bahamas 64)", DEVICE_PCI, S3_PARADISE_BAHAMAS64, s3_init, @@ -6609,7 +7174,7 @@ const device_t s3_bahamas64_pci_device = const device_t s3_diamond_stealth64_964_vlb_device = { - "S3 Vision964 (Diamond Stealth64 VRAM) VLB", + "S3 Vision964 VLB (Diamond Stealth64 VRAM)", DEVICE_VLB, S3_DIAMOND_STEALTH64_964, s3_init, @@ -6623,7 +7188,7 @@ const device_t s3_diamond_stealth64_964_vlb_device = const device_t s3_diamond_stealth64_964_pci_device = { - "S3 Vision964 (Diamond Stealth64 VRAM) PCI", + "S3 Vision964 PCI (Diamond Stealth64 VRAM)", DEVICE_PCI, S3_DIAMOND_STEALTH64_964, s3_init, @@ -6635,9 +7200,51 @@ const device_t s3_diamond_stealth64_964_pci_device = s3_standard_config }; +const device_t s3_mirovideo_40sv_968_vlb_device = +{ + "S3 Vision968 VLB (MiroVIDEO 40SV)", + DEVICE_VLB, + S3_MIROVIDEO40SV_968, + s3_init, + s3_close, + NULL, + { s3_mirovideo_40sv_968_available }, + s3_speed_changed, + s3_force_redraw, + s3_standard_config +}; + +const device_t s3_mirovideo_40sv_968_pci_device = +{ + "S3 Vision968 PCI (MiroVIDEO 40SV)", + DEVICE_PCI, + S3_MIROVIDEO40SV_968, + s3_init, + s3_close, + NULL, + { s3_mirovideo_40sv_968_available }, + s3_speed_changed, + s3_force_redraw, + s3_standard_config +}; + +const device_t s3_spea_mercury_p64v_pci_device = +{ + "S3 Vision968 PCI (SPEA Mercury P64V)", + DEVICE_PCI, + S3_SPEA_MERCURY_P64V, + s3_init, + s3_close, + NULL, + { s3_spea_mercury_p64v_pci_available }, + s3_speed_changed, + s3_force_redraw, + s3_standard_config +}; + const device_t s3_9fx_vlb_device = { - "Number 9 9FX (S3 Trio64) VLB", + "S3 Trio64 VLB (Number 9 9FX 330)", DEVICE_VLB, S3_NUMBER9_9FX, s3_init, @@ -6651,7 +7258,7 @@ const device_t s3_9fx_vlb_device = const device_t s3_9fx_pci_device = { - "Number 9 9FX (S3 Trio64) PCI", + "S3 Trio64 PCI (Number 9 9FX 330)", DEVICE_PCI, S3_NUMBER9_9FX, s3_init, @@ -6665,7 +7272,7 @@ const device_t s3_9fx_pci_device = const device_t s3_phoenix_trio32_vlb_device = { - "Phoenix S3 Trio32 VLB", + "S3 Trio32 VLB (Phoenix)", DEVICE_VLB, S3_PHOENIX_TRIO32, s3_init, @@ -6679,7 +7286,7 @@ const device_t s3_phoenix_trio32_vlb_device = const device_t s3_phoenix_trio32_pci_device = { - "Phoenix S3 Trio32 PCI", + "S3 Trio32 PCI (Phoenix)", DEVICE_PCI, S3_PHOENIX_TRIO32, s3_init, @@ -6693,7 +7300,7 @@ const device_t s3_phoenix_trio32_pci_device = const device_t s3_diamond_stealth_se_vlb_device = { - "Diamond Stealth SE (S3 Trio32) VLB", + "S3 Trio32 VLB (Diamond Stealth SE)", DEVICE_VLB, S3_DIAMOND_STEALTH_SE, s3_init, @@ -6707,7 +7314,7 @@ const device_t s3_diamond_stealth_se_vlb_device = const device_t s3_diamond_stealth_se_pci_device = { - "Diamond Stealth SE (S3 Trio32) PCI", + "S3 Trio32 PCI (Diamond Stealth SE)", DEVICE_PCI, S3_DIAMOND_STEALTH_SE, s3_init, @@ -6722,7 +7329,7 @@ const device_t s3_diamond_stealth_se_pci_device = const device_t s3_phoenix_trio64_vlb_device = { - "Phoenix S3 Trio64 VLB", + "S3 Trio64 VLB (Phoenix)", DEVICE_VLB, S3_PHOENIX_TRIO64, s3_init, @@ -6736,7 +7343,7 @@ const device_t s3_phoenix_trio64_vlb_device = const device_t s3_phoenix_trio64_onboard_pci_device = { - "Phoenix S3 Trio64 On-Board PCI", + "S3 Trio64 PCI On-Board (Phoenix)", DEVICE_PCI, S3_PHOENIX_TRIO64_ONBOARD, s3_init, @@ -6750,7 +7357,7 @@ const device_t s3_phoenix_trio64_onboard_pci_device = const device_t s3_phoenix_trio64_pci_device = { - "Phoenix S3 Trio64 PCI", + "S3 Trio64 PCI (Phoenix)", DEVICE_PCI, S3_PHOENIX_TRIO64, s3_init, @@ -6762,23 +7369,9 @@ const device_t s3_phoenix_trio64_pci_device = s3_standard_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_standard_config -}; - const device_t s3_phoenix_trio64vplus_onboard_pci_device = { - "Phoenix S3 Trio64V+ On-Board PCI", + "S3 Trio64V+ PCI On-Board (Phoenix)", DEVICE_PCI, S3_PHOENIX_TRIO64VPLUS_ONBOARD, s3_init, @@ -6792,7 +7385,7 @@ const device_t s3_phoenix_trio64vplus_onboard_pci_device = const device_t s3_phoenix_trio64vplus_pci_device = { - "Phoenix S3 Trio64V+ PCI", + "S3 Trio64V+ PCI (Phoenix)", DEVICE_PCI, S3_PHOENIX_TRIO64VPLUS, s3_init, @@ -6806,7 +7399,7 @@ const device_t s3_phoenix_trio64vplus_pci_device = const device_t s3_phoenix_vision864_vlb_device = { - "Phoenix S3 Vision864 VLB", + "S3 Vision864 VLB (Phoenix)", DEVICE_VLB, S3_PHOENIX_VISION864, s3_init, @@ -6820,7 +7413,7 @@ const device_t s3_phoenix_vision864_vlb_device = const device_t s3_phoenix_vision864_pci_device = { - "Phoenix S3 Vision864 PCI", + "S3 Vision864 PCI (Phoenix)", DEVICE_PCI, S3_PHOENIX_VISION864, s3_init, @@ -6834,7 +7427,7 @@ const device_t s3_phoenix_vision864_pci_device = const device_t s3_phoenix_vision868_vlb_device = { - "Phoenix S3 Vision868 VLB", + "S3 Vision868 VLB (Phoenix)", DEVICE_VLB, S3_PHOENIX_VISION868, s3_init, @@ -6848,7 +7441,7 @@ const device_t s3_phoenix_vision868_vlb_device = const device_t s3_phoenix_vision868_pci_device = { - "Phoenix S3 Vision868 PCI", + "S3 Vision868 PCI (Phoenix)", DEVICE_PCI, S3_PHOENIX_VISION868, s3_init, @@ -6862,7 +7455,7 @@ const device_t s3_phoenix_vision868_pci_device = const device_t s3_diamond_stealth64_vlb_device = { - "S3 Trio64 (Diamond Stealth64 DRAM) VLB", + "S3 Trio64 VLB (Diamond Stealth64 DRAM)", DEVICE_VLB, S3_DIAMOND_STEALTH64_764, s3_init, @@ -6876,7 +7469,7 @@ const device_t s3_diamond_stealth64_vlb_device = const device_t s3_diamond_stealth64_pci_device = { - "S3 Trio64 (Diamond Stealth64 DRAM) PCI", + "S3 Trio64 PCI (Diamond Stealth64 DRAM)", DEVICE_PCI, S3_DIAMOND_STEALTH64_764, s3_init, @@ -6888,24 +7481,24 @@ const device_t s3_diamond_stealth64_pci_device = s3_9fx_config }; -const device_t s3_elsa_winner2000_pro_x_964_pci_device = +const device_t s3_spea_mirage_p64_vlb_device = { - "S3 Vision964 (ELSA Winner 2000 Pro/X) PCI", - DEVICE_PCI, - S3_ELSAWIN2KPROX_964, - s3_init, - s3_close, + "S3 Trio64 VLB (SPEA Mirage P64)", + DEVICE_VLB, + S3_SPEA_MIRAGE_P64, + s3_init, + s3_close, NULL, - { s3_elsa_winner2000_pro_x_964_available }, - s3_speed_changed, - s3_force_redraw, - s3_968_config + { s3_spea_mirage_p64_vlb_available }, + s3_speed_changed, + s3_force_redraw, + s3_9fx_config }; -const device_t s3_elsa_winner2000_pro_x_964_vlb_device = +const device_t s3_elsa_winner2000_pro_x_964_pci_device = { - "S3 Vision964 (ELSA Winner 2000 Pro/X) VLB", - DEVICE_VLB, + "S3 Vision964 PCI (ELSA Winner 2000 Pro/X)", + DEVICE_PCI, S3_ELSAWIN2KPROX_964, s3_init, s3_close, @@ -6918,7 +7511,7 @@ const device_t s3_elsa_winner2000_pro_x_964_vlb_device = const device_t s3_elsa_winner2000_pro_x_pci_device = { - "S3 Vision968 (ELSA Winner 2000 Pro/X) PCI", + "S3 Vision968 PCI (ELSA Winner 2000 Pro/X)", DEVICE_PCI, S3_ELSAWIN2KPROX, s3_init, @@ -6930,21 +7523,6 @@ const device_t s3_elsa_winner2000_pro_x_pci_device = s3_968_config }; -const device_t s3_elsa_winner2000_pro_x_vlb_device = -{ - "S3 Vision968 (ELSA Winner 2000 Pro/X) VLB", - DEVICE_VLB, - S3_ELSAWIN2KPROX, - s3_init, - s3_close, - NULL, - { s3_elsa_winner2000_pro_x_available }, - s3_speed_changed, - s3_force_redraw, - s3_968_config -}; - - const device_t s3_trio64v2_dx_pci_device = { "S3 Trio64V2/DX PCI", diff --git a/src/video/vid_table.c b/src/video/vid_table.c index d683bb74f..6e4a758df 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -53,7 +53,6 @@ static const VIDEO_CARD video_cards[] = { { "none", NULL }, { "internal", NULL }, - { "ami_s3_924", &s3_ami_86c924_isa_device }, { "egawonder800", &atiega_device }, { "mach64gx_isa", &mach64gx_isa_device }, { "ati28800k", &ati28800k_device }, @@ -79,7 +78,6 @@ video_cards[] = { { "compaq_cga", &compaq_cga_device }, { "compaq_cga_2", &compaq_cga_2_device }, { "compaq_ega", &cpqega_device }, - { "stealthvram_isa", &s3_diamond_stealth_vram_isa_device }, { "ega", &ega_device }, { "g2_gc205", &g2_gc205_device }, { "hercules", &hercules_device }, @@ -90,13 +88,11 @@ video_cards[] = { { "kasan16vga", &et4000_kasan_isa_device }, { "mda", &mda_device }, { "genius", &genius_device }, - { "metheus928_isa", &s3_metheus_86c928_isa_device }, { "nga", &nga_device }, { "ogc", &ogc_device }, { "oti037c", &oti037c_device }, { "oti067", &oti067_device }, { "oti077", &oti077_device }, - { "orchid_s3_911", &s3_orchid_86c911_isa_device }, { "pvga1a", ¶dise_pvga1a_device }, { "wd90c11", ¶dise_wd90c11_device }, { "wd90c30", ¶dise_wd90c30_device }, @@ -104,8 +100,13 @@ video_cards[] = { { "pgc", &pgc_device }, { "radius_isa", &radius_svga_multiview_isa_device }, { "rtg3106", &realtek_rtg3106_device }, + { "stealthvram_isa", &s3_diamond_stealth_vram_isa_device }, + { "orchid_s3_911", &s3_orchid_86c911_isa_device }, + { "ami_s3_924", &s3_ami_86c924_isa_device }, + { "metheus928_isa", &s3_metheus_86c928_isa_device }, + { "px_86c801_isa", &s3_phoenix_86c801_isa_device }, + { "px_s3_v7_801_isa", &s3_spea_mirage_86c801_isa_device }, { "sigma400", &sigma_device }, - { "px_s3_v7_801_isa", &s3_v7mirage_86c801_isa_device }, { "tvga8900b", &tvga8900b_device }, { "tvga8900d", &tvga8900d_device }, { "tvga9000b", &tvga9000b_device }, @@ -133,28 +134,30 @@ video_cards[] = { { "cl_gd5480_pci", &gd5480_pci_device }, { "ctl3d_banshee_pci", &creative_voodoo_banshee_device }, { "stealth32_pci", &et4000w32p_pci_device }, + { "stealth64v_pci", &s3_diamond_stealth64_964_pci_device }, + { "elsawin2kprox_964_pci", &s3_elsa_winner2000_pro_x_964_pci_device }, + { "bahamas64_pci", &s3_bahamas64_pci_device }, + { "px_vision864_pci", &s3_phoenix_vision864_pci_device }, + { "stealthse_pci", &s3_diamond_stealth_se_pci_device }, + { "px_trio32_pci", &s3_phoenix_trio32_pci_device }, + { "stealth64d_pci", &s3_diamond_stealth64_pci_device }, + { "n9_9fx_pci", &s3_9fx_pci_device }, + { "px_trio64_pci", &s3_phoenix_trio64_pci_device }, + { "elsawin2kprox_pci", &s3_elsa_winner2000_pro_x_pci_device }, + { "mirovideo40sv_pci", &s3_mirovideo_40sv_968_pci_device }, + { "spea_mercury64p_pci", &s3_spea_mercury_p64v_pci_device }, + { "px_vision868_pci", &s3_phoenix_vision868_pci_device }, + { "px_trio64vplus_pci", &s3_phoenix_trio64vplus_pci_device }, + { "trio64v2dx_pci", &s3_trio64v2_dx_pci_device }, { "stealth3d_2000_pci", &s3_virge_pci_device }, { "stealth3d_3000_pci", &s3_virge_988_pci_device }, - { "stealth64d_pci", &s3_diamond_stealth64_pci_device }, - { "stealth64v_pci", &s3_diamond_stealth64_964_pci_device }, - { "stealthse_pci", &s3_diamond_stealth_se_pci_device }, - { "elsawin2kprox_964_pci", &s3_elsa_winner2000_pro_x_964_pci_device }, - { "elsawin2kprox_pci", &s3_elsa_winner2000_pro_x_pci_device }, #if defined(DEV_BRANCH) && defined(USE_MGA) { "mystique", &mystique_device }, { "mystique_220", &mystique_220_device }, #endif - { "n9_9fx_pci", &s3_9fx_pci_device }, - { "bahamas64_pci", &s3_bahamas64_pci_device }, - { "px_vision864_pci", &s3_phoenix_vision864_pci_device }, - { "px_vision868_pci", &s3_phoenix_vision868_pci_device }, - { "px_trio32_pci", &s3_phoenix_trio32_pci_device }, - { "px_trio64_pci", &s3_phoenix_trio64_pci_device }, - { "px_trio64vplus_pci", &s3_phoenix_trio64vplus_pci_device }, #if defined(DEV_BRANCH) && defined(USE_S3TRIO3D2X) { "trio3d2x", &s3_trio3d_2x_pci_device }, #endif - { "trio64v2dx_pci", &s3_trio64v2_dx_pci_device }, { "virge325_pci", &s3_virge_325_pci_device }, { "virge375_pci", &s3_virge_375_pci_device }, { "virge375_vbe20_pci", &s3_virge_375_4_pci_device }, @@ -179,21 +182,20 @@ video_cards[] = { { "cl_gd5430_vlb", &gd5430_vlb_device }, { "stealth3d_2000_vlb", &s3_virge_vlb_device }, { "stealth3d_3000_vlb", &s3_virge_988_vlb_device }, - { "stealth64d_vlb", &s3_diamond_stealth64_vlb_device }, - { "stealth64v_vlb", &s3_diamond_stealth64_964_vlb_device }, - { "stealthse_vlb", &s3_diamond_stealth_se_vlb_device }, - { "elsawin2kprox_964_vlb", &s3_elsa_winner2000_pro_x_964_vlb_device }, - { "elsawin2kprox_vlb", &s3_elsa_winner2000_pro_x_vlb_device }, - { "ht216_32", &ht216_32_standalone_device }, { "metheus928_vlb", &s3_metheus_86c928_vlb_device }, - { "n9_9fx_vlb", &s3_9fx_vlb_device }, - { "bahamas64_vlb", &s3_bahamas64_vlb_device }, + { "mirocrystal10sd_vlb", &s3_mirocrystal_10sd_805_vlb_device }, { "px_86c805_vlb", &s3_phoenix_86c805_vlb_device }, + { "stealth64v_vlb", &s3_diamond_stealth64_964_vlb_device }, + { "bahamas64_vlb", &s3_bahamas64_vlb_device }, { "px_vision864_vlb", &s3_phoenix_vision864_vlb_device }, - { "px_vision868_vlb", &s3_phoenix_vision868_vlb_device }, + { "stealthse_vlb", &s3_diamond_stealth_se_vlb_device }, { "px_trio32_vlb", &s3_phoenix_trio32_vlb_device }, + { "stealth64d_vlb", &s3_diamond_stealth64_vlb_device }, + { "n9_9fx_vlb", &s3_9fx_vlb_device }, { "px_trio64_vlb", &s3_phoenix_trio64_vlb_device }, - { "px_trio64vplus_vlb", &s3_phoenix_trio64vplus_vlb_device }, + { "spea_miragep64_vlb", &s3_spea_mirage_p64_vlb_device }, + { "px_vision868_vlb", &s3_phoenix_vision868_vlb_device }, + { "ht216_32", &ht216_32_standalone_device }, { "virge325_vlb", &s3_virge_325_vlb_device }, { "virge375_vlb", &s3_virge_375_vlb_device }, { "virge375_vbe20_vlb", &s3_virge_375_4_vlb_device }, From 229e61b74d5e3cd183c007aec1c0a30577e2dc62 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 3 Sep 2021 00:27:08 +0200 Subject: [PATCH 21/24] Minor pix trans fixes to the S3 code (R/W). --- src/video/vid_s3.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 36220e8f0..289a576df 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -1039,7 +1039,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; s3->accel.pix_trans[0] = val; if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && !(s3->accel.cmd & 0x600) && (s3->accel.cmd & 0x100) && - (s3->accel.cmd & 2)) { + ((s3->accel.cmd & 2) || ((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) { s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); } else if (!(s3->accel.cmd & 0x600) && (s3->accel.cmd & 0x100)) s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); @@ -1049,7 +1049,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) if (s3_cpu_dest(s3)) break; s3->accel.pix_trans[1] = val; - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (s3->accel.cmd & 2)) { + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && ((s3->accel.cmd & 2) || ((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) { if (s3->accel.cmd & 0x100) { switch (s3->accel.cmd & 0x600) { case 0x000: @@ -1106,7 +1106,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) if (s3_cpu_dest(s3)) break; s3->accel.pix_trans[3] = val; - if ((s3->accel.multifunc[0xa]& 0xc0) == 0x80 && (s3->accel.cmd & 2)) { + if ((s3->accel.multifunc[0xa]& 0xc0) == 0x80 && ((s3->accel.cmd & 2) || ((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) { if (s3->accel.cmd & 0x100) { switch (s3->accel.cmd & 0x600) { case 0x000: @@ -1285,7 +1285,7 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) if (svga->crtc[0x53] & 0x08) { if ((addr & 0x1ffff) < 0x8000) { if (s3->accel.cmd & 0x100) { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (s3->accel.cmd & 2)) + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && ((s3->accel.cmd & 2) || ((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); @@ -3933,7 +3933,7 @@ s3_accel_read_l(uint32_t addr, void *p) temp |= s3->accel.pix_trans[2] << 16; temp |= s3->accel.pix_trans[3] << 24; - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (s3->accel.cmd & 2)) { + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && ((s3->accel.cmd & 2) || ((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40))) { if ((s3->accel.cmd & 0x200) == 0x000) { s3_accel_start(8, 1, 0xffffffff, 0, s3); s3_accel_start(8, 1, 0xffffffff, 0, s3); From 87f598816bc394a925ef596a3cd184ade88975fe Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 Sep 2021 00:29:25 +0200 Subject: [PATCH 22/24] Fixed the Amstrad colors, closes #1517. --- src/machine/m_amstrad.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index be44fa734..24fc1be51 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -1643,8 +1643,6 @@ vid_init_200(amstrad_t *ams) memset(vid, 0x00, sizeof(amsvid_t)); vid->emulation = device_get_config_int("video_emulation"); - cga_palette = (device_get_config_int("display_type") << 1); - ams_inform(vid); /* Default to CGA */ vid->dipswitches = 0x10; @@ -1677,6 +1675,9 @@ vid_init_200(amstrad_t *ams) cga_init(cga); mda_init(mda); + cga_palette = (device_get_config_int("display_type") << 1); + ams_inform(vid); + /* Attribute 8 is white on black (on a real MDA it's black on black) */ mda_setcol(0x08, 0, 1, 15); mda_setcol(0x88, 0, 1, 15); From 2415673c7a8ca828c599103c52702b413b065c4f Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 Sep 2021 00:41:10 +0200 Subject: [PATCH 23/24] Some small S3 fixes (bugs found by clang). --- src/video/vid_s3.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 289a576df..5e9a65491 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -522,7 +522,7 @@ s3_enable_fifo(s3_t *s3) return 1; /* FIFO always enabled on these chips. */ //return !!((svga->crtc[0x40] & 0x08) || (s3->accel.advfunc_cntl & 0x40)); - return 0; /*Disable FIFO on pre-964 cards due to glitches going around*/ + return 0; /*Disable FIFO on pre-964 cards due to glitches going around*/ } static void @@ -2723,8 +2723,8 @@ static void s3_recalctimings(svga_t *svga) svga->render = svga_render_15bpp_highres; if (s3->chip <= S3_86C924) svga->rowoffset >>= 1; - if ((s3->chip != S3_VISION964) && (s3->card_type != S3_SPEA_MIRAGE_86C801 || - (s3->card_type != S3_SPEA_MIRAGE_86C805))) { + if ((s3->chip != S3_VISION964) && (s3->card_type != S3_SPEA_MIRAGE_86C801) && + (s3->card_type != S3_SPEA_MIRAGE_86C805)) { if (s3->chip == S3_86C928) svga->hdisp *= 2; else if (s3->chip != S3_VISION968) @@ -2740,13 +2740,13 @@ static void s3_recalctimings(svga_t *svga) svga->render = svga_render_16bpp_highres; if (s3->chip <= S3_86C924) svga->rowoffset >>= 1; - if ((s3->chip != S3_VISION964) && (s3->card_type != S3_SPEA_MIRAGE_86C801 || - (s3->card_type != S3_SPEA_MIRAGE_86C805))) { + if ((s3->chip != S3_VISION964) && (s3->card_type != S3_SPEA_MIRAGE_86C801) && + (s3->card_type != S3_SPEA_MIRAGE_86C805)) { if (s3->chip == S3_86C928) svga->hdisp *= 2; else if (s3->chip != S3_VISION968) svga->hdisp /= 2; - } else if (s3->card_type == S3_SPEA_MIRAGE_86C801 || s3->card_type == S3_SPEA_MIRAGE_86C805) { + } else if ((s3->card_type == S3_SPEA_MIRAGE_86C801) || (s3->card_type == S3_SPEA_MIRAGE_86C805)) { svga->hdisp /= 2; } if ((s3->chip != S3_VISION868) && (s3->chip != S3_TRIO32) && From dc33476e0d1fcb44507e19a3fb98498a94c5d583 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 Sep 2021 00:45:47 +0200 Subject: [PATCH 24/24] Fixed the PIT BCD counter for signedness (bug again found by clang). --- src/pit.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/pit.c b/src/pit.c index dd4613d76..582c748a7 100644 --- a/src/pit.c +++ b/src/pit.c @@ -110,20 +110,20 @@ ctr_decrease_count(ctr_t *ctr) { if (ctr->bcd) { ctr->units--; - if (ctr->units == 0xff) { - ctr->units = 9; + if (ctr->units == -1) { + ctr->units = -7; ctr->tens--; - if (ctr->tens == 0xff) { - ctr->tens = 9; + if (ctr->tens == -1) { + ctr->tens = -7; ctr->hundreds--; - if (ctr->hundreds == 0xff) { - ctr->hundreds = 9; + if (ctr->hundreds == -1) { + ctr->hundreds = -7; ctr->thousands--; - if (ctr->thousands == 0xff) { - ctr->thousands = 9; + if (ctr->thousands == -1) { + ctr->thousands = -7; ctr->myriads--; - if (ctr->myriads == 0xff) - ctr->myriads = 0; /* 0 - 1 should wrap around to 9999. */ + if (ctr->myriads == -1) + ctr->myriads = -7; /* 0 - 1 should wrap around to 9999. */ } } }