From 024083fd998cc51fa54f2befe9528f23ace8077e Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 2 Sep 2021 23:20:57 +0200 Subject: [PATCH 01/13] 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 02/13] 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 03/13] 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 04/13] 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 05/13] 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 06/13] 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 07/13] 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 08/13] 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 09/13] 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. */ } } } From bd1117a13fa4ce19ddae916b839a633f787555ec Mon Sep 17 00:00:00 2001 From: Daniel Gurney Date: Fri, 3 Sep 2021 19:58:08 +0300 Subject: [PATCH 10/13] Add missing include for arm64 macOS --- src/cpu/386_dynarec.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index d396d122a..29d1382fa 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -31,6 +31,9 @@ #endif #include "386_common.h" +#if defined(__APPLE__) && defined(__aarch64__) +#include +#endif #define CPU_BLOCK_END() cpu_block_end = 1 From 136c136608596538c17001be10d85501fc036dd1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 Sep 2021 19:23:50 +0200 Subject: [PATCH 11/13] Ported some more Apple-related fixes from PCem. --- src/86box.c | 18 ++++++++++++++++++ src/cpu/386_dynarec.c | 3 +++ 2 files changed, 21 insertions(+) diff --git a/src/86box.c b/src/86box.c index 82c847eaa..b8715d991 100644 --- a/src/86box.c +++ b/src/86box.c @@ -26,6 +26,13 @@ #include #include #include +#ifdef __APPLE__ +#include +#include +#ifdef __aarch64__ +#include +#endif +#endif #define HAVE_STDARG_H #include <86box/86box.h> @@ -780,7 +787,13 @@ pc_init_modules(void) mem_init(); #ifdef USE_DYNAREC +#if defined(__APPLE__) && defined(__aarch64__) + pthread_jit_write_protect_np(0); +#endif codegen_init(); +#if defined(__APPLE__) && defined(__aarch64__) + pthread_jit_write_protect_np(1); +#endif #endif keyboard_init(); @@ -1104,7 +1117,12 @@ pc_run(void) if (title_update) { swprintf(temp, sizeof_w(temp), mouse_msg[!!mouse_capture], fps); +#ifdef __APPLE__ + /* Needed due to modifying the UI on the non-main thread is a big no-no. */ + dispatch_async_f(dispatch_get_main_queue(), strdup(temp), _ui_window_title); +#else ui_window_title(temp); +#endif title_update = 0; } } diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index d396d122a..cf2f87e05 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -3,6 +3,9 @@ #include #include #include +#if defined(__APPLE__) && defined(__aarch64__) +#include +#endif #include #include #ifndef INFINITY From b1c985c14c131cc8083fe2b8345dd1a59d773dab Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 Sep 2021 19:35:25 +0200 Subject: [PATCH 12/13] Fixed the shim. --- src/86box.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/86box.c b/src/86box.c index b8715d991..7c9d919d0 100644 --- a/src/86box.c +++ b/src/86box.c @@ -1089,6 +1089,15 @@ pc_close(thread_t *ptr) } +#ifdef __APPLE__ +static void _ui_window_title(void *s) +{ + ui_window_title((const char *) s); + free(s); +} +#endif + + void pc_run(void) { @@ -1119,7 +1128,7 @@ pc_run(void) swprintf(temp, sizeof_w(temp), mouse_msg[!!mouse_capture], fps); #ifdef __APPLE__ /* Needed due to modifying the UI on the non-main thread is a big no-no. */ - dispatch_async_f(dispatch_get_main_queue(), strdup(temp), _ui_window_title); + dispatch_async_f(dispatch_get_main_queue(), strdup((const char *) temp), _ui_window_title); #else ui_window_title(temp); #endif From 4b2402db2e50e54e28d3037bdf4664b2be9b23b2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 Sep 2021 19:45:28 +0200 Subject: [PATCH 13/13] And fixed it again. --- src/86box.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/86box.c b/src/86box.c index 7c9d919d0..eca8544a5 100644 --- a/src/86box.c +++ b/src/86box.c @@ -1092,7 +1092,7 @@ pc_close(thread_t *ptr) #ifdef __APPLE__ static void _ui_window_title(void *s) { - ui_window_title((const char *) s); + ui_window_title((const wchar_t *) s); free(s); } #endif @@ -1128,7 +1128,7 @@ pc_run(void) swprintf(temp, sizeof_w(temp), mouse_msg[!!mouse_capture], fps); #ifdef __APPLE__ /* Needed due to modifying the UI on the non-main thread is a big no-no. */ - dispatch_async_f(dispatch_get_main_queue(), strdup((const char *) temp), _ui_window_title); + dispatch_async_f(dispatch_get_main_queue(), wcsdup((const wchar_t *) temp), _ui_window_title); #else ui_window_title(temp); #endif