From 8b316f869b3ede2ab1b4da2c0656525a59714cae Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 9 Sep 2021 23:51:26 +0600 Subject: [PATCH 1/3] Include SDL.h before anything else This also cleans up the unnecessary source-level defines --- src/unix/unix.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/unix/unix.c b/src/unix/unix.c index ec71dee84..93d3ede73 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -2,10 +2,7 @@ #define _FILE_OFFSET_BITS 64 #define _LARGEFILE64_SOURCE 1 #endif -#define _POSIX_C_SOURCE 200809L -#ifdef __APPLE__ -#define _DARWIN_C_SOURCE 1 -#endif +#include #include #include #include @@ -20,7 +17,7 @@ #include #include #include -#include + #include <86box/86box.h> #include <86box/keyboard.h> #include <86box/mouse.h> From 2092f1dceb9a97800f7a4c1c442bc42fcd9e3b33 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 10 Sep 2021 18:01:21 +0600 Subject: [PATCH 2/3] Update unix_sdl.c --- src/unix/unix_sdl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/unix/unix_sdl.c b/src/unix/unix_sdl.c index e5abdcd32..ff31e5786 100644 --- a/src/unix/unix_sdl.c +++ b/src/unix/unix_sdl.c @@ -367,7 +367,7 @@ sdl_init_common(int flags) } sdl_mutex = SDL_CreateMutex(); - sdl_win = SDL_CreateWindow("86Box", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, scrnsz_x, scrnsz_y, SDL_WINDOW_OPENGL); + sdl_win = SDL_CreateWindow("86Box", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, scrnsz_x, scrnsz_y, SDL_WINDOW_OPENGL | (vid_resize & 1 ? SDL_WINDOW_RESIZABLE : 0)); sdl_set_fs(video_fullscreen); if (!(video_fullscreen & 1)) { From 04e48a071e4b5ec59ab7c7a01b743d82510c68a4 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 11 Sep 2021 22:02:31 +0200 Subject: [PATCH 3/3] S3 changes part 3: Added the Phoenix S3 Vision968 (IBM RGB) and the MiroCRYSTAL 20SD VLB (864, SDAC) (alongside their BIOSes). Added the vendor specific bits of CRTC5c used by the MiroVIDEO 40SV Ergo (968), Phoenix 868 and Phoenix 968. Restored FIFO in the pre-964 cards, but without threading (Warning, code might be bloated for this). Fixed horizontal issue with the SPEA Mercury P64V (968). --- src/include/86box/video.h | 6 +- src/video/vid_s3.c | 642 +++++++++++++++++++++++++++++++------- src/video/vid_table.c | 5 +- 3 files changed, 544 insertions(+), 109 deletions(-) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 2232667ef..be7591dc7 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -349,6 +349,7 @@ extern const device_t s3_phoenix_trio64vplus_pci_device; extern const device_t s3_phoenix_trio64vplus_onboard_pci_device; extern const device_t s3_mirocrystal_20sv_964_vlb_device; extern const device_t s3_mirocrystal_20sv_964_pci_device; +extern const device_t s3_mirocrystal_20sd_864_vlb_device; extern const device_t s3_phoenix_vision864_pci_device; extern const device_t s3_phoenix_vision864_vlb_device; extern const device_t s3_phoenix_vision868_pci_device; @@ -357,8 +358,9 @@ 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_mirovideo_40sv_ergo_968_pci_device; +extern const device_t s3_phoenix_vision968_pci_device; +extern const device_t s3_phoenix_vision968_vlb_device; extern const device_t s3_spea_mercury_p64v_pci_device; extern const device_t s3_elsa_winner2000_pro_x_964_pci_device; extern const device_t s3_elsa_winner2000_pro_x_pci_device; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 5aa4922f2..8c204b43e 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -46,6 +46,7 @@ #define ROM_MIROCRYSTAL10SD_805 "roms/video/s3/MIROcrystal10SD_VLB.VBI" #define ROM_MIROCRYSTAL20SV_964_VLB "roms/video/s3/S3_964VL_BT485_27C256_miroCRYSTAL_20sv_ver1.2.bin" #define ROM_MIROCRYSTAL20SV_964_PCI "roms/video/s3/mirocrystal.VBI" +#define ROM_MIROCRYSTAL20SD_864_VLB "roms/video/s3/Miro20SD.BIN" #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" @@ -61,8 +62,9 @@ #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_MIROVIDEO40SV_ERGO_968_PCI "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" +#define ROM_PHOENIX_VISION968 "roms/video/s3/1-DSV3968P.BIN" enum { @@ -89,11 +91,13 @@ enum S3_ELSAWIN2KPROX_964, S3_ELSAWIN2KPROX, S3_PHOENIX_VISION868, - S3_MIROVIDEO40SV_968, + S3_MIROVIDEO40SV_ERGO_968, S3_MIROCRYSTAL10SD_805, S3_SPEA_MIRAGE_P64, S3_SPEA_MERCURY_P64V, - S3_MIROCRYSTAL20SV_964 + S3_MIROCRYSTAL20SV_964, + S3_MIROCRYSTAL20SD_864, + S3_PHOENIX_VISION968 }; @@ -253,6 +257,12 @@ typedef struct s3_t int ssv_len1, ssv_len2; uint8_t ssv_dir1, ssv_dir2; uint8_t ssv_draw1, ssv_draw2; + + /*S3 928 and 80x cards only*/ + int setup_fifo_slot, setup_fifo_slot2; + int draw_fifo_slot, draw_fifo_slot2; + int port_slot1, port_slot2; + int port_slot3, port_slot4; } accel; struct { @@ -471,14 +481,16 @@ s3_cpu_dest(s3_t *s3) 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)); - return 0; /*Disable FIFO on pre-964 cards due to glitches going around*/ + 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 @@ -487,6 +499,12 @@ s3_accel_out_pixtrans_w(s3_t *s3, uint16_t val) svga_t *svga = &s3->svga; if (s3->accel.cmd & 0x100) { + s3->accel.port_slot1++; + s3->accel.port_slot2++; + if (s3->accel.port_slot1 || s3->accel.port_slot2) + s3->accel.draw_fifo_slot++; + if (s3->accel.draw_fifo_slot > 8) + s3->accel.draw_fifo_slot = 1; switch (s3->accel.cmd & 0x600) { case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { @@ -546,6 +564,10 @@ s3_accel_out_pixtrans_w(s3_t *s3, uint16_t val) } break; } + + if ((s3_enable_fifo(s3) && s3->chip >= S3_VISION964) || (s3_enable_fifo(s3) == 0)) { + s3->accel.draw_fifo_slot = 0; + } } } @@ -553,6 +575,12 @@ static void s3_accel_out_pixtrans_l(s3_t *s3, uint32_t val) { if (s3->accel.cmd & 0x100) { + s3->accel.port_slot1++; + s3->accel.port_slot2++; + if (s3->accel.port_slot1 || s3->accel.port_slot2) + s3->accel.draw_fifo_slot++; + if (s3->accel.draw_fifo_slot > 8) + s3->accel.draw_fifo_slot = 1; switch (s3->accel.cmd & 0x600) { case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { @@ -612,6 +640,10 @@ s3_accel_out_pixtrans_l(s3_t *s3, uint32_t val) } break; } + + if ((s3_enable_fifo(s3) && s3->chip >= S3_VISION964) || (s3_enable_fifo(s3) == 0)) { + s3->accel.draw_fifo_slot = 0; + } } } @@ -622,6 +654,12 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) switch (port) { case 0x8148: case 0x82e8: + s3->accel.port_slot1++; + s3->accel.port_slot2++; + if (s3->accel.port_slot1 || s3->accel.port_slot2) + s3->accel.draw_fifo_slot++; + if (s3->accel.draw_fifo_slot > 8) + s3->accel.draw_fifo_slot = 1; s3->accel.cur_y_bitres = (s3->accel.cur_y_bitres & 0xff00) | val; s3->accel.cur_y = (s3->accel.cur_y & 0xf00) | val; s3->accel.poly_cy = s3->accel.cur_y; @@ -642,6 +680,12 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0x8548: case 0x86e8: + s3->accel.port_slot1++; + s3->accel.port_slot2++; + if (s3->accel.port_slot1 || s3->accel.port_slot2) + s3->accel.draw_fifo_slot++; + if (s3->accel.draw_fifo_slot > 8) + s3->accel.draw_fifo_slot = 1; s3->accel.cur_x_bitres = (s3->accel.cur_x_bitres & 0xff00) | val; s3->accel.cur_x = (s3->accel.cur_x & 0xf00) | val; s3->accel.poly_cx = s3->accel.cur_x << 20; @@ -664,6 +708,12 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0x8948: case 0x8ae8: + s3->accel.port_slot1++; + s3->accel.port_slot2++; + if (s3->accel.port_slot1 || s3->accel.port_slot2) + s3->accel.draw_fifo_slot++; + if (s3->accel.draw_fifo_slot > 8) + s3->accel.draw_fifo_slot = 1; s3->accel.desty_axstp = (s3->accel.desty_axstp & 0x3f00) | val; s3->accel.point_1_updated = 1; break; @@ -685,6 +735,12 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0x8d48: case 0x8ee8: + s3->accel.port_slot1++; + s3->accel.port_slot2++; + if (s3->accel.port_slot1 || s3->accel.port_slot2) + s3->accel.draw_fifo_slot++; + if (s3->accel.draw_fifo_slot > 8) + s3->accel.draw_fifo_slot = 1; s3->accel.destx_distp = (s3->accel.destx_distp & 0x3f00) | val; s3->accel.point_1_updated = 1; break; @@ -704,6 +760,12 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0x9148: case 0x92e8: + s3->accel.port_slot1++; + s3->accel.port_slot2++; + if (s3->accel.port_slot1 || s3->accel.port_slot2) + s3->accel.draw_fifo_slot++; + if (s3->accel.draw_fifo_slot > 8) + s3->accel.draw_fifo_slot = 1; s3->accel.err_term = (s3->accel.err_term & 0x3f00) | val; break; case 0x9149: case 0x92e9: @@ -721,6 +783,12 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0x9548: case 0x96e8: + s3->accel.port_slot1++; + s3->accel.port_slot2++; + if (s3->accel.port_slot1 || s3->accel.port_slot2) + s3->accel.draw_fifo_slot++; + if (s3->accel.draw_fifo_slot > 8) + s3->accel.draw_fifo_slot = 1; s3->accel.maj_axis_pcnt = (s3->accel.maj_axis_pcnt & 0xf00) | val; break; case 0x9459: case 0x96e9: @@ -738,6 +806,12 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0x9948: case 0x9ae8: + s3->accel.port_slot1++; + s3->accel.port_slot2++; + if (s3->accel.port_slot1 || s3->accel.port_slot2) + s3->accel.draw_fifo_slot++; + if (s3->accel.draw_fifo_slot > 8) + s3->accel.draw_fifo_slot = 1; s3->accel.cmd = (s3->accel.cmd & 0xff00) | val; s3->data_available = 0; s3->accel.b2e8_pix = 0; @@ -767,6 +841,12 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xa148: case 0xa2e8: + s3->accel.port_slot3++; + s3->accel.port_slot4++; + if (s3->accel.port_slot3 || s3->accel.port_slot4) + s3->accel.setup_fifo_slot++; + if (s3->accel.setup_fifo_slot > 8) + s3->accel.setup_fifo_slot = 1; if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); else @@ -803,6 +883,12 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xa548: case 0xa6e8: + s3->accel.port_slot3++; + s3->accel.port_slot4++; + if (s3->accel.port_slot3 || s3->accel.port_slot4) + s3->accel.setup_fifo_slot++; + if (s3->accel.setup_fifo_slot > 8) + s3->accel.setup_fifo_slot = 1; if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); else @@ -839,6 +925,12 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xa948: case 0xaae8: + s3->accel.port_slot3++; + s3->accel.port_slot4++; + if (s3->accel.port_slot3 || s3->accel.port_slot4) + s3->accel.setup_fifo_slot++; + if (s3->accel.setup_fifo_slot > 8) + s3->accel.setup_fifo_slot = 1; if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); else @@ -875,6 +967,12 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xad48: case 0xaee8: + s3->accel.port_slot3++; + s3->accel.port_slot4++; + if (s3->accel.port_slot3 || s3->accel.port_slot4) + s3->accel.setup_fifo_slot++; + if (s3->accel.setup_fifo_slot > 8) + s3->accel.setup_fifo_slot = 1; if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); else @@ -911,6 +1009,12 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xb148: case 0xb2e8: + s3->accel.port_slot1++; + s3->accel.port_slot2++; + if (s3->accel.port_slot1 || s3->accel.port_slot2) + s3->accel.draw_fifo_slot++; + if (s3->accel.draw_fifo_slot > 8) + s3->accel.draw_fifo_slot = 1; if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); else @@ -947,10 +1051,22 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xb548: case 0xb6e8: + s3->accel.port_slot3++; + s3->accel.port_slot4++; + if (s3->accel.port_slot3 || s3->accel.port_slot4) + s3->accel.setup_fifo_slot++; + if (s3->accel.setup_fifo_slot > 8) + s3->accel.setup_fifo_slot = 1; s3->accel.bkgd_mix = val; break; case 0xb948: case 0xbae8: + s3->accel.port_slot3++; + s3->accel.port_slot4++; + if (s3->accel.port_slot3 || s3->accel.port_slot4) + s3->accel.setup_fifo_slot++; + if (s3->accel.setup_fifo_slot > 8) + s3->accel.setup_fifo_slot = 1; s3->accel.frgd_mix = val; break; @@ -960,6 +1076,24 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xbd49: case 0xbee9: s3->accel.multifunc_cntl = (s3->accel.multifunc_cntl & 0xff) | (val << 8); s3->accel.multifunc[s3->accel.multifunc_cntl >> 12] = s3->accel.multifunc_cntl & 0xfff; + switch (s3->accel.multifunc_cntl >> 12) { + case 0: + s3->accel.port_slot1++; + s3->accel.port_slot2++; + if (s3->accel.port_slot1 || s3->accel.port_slot2) + s3->accel.draw_fifo_slot++; + if (s3->accel.draw_fifo_slot > 8) + s3->accel.draw_fifo_slot = 1; + break; + case 0xa: + s3->accel.port_slot3++; + s3->accel.port_slot4++; + if (s3->accel.port_slot3 || s3->accel.port_slot4) + s3->accel.setup_fifo_slot++; + if (s3->accel.setup_fifo_slot > 8) + s3->accel.setup_fifo_slot = 1; + break; + } break; case 0xd148: case 0xd2e8: @@ -1057,6 +1191,12 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; s3->accel.pix_trans[0] = val; if (s3->accel.cmd & 0x100) { + s3->accel.port_slot1++; + s3->accel.port_slot2++; + if (s3->accel.port_slot1 || s3->accel.port_slot2) + s3->accel.draw_fifo_slot++; + if (s3->accel.draw_fifo_slot > 8) + s3->accel.draw_fifo_slot = 1; if (!(s3->accel.cmd & 0x600)) { if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) @@ -1193,6 +1333,13 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) } break; } + + if ((s3_enable_fifo(s3) && s3->chip >= S3_VISION964) || (s3_enable_fifo(s3) == 0)) { + if (s3->accel.port_slot1 || s3->accel.port_slot2) { + s3->accel.draw_fifo_slot = 0; + } else if (s3->accel.port_slot3 || s3->accel.port_slot4) + s3->accel.setup_fifo_slot = 0; + } } static void @@ -1373,6 +1520,13 @@ 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) { + s3->accel.port_slot1++; + s3->accel.port_slot2++; + if (s3->accel.port_slot1 || s3->accel.port_slot2) + s3->accel.draw_fifo_slot++; + if (s3->accel.draw_fifo_slot > 8) + s3->accel.draw_fifo_slot = 1; + if ((s3->accel.cmd & 0x600) == 0x200) { if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) @@ -1390,6 +1544,9 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) } else s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); } + if ((s3_enable_fifo(s3) && s3->chip >= S3_VISION964) || (s3_enable_fifo(s3) == 0)) { + s3->accel.draw_fifo_slot = 0; + } } } } @@ -2175,8 +2332,9 @@ s3_io_set_alt(s3_t *s3) if (!s3->translate) return; - if ((s3->chip == S3_VISION968 || s3->chip == S3_VISION868) && (svga->seqregs[9] & 0x80)) + if ((s3->chip == S3_VISION968 || s3->chip == S3_VISION868) && (svga->seqregs[9] & 0x80)) { return; + } io_sethandler(0x4148, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0x4548, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); @@ -2233,8 +2391,9 @@ s3_io_set(s3_t *s3) io_sethandler(0x03c0, 0x0020, s3_in, NULL, NULL, s3_out, NULL, NULL, s3); - if ((s3->chip == S3_VISION968 || s3->chip == S3_VISION868) && (svga->seqregs[9] & 0x80)) + if ((s3->chip == S3_VISION968 || s3->chip == S3_VISION868) && (svga->seqregs[9] & 0x80)) { return; + } io_sethandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); @@ -2354,9 +2513,10 @@ s3_out(uint16_t addr, uint8_t val, void *p) else 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 && s3->card_type == S3_ELSAWIN2KPROX)) + } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_ELSAWIN2KPROX || + s3->card_type == S3_PHOENIX_VISION968))) ibm_rgb528_ramdac_out(addr, rs2, val, svga->ramdac, svga); - else if ((s3->chip == S3_VISION968 && (s3->card_type == S3_MIROVIDEO40SV_968 || s3->card_type == S3_SPEA_MERCURY_P64V))) { + else if ((s3->chip == S3_VISION968 && (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968))) { rs3 = !!(svga->crtc[0x55] & 0x02); 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)) @@ -2383,7 +2543,7 @@ s3_out(uint16_t addr, uint8_t val, void *p) return; if ((svga->crtcreg == 0x36) && (svga->crtc[0x39] != 0xa5)) return; - if (s3->chip == S3_TRIO64V2 && svga->crtcreg >= 0x80) + if ((s3->chip == S3_TRIO64V2) && svga->crtcreg >= 0x80) return; old = svga->crtc[svga->crtcreg]; svga->crtc[svga->crtcreg] = val; @@ -2418,6 +2578,19 @@ s3_out(uint16_t addr, uint8_t val, void *p) } s3->bpp = (svga->crtc[0x50] >> 4) & 3; break; + + case 0x5c: + if ((val & 0xa0) == 0x80) + i2c_gpio_set(s3->i2c, !!(val & 0x40), !!(val & 0x10)); + if (s3->card_type == S3_PHOENIX_VISION868 || s3->card_type == S3_PHOENIX_VISION968) { + if ((val & 0x20) && (!(svga->crtc[0x55] & 0x01) && !(svga->crtc[0x43] & 2))) + svga->dac_addr |= 0x20; + } else if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968) { + if ((val & 0x80) && (!(svga->crtc[0x55] & 0x01) && !(svga->crtc[0x43] & 2))) + svga->dac_addr |= 0x02; + } + break; + case 0x69: if (s3->chip >= S3_VISION964) s3->ma_ext = val & 0x1f; @@ -2444,6 +2617,7 @@ s3_out(uint16_t addr, uint8_t val, void *p) else s3->ma_ext = (s3->ma_ext & ~0xc) | ((val & 3) << 2); break; + case 0x6a: if (s3->chip >= S3_VISION964) { s3->bank = val; @@ -2530,11 +2704,6 @@ s3_out(uint16_t addr, uint8_t val, void *p) } break; - case 0x5c: - if ((val & 0xa0) == 0x80) - i2c_gpio_set(s3->i2c, !!(val & 0x40), !!(val & 0x10)); - break; - case 0x42: if ((s3->chip == S3_VISION964) || (s3->chip == S3_VISION968) || (s3->chip == S3_86C928)) { if (((svga->miscout >> 2) & 3) == 3) @@ -2612,8 +2781,14 @@ s3_in(uint16_t addr, void *p) break; case 0x3c5: - if (svga->seqaddr >= 0x10 && svga->seqaddr < 0x20) - return svga->seqregs[svga->seqaddr]; + if (svga->seqaddr >= 0x10 && svga->seqaddr < 0x20) { + temp = svga->seqregs[svga->seqaddr]; + /* This is needed for the Intel Advanced/ATX's built-in S3 Trio64V+ BIOS to not + get stuck in an infinite loop. */ + if ((s3->card_type == S3_PHOENIX_TRIO64VPLUS_ONBOARD) && (svga->seqaddr == 0x17)) + svga->seqregs[svga->seqaddr] ^= 0x01; + return temp; + } break; case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: @@ -2623,9 +2798,10 @@ 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 && s3->card_type == S3_ELSAWIN2KPROX)) + } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_ELSAWIN2KPROX || + s3->card_type == S3_PHOENIX_VISION968))) return ibm_rgb528_ramdac_in(addr, rs2, svga->ramdac, svga); - else if ((s3->chip == S3_VISION968 && (s3->card_type == S3_MIROVIDEO40SV_968 || s3->card_type == S3_SPEA_MERCURY_P64V))) { + else if ((s3->chip == S3_VISION968 && (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968))) { rs3 = !!(svga->crtc[0x55] & 0x02); 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)) @@ -2648,7 +2824,10 @@ s3_in(uint16_t addr, void *p) case 0x31: return (svga->crtc[0x31] & 0xcf) | ((s3->ma_ext & 3) << 4); case 0x35: return (svga->crtc[0x35] & 0xf0) | (s3->bank & 0xf); case 0x45: s3->hwc_col_stack_pos = 0; break; - case 0x51: return (svga->crtc[0x51] & 0xf0) | ((s3->bank >> 2) & 0xc) | ((s3->ma_ext >> 2) & 3); + case 0x51: + if (s3->chip == S3_86C801 || s3->chip == S3_86C805) + return (svga->crtc[0x51] & 0xfa) | ((s3->bank >> 2) & 0x4) | ((s3->ma_ext >> 2) & 1); + return (svga->crtc[0x51] & 0xf0) | ((s3->bank >> 2) & 0xc) | ((s3->ma_ext >> 2) & 3); case 0x5c: /* General Output Port Register */ temp = svga->crtc[svga->crtcreg] & 0xa0; if (((svga->miscout >> 2) & 3) == 3) @@ -2667,7 +2846,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 && s3->card_type != S3_MIROVIDEO40SV_968) { + if (s3->chip != S3_TRIO64V2) { if (svga->crtc[0x53] & 0x08) { return (s3->chip == S3_TRIO64V) ? (svga->crtc[0x59] & 0xfc) : (svga->crtc[0x59] & 0xfe); } else { @@ -2677,10 +2856,10 @@ s3_in(uint16_t addr, void *p) return svga->crtc[0x6b]; break; case 0x6c: - if (s3->chip != S3_TRIO64V2 && s3->card_type != S3_MIROVIDEO40SV_968) { - if (svga->crtc[0x53] & 0x08) + if (s3->chip != S3_TRIO64V2) { + if (svga->crtc[0x53] & 0x08) { return 0x00; - else + } else return (svga->crtc[0x5a] & 0x80); } else return svga->crtc[0x6c]; @@ -2721,7 +2900,7 @@ static void s3_recalctimings(svga_t *svga) else bt48x_recalctimings(svga->ramdac, svga); } else if (s3->chip == S3_VISION968) { - if (s3->card_type == S3_MIROVIDEO40SV_968 || s3->card_type == S3_SPEA_MERCURY_P64V) + if (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968) tvp3026_recalctimings(svga->ramdac, svga); else ibm_rgb528_recalctimings(svga->ramdac, svga); @@ -2741,10 +2920,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)) || (svga->crtc[0x3a] & 0x10)) { - pclog("CRTC14 bit 6 byte mode = %02x, CRTC17 bit 6 byte mode = %02x, CRTC17 bit 5 word mode ma15 = %02x, CRTC31 bit 3 dword mode = %02x\n", - svga->crtc[0x14] & 0x40, svga->crtc[0x17] & 0x40, svga->crtc[0x17] & 0x20, svga->crtc[0x31] & 0x08); - + if (((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) || (svga->crtc[0x3a] & 0x10)) { if (svga->crtc[0x31] & 0x08) /*This would typically force dword mode, but we are encountering accel bugs with it, so force byte mode instead*/ svga->force_byte_mode = 1; else @@ -2766,11 +2942,13 @@ static void s3_recalctimings(svga_t *svga) svga->hdisp *= 2; } - if (s3->card_type == S3_MIROVIDEO40SV_968) { + if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_MIROCRYSTAL20SD_864 || + s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_SPEA_MERCURY_P64V) { if (svga->hdisp != 1408) svga->hdisp = s3->width; } if (s3->card_type == S3_MIROCRYSTAL10SD_805) { + pclog("S3 CRTC51 = %02x, CRTC5D = %02x, CRTC5E = %02x, CRTC35 = %02x\n", svga->crtc[0x51], svga->crtc[0x5d], svga->crtc[0x5e], svga->crtc[0x35]); if (svga->rowoffset == 256 && ((svga->crtc[0x51] & 0x30) == 0x00 && !(svga->crtc[0x43] & 0x04))) svga->rowoffset >>= 1; } @@ -2792,6 +2970,16 @@ static void s3_recalctimings(svga_t *svga) if (s3->width == 1280 || s3->width == 1600) svga->hdisp *= 2; } + if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_PHOENIX_VISION968 || + s3->card_type == S3_SPEA_MERCURY_P64V) { + 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 16: svga->render = svga_render_16bpp_highres; @@ -2811,7 +2999,8 @@ static void s3_recalctimings(svga_t *svga) if (s3->width == 1280 || s3->width == 1600) svga->hdisp *= 2; } - if (s3->card_type == S3_MIROVIDEO40SV_968) { + if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_PHOENIX_VISION968 || + s3->card_type == S3_SPEA_MERCURY_P64V) { if (svga->hdisp == (1408*2)) svga->hdisp /= 2; else @@ -2829,7 +3018,8 @@ static void s3_recalctimings(svga_t *svga) else svga->hdisp = (svga->hdisp * 2) / 3; } else { - if (s3->card_type == S3_MIROVIDEO40SV_968) + if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_PHOENIX_VISION968 || + s3->card_type == S3_SPEA_MERCURY_P64V) svga->hdisp = s3->width; } break; @@ -2844,7 +3034,9 @@ static void s3_recalctimings(svga_t *svga) } if (s3->width == 1280 || s3->width == 1600 || (s3->card_type == S3_SPEA_MERCURY_P64V)) svga->hdisp *= 2; - if (s3->card_type == S3_MIROVIDEO40SV_968 || s3->card_type == S3_MIROCRYSTAL20SV_964) + if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_MIROCRYSTAL20SV_964 || + s3->card_type == S3_MIROCRYSTAL20SD_864 || s3->card_type == S3_PHOENIX_VISION968 || + s3->card_type == S3_SPEA_MERCURY_P64V) svga->hdisp = s3->width; break; } @@ -3067,7 +3259,7 @@ s3_updatemapping(s3_t *s3) mem_mapping_enable(&s3->mmio_mapping); } else mem_mapping_disable(&s3->mmio_mapping); - + /* New MMIO. */ if (svga->crtc[0x53] & 0x08) mem_mapping_set_addr(&s3->new_mmio_mapping, s3->linear_base + 0x1000000, 0x20000); @@ -3104,7 +3296,10 @@ s3_accel_out(uint16_t port, uint8_t val, void *p) if (port >= 0x8000) { if (s3_enable_fifo(s3)) { - s3_queue(s3, port, val, FIFO_OUT_BYTE); + if (s3->chip <= S3_86C805) + s3_accel_out_fifo(s3, port, val); + else + s3_queue(s3, port, val, FIFO_OUT_BYTE); } else { s3_accel_out_fifo(s3, port, val); } @@ -3150,9 +3345,12 @@ s3_accel_out_w(uint16_t port, uint16_t val, void *p) if (!s3->enable_8514) return; - if (s3_enable_fifo(s3)) - s3_queue(s3, port, val, FIFO_OUT_WORD); - else + if (s3_enable_fifo(s3)) { + if (s3->chip <= S3_86C805) + s3_accel_out_fifo_w(s3, port, val); + else + s3_queue(s3, port, val, FIFO_OUT_WORD); + } else s3_accel_out_fifo_w(s3, port, val); } @@ -3164,9 +3362,12 @@ s3_accel_out_l(uint16_t port, uint32_t val, void *p) if (!s3->enable_8514) return; - if (s3_enable_fifo(s3)) - s3_queue(s3, port, val, FIFO_OUT_DWORD); - else + if (s3_enable_fifo(s3)) { + if (s3->chip <= S3_86C805) + s3_accel_out_fifo_l(s3, port, val); + else + s3_queue(s3, port, val, FIFO_OUT_DWORD); + } else s3_accel_out_fifo_l(s3, port, val); } @@ -3188,6 +3389,7 @@ s3_accel_in(uint16_t port, void *p) case 0x8148: case 0x82e8: s3_wait_fifo_idle(s3); + return s3->accel.cur_y & 0xff; case 0x8149: case 0x82e9: s3_wait_fifo_idle(s3); @@ -3249,29 +3451,122 @@ s3_accel_in(uint16_t port, void *p) case 0x8118: case 0x9948: case 0x9ae8: temp = 0; /* FIFO empty */ - if (!s3->blitter_busy) + if (!s3->blitter_busy && s3->chip >= S3_VISION964) wake_fifo_thread(s3); if (FIFO_FULL && (s3->chip >= S3_VISION964)) temp = 0xff; /*FIFO full*/ - return temp; /*FIFO empty*/ + else if (s3->chip <= S3_86C805) { + if (s3_enable_fifo(s3)) { + if (s3->accel.port_slot3) { + if (s3->accel.setup_fifo_slot) { + switch (s3->accel.setup_fifo_slot) { + case 1: + temp = 1; + break; + case 2: + temp = 3; + break; + case 3: + temp = 7; + break; + case 4: + temp = 0x0f; + break; + case 5: + temp = 0x1f; + break; + case 6: + temp = 0x3f; + break; + case 7: + temp = 0x7f; + break; + case 8: + temp = 0xff; + break; + } + } + + s3->accel.setup_fifo_slot2 = s3->accel.setup_fifo_slot; + s3->accel.setup_fifo_slot = 0; + s3->accel.port_slot3 = 0; + } else if (s3->accel.port_slot1) { + if (s3->accel.draw_fifo_slot) { + switch (s3->accel.draw_fifo_slot) { + case 1: + temp = 1; + break; + case 2: + temp = 3; + break; + case 3: + temp = 7; + break; + case 4: + temp = 0x0f; + break; + case 5: + temp = 0x1f; + break; + case 6: + temp = 0x3f; + break; + case 7: + temp = 0x7f; + break; + case 8: + temp = 0xff; + break; + } + } + + s3->accel.draw_fifo_slot2 = s3->accel.draw_fifo_slot; + s3->accel.draw_fifo_slot = 0; + s3->accel.port_slot1 = 0; + } + } + } + return temp; case 0x8119: case 0x9949: case 0x9ae9: - if (!s3->blitter_busy) + if (!s3->blitter_busy && s3->chip >= S3_VISION964) wake_fifo_thread(s3); temp = 0; - if ((s3->chip >= S3_86C928) && s3_enable_fifo(s3)) { - if (!FIFO_EMPTY || s3->force_busy) { - temp |= 0x02; /*Hardware busy*/ + if (s3_enable_fifo(s3)) { + if (s3->chip >= S3_VISION964) { + if (!FIFO_EMPTY || s3->force_busy) { + temp |= 0x02; /*Hardware busy*/ + } else { + temp |= 0x04; /*FIFO empty*/ + } + s3->force_busy = 0; + if (FIFO_FULL) + temp |= 0xf8; /*FIFO full*/ } else { - temp |= 0x04; /*FIFO empty*/ + if (s3->force_busy) { + temp |= 0x02; /*Hardware busy*/ + } else { + if (s3->accel.port_slot2) { + s3->accel.port_slot2 = 0; + if (!s3->accel.draw_fifo_slot2) + temp |= 0x04; /*FIFO empty*/ + if (s3->accel.draw_fifo_slot2) + s3->accel.draw_fifo_slot2 = 0; + } else if (s3->accel.port_slot4) { + s3->accel.port_slot4 = 0; + if (!s3->accel.setup_fifo_slot2) + temp |= 0x04; /*FIFO empty*/ + if (s3->accel.setup_fifo_slot2) + s3->accel.setup_fifo_slot2 = 0; + } + } + + s3->force_busy = 0; + if (s3->data_available) { + temp |= 0x01; /*Read Data available*/ + s3->data_available = 0; + } } - s3->force_busy = 0; - if (s3->data_available && (s3->chip <= S3_86C805)) { - temp |= 0x01; /*Read Data available*/ - s3->data_available = 0; - } - if (FIFO_FULL && s3->chip >= S3_VISION964) - temp |= 0xf8; /*FIFO full*/ } else { if (s3->force_busy) { temp |= 0x02; /*Hardware busy*/ @@ -3508,6 +3803,12 @@ s3_accel_in(uint16_t port, void *p) break; READ_PIXTRANS_BYTE_IO(0) if (s3->accel.cmd & 0x100) { + s3->accel.port_slot1++; + s3->accel.port_slot2++; + if (s3->accel.port_slot1 || s3->accel.port_slot2) + s3->accel.draw_fifo_slot++; + if (s3->accel.draw_fifo_slot > 8) + s3->accel.draw_fifo_slot = 1; switch (s3->accel.cmd & 0x600) { case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { @@ -3602,6 +3903,10 @@ s3_accel_in(uint16_t port, void *p) return temp; } + if (s3_enable_fifo(s3) == 0) { + s3->accel.draw_fifo_slot = 0; + } + return 0xff; } @@ -3619,6 +3924,13 @@ s3_accel_in_w(uint16_t port, void *p) if (s3_cpu_dest(s3)) { READ_PIXTRANS_WORD + s3->accel.port_slot1++; + s3->accel.port_slot2++; + if (s3->accel.port_slot1 || s3->accel.port_slot2) + s3->accel.draw_fifo_slot++; + if (s3->accel.draw_fifo_slot > 8) + s3->accel.draw_fifo_slot = 1; + switch (s3->accel.cmd & 0x600) { case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { @@ -3639,6 +3951,10 @@ s3_accel_in_w(uint16_t port, void *p) s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); break; } + + if (s3_enable_fifo(s3) == 0) { + s3->accel.draw_fifo_slot = 0; + } } return temp; } @@ -3657,6 +3973,13 @@ s3_accel_in_l(uint16_t port, void *p) if (s3_cpu_dest(s3)) { READ_PIXTRANS_LONG + s3->accel.port_slot1++; + s3->accel.port_slot2++; + if (s3->accel.port_slot1 || s3->accel.port_slot2) + s3->accel.draw_fifo_slot++; + if (s3->accel.draw_fifo_slot > 8) + s3->accel.draw_fifo_slot = 1; + switch (s3->accel.cmd & 0x600) { case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { @@ -3687,6 +4010,10 @@ s3_accel_in_l(uint16_t port, void *p) } break; } + + if (s3_enable_fifo(s3) == 0) { + s3->accel.draw_fifo_slot = 0; + } } return temp; @@ -3702,11 +4029,15 @@ s3_accel_write(uint32_t addr, uint8_t val, void *p) if (!s3->enable_8514) return; - if (s3_enable_fifo(s3)) { - if (svga->crtc[0x53] & 0x08) - s3_queue(s3, addr & 0x1ffff, val, FIFO_WRITE_BYTE); - else - s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_BYTE); + if (s3_enable_fifo(s3)) { + if (s3->chip <= S3_86C805) { + s3_accel_write_fifo(s3, addr & 0xffff, val); + } else { + if (svga->crtc[0x53] & 0x08) + s3_queue(s3, addr & 0x1ffff, val, FIFO_WRITE_BYTE); + else + s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_BYTE); + } } else s3_accel_write_fifo(s3, addr & 0xffff, val); } @@ -3721,10 +4052,14 @@ s3_accel_write_w(uint32_t addr, uint16_t val, void *p) return; if (s3_enable_fifo(s3)) { - if (svga->crtc[0x53] & 0x08) - s3_queue(s3, addr & 0x1ffff, val, FIFO_WRITE_WORD); - else - s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_WORD); + if (s3->chip <= S3_86C805) { + s3_accel_write_fifo_w(s3, addr & 0xffff, val); + } else { + if (svga->crtc[0x53] & 0x08) + s3_queue(s3, addr & 0x1ffff, val, FIFO_WRITE_WORD); + else + s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_WORD); + } } else s3_accel_write_fifo_w(s3, addr & 0xffff, val); } @@ -3739,10 +4074,14 @@ s3_accel_write_l(uint32_t addr, uint32_t val, void *p) return; if (s3_enable_fifo(s3)) { - if (svga->crtc[0x53] & 0x08) - s3_queue(s3, addr & 0x1ffff, val, FIFO_WRITE_DWORD); - else - s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_DWORD); + if (s3->chip <= S3_86C805) { + s3_accel_write_fifo_l(s3, addr & 0xffff, val); + } else { + if (svga->crtc[0x53] & 0x08) + s3_queue(s3, addr & 0x1ffff, val, FIFO_WRITE_DWORD); + else + s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_DWORD); + } } else s3_accel_write_fifo_l(s3, addr & 0xffff, val); } @@ -3789,6 +4128,13 @@ s3_accel_read(uint32_t addr, void *p) } else if (s3_cpu_dest(s3)) { READ_PIXTRANS_BYTE_MM + s3->accel.port_slot1++; + s3->accel.port_slot2++; + if (s3->accel.port_slot1 || s3->accel.port_slot2) + s3->accel.draw_fifo_slot++; + if (s3->accel.draw_fifo_slot > 8) + s3->accel.draw_fifo_slot = 1; + switch (s3->accel.cmd & 0x600) { case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { @@ -3809,6 +4155,10 @@ s3_accel_read(uint32_t addr, void *p) s3_accel_start(2, 1, 0xffffffff, temp | (temp << 8) | (temp << 16) | (temp << 24), s3); break; } + + if (s3_enable_fifo(s3) == 0) { + s3->accel.draw_fifo_slot = 0; + } } } @@ -3840,6 +4190,13 @@ s3_accel_read_w(uint32_t addr, void *p) } else if (s3_cpu_dest(s3)) { READ_PIXTRANS_WORD + s3->accel.port_slot1++; + s3->accel.port_slot2++; + if (s3->accel.port_slot1 || s3->accel.port_slot2) + s3->accel.draw_fifo_slot++; + if (s3->accel.draw_fifo_slot > 8) + s3->accel.draw_fifo_slot = 1; + switch (s3->accel.cmd & 0x600) { case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { @@ -3860,6 +4217,10 @@ s3_accel_read_w(uint32_t addr, void *p) s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); break; } + + if (s3_enable_fifo(s3) == 0) { + s3->accel.draw_fifo_slot = 0; + } } } @@ -3998,6 +4359,13 @@ s3_accel_read_l(uint32_t addr, void *p) } else if (s3_cpu_dest(s3)) { READ_PIXTRANS_LONG + s3->accel.port_slot1++; + s3->accel.port_slot2++; + if (s3->accel.port_slot1 || s3->accel.port_slot2) + s3->accel.draw_fifo_slot++; + if (s3->accel.draw_fifo_slot > 8) + s3->accel.draw_fifo_slot = 1; + switch (s3->accel.cmd & 0x600) { case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { @@ -4028,6 +4396,10 @@ s3_accel_read_l(uint32_t addr, void *p) } break; } + + if (s3_enable_fifo(s3) == 0) { + s3->accel.draw_fifo_slot = 0; + } } } @@ -4851,6 +5223,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ /*Bit 4 of the Command register is the draw yes bit, which enables writing to memory/reading from memory when enabled. When this bit is disabled, no writing to memory/reading from memory is allowed. (This bit is almost meaningless on the NOP command)*/ + switch (cmd) { case 0: /*NOP (Short Stroke Vectors)*/ @@ -5176,7 +5549,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.cy |= ~0xfff; } } - + s3->accel.dest = dstbase + s3->accel.cy * s3->width; if (s3_cpu_src(s3)) { @@ -5410,7 +5783,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ } } } - + s3->accel.src = srcbase + s3->accel.cy * s3->width; s3->accel.dest = dstbase + s3->accel.dy * s3->width; } @@ -5422,6 +5795,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; + if (!cpu_input && frgd_mix == 3 && !vram_mask && !compare_mode && (s3->accel.cmd & 0xa0) == 0xa0 && (s3->accel.frgd_mix & 0xf) == 7 && (s3->accel.bkgd_mix & 0xf) == 7) @@ -5449,7 +5823,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - + s3->accel.cy++; s3->accel.dy++; @@ -5505,6 +5879,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ mix_dat <<= 1; mix_dat |= 1; + if (s3->bpp == 0) cpu_dat >>= 8; else cpu_dat >>= 16; @@ -5530,7 +5905,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ { s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; s3->accel.dx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; - } + } s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; @@ -5550,11 +5925,13 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.sy--; - if (cpu_input) + if (cpu_input) { return; + } - if (s3->accel.sy < 0) + if (s3->accel.sy < 0) { return; + } } } } @@ -5575,7 +5952,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if (s3->accel.cur_x_bit12) s3->accel.cx |= ~0xfff; s3->accel.cy = s3->accel.cur_y & 0xfff; if (s3->accel.cur_y_bit12) s3->accel.cy |= ~0xfff; - + /*Align source with destination*/ s3->accel.pattern = (s3->accel.cy * s3->width) + s3->accel.cx; s3->accel.dest = dstbase + s3->accel.dy * s3->width; @@ -5675,9 +6052,12 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.sy--; - if (cpu_input/* && (s3->accel.multifunc[0xa] & 0xc0) == 0x80*/) return; - if (s3->accel.sy < 0) + if (cpu_input) { return; + } + if (s3->accel.sy < 0) { + return; + } } } break; @@ -6097,7 +6477,7 @@ s3_pci_write(int func, int addr, uint8_t val, void *p) { s3_t *s3 = (s3_t *)p; svga_t *svga = &s3->svga; - + switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: @@ -6176,7 +6556,7 @@ static int vram_sizes[] = 0, 0, /*4 MB*/ 0, - 0, + 0, /*6 MB*/ 0, 3 /*8 MB*/ }; @@ -6239,6 +6619,11 @@ static void *s3_init(const device_t *info) else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c801); break; + case S3_MIROCRYSTAL20SD_864: + bios_fn = ROM_MIROCRYSTAL20SD_864_VLB; + chip = S3_VISION864; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision864_vlb); + break; case S3_PARADISE_BAHAMAS64: bios_fn = ROM_PARADISE_BAHAMAS64; chip = S3_VISION864; @@ -6275,14 +6660,19 @@ static void *s3_init(const device_t *info) chip = S3_VISION964; if (info->flags & DEVICE_PCI) { bios_fn = ROM_MIROCRYSTAL20SV_964_PCI; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision864_pci); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision964_pci); } else { bios_fn = ROM_MIROCRYSTAL20SV_964_VLB; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision864_vlb); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision964_vlb); } break; - case S3_MIROVIDEO40SV_968: - bios_fn = ROM_MIROVIDEO40SV_968; + case S3_MIROVIDEO40SV_ERGO_968: + bios_fn = ROM_MIROVIDEO40SV_ERGO_968_PCI; + chip = S3_VISION968; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_pci); + break; + case S3_PHOENIX_VISION968: + bios_fn = ROM_PHOENIX_VISION968; chip = S3_VISION968; if (info->flags & DEVICE_PCI) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_pci); @@ -6385,7 +6775,7 @@ static void *s3_init(const device_t *info) memset(s3, 0, sizeof(s3_t)); - if (info->local == S3_MIROCRYSTAL10SD_805 || info->local == S3_SPEA_MIRAGE_86C801 || + if (info->local == S3_SPEA_MIRAGE_86C801 || info->local == S3_SPEA_MIRAGE_86C805) vram = 1; else @@ -6455,9 +6845,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 && info->local == S3_ELSAWIN2KPROX)) + else if ((chip == S3_VISION964 && info->local == S3_ELSAWIN2KPROX_964) || (chip == S3_VISION968 && (info->local == S3_ELSAWIN2KPROX || + info->local == S3_PHOENIX_VISION968))) svga->dac_hwcursor_draw = ibm_rgb528_hwcursor_draw; - else if (chip == S3_VISION968 && (info->local == S3_MIROVIDEO40SV_968 || info->local == S3_SPEA_MERCURY_P64V)) + else if (chip == S3_VISION968 && (info->local == S3_SPEA_MERCURY_P64V || info->local == S3_MIROVIDEO40SV_ERGO_968)) svga->dac_hwcursor_draw = tvp3026_hwcursor_draw; if (chip >= S3_VISION964) { @@ -6568,7 +6959,7 @@ static void *s3_init(const device_t *info) case S3_SPEA_MIRAGE_86C801: case S3_SPEA_MIRAGE_86C805: - svga->decode_mask = (2 << 20) - 1; + svga->decode_mask = (1 << 20) - 1; stepping = 0xa0; /*86C801/86C805*/ s3->id = stepping; s3->id_ext = stepping; @@ -6612,6 +7003,7 @@ static void *s3_init(const device_t *info) case S3_PARADISE_BAHAMAS64: case S3_PHOENIX_VISION864: + case S3_MIROCRYSTAL20SD_864: svga->decode_mask = (8 << 20) - 1; if (info->local == S3_PARADISE_BAHAMAS64) stepping = 0xc0; /*Vision864*/ @@ -6644,11 +7036,11 @@ static void *s3_init(const device_t *info) svga->clock_gen = device_add(&icd2061_device); svga->getclock = icd2061_getclock; break; - case S3_ELSAWIN2KPROX: - case S3_MIROVIDEO40SV_968: case S3_SPEA_MERCURY_P64V: + case S3_MIROVIDEO40SV_ERGO_968: + case S3_PHOENIX_VISION968: svga->decode_mask = (8 << 20) - 1; s3->id = 0xe1; /*Vision968*/ s3->id_ext = s3->id_ext_pci = 0xf0; @@ -6664,8 +7056,8 @@ static void *s3_init(const device_t *info) svga->crtc[0x59] = 0x00; svga->crtc[0x5a] = 0x0a; } - - if (info->local == S3_ELSAWIN2KPROX) + + if (info->local == S3_ELSAWIN2KPROX || info->local == S3_PHOENIX_VISION968) svga->ramdac = device_add(&ibm_rgb528_ramdac_device); else svga->ramdac = device_add(&tvp3026_ramdac_device); @@ -6675,7 +7067,7 @@ static void *s3_init(const device_t *info) break; case S3_PHOENIX_VISION868: - svga->decode_mask = (8 << 20) - 1; + svga->decode_mask = (4 << 20) - 1; s3->id = 0xe1; /*Vision868*/ s3->id_ext = 0x90; s3->id_ext_pci = 0x80; @@ -6843,9 +7235,19 @@ static int s3_diamond_stealth64_964_available(void) return rom_present(ROM_DIAMOND_STEALTH64_964); } -static int s3_mirovideo_40sv_968_available(void) +static int s3_mirovideo_40sv_ergo_968_pci_available(void) { - return rom_present(ROM_MIROVIDEO40SV_968); + return rom_present(ROM_MIROVIDEO40SV_ERGO_968_PCI); +} + +static int s3_phoenix_vision968_available(void) +{ + return rom_present(ROM_PHOENIX_VISION968); +} + +static int s3_mirocrystal_20sd_864_vlb_available(void) +{ + return rom_present(ROM_MIROCRYSTAL20SD_864_VLB); } static int s3_spea_mercury_p64v_pci_available(void) @@ -7126,7 +7528,7 @@ const device_t s3_spea_mirage_86c805_vlb_device = const device_t s3_mirocrystal_10sd_805_vlb_device = { - "S3 86c805 VLB (MiroCrystal 10SD)", + "S3 86c805 VLB (MiroCRYSTAL 10SD)", DEVICE_VLB, S3_MIROCRYSTAL10SD_805, s3_init, @@ -7135,7 +7537,7 @@ const device_t s3_mirocrystal_10sd_805_vlb_device = { s3_mirocrystal_10sd_805_available }, s3_speed_changed, s3_force_redraw, - NULL + s3_9fx_config }; const device_t s3_phoenix_86c801_isa_device = @@ -7194,6 +7596,20 @@ const device_t s3_metheus_86c928_vlb_device = s3_standard_config }; +const device_t s3_mirocrystal_20sd_864_vlb_device = +{ + "S3 Vision864 VLB (MiroCRYSTAL 20SD)", + DEVICE_VLB, + S3_MIROCRYSTAL20SD_864, + s3_init, + s3_close, + NULL, + { s3_mirocrystal_20sd_864_vlb_available }, + s3_speed_changed, + s3_force_redraw, + s3_9fx_config +}; + const device_t s3_bahamas64_vlb_device = { "S3 Vision864 VLB (Paradise Bahamas 64)", @@ -7279,29 +7695,43 @@ const device_t s3_diamond_stealth64_964_pci_device = s3_standard_config }; -const device_t s3_mirovideo_40sv_968_vlb_device = +const device_t s3_phoenix_vision968_pci_device = { - "S3 Vision968 VLB (MiroVIDEO 40SV)", - DEVICE_VLB, - S3_MIROVIDEO40SV_968, + "S3 Vision968 PCI (Phoenix)", + DEVICE_PCI, + S3_PHOENIX_VISION968, s3_init, s3_close, NULL, - { s3_mirovideo_40sv_968_available }, + { s3_phoenix_vision968_available }, s3_speed_changed, s3_force_redraw, s3_standard_config }; -const device_t s3_mirovideo_40sv_968_pci_device = +const device_t s3_phoenix_vision968_vlb_device = { - "S3 Vision968 PCI (MiroVIDEO 40SV)", - DEVICE_PCI, - S3_MIROVIDEO40SV_968, + "S3 Vision968 VLB (Phoenix)", + DEVICE_VLB, + S3_PHOENIX_VISION968, s3_init, s3_close, NULL, - { s3_mirovideo_40sv_968_available }, + { s3_phoenix_vision968_available }, + s3_speed_changed, + s3_force_redraw, + s3_standard_config +}; + +const device_t s3_mirovideo_40sv_ergo_968_pci_device = +{ + "S3 Vision968 PCI (MiroVIDEO 40SV Ergo)", + DEVICE_PCI, + S3_MIROVIDEO40SV_ERGO_968, + s3_init, + s3_close, + NULL, + { s3_mirovideo_40sv_ergo_968_pci_available }, s3_speed_changed, s3_force_redraw, s3_standard_config diff --git a/src/video/vid_table.c b/src/video/vid_table.c index a26727e25..a34e77b48 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -145,7 +145,8 @@ video_cards[] = { { "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 }, + { "mirovideo40sv_pci", &s3_mirovideo_40sv_ergo_968_pci_device }, + { "px_vision968_pci", &s3_phoenix_vision968_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 }, @@ -189,6 +190,7 @@ video_cards[] = { { "px_s3_v7_805_vlb", &s3_spea_mirage_86c805_vlb_device }, { "stealth64v_vlb", &s3_diamond_stealth64_964_vlb_device }, { "mirocrystal20sv_vlb", &s3_mirocrystal_20sv_964_vlb_device }, + { "mirocrystal20sd_vlb", &s3_mirocrystal_20sd_864_vlb_device }, { "bahamas64_vlb", &s3_bahamas64_vlb_device }, { "px_vision864_vlb", &s3_phoenix_vision864_vlb_device }, { "stealthse_vlb", &s3_diamond_stealth_se_vlb_device }, @@ -197,6 +199,7 @@ video_cards[] = { { "n9_9fx_vlb", &s3_9fx_vlb_device }, { "px_trio64_vlb", &s3_phoenix_trio64_vlb_device }, { "spea_miragep64_vlb", &s3_spea_mirage_p64_vlb_device }, + { "px_vision968_vlb", &s3_phoenix_vision968_vlb_device }, { "px_vision868_vlb", &s3_phoenix_vision868_vlb_device }, { "ht216_32", &ht216_32_standalone_device }, { "virge325_vlb", &s3_virge_325_vlb_device },