diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 9a9f7a553..ad1f34d96 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -334,6 +334,7 @@ extern const device_t s3_metheus_86c928_isa_device; extern const device_t s3_metheus_86c928_vlb_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_8s_805_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; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 3f4987bab..a1e52e02e 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -43,6 +43,7 @@ #define ROM_METHEUS_86C928 "roms/video/s3/928.vbi" #define ROM_SPEA_MIRAGE_86C801 "roms/video/s3/V7MIRAGE.VBI" #define ROM_SPEA_MIRAGE_86C805 "roms/video/s3/86c805pspeavlbus.BIN" +#define ROM_MIROCRYSTAL8S_805 "roms/video/s3/S3_805VL_ATT20C491_miroCRYSTAL_8s_ver1.4.BIN" #define ROM_MIROCRYSTAL10SD_805 "roms/video/s3/MIROcrystal10SD_VLB.VBI" #define ROM_MIROCRYSTAL20SV_964_VLB "roms/video/s3/S3_964VL_BT485_27C256_miroCRYSTAL_20sv_ver1.2.bin" #define ROM_MIROCRYSTAL20SV_964_PCI "roms/video/s3/mirocrystal.VBI" @@ -98,7 +99,8 @@ enum S3_SPEA_MERCURY_P64V, S3_MIROCRYSTAL20SV_964, S3_MIROCRYSTAL20SD_864, - S3_PHOENIX_VISION968 + S3_PHOENIX_VISION968, + S3_MIROCRYSTAL8S_805 }; @@ -255,15 +257,15 @@ 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; + int ssv_len; + uint8_t ssv_dir; + uint8_t ssv_draw; - /*S3 928 and 80x cards only*/ - int setup_fifo_slot, setup_fifo_slot2; - int draw_fifo_slot, draw_fifo_slot2; - int port_slot1, port_slot2; - int port_slot3, port_slot4; + /*For non-threaded FIFO*/ + int setup_fifo_slot; + int draw_fifo_slot; + int setup_fifo, setup_fifo2; + int draw_fifo, draw_fifo2; } accel; struct { @@ -384,21 +386,6 @@ 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); -static __inline void -wake_fifo_thread(s3_t *s3) -{ - thread_set_event(s3->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ -} - -static void -s3_wait_fifo_idle(s3_t *s3) -{ - while (!FIFO_EMPTY) { - wake_fifo_thread(s3); - thread_wait_event(s3->fifo_not_full_event, 1); - } -} - static void s3_update_irqs(s3_t *s3) { @@ -413,6 +400,7 @@ s3_update_irqs(s3_t *s3) } void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3); +void s3_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3, uint8_t ssv); static void s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3); #define WRITE8(addr, var, val) switch ((addr) & 3) \ @@ -491,21 +479,14 @@ 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*/ } static void s3_accel_out_pixtrans_w(s3_t *s3, uint16_t val) { svga_t *svga = &s3->svga; - + if (s3->accel.cmd & 0x100) { - s3->accel.port_slot1++; - s3->accel.port_slot2++; - if (s3->accel.port_slot1 || s3->accel.port_slot2) - s3->accel.draw_fifo_slot++; - if (s3->accel.draw_fifo_slot > 8) - s3->accel.draw_fifo_slot = 1; switch (s3->accel.cmd & 0x600) { case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { @@ -565,10 +546,6 @@ s3_accel_out_pixtrans_w(s3_t *s3, uint16_t val) } break; } - - if ((s3_enable_fifo(s3) && s3->chip >= S3_VISION964) || (s3_enable_fifo(s3) == 0)) { - s3->accel.draw_fifo_slot = 0; - } } } @@ -576,12 +553,6 @@ static void s3_accel_out_pixtrans_l(s3_t *s3, uint32_t val) { if (s3->accel.cmd & 0x100) { - s3->accel.port_slot1++; - s3->accel.port_slot2++; - if (s3->accel.port_slot1 || s3->accel.port_slot2) - s3->accel.draw_fifo_slot++; - if (s3->accel.draw_fifo_slot > 8) - s3->accel.draw_fifo_slot = 1; switch (s3->accel.cmd & 0x600) { case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { @@ -641,10 +612,6 @@ s3_accel_out_pixtrans_l(s3_t *s3, uint32_t val) } break; } - - if ((s3_enable_fifo(s3) && s3->chip >= S3_VISION964) || (s3_enable_fifo(s3) == 0)) { - s3->accel.draw_fifo_slot = 0; - } } } @@ -655,12 +622,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) switch (port) { case 0x8148: case 0x82e8: - s3->accel.port_slot1++; - s3->accel.port_slot2++; - if (s3->accel.port_slot1 || s3->accel.port_slot2) - s3->accel.draw_fifo_slot++; - if (s3->accel.draw_fifo_slot > 8) - s3->accel.draw_fifo_slot = 1; + s3->accel.draw_fifo_slot++; s3->accel.cur_y_bitres = (s3->accel.cur_y_bitres & 0xff00) | val; s3->accel.cur_y = (s3->accel.cur_y & 0xf00) | val; s3->accel.poly_cy = s3->accel.cur_y; @@ -672,6 +634,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.poly_cy = s3->accel.cur_y; break; case 0x814a: case 0x82ea: + s3->accel.draw_fifo_slot++; s3->accel.cur_y2 = (s3->accel.cur_y2 & 0xf00) | val; s3->accel.poly_cy2 = s3->accel.cur_y2; break; @@ -681,12 +644,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0x8548: case 0x86e8: - s3->accel.port_slot1++; - s3->accel.port_slot2++; - if (s3->accel.port_slot1 || s3->accel.port_slot2) - s3->accel.draw_fifo_slot++; - if (s3->accel.draw_fifo_slot > 8) - s3->accel.draw_fifo_slot = 1; + s3->accel.draw_fifo_slot++; s3->accel.cur_x_bitres = (s3->accel.cur_x_bitres & 0xff00) | val; s3->accel.cur_x = (s3->accel.cur_x & 0xf00) | val; s3->accel.poly_cx = s3->accel.cur_x << 20; @@ -700,6 +658,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.poly_x = s3->accel.poly_cx >> 20; break; case 0x854a: case 0x86ea: + s3->accel.draw_fifo_slot++; s3->accel.cur_x2 = (s3->accel.cur_x2 & 0xf00) | val; s3->accel.poly_cx2 = s3->accel.cur_x2 << 20; break; @@ -709,12 +668,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0x8948: case 0x8ae8: - s3->accel.port_slot1++; - s3->accel.port_slot2++; - if (s3->accel.port_slot1 || s3->accel.port_slot2) - s3->accel.draw_fifo_slot++; - if (s3->accel.draw_fifo_slot > 8) - s3->accel.draw_fifo_slot = 1; + s3->accel.draw_fifo_slot++; s3->accel.desty_axstp = (s3->accel.desty_axstp & 0x3f00) | val; s3->accel.point_1_updated = 1; break; @@ -725,6 +679,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.point_1_updated = 1; break; case 0x894a: case 0x8aea: + s3->accel.draw_fifo_slot++; s3->accel.desty_axstp2 = (s3->accel.desty_axstp2 & 0x3f00) | val; s3->accel.point_2_updated = 1; break; @@ -736,12 +691,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0x8d48: case 0x8ee8: - s3->accel.port_slot1++; - s3->accel.port_slot2++; - if (s3->accel.port_slot1 || s3->accel.port_slot2) - s3->accel.draw_fifo_slot++; - if (s3->accel.draw_fifo_slot > 8) - s3->accel.draw_fifo_slot = 1; + s3->accel.draw_fifo_slot++; s3->accel.destx_distp = (s3->accel.destx_distp & 0x3f00) | val; s3->accel.point_1_updated = 1; break; @@ -752,6 +702,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.point_1_updated = 1; break; case 0x8d4a: case 0x8eea: + s3->accel.draw_fifo_slot++; s3->accel.x2 = (s3->accel.x2 & 0xf00) | val; s3->accel.point_2_updated = 1; break; @@ -761,12 +712,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0x9148: case 0x92e8: - s3->accel.port_slot1++; - s3->accel.port_slot2++; - if (s3->accel.port_slot1 || s3->accel.port_slot2) - s3->accel.draw_fifo_slot++; - if (s3->accel.draw_fifo_slot > 8) - s3->accel.draw_fifo_slot = 1; + s3->accel.draw_fifo_slot++; s3->accel.err_term = (s3->accel.err_term & 0x3f00) | val; break; case 0x9149: case 0x92e9: @@ -784,12 +730,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0x9548: case 0x96e8: - s3->accel.port_slot1++; - s3->accel.port_slot2++; - if (s3->accel.port_slot1 || s3->accel.port_slot2) - s3->accel.draw_fifo_slot++; - if (s3->accel.draw_fifo_slot > 8) - s3->accel.draw_fifo_slot = 1; + s3->accel.draw_fifo_slot++; s3->accel.maj_axis_pcnt = (s3->accel.maj_axis_pcnt & 0xf00) | val; break; case 0x9459: case 0x96e9: @@ -807,12 +748,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0x9948: case 0x9ae8: - s3->accel.port_slot1++; - s3->accel.port_slot2++; - if (s3->accel.port_slot1 || s3->accel.port_slot2) - s3->accel.draw_fifo_slot++; - if (s3->accel.draw_fifo_slot > 8) - s3->accel.draw_fifo_slot = 1; + s3->accel.draw_fifo_slot++; s3->accel.cmd = (s3->accel.cmd & 0xff00) | val; s3->data_available = 0; s3->accel.b2e8_pix = 0; @@ -835,19 +771,25 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.short_stroke = (s3->accel.short_stroke & 0xff00) | val; break; case 0x9d49: case 0x9ee9: - s3->accel.short_stroke = (s3->accel.short_stroke & 0xff) | (val << 8); + 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*/ + + 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_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff); + s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8); + } else { + s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8); + s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff); + } break; case 0xa148: case 0xa2e8: - s3->accel.port_slot3++; - s3->accel.port_slot4++; - if (s3->accel.port_slot3 || s3->accel.port_slot4) - s3->accel.setup_fifo_slot++; - if (s3->accel.setup_fifo_slot > 8) - s3->accel.setup_fifo_slot = 1; + s3->accel.setup_fifo_slot++; if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); else @@ -884,12 +826,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xa548: case 0xa6e8: - s3->accel.port_slot3++; - s3->accel.port_slot4++; - if (s3->accel.port_slot3 || s3->accel.port_slot4) - s3->accel.setup_fifo_slot++; - if (s3->accel.setup_fifo_slot > 8) - s3->accel.setup_fifo_slot = 1; + s3->accel.setup_fifo_slot++; if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); else @@ -926,12 +863,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xa948: case 0xaae8: - s3->accel.port_slot3++; - s3->accel.port_slot4++; - if (s3->accel.port_slot3 || s3->accel.port_slot4) - s3->accel.setup_fifo_slot++; - if (s3->accel.setup_fifo_slot > 8) - s3->accel.setup_fifo_slot = 1; + s3->accel.setup_fifo_slot++; if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); else @@ -968,12 +900,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xad48: case 0xaee8: - s3->accel.port_slot3++; - s3->accel.port_slot4++; - if (s3->accel.port_slot3 || s3->accel.port_slot4) - s3->accel.setup_fifo_slot++; - if (s3->accel.setup_fifo_slot > 8) - s3->accel.setup_fifo_slot = 1; + s3->accel.setup_fifo_slot++; if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); else @@ -1010,12 +937,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xb148: case 0xb2e8: - s3->accel.port_slot1++; - s3->accel.port_slot2++; - if (s3->accel.port_slot1 || s3->accel.port_slot2) - s3->accel.draw_fifo_slot++; - if (s3->accel.draw_fifo_slot > 8) - s3->accel.draw_fifo_slot = 1; if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); else @@ -1052,22 +973,12 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xb548: case 0xb6e8: - s3->accel.port_slot3++; - s3->accel.port_slot4++; - if (s3->accel.port_slot3 || s3->accel.port_slot4) - s3->accel.setup_fifo_slot++; - if (s3->accel.setup_fifo_slot > 8) - s3->accel.setup_fifo_slot = 1; + s3->accel.setup_fifo_slot++; s3->accel.bkgd_mix = val; break; case 0xb948: case 0xbae8: - s3->accel.port_slot3++; - s3->accel.port_slot4++; - if (s3->accel.port_slot3 || s3->accel.port_slot4) - s3->accel.setup_fifo_slot++; - if (s3->accel.setup_fifo_slot > 8) - s3->accel.setup_fifo_slot = 1; + s3->accel.setup_fifo_slot++; s3->accel.frgd_mix = val; break; @@ -1079,31 +990,23 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.multifunc[s3->accel.multifunc_cntl >> 12] = s3->accel.multifunc_cntl & 0xfff; switch (s3->accel.multifunc_cntl >> 12) { case 0: - s3->accel.port_slot1++; - s3->accel.port_slot2++; - if (s3->accel.port_slot1 || s3->accel.port_slot2) - s3->accel.draw_fifo_slot++; - if (s3->accel.draw_fifo_slot > 8) - s3->accel.draw_fifo_slot = 1; + s3->accel.draw_fifo_slot++; break; case 0xa: - s3->accel.port_slot3++; - s3->accel.port_slot4++; - if (s3->accel.port_slot3 || s3->accel.port_slot4) - s3->accel.setup_fifo_slot++; - if (s3->accel.setup_fifo_slot > 8) - s3->accel.setup_fifo_slot = 1; + s3->accel.setup_fifo_slot++; break; } break; case 0xd148: case 0xd2e8: + s3->accel.setup_fifo_slot++; s3->accel.ropmix = (s3->accel.ropmix & 0xff00) | val; break; case 0xd149: case 0xd2e9: s3->accel.ropmix = (s3->accel.ropmix & 0x00ff) | (val << 8); break; case 0xe548: case 0xe6e8: + s3->accel.setup_fifo_slot++; if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); else @@ -1139,18 +1042,21 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) } break; case 0xe948: case 0xeae8: + s3->accel.draw_fifo_slot++; s3->accel.pat_y = (s3->accel.pat_y & 0xf00) | val; break; case 0xe949: case 0xeae9: s3->accel.pat_y = (s3->accel.pat_y & 0xff) | ((val & 0x1f) << 8); break; case 0xe94a: case 0xeaea: + s3->accel.draw_fifo_slot++; s3->accel.pat_x = (s3->accel.pat_x & 0xf00) | val; break; case 0xe94b: case 0xeaeb: s3->accel.pat_x = (s3->accel.pat_x & 0xff) | ((val & 0x1f) << 8); break; case 0xed48: case 0xeee8: + s3->accel.setup_fifo_slot++; if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); else @@ -1192,12 +1098,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; s3->accel.pix_trans[0] = val; if (s3->accel.cmd & 0x100) { - s3->accel.port_slot1++; - s3->accel.port_slot2++; - if (s3->accel.port_slot1 || s3->accel.port_slot2) - s3->accel.draw_fifo_slot++; - if (s3->accel.draw_fifo_slot > 8) - s3->accel.draw_fifo_slot = 1; if (!(s3->accel.cmd & 0x600)) { if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) @@ -1257,7 +1157,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) } break; case 0x600: - if (s3->chip == S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip >= S3_TRIO64V) { + if (s3->chip == S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868 || s3->chip >= S3_TRIO64V) { if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { s3_accel_start(8, 1, s3->accel.pix_trans[1], 0, s3); @@ -1319,7 +1219,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3_accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); break; case 0x600: - if (s3->chip == S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip >= S3_TRIO64V) { + if (s3->chip == S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868 || s3->chip >= S3_TRIO64V) { if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { s3_accel_start(8, 1, s3->accel.pix_trans[3], 0, s3); @@ -1335,29 +1235,45 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; } - if ((s3_enable_fifo(s3) && s3->chip >= S3_VISION964) || (s3_enable_fifo(s3) == 0)) { - if (s3->accel.port_slot1 || s3->accel.port_slot2) { - s3->accel.draw_fifo_slot = 0; - } else if (s3->accel.port_slot3 || s3->accel.port_slot4) - s3->accel.setup_fifo_slot = 0; + if (s3_enable_fifo(s3) == 0) { + s3->accel.setup_fifo_slot = 0; + s3->accel.draw_fifo_slot = 0; } } static void s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val) { - if (port == 0xb2e8) { - s3->accel.b2e8_pix = 1; + if (port != 0x9ee8 && port != 0x9d48) { + if (port == 0xb2e8) { + s3->accel.b2e8_pix = 1; + } else { + s3->accel.b2e8_pix = 0; + } + s3_accel_out_pixtrans_w(s3, val); } else { - s3->accel.b2e8_pix = 0; + s3->accel.short_stroke = val; + s3->accel.ssv_state = 1; + + 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_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff); + s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8); + } else { + s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8); + s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff); + } } - s3_accel_out_pixtrans_w(s3, val); } static void s3_accel_out_fifo_l(s3_t *s3, uint16_t port, uint32_t val) -{ +{ s3_accel_out_pixtrans_l(s3, val); } @@ -1391,9 +1307,9 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) case 0x8118: addr = 0x9ae8; break; /*ALT_CMD*/ case 0x811a: addr = 0x9aea; break; - - case 0x811c: addr = 0x9ee8; break; /*SHORT_STROKE*/ - + + case 0x811c: addr = 0x9ee8; break; + case 0x8120: case 0x8122: /*BKGD_COLOR*/ WRITE8(addr, s3->accel.bkgd_color, val); return; @@ -1521,13 +1437,6 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) s3_accel_out_fifo(s3, addr & 0xffff, val); } else { if (s3->accel.cmd & 0x100) { - s3->accel.port_slot1++; - s3->accel.port_slot2++; - if (s3->accel.port_slot1 || s3->accel.port_slot2) - s3->accel.draw_fifo_slot++; - if (s3->accel.draw_fifo_slot > 8) - s3->accel.draw_fifo_slot = 1; - if ((s3->accel.cmd & 0x600) == 0x200) { if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) @@ -1545,9 +1454,6 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) } else s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); } - if ((s3_enable_fifo(s3) && s3->chip >= S3_VISION964) || (s3_enable_fifo(s3) == 0)) { - s3->accel.draw_fifo_slot = 0; - } } } } @@ -1571,12 +1477,19 @@ s3_accel_write_fifo_w(s3_t *s3, uint32_t addr, uint16_t val) case 0xff20: s3_accel_write_fifo(s3, addr, val); break; + case 0x811c: + s3_accel_out_fifo_w(s3, 0x9ee8, val); + break; } } } else { if (addr & 0x8000) { - s3_accel_write_fifo(s3, addr, val); - s3_accel_write_fifo(s3, addr + 1, val >> 8); + if (addr == 0x811c) + s3_accel_out_fifo_w(s3, 0x9ee8, val); + else { + s3_accel_write_fifo(s3, addr, val); + s3_accel_write_fifo(s3, addr + 1, val >> 8); + } } else { s3_accel_out_pixtrans_w(s3, val); } @@ -1791,59 +1704,6 @@ s3_accel_write_fifo_l(s3_t *s3, uint32_t addr, uint32_t val) } } -static void -fifo_thread(void *param) -{ - s3_t *s3 = (s3_t *)param; - - while (s3->thread_run) - { - thread_set_event(s3->fifo_not_full_event); - thread_wait_event(s3->wake_fifo_thread, -1); - thread_reset_event(s3->wake_fifo_thread); - s3->blitter_busy = 1; - while (!FIFO_EMPTY) - { - uint64_t start_time = plat_timer_read(); - uint64_t end_time; - fifo_entry_t *fifo = &s3->fifo[s3->fifo_read_idx & FIFO_MASK]; - - switch (fifo->addr_type & FIFO_TYPE) - { - case FIFO_WRITE_BYTE: - s3_accel_write_fifo(s3, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_WRITE_WORD: - s3_accel_write_fifo_w(s3, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_WRITE_DWORD: - s3_accel_write_fifo_l(s3, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_OUT_BYTE: - s3_accel_out_fifo(s3, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_OUT_WORD: - s3_accel_out_fifo_w(s3, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_OUT_DWORD: - s3_accel_out_fifo_l(s3, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - } - - s3->fifo_read_idx++; - fifo->addr_type = FIFO_INVALID; - - if (FIFO_ENTRIES > 0xe000) - thread_set_event(s3->fifo_not_full_event); - - end_time = plat_timer_read(); - s3->blitter_time += end_time - start_time; - } - s3->blitter_busy = 0; - s3->subsys_stat |= INT_FIFO_EMP; - s3_update_irqs(s3); - } -} static void s3_vblank_start(svga_t *svga) @@ -1854,29 +1714,6 @@ s3_vblank_start(svga_t *svga) s3_update_irqs(s3); } -static void -s3_queue(s3_t *s3, uint32_t addr, uint32_t val, uint32_t type) -{ - fifo_entry_t *fifo = &s3->fifo[s3->fifo_write_idx & FIFO_MASK]; - - if (FIFO_FULL) - { - thread_reset_event(s3->fifo_not_full_event); - if (FIFO_FULL) - { - thread_wait_event(s3->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ - } - } - - fifo->val = val; - fifo->addr_type = (addr & FIFO_ADDR) | type; - - s3->fifo_write_idx++; - - if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) - wake_fifo_thread(s3); -} - static uint32_t s3_hwcursor_convert_addr(svga_t *svga) @@ -1893,6 +1730,7 @@ s3_hwcursor_convert_addr(svga_t *svga) } + static void s3_hwcursor_draw(svga_t *svga, int displine) { @@ -1911,9 +1749,11 @@ s3_hwcursor_draw(svga_t *svga, int displine) 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; + if (s3->card_type != S3_MIROCRYSTAL10SD_805 && s3->card_type != S3_MIROCRYSTAL8S_805) { + if (!(svga->crtc[0x45] & 0x04)) { + shift = 2; + width = 8; + } } } break; @@ -1922,9 +1762,15 @@ s3_hwcursor_draw(svga_t *svga, int displine) 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; + if (s3->card_type != S3_MIROCRYSTAL10SD_805 && s3->card_type != S3_MIROCRYSTAL8S_805) { + if (!(svga->crtc[0x45] & 0x04)) { + shift = 2; + width = 8; + } + } else if (s3->card_type == S3_MIROCRYSTAL10SD_805) { + if (!(svga->crtc[0x45] & 0x04)) { + offset <<= 1; + } } } break; @@ -1960,8 +1806,9 @@ s3_hwcursor_draw(svga_t *svga, int displine) for (x = 0; x < 64; x += 16) { - dat[0] = (svga->vram[real_addr & svga->vram_display_mask] << 8) | svga->vram[(real_addr + 1) & svga->vram_display_mask]; - dat[1] = (svga->vram[(real_addr + 2) & svga->vram_display_mask] << 8) | svga->vram[(real_addr + 3) & svga->vram_display_mask]; + dat[0] = (svga->vram[real_addr & s3->vram_mask] << 8) | svga->vram[(real_addr + 1) & s3->vram_mask]; + dat[1] = (svga->vram[(real_addr + 2) & s3->vram_mask] << 8) | svga->vram[(real_addr + 3) & s3->vram_mask]; + if (svga->crtc[0x55] & 0x10) { /*X11*/ for (xx = 0; xx < 16; xx++) { @@ -1976,17 +1823,17 @@ s3_hwcursor_draw(svga_t *svga, int displine) } } else { /*Windows*/ - for (xx = 0; xx < width; xx++) { - if (offset >= svga->hwcursor_latch.x) { + 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; else if (dat[1] & 0x8000) buffer32->line[displine][offset + svga->x_add] ^= 0xffffff; - } - - offset++; - dat[0] <<= shift; - dat[1] <<= shift; + } + + offset++; + dat[0] <<= shift; + dat[1] <<= shift; } } svga->hwcursor_latch.addr += 4; @@ -2290,7 +2137,7 @@ s3_io_remove_alt(s3_t *s3) io_removehandler(0x9148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0x9548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0x9948, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x9d48, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x9d48, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); io_removehandler(0xa148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0xa548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0xa948, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); @@ -2324,7 +2171,7 @@ s3_io_remove(s3_t *s3) io_removehandler(0x92e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0x96e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x9ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x9ee8, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); io_removehandler(0xa2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0xa6e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0xaae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); @@ -2382,7 +2229,7 @@ s3_io_set_alt(s3_t *s3) io_sethandler(0x9948, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); else io_sethandler(0x9948, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x9d48, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x9d48, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); io_sethandler(0xa148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0xa548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0xa948, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); @@ -2441,7 +2288,7 @@ s3_io_set(s3_t *s3) io_sethandler(0x9ae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); else io_sethandler(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x9ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x9ee8, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); io_sethandler(0xa2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0xa6e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0xaae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); @@ -2476,7 +2323,7 @@ s3_out(uint16_t addr, uint8_t val, void *p) addr ^= 0x60; switch (addr) - { + { case 0x3c2: if ((s3->chip == S3_VISION964) || (s3->chip == S3_VISION968) || (s3->chip == S3_86C928)) { if (((val >> 2) & 3) != 3) @@ -2540,7 +2387,7 @@ s3_out(uint16_t addr, uint8_t val, void *p) else if ((s3->chip == S3_VISION968 && (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968))) { rs3 = !!(svga->crtc[0x55] & 0x02); tvp3026_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); - } else if (((s3->chip == S3_86C801) || (s3->chip == S3_86C805)) && (s3->card_type != S3_MIROCRYSTAL10SD_805)) + } else if (((s3->chip == S3_86C801) || (s3->chip == S3_86C805)) && (s3->card_type != S3_MIROCRYSTAL10SD_805 && s3->card_type != S3_MIROCRYSTAL8S_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); @@ -2568,20 +2415,21 @@ s3_out(uint16_t addr, uint8_t val, void *p) return; old = svga->crtc[svga->crtcreg]; svga->crtc[svga->crtcreg] = val; + switch (svga->crtcreg) { case 0x31: s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4); break; case 0x32: - if (svga->crtc[0x31] & 0x30) - svga->vram_display_mask = (val & 0x40) ? 0x3ffff : s3->vram_mask; + if ((svga->crtc[0x31] & 0x30) && (svga->crtc[0x51] & 0x01) && (val & 0x40)) + svga->vram_display_mask = 0x3ffff; else svga->vram_display_mask = s3->vram_mask; break; case 0x40: - s3->enable_8514 = !!(svga->crtc[0x40] & 1); + s3->enable_8514 = (val & 0x01); break; case 0x50: @@ -2616,7 +2464,7 @@ s3_out(uint16_t addr, uint8_t val, void *p) if (s3->chip >= S3_VISION964) s3->ma_ext = val & 0x1f; break; - + case 0x35: s3->bank = (s3->bank & 0x70) | (val & 0xf); if (svga->chain4) @@ -2625,18 +2473,17 @@ s3_out(uint16_t addr, uint8_t val, void *p) svga->write_bank = svga->read_bank = s3->bank << 14; break; case 0x51: - if (s3->chip == S3_86C801 || s3->chip == S3_86C805) + if (s3->chip == S3_86C801 || s3->chip == S3_86C805) { s3->bank = (s3->bank & 0x6f) | ((val & 0x4) << 2); - else + s3->ma_ext = (s3->ma_ext & ~0x4) | ((val & 1) << 2); + } else { s3->bank = (s3->bank & 0x4f) | ((val & 0xc) << 2); + s3->ma_ext = (s3->ma_ext & ~0xc) | ((val & 3) << 2); + } if (svga->chain4) svga->write_bank = svga->read_bank = s3->bank << 16; else svga->write_bank = svga->read_bank = s3->bank << 14; - if (s3->chip == S3_86C801 || s3->chip == S3_86C805) - s3->ma_ext = (s3->ma_ext & ~0x4) | ((val & 1) << 2); - else - s3->ma_ext = (s3->ma_ext & ~0xc) | ((val & 3) << 2); break; case 0x6a: @@ -2648,12 +2495,7 @@ s3_out(uint16_t addr, uint8_t val, void *p) svga->write_bank = svga->read_bank = s3->bank << 14; } break; - - case 0x3a: - if (val & 0x10) - svga->gdcreg[5] |= 0x40; /*Horrible cheat*/ - break; - + case 0x45: if (s3->chip == S3_VISION964 || s3->chip == S3_VISION968) break; @@ -2664,16 +2506,19 @@ s3_out(uint16_t addr, uint8_t val, void *p) if (s3->chip == S3_VISION964 || s3->chip == S3_VISION968) break; svga->hwcursor.x = ((svga->crtc[0x46] << 8) | svga->crtc[0x47]) & 0x7ff; - if (svga->bpp == 32) svga->hwcursor.x >>= 1; + if (svga->bpp == 32 && s3->chip != S3_VISION868) svga->hwcursor.x >>= 1; svga->hwcursor.y = ((svga->crtc[0x48] << 8) | svga->crtc[0x49]) & 0x7ff; - svga->hwcursor.xoff = svga->crtc[0x4e] & 63; - svga->hwcursor.yoff = svga->crtc[0x4f] & 63; + svga->hwcursor.xoff = svga->crtc[0x4e] & 0x3f; + svga->hwcursor.yoff = svga->crtc[0x4f] & 0x3f; svga->hwcursor.addr = ((((svga->crtc[0x4c] << 8) | svga->crtc[0x4d]) & 0xfff) * 1024) + (svga->hwcursor.yoff * 16); - if ((s3->chip >= S3_TRIO32) && svga->bpp == 32) + if ((s3->chip >= S3_TRIO32) && (s3->chip != S3_VISION868) && svga->bpp == 32) 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)) + else if ((s3->chip >= S3_86C928 && s3->chip <= S3_86C805) && (svga->bpp == 15 || svga->bpp == 16)) { + if ((s3->card_type == S3_MIROCRYSTAL10SD_805) && !(svga->crtc[0x45] & 0x04) && svga->bpp == 16) + svga->hwcursor.x >>= 2; + else + svga->hwcursor.x >>= 1; + } else if ((s3->chip >= S3_86C928 && s3->chip <= S3_86C805) && (svga->bpp == 24)) svga->hwcursor.x /= 3; break; @@ -2735,7 +2580,7 @@ s3_out(uint16_t addr, uint8_t val, void *p) case 0x43: if (s3->chip < S3_VISION964) { s3_io_remove_alt(s3); - s3->translate = !!(svga->crtc[0x43] & 0x10); + s3->translate = !!(val & 0x10); s3_io_set_alt(s3); } break; @@ -2825,7 +2670,7 @@ s3_in(uint16_t addr, void *p) else if ((s3->chip == S3_VISION968 && (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968))) { rs3 = !!(svga->crtc[0x55] & 0x02); return tvp3026_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); - } else if (((s3->chip == S3_86C801) || (s3->chip == S3_86C805)) && (s3->card_type != S3_MIROCRYSTAL10SD_805)) + } else if (((s3->chip == S3_86C801) || (s3->chip == S3_86C805)) && (s3->card_type != S3_MIROCRYSTAL10SD_805 && s3->card_type != S3_MIROCRYSTAL8S_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); @@ -2845,10 +2690,7 @@ s3_in(uint16_t addr, void *p) case 0x31: return (svga->crtc[0x31] & 0xcf) | ((s3->ma_ext & 3) << 4); case 0x35: return (svga->crtc[0x35] & 0xf0) | (s3->bank & 0xf); case 0x45: s3->hwc_col_stack_pos = 0; break; - case 0x51: - if (s3->chip == S3_86C801 || s3->chip == S3_86C805) - return (svga->crtc[0x51] & 0xfa) | ((s3->bank >> 2) & 0x4) | ((s3->ma_ext >> 2) & 1); - return (svga->crtc[0x51] & 0xf0) | ((s3->bank >> 2) & 0xc) | ((s3->ma_ext >> 2) & 3); + case 0x51: return (svga->crtc[0x51] & 0xf0) | ((s3->bank >> 2) & 0xc) | ((s3->ma_ext >> 2) & 3); case 0x5c: /* General Output Port Register */ temp = svga->crtc[svga->crtcreg] & 0xa0; if (((svga->miscout >> 2) & 3) == 3) @@ -2897,6 +2739,14 @@ static void s3_recalctimings(svga_t *svga) int clk_sel = (svga->miscout >> 2) & 3; svga->hdisp = svga->hdisp_old; + + if (!svga->scrblank && svga->attr_palette_enable) { + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + if (svga->crtc[0x3a] & 0x10) /*256+ color register*/ + svga->gdcreg[5] |= 0x40; + } + } + svga->ma_latch |= (s3->ma_ext << 16); if (s3->chip >= S3_86C928) { @@ -2941,12 +2791,31 @@ static void s3_recalctimings(svga_t *svga) svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)); - if (((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) || (svga->crtc[0x3a] & 0x10)) { - if (svga->crtc[0x31] & 0x08) /*This would typically force dword mode, but we are encountering accel bugs with it, so force byte mode instead*/ - svga->force_byte_mode = 1; - else + if (s3->card_type == S3_MIROCRYSTAL10SD_805 || s3->card_type == S3_MIROCRYSTAL20SD_864 || + s3->card_type == S3_MIROCRYSTAL20SV_964 || s3->card_type == S3_SPEA_MIRAGE_86C801 || + s3->card_type == S3_SPEA_MIRAGE_86C805 || s3->card_type == S3_MIROCRYSTAL8S_805) { + if (svga->bpp != 32) { + if (svga->crtc[0x31] & 2) /*This is needed if the pixel width gets set with delays*/ + s3->width = 2048; + } + } else if (s3->chip == S3_86C928) { + if (svga->bpp == 15) { + if (s3->width == 800) + s3->width = 1024; + } + } + + if (s3->chip != S3_TRIO64 && s3->chip != S3_TRIO32) { + if (svga->crtc[0x31] & 0x08) {/*This would typically force dword mode, but we are encountering accel bugs with it, so force byte mode instead*/ + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) + svga->force_byte_mode = 0; + else + svga->force_byte_mode = 1; + } else svga->force_byte_mode = 0; + } + if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { switch (svga->bpp) { case 8: svga->render = svga_render_8bpp_highres; @@ -2967,10 +2836,40 @@ static void s3_recalctimings(svga_t *svga) s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_SPEA_MERCURY_P64V) { if (svga->hdisp != 1408) svga->hdisp = s3->width; + if (s3->card_type == S3_MIROCRYSTAL20SD_864) { + if (s3->width == 2048) { + switch (svga->dispend) { + case 400: + case 480: + svga->hdisp = 640; + break; + + case 576: + svga->hdisp = 768; + break; + + case 600: + svga->hdisp = 800; + break; + + case 768: + svga->hdisp = 1024; + break; + + case 864: + svga->hdisp = 1152; + break; + + case 1024: + if (svga->vtotal == 1066) + svga->hdisp = 1280; + break; + } + } + } } - if (s3->card_type == S3_MIROCRYSTAL10SD_805) { - pclog("S3 CRTC51 = %02x, CRTC5D = %02x, CRTC5E = %02x, CRTC35 = %02x\n", svga->crtc[0x51], svga->crtc[0x5d], svga->crtc[0x5e], svga->crtc[0x35]); - if (svga->rowoffset == 256 && ((svga->crtc[0x51] & 0x30) == 0x00 && !(svga->crtc[0x43] & 0x04))) + if (s3->card_type == S3_MIROCRYSTAL10SD_805 || s3->card_type == S3_MIROCRYSTAL8S_805) { + if (svga->rowoffset == 256 && (((svga->crtc[0x51] & 0x30) == 0x00 && !(svga->crtc[0x43] & 0x04)))) svga->rowoffset >>= 1; } } @@ -3057,8 +2956,27 @@ static void s3_recalctimings(svga_t *svga) svga->hdisp *= 2; if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_MIROCRYSTAL20SV_964 || s3->card_type == S3_MIROCRYSTAL20SD_864 || s3->card_type == S3_PHOENIX_VISION968 || - s3->card_type == S3_SPEA_MERCURY_P64V) + s3->card_type == S3_SPEA_MERCURY_P64V) { svga->hdisp = s3->width; + if (s3->card_type == S3_MIROCRYSTAL20SD_864 || s3->card_type == S3_MIROCRYSTAL20SV_964) { + if ((svga->crtc[0x31] & 2) && (svga->crtc[0x50] & 0xc1) != 0x00) { + switch (svga->dispend) { + case 400: + case 480: + svga->hdisp = 640; + break; + + case 576: + svga->hdisp = 768; + break; + + case 600: + svga->hdisp = 800; + break; + } + } + } + } break; } } else { @@ -3096,6 +3014,13 @@ static void s3_trio64v_recalctimings(svga_t *svga) s3_t *s3 = (s3_t *)svga->p; int clk_sel = (svga->miscout >> 2) & 3; + if (!svga->scrblank && svga->attr_palette_enable) { + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + if (svga->crtc[0x3a] & 0x10) /*256+ color register*/ + svga->gdcreg[5] |= 0x40; + } + } + svga->hdisp = svga->hdisp_old; if (svga->crtc[0x5d] & 0x01) svga->htotal |= 0x100; @@ -3333,19 +3258,12 @@ s3_accel_out(uint16_t port, uint8_t val, void *p) s3_t *s3 = (s3_t *)p; svga_t *svga = &s3->svga; - if (!s3->enable_8514) - return; - if (port >= 0x8000) { - if (s3_enable_fifo(s3)) { - if (s3->chip <= S3_86C805) - s3_accel_out_fifo(s3, port, val); - else - s3_queue(s3, port, val, FIFO_OUT_BYTE); - } else { - s3_accel_out_fifo(s3, port, val); - } + if (!s3->enable_8514) + return; + + s3_accel_out_fifo(s3, port, val); } else { @@ -3386,15 +3304,9 @@ s3_accel_out_w(uint16_t port, uint16_t val, void *p) s3_t *s3 = (s3_t *)p; if (!s3->enable_8514) - return; + return; - if (s3_enable_fifo(s3)) { - if (s3->chip <= S3_86C805) - s3_accel_out_fifo_w(s3, port, val); - else - s3_queue(s3, port, val, FIFO_OUT_WORD); - } else - s3_accel_out_fifo_w(s3, port, val); + s3_accel_out_fifo_w(s3, port, val); } static void @@ -3403,15 +3315,9 @@ s3_accel_out_l(uint16_t port, uint32_t val, void *p) s3_t *s3 = (s3_t *)p; if (!s3->enable_8514) - return; + return; - if (s3_enable_fifo(s3)) { - if (s3->chip <= S3_86C805) - s3_accel_out_fifo_l(s3, port, val); - else - s3_queue(s3, port, val, FIFO_OUT_DWORD); - } else - s3_accel_out_fifo_l(s3, port, val); + s3_accel_out_fifo_l(s3, port, val); } static uint8_t @@ -3431,62 +3337,49 @@ s3_accel_in(uint16_t port, void *p) return s3->subsys_cntl; case 0x8148: case 0x82e8: - s3_wait_fifo_idle(s3); - return s3->accel.cur_y & 0xff; case 0x8149: case 0x82e9: - s3_wait_fifo_idle(s3); - return s3->accel.cur_y >> 8; + return s3->accel.cur_y >> 8; case 0x8548: case 0x86e8: - s3_wait_fifo_idle(s3); return s3->accel.cur_x & 0xff; case 0x8549: case 0x86e9: - s3_wait_fifo_idle(s3); - return s3->accel.cur_x >> 8; + return s3->accel.cur_x >> 8; case 0x8948: case 0x8ae8: if (s3->chip >= S3_86C928) { - s3_wait_fifo_idle(s3); return s3->accel.desty_axstp & 0xff; } break; case 0x8949: case 0x8ae9: if (s3->chip >= S3_86C928) { - s3_wait_fifo_idle(s3); return s3->accel.desty_axstp >> 8; } break; case 0x8d48: case 0x8ee8: if (s3->chip >= S3_86C928) { - s3_wait_fifo_idle(s3); return s3->accel.destx_distp & 0xff; } break; case 0x8d49: case 0x8ee9: if (s3->chip >= S3_86C928) { - s3_wait_fifo_idle(s3); return s3->accel.destx_distp >> 8; } break; case 0x9148: case 0x92e8: - s3_wait_fifo_idle(s3); return s3->accel.err_term & 0xff; case 0x9149: case 0x92e9: - s3_wait_fifo_idle(s3); return s3->accel.err_term >> 8; case 0x9548: case 0x96e8: if (s3->chip >= S3_86C928) { - s3_wait_fifo_idle(s3); return s3->accel.maj_axis_pcnt & 0xff; } break; case 0x9549: case 0x96e9: if (s3->chip >= S3_86C928) { - s3_wait_fifo_idle(s3); return s3->accel.maj_axis_pcnt >> 8; } break; @@ -3494,128 +3387,55 @@ s3_accel_in(uint16_t port, void *p) case 0x8118: case 0x9948: case 0x9ae8: temp = 0; /* FIFO empty */ - if (!s3->blitter_busy && s3->chip >= S3_VISION964) - wake_fifo_thread(s3); - if (FIFO_FULL && (s3->chip >= S3_VISION964)) - temp = 0xff; /*FIFO full*/ - else if (s3->chip <= S3_86C805) { - if (s3_enable_fifo(s3)) { - if (s3->accel.port_slot3) { - if (s3->accel.setup_fifo_slot) { - switch (s3->accel.setup_fifo_slot) { - case 1: - temp = 1; - break; - case 2: - temp = 3; - break; - case 3: - temp = 7; - break; - case 4: - temp = 0x0f; - break; - case 5: - temp = 0x1f; - break; - case 6: - temp = 0x3f; - break; - case 7: - temp = 0x7f; - break; - case 8: - temp = 0xff; - break; - } - } - - s3->accel.setup_fifo_slot2 = s3->accel.setup_fifo_slot; - s3->accel.setup_fifo_slot = 0; - s3->accel.port_slot3 = 0; - } else if (s3->accel.port_slot1) { - if (s3->accel.draw_fifo_slot) { - switch (s3->accel.draw_fifo_slot) { - case 1: - temp = 1; - break; - case 2: - temp = 3; - break; - case 3: - temp = 7; - break; - case 4: - temp = 0x0f; - break; - case 5: - temp = 0x1f; - break; - case 6: - temp = 0x3f; - break; - case 7: - temp = 0x7f; - break; - case 8: - temp = 0xff; - break; - } - } - - s3->accel.draw_fifo_slot2 = s3->accel.draw_fifo_slot; - s3->accel.draw_fifo_slot = 0; - s3->accel.port_slot1 = 0; - } + if (s3_enable_fifo(s3)) { + if (s3->accel.setup_fifo_slot) { + temp = s3->accel.setup_fifo; + s3->accel.setup_fifo = 0; + } else if (s3->accel.draw_fifo_slot) { + temp = s3->accel.draw_fifo; + s3->accel.draw_fifo = 0; } } return temp; case 0x8119: case 0x9949: case 0x9ae9: - if (!s3->blitter_busy && s3->chip >= S3_VISION964) - wake_fifo_thread(s3); temp = 0; if (s3_enable_fifo(s3)) { - if (s3->chip >= S3_VISION964) { - if (!FIFO_EMPTY || s3->force_busy) { - temp |= 0x02; /*Hardware busy*/ - } else { - temp |= 0x04; /*FIFO empty*/ - } - s3->force_busy = 0; - if (FIFO_FULL) - temp |= 0xf8; /*FIFO full*/ + if ((s3->accel.setup_fifo_slot && s3->accel.draw_fifo_slot) || s3->force_busy) { + temp |= 0x02; /*Hardware busy*/ } else { - if (s3->force_busy) { - temp |= 0x02; /*Hardware busy*/ - } else { - if (s3->accel.port_slot2) { - s3->accel.port_slot2 = 0; - if (!s3->accel.draw_fifo_slot2) - temp |= 0x04; /*FIFO empty*/ - if (s3->accel.draw_fifo_slot2) - s3->accel.draw_fifo_slot2 = 0; - } else if (s3->accel.port_slot4) { - s3->accel.port_slot4 = 0; - if (!s3->accel.setup_fifo_slot2) - temp |= 0x04; /*FIFO empty*/ - if (s3->accel.setup_fifo_slot2) - s3->accel.setup_fifo_slot2 = 0; - } - } + temp |= 0x04; /*FIFO empty*/ + s3->subsys_stat |= INT_FIFO_EMP; + s3_update_irqs(s3); + } - s3->force_busy = 0; - if (s3->data_available) { - temp |= 0x01; /*Read Data available*/ - s3->data_available = 0; + s3->force_busy = 0; + + if (s3->chip >= S3_VISION964) { + if (s3->accel.setup_fifo_slot > 8) { + temp |= s3->accel.setup_fifo2; + s3->accel.setup_fifo2 = 0; + } else if (s3->accel.draw_fifo_slot > 8) { + temp |= s3->accel.draw_fifo2; + s3->accel.draw_fifo2 = 0; } } + + if (s3->accel.setup_fifo_slot) + s3->accel.setup_fifo_slot--; + if (s3->accel.draw_fifo_slot) + s3->accel.draw_fifo_slot--; + + if (s3->data_available) { + temp |= 0x01; /*Read Data available*/ + s3->data_available = 0; + } } else { if (s3->force_busy) { temp |= 0x02; /*Hardware busy*/ } s3->force_busy = 0; - if (s3->data_available && (s3->chip <= S3_86C805)) { + if (s3->data_available) { temp |= 0x01; /*Read Data available*/ s3->data_available = 0; } @@ -3624,126 +3444,101 @@ s3_accel_in(uint16_t port, void *p) case 0x9d48: case 0x9ee8: if (s3->chip >= S3_86C928) { - s3_wait_fifo_idle(s3); return s3->accel.short_stroke & 0xff; } break; case 0x9d49: case 0x9ee9: if (s3->chip >= S3_86C928) { - s3_wait_fifo_idle(s3); return s3->accel.short_stroke >> 8; } break; case 0xa148: case 0xa2e8: if (s3->chip >= S3_86C928) { - s3_wait_fifo_idle(s3); return s3->accel.bkgd_color & 0xff; } break; case 0xa149: case 0xa2e9: if (s3->chip >= S3_86C928) { - s3_wait_fifo_idle(s3); return s3->accel.bkgd_color >> 8; } break; case 0xa14a: case 0xa2ea: - s3_wait_fifo_idle(s3); return s3->accel.bkgd_color >> 16; case 0xa14b: case 0xa2eb: - s3_wait_fifo_idle(s3); return s3->accel.bkgd_color >> 24; case 0xa548: case 0xa6e8: if (s3->chip >= S3_86C928) { - s3_wait_fifo_idle(s3); return s3->accel.frgd_color & 0xff; } break; case 0xa549: case 0xa6e9: if (s3->chip >= S3_86C928) { - s3_wait_fifo_idle(s3); return s3->accel.frgd_color >> 8; } break; case 0xa54a: case 0xa6ea: - s3_wait_fifo_idle(s3); return s3->accel.frgd_color >> 16; case 0xa54b: case 0xa6eb: - s3_wait_fifo_idle(s3); return s3->accel.frgd_color >> 24; case 0xa948: case 0xaae8: - if (s3->chip >= S3_86C928) { - s3_wait_fifo_idle(s3); + if (s3->chip >= S3_86C928) { return s3->accel.wrt_mask & 0xff; } break; case 0xa949: case 0xaae9: if (s3->chip >= S3_86C928) { - s3_wait_fifo_idle(s3); return s3->accel.wrt_mask >> 8; } break; case 0xa94a: case 0xaaea: - s3_wait_fifo_idle(s3); return s3->accel.wrt_mask >> 16; case 0xa94b: case 0xaaeb: - s3_wait_fifo_idle(s3); return s3->accel.wrt_mask >> 24; case 0xad48: case 0xaee8: if (s3->chip >= S3_86C928) { - s3_wait_fifo_idle(s3); return s3->accel.rd_mask & 0xff; } break; case 0xad49: case 0xaee9: - s3_wait_fifo_idle(s3); return s3->accel.rd_mask >> 8; case 0xad4a: case 0xaeea: - s3_wait_fifo_idle(s3); return s3->accel.rd_mask >> 16; case 0xad4b: case 0xaeeb: - s3_wait_fifo_idle(s3); return s3->accel.rd_mask >> 24; case 0xb148: case 0xb2e8: if (s3->chip >= S3_86C928) { - s3_wait_fifo_idle(s3); return s3->accel.color_cmp & 0xff; } break; case 0xb149: case 0xb2e9: if (s3->chip >= S3_86C928) { - s3_wait_fifo_idle(s3); return s3->accel.color_cmp >> 8; } break; case 0xb14a: case 0xb2ea: - s3_wait_fifo_idle(s3); return s3->accel.color_cmp >> 16; case 0xb14b: case 0xb2eb: - s3_wait_fifo_idle(s3); return s3->accel.color_cmp >> 24; case 0xb548: case 0xb6e8: if (s3->chip >= S3_86C928) { - s3_wait_fifo_idle(s3); return s3->accel.bkgd_mix; } break; case 0xb948: case 0xbae8: if (s3->chip >= S3_86C928) { - s3_wait_fifo_idle(s3); return s3->accel.frgd_mix; } break; case 0xbd48: case 0xbee8: if (s3->chip >= S3_86C928) { - s3_wait_fifo_idle(s3); temp = s3->accel.multifunc[0xf] & 0xf; switch (temp) { @@ -3764,7 +3559,6 @@ s3_accel_in(uint16_t port, void *p) break; case 0xbd49: case 0xbee9: if (s3->chip >= S3_86C928) { - s3_wait_fifo_idle(s3); temp = s3->accel.multifunc[0xf] & 0xf; s3->accel.multifunc[0xf]++; switch (temp) @@ -3786,59 +3580,45 @@ s3_accel_in(uint16_t port, void *p) break; case 0xd148: case 0xd2e8: - s3_wait_fifo_idle(s3); return s3->accel.ropmix & 0xff; case 0xd149: case 0xd2e9: - s3_wait_fifo_idle(s3); return s3->accel.ropmix >> 8; case 0xe548: case 0xe6e8: - s3_wait_fifo_idle(s3); return s3->accel.pat_bg_color & 0xff; case 0xe549: case 0xe6e9: - s3_wait_fifo_idle(s3); return s3->accel.pat_bg_color >> 8; case 0xe54a: case 0xe6ea: - s3_wait_fifo_idle(s3); return s3->accel.pat_bg_color >> 16; case 0xe54b: case 0xe6eb: - s3_wait_fifo_idle(s3); return s3->accel.pat_bg_color >> 24; case 0xe948: case 0xeae8: - s3_wait_fifo_idle(s3); return s3->accel.pat_y & 0xff; case 0xe949: case 0xeae9: - s3_wait_fifo_idle(s3); return s3->accel.pat_y >> 8; case 0xe94a: case 0xeaea: - s3_wait_fifo_idle(s3); return s3->accel.pat_x & 0xff; case 0xe94b: case 0xeaeb: - s3_wait_fifo_idle(s3); return s3->accel.pat_x >> 8; case 0xed48: case 0xeee8: - s3_wait_fifo_idle(s3); return s3->accel.pat_fg_color & 0xff; case 0xed49: case 0xeee9: - s3_wait_fifo_idle(s3); return s3->accel.pat_fg_color >> 8; case 0xed4a: case 0xeeea: - s3_wait_fifo_idle(s3); return s3->accel.pat_fg_color >> 16; case 0xed4b: case 0xeeeb: - s3_wait_fifo_idle(s3); return s3->accel.pat_fg_color >> 24; case 0xe148: case 0xe2e8: @@ -3846,21 +3626,15 @@ s3_accel_in(uint16_t port, void *p) break; READ_PIXTRANS_BYTE_IO(0) if (s3->accel.cmd & 0x100) { - s3->accel.port_slot1++; - s3->accel.port_slot2++; - if (s3->accel.port_slot1 || s3->accel.port_slot2) - s3->accel.draw_fifo_slot++; - if (s3->accel.draw_fifo_slot > 8) - s3->accel.draw_fifo_slot = 1; switch (s3->accel.cmd & 0x600) { case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((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 - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); } else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); break; case 0x200: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { @@ -3892,12 +3666,23 @@ s3_accel_in(uint16_t port, void *p) break; case 0x200: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + if (s3->accel.cmd & 0x1000) + s3_accel_start(16, 1, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), 0, s3); + else + s3_accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); + } else { + if (s3->accel.cmd & 0x1000) + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); + else + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + } + } else { + if (s3->accel.cmd & 0x1000) + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); else s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); - } else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + } break; } } @@ -3946,10 +3731,6 @@ s3_accel_in(uint16_t port, void *p) return temp; } - if (s3_enable_fifo(s3) == 0) { - s3->accel.draw_fifo_slot = 0; - } - return 0xff; } @@ -3963,42 +3744,40 @@ s3_accel_in_w(uint16_t port, void *p) if (!s3->enable_8514) return 0xffff; + + if (port != 0x9ee8 && port != 0x9d48) { + if (s3_cpu_dest(s3)) { + READ_PIXTRANS_WORD - if (s3_cpu_dest(s3)) { - READ_PIXTRANS_WORD - - s3->accel.port_slot1++; - s3->accel.port_slot2++; - if (s3->accel.port_slot1 || s3->accel.port_slot2) - s3->accel.draw_fifo_slot++; - if (s3->accel.draw_fifo_slot > 8) - s3->accel.draw_fifo_slot = 1; - - switch (s3->accel.cmd & 0x600) { - case 0x000: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, temp | (temp << 16), 0, s3); - else + switch (s3->accel.cmd & 0x600) { + case 0x000: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + if (s3->accel.cmd & 0x1000) + temp = (temp >> 8) | (temp << 8); + s3_accel_start(8, 1, temp | (temp << 16), 0, s3); + } else + s3_accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); + } else s3_accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); - } else - s3_accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); - break; - case 0x200: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(16, 1, temp | (temp << 16), 0, s3); - else + break; + case 0x200: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + if (s3->accel.cmd & 0x1000) + temp = (temp >> 8) | (temp << 8); + s3_accel_start(16, 1, temp | (temp << 16), 0, s3); + } else + s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); + } else s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); - } else - s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); - break; - } - - if (s3_enable_fifo(s3) == 0) { - s3->accel.draw_fifo_slot = 0; + break; + } } + } else { + temp = s3->accel.short_stroke; } + return temp; } @@ -4016,17 +3795,12 @@ s3_accel_in_l(uint16_t port, void *p) if (s3_cpu_dest(s3)) { READ_PIXTRANS_LONG - s3->accel.port_slot1++; - s3->accel.port_slot2++; - if (s3->accel.port_slot1 || s3->accel.port_slot2) - s3->accel.draw_fifo_slot++; - if (s3->accel.draw_fifo_slot > 8) - s3->accel.draw_fifo_slot = 1; - switch (s3->accel.cmd & 0x600) { case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + if (s3->accel.cmd & 0x1000) + temp = ((temp & 0xff00ff00) >> 8) | ((temp & 0x00ff00ff) << 8); s3_accel_start(8, 1, temp, 0, s3); s3_accel_start(8, 1, temp >> 16, 0, s3); } else { @@ -4041,6 +3815,8 @@ s3_accel_in_l(uint16_t port, void *p) case 0x200: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + if (s3->accel.cmd & 0x1000) + temp = ((temp & 0xff00ff00) >> 8) | ((temp & 0x00ff00ff) << 8); s3_accel_start(16, 1, temp, 0, s3); s3_accel_start(16, 1, temp >> 16, 0, s3); } else { @@ -4053,10 +3829,6 @@ s3_accel_in_l(uint16_t port, void *p) } break; } - - if (s3_enable_fifo(s3) == 0) { - s3->accel.draw_fifo_slot = 0; - } } return temp; @@ -4069,20 +3841,13 @@ s3_accel_write(uint32_t addr, uint8_t val, void *p) s3_t *s3 = (s3_t *)p; svga_t *svga = &s3->svga; - if (!s3->enable_8514) + if (!s3->enable_8514) return; - if (s3_enable_fifo(s3)) { - if (s3->chip <= S3_86C805) { + if (svga->crtc[0x53] & 0x08) + s3_accel_write_fifo(s3, addr & 0x1ffff, val); + else s3_accel_write_fifo(s3, addr & 0xffff, val); - } else { - if (svga->crtc[0x53] & 0x08) - s3_queue(s3, addr & 0x1ffff, val, FIFO_WRITE_BYTE); - else - s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_BYTE); - } - } else - s3_accel_write_fifo(s3, addr & 0xffff, val); } static void @@ -4091,20 +3856,13 @@ s3_accel_write_w(uint32_t addr, uint16_t val, void *p) s3_t *s3 = (s3_t *)p; svga_t *svga = &s3->svga; - if (!s3->enable_8514) + if (!s3->enable_8514) return; - if (s3_enable_fifo(s3)) { - if (s3->chip <= S3_86C805) { + if (svga->crtc[0x53] & 0x08) + s3_accel_write_fifo_w(s3, addr & 0x1ffff, val); + else s3_accel_write_fifo_w(s3, addr & 0xffff, val); - } else { - if (svga->crtc[0x53] & 0x08) - s3_queue(s3, addr & 0x1ffff, val, FIFO_WRITE_WORD); - else - s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_WORD); - } - } else - s3_accel_write_fifo_w(s3, addr & 0xffff, val); } static void @@ -4113,20 +3871,13 @@ s3_accel_write_l(uint32_t addr, uint32_t val, void *p) s3_t *s3 = (s3_t *)p; svga_t *svga = &s3->svga; - if (!s3->enable_8514) + if (!s3->enable_8514) return; - if (s3_enable_fifo(s3)) { - if (s3->chip <= S3_86C805) { + if (svga->crtc[0x53] & 0x08) + s3_accel_write_fifo_l(s3, addr & 0x1ffff, val); + else s3_accel_write_fifo_l(s3, addr & 0xffff, val); - } else { - if (svga->crtc[0x53] & 0x08) - s3_queue(s3, addr & 0x1ffff, val, FIFO_WRITE_DWORD); - else - s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_DWORD); - } - } else - s3_accel_write_fifo_l(s3, addr & 0xffff, val); } static uint8_t @@ -4136,9 +3887,8 @@ s3_accel_read(uint32_t addr, void *p) svga_t *svga = &s3->svga; uint8_t temp = 0x00; - if (!s3->enable_8514) { - return 0xff; - } + if (!s3->enable_8514) + return 0xff; if (svga->crtc[0x53] & 0x08) { if ((addr >= 0x08000) && (addr <= 0x0803f)) @@ -4171,13 +3921,6 @@ s3_accel_read(uint32_t addr, void *p) } else if (s3_cpu_dest(s3)) { READ_PIXTRANS_BYTE_MM - s3->accel.port_slot1++; - s3->accel.port_slot2++; - if (s3->accel.port_slot1 || s3->accel.port_slot2) - s3->accel.draw_fifo_slot++; - if (s3->accel.draw_fifo_slot > 8) - s3->accel.draw_fifo_slot = 1; - switch (s3->accel.cmd & 0x600) { case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { @@ -4198,10 +3941,6 @@ s3_accel_read(uint32_t addr, void *p) s3_accel_start(2, 1, 0xffffffff, temp | (temp << 8) | (temp << 16) | (temp << 24), s3); break; } - - if (s3_enable_fifo(s3) == 0) { - s3->accel.draw_fifo_slot = 0; - } } } @@ -4216,11 +3955,14 @@ s3_accel_read_w(uint32_t addr, void *p) uint16_t temp = 0x0000; uint16_t *vram_w = (uint16_t *)svga->vram; - if (!s3->enable_8514) + if (!s3->enable_8514) return 0xffff; if (svga->crtc[0x53] & 0x08) { switch (addr & 0x1fffe) { + case 0x811c: + return s3->accel.short_stroke; + default: return s3_accel_read(addr, p) | s3_accel_read(addr + 1, p) << 8; @@ -4228,18 +3970,15 @@ s3_accel_read_w(uint32_t addr, void *p) return 0xffff; } else { if (addr & 0x8000) { - temp = s3_accel_read((addr & 0xfffe), p); - temp |= s3_accel_read((addr & 0xfffe) + 1, p) << 8; + if (addr == 0x811c) + temp = s3->accel.short_stroke; + else { + temp = s3_accel_read((addr & 0xfffe), p); + temp |= s3_accel_read((addr & 0xfffe) + 1, p) << 8; + } } else if (s3_cpu_dest(s3)) { READ_PIXTRANS_WORD - s3->accel.port_slot1++; - s3->accel.port_slot2++; - if (s3->accel.port_slot1 || s3->accel.port_slot2) - s3->accel.draw_fifo_slot++; - if (s3->accel.draw_fifo_slot > 8) - s3->accel.draw_fifo_slot = 1; - switch (s3->accel.cmd & 0x600) { case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { @@ -4260,10 +3999,6 @@ s3_accel_read_w(uint32_t addr, void *p) s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); break; } - - if (s3_enable_fifo(s3) == 0) { - s3->accel.draw_fifo_slot = 0; - } } } @@ -4279,7 +4014,7 @@ s3_accel_read_l(uint32_t addr, void *p) uint32_t temp = 0x00000000; uint16_t *vram_w = (uint16_t *)svga->vram; - if (!s3->enable_8514) + if (!s3->enable_8514) return 0xffffffff; if (svga->crtc[0x53] & 0x08) { @@ -4402,13 +4137,6 @@ s3_accel_read_l(uint32_t addr, void *p) } else if (s3_cpu_dest(s3)) { READ_PIXTRANS_LONG - s3->accel.port_slot1++; - s3->accel.port_slot2++; - if (s3->accel.port_slot1 || s3->accel.port_slot2) - s3->accel.draw_fifo_slot++; - if (s3->accel.draw_fifo_slot > 8) - s3->accel.draw_fifo_slot = 1; - switch (s3->accel.cmd & 0x600) { case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { @@ -4439,10 +4167,6 @@ s3_accel_read_l(uint32_t addr, void *p) } break; } - - if (s3_enable_fifo(s3) == 0) { - s3->accel.draw_fifo_slot = 0; - } } } @@ -5171,6 +4895,122 @@ s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3) } } +static void +s3_fifo_slots(s3_t *s3) +{ + switch (s3->accel.setup_fifo_slot) { + case 1: + s3->accel.setup_fifo |= 1; + break; + case 2: + s3->accel.setup_fifo |= 3; + break; + case 3: + s3->accel.setup_fifo |= 7; + break; + case 4: + s3->accel.setup_fifo |= 0x0f; + break; + case 5: + s3->accel.setup_fifo |= 0x1f; + break; + case 6: + s3->accel.setup_fifo |= 0x3f; + break; + case 7: + s3->accel.setup_fifo |= 0x7f; + break; + case 8: + s3->accel.setup_fifo |= 0xff; /* FIFO full */ + break; + case 9: + s3->accel.setup_fifo |= 0xff; + s3->accel.setup_fifo2 |= 0x08; + break; + case 10: + s3->accel.setup_fifo |= 0xff; + s3->accel.setup_fifo2 |= 0x18; + break; + case 11: + s3->accel.setup_fifo |= 0xff; + s3->accel.setup_fifo2 |= 0x38; + break; + case 12: + s3->accel.setup_fifo |= 0xff; + s3->accel.setup_fifo2 |= 0x78; + break; + case 13: + s3->accel.setup_fifo |= 0xff; + s3->accel.setup_fifo2 |= 0xf8; /* FIFO full */ + break; + } + + switch (s3->accel.draw_fifo_slot) { + case 1: + s3->accel.draw_fifo |= 1; + break; + case 2: + s3->accel.draw_fifo |= 3; + break; + case 3: + s3->accel.draw_fifo |= 7; + break; + case 4: + s3->accel.draw_fifo |= 0x0f; + break; + case 5: + s3->accel.draw_fifo |= 0x1f; + break; + case 6: + s3->accel.draw_fifo |= 0x3f; + break; + case 7: + s3->accel.draw_fifo |= 0x7f; + break; + case 8: + s3->accel.draw_fifo |= 0xff; /* FIFO full */ + break; + case 9: + s3->accel.draw_fifo |= 0xff; + s3->accel.draw_fifo2 |= 0x08; + break; + case 10: + s3->accel.draw_fifo |= 0xff; + s3->accel.draw_fifo2 |= 0x18; + break; + case 11: + s3->accel.draw_fifo |= 0xff; + s3->accel.draw_fifo2 |= 0x38; + break; + case 12: + s3->accel.draw_fifo |= 0xff; + s3->accel.draw_fifo2 |= 0x78; + break; + case 13: + s3->accel.draw_fifo |= 0xff; + s3->accel.draw_fifo2 |= 0xf8; /* FIFO full */ + break; + } +} + +void +s3_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3, uint8_t ssv) +{ + if (!cpu_input) { + s3->accel.ssv_len = ssv & 0x0f; + s3->accel.ssv_dir = ssv & 0xe0; + s3->accel.ssv_draw = ssv & 0x10; + + s3_fifo_slots(s3); + + if (s3_cpu_src(s3)) { + return; /*Wait for data from CPU*/ + } + } + + s3_accel_start(count, cpu_input, mix_dat, cpu_dat, s3); +} + void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3) { @@ -5262,50 +5102,22 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ case 0x400: mix_mask = 0x80000000; break; case 0x600: mix_mask = (s3->chip == S3_TRIO32 || s3->chip >= S3_TRIO64V || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) ? 0x80 : 0x80000000; break; } - + /*Bit 4 of the Command register is the draw yes bit, which enables writing to memory/reading from memory when enabled. When this bit is disabled, no writing to memory/reading from memory is allowed. (This bit is almost meaningless on the NOP command)*/ - switch (cmd) { case 0: /*NOP (Short Stroke Vectors)*/ 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) + { + while (count-- && s3->accel.ssv_len >= 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) @@ -5326,7 +5138,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ MIX - if (s3->accel.ssv_draw1) { + if (s3->accel.ssv_draw) { WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); } } @@ -5336,10 +5148,10 @@ 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->accel.ssv_len1) + if (!s3->accel.ssv_len) break; - switch (s3->accel.ssv_dir1 & 0xe0) + switch (s3->accel.ssv_dir & 0xe0) { case 0x00: s3->accel.cx++; break; case 0x20: s3->accel.cx++; s3->accel.cy--; break; @@ -5350,56 +5162,10 @@ 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.ssv_len1--; + + s3->accel.ssv_len--; } - - 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; } @@ -5414,11 +5180,13 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.sy = s3->accel.maj_axis_pcnt; + s3_fifo_slots(s3); + 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; @@ -5595,6 +5363,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.dest = dstbase + s3->accel.cy * s3->width; + s3_fifo_slots(s3); + if (s3_cpu_src(s3)) { s3->data_available = 0; return; /*Wait for data from CPU*/ @@ -5717,6 +5487,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ polygon_setup(s3); + s3_fifo_slots(s3); + if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ end_y1 = s3->accel.desty_axstp; @@ -5829,6 +5601,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.src = srcbase + s3->accel.cy * s3->width; s3->accel.dest = dstbase + s3->accel.dy * s3->width; + + s3_fifo_slots(s3); } if ((s3->accel.cmd & 0x100) && !cpu_input) { @@ -6004,6 +5778,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.cy = s3->accel.dy & 7; s3->accel.src = srcbase + s3->accel.pattern + (s3->accel.cy * s3->width); + + s3_fifo_slots(s3); } if ((s3->accel.cmd & 0x100) && !cpu_input) { @@ -6126,6 +5902,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.cy = s3->accel.cur_y; if (s3->accel.cur_y_bit12) s3->accel.cy |= ~0xfff; + + s3_fifo_slots(s3); } if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ @@ -6218,6 +5996,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ polygon_setup(s3); + s3_fifo_slots(s3); + if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ end_y1 = s3->accel.desty_axstp; @@ -6227,6 +6007,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; + while ((s3->accel.poly_cy < end_y1) && (s3->accel.poly_cy2 < end_y2)) { int y = s3->accel.poly_cy; @@ -6327,7 +6108,9 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.dest = dstbase + (s3->accel.dy * s3->width); s3->accel.src = srcbase + (s3->accel.cy * s3->width); - s3->accel.pattern = (s3->accel.py * s3->width); + s3->accel.pattern = (s3->accel.py * s3->width); + + s3_fifo_slots(s3); } if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ @@ -6639,6 +6422,11 @@ static void *s3_init(const device_t *info) chip = S3_86C805; video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c805); break; + case S3_MIROCRYSTAL8S_805: + bios_fn = ROM_MIROCRYSTAL8S_805; + chip = S3_86C805; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c805); + break; case S3_MIROCRYSTAL10SD_805: bios_fn = ROM_MIROCRYSTAL10SD_805; chip = S3_86C805; @@ -6823,11 +6611,7 @@ static void *s3_init(const device_t *info) memset(s3, 0, sizeof(s3_t)); - if (info->local == S3_SPEA_MIRAGE_86C801 || - info->local == S3_SPEA_MIRAGE_86C805) - vram = 1; - else - vram = device_get_config_int("memory"); + vram = device_get_config_int("memory"); if (vram) vram_size = vram << 20; @@ -6991,6 +6775,7 @@ static void *s3_init(const device_t *info) svga->getclock = ics2494_getclock; break; + case S3_MIROCRYSTAL8S_805: case S3_MIROCRYSTAL10SD_805: svga->decode_mask = (2 << 20) - 1; stepping = 0xa0; /*86C801/86C805*/ @@ -7007,7 +6792,7 @@ static void *s3_init(const device_t *info) case S3_SPEA_MIRAGE_86C801: case S3_SPEA_MIRAGE_86C805: - svga->decode_mask = (1 << 20) - 1; + svga->decode_mask = (2 << 20) - 1; stepping = 0xa0; /*86C801/86C805*/ s3->id = stepping; s3->id_ext = stepping; @@ -7115,7 +6900,7 @@ static void *s3_init(const device_t *info) break; case S3_PHOENIX_VISION868: - svga->decode_mask = (4 << 20) - 1; + svga->decode_mask = (8 << 20) - 1; s3->id = 0xe1; /*Vision868*/ s3->id_ext = 0x90; s3->id_ext_pci = 0x80; @@ -7206,11 +6991,6 @@ static void *s3_init(const device_t *info) svga->packed_chain4 = 1; - s3->wake_fifo_thread = thread_create_event(); - s3->fifo_not_full_event = thread_create_event(); - s3->thread_run = 1; - s3->fifo_thread = thread_create(fifo_thread, s3); - return s3; } @@ -7244,6 +7024,11 @@ static int s3_phoenix_86c80x_available(void) return rom_present(ROM_PHOENIX_86C80X); } +static int s3_mirocrystal_8s_805_available(void) +{ + return rom_present(ROM_MIROCRYSTAL8S_805); +} + static int s3_mirocrystal_10sd_805_available(void) { return rom_present(ROM_MIROCRYSTAL10SD_805); @@ -7360,12 +7145,6 @@ static void s3_close(void *p) svga_close(&s3->svga); - s3->thread_run = 0; - thread_set_event(s3->wake_fifo_thread); - thread_wait(s3->fifo_thread, -1); - thread_destroy_event(s3->wake_fifo_thread); - thread_destroy_event(s3->fifo_not_full_event); - ddc_close(s3->ddc); i2c_gpio_close(s3->i2c); @@ -7558,7 +7337,7 @@ const device_t s3_spea_mirage_86c801_isa_device = { s3_spea_mirage_86c801_available }, s3_speed_changed, s3_force_redraw, - NULL + s3_9fx_config }; const device_t s3_spea_mirage_86c805_vlb_device = @@ -7572,9 +7351,24 @@ const device_t s3_spea_mirage_86c805_vlb_device = { s3_spea_mirage_86c805_available }, s3_speed_changed, s3_force_redraw, - NULL + s3_9fx_config }; +const device_t s3_mirocrystal_8s_805_vlb_device = +{ + "S3 86c805 VLB (MiroCRYSTAL 8S)", + DEVICE_VLB, + S3_MIROCRYSTAL8S_805, + s3_init, + s3_close, + NULL, + { s3_mirocrystal_8s_805_available }, + s3_speed_changed, + s3_force_redraw, + s3_9fx_config +}; + + const device_t s3_mirocrystal_10sd_805_vlb_device = { "S3 86c805 VLB (MiroCRYSTAL 10SD)", diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 6eba7e4e1..ae6eb08de 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -187,6 +187,7 @@ video_cards[] = { { "stealth3d_2000_vlb", &s3_virge_vlb_device }, { "stealth3d_3000_vlb", &s3_virge_988_vlb_device }, { "metheus928_vlb", &s3_metheus_86c928_vlb_device }, + { "mirocrystal8s_vlb", &s3_mirocrystal_8s_805_vlb_device }, { "mirocrystal10sd_vlb", &s3_mirocrystal_10sd_805_vlb_device }, { "px_86c805_vlb", &s3_phoenix_86c805_vlb_device }, { "px_s3_v7_805_vlb", &s3_spea_mirage_86c805_vlb_device },