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 },