diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index b588a3daf..a66dd8c03 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -449,6 +449,7 @@ extern void ibm_rgb528_ramdac_set_ref_clock(void *priv, svga_t *svga, float r extern void icd2061_write(void *priv, int val); extern float icd2061_getclock(int clock, void *priv); +extern void icd2061_set_ref_clock(void *priv, svga_t *svga, float ref_clock); /* The code is the same, the #define's are so that the correct name can be used. */ # define ics9161_write icd2061_write @@ -465,6 +466,8 @@ extern uint8_t sc1148x_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svg extern void sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga); extern uint8_t sc1502x_ramdac_in(uint16_t addr, void *priv, svga_t *svga); +extern void sc1502x_rs2_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga); +extern uint8_t sc1502x_rs2_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga); extern void sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga); extern uint8_t sdac_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga); @@ -516,6 +519,7 @@ extern const device_t sc11487_ramdac_device; extern const device_t sc11486_ramdac_device; extern const device_t sc11484_nors2_ramdac_device; extern const device_t sc1502x_ramdac_device; +extern const device_t sc1502x_rs2_ramdac_device; extern const device_t sdac_ramdac_device; extern const device_t stg_ramdac_device; extern const device_t tkd8001_ramdac_device; diff --git a/src/include/86box/video.h b/src/include/86box/video.h index b5be81bbb..81424dbcb 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -412,7 +412,7 @@ extern const device_t cga_pravetz_device; /* Compaq CGA */ extern const device_t compaq_cga_device; extern const device_t compaq_cga_2_device; -extern const device_t compaq_plasma_device; +extern const device_t compaq_plasma_device; /* Olivetti OGC */ extern const device_t ogc_device; @@ -513,8 +513,11 @@ extern const device_t realtek_rtg3106_device; extern const device_t s3_orchid_86c911_isa_device; extern const device_t s3_diamond_stealth_vram_isa_device; extern const device_t s3_ami_86c924_isa_device; +extern const device_t s3_elsa_winner1000_86c928_vlb_device; +extern const device_t s3_elsa_winner2000_86c928_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_elsa_winner1000_86c928_pci_device; extern const device_t s3_spea_mercury_lite_86c928_pci_device; extern const device_t s3_spea_mirage_86c801_isa_device; extern const device_t s3_winner1000_805_isa_device; @@ -635,9 +638,9 @@ extern const device_t wy700_device; extern const device_t v6355d_device; /* Tandy */ -extern const device_t tandy_1000_video_device; -extern const device_t tandy_1000hx_video_device; -extern const device_t tandy_1000sl_video_device; +extern const device_t tandy_1000_video_device; +extern const device_t tandy_1000hx_video_device; +extern const device_t tandy_1000sl_video_device; #endif diff --git a/src/video/clockgen/vid_clockgen_icd2061.c b/src/video/clockgen/vid_clockgen_icd2061.c index 7b80a5484..f1925e769 100644 --- a/src/video/clockgen/vid_clockgen_icd2061.c +++ b/src/video/clockgen/vid_clockgen_icd2061.c @@ -29,10 +29,15 @@ #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/device.h> +#include <86box/mem.h> +#include <86box/timer.h> +#include <86box/video.h> +#include <86box/vid_svga.h> #include <86box/plat_unused.h> typedef struct icd2061_t { - float freq[3]; + float freq[3]; + float ref_clock; int count; int bit_count; @@ -121,7 +126,7 @@ icd2061_write(void *priv, int val) q = qa + 2; /* Q (ICD2061) / M (ICS9161) */ ps = (icd2061->ctrl & (1 << a)) ? 4 : 2; /* Prescale */ - icd2061->freq[a] = ((float) (p_ * ps) / (float) (q * m)) * 14318184.0f; + icd2061->freq[a] = ((float) (p_ * ps) / (float) (q * m)) * icd2061->ref_clock; icd2061_log("P = %02X, M = %01X, Q = %02X, freq[%i] = %f\n", p_, m, q, a, icd2061->freq[a]); } else if (a == 6) { @@ -149,12 +154,24 @@ icd2061_getclock(int clock, void *priv) return icd2061->freq[clock]; } +void +icd2061_set_ref_clock(void *priv, svga_t *svga, float ref_clock) +{ + icd2061_t *icd2061 = (icd2061_t *) priv; + + if (icd2061) + icd2061->ref_clock = ref_clock; + + svga_recalctimings(svga); +} + static void * icd2061_init(UNUSED(const device_t *info)) { icd2061_t *icd2061 = (icd2061_t *) malloc(sizeof(icd2061_t)); memset(icd2061, 0, sizeof(icd2061_t)); + icd2061->ref_clock = 14318184.0f; icd2061->freq[0] = 25175000.0; icd2061->freq[1] = 28322000.0; icd2061->freq[2] = 28322000.0; diff --git a/src/video/ramdac/vid_ramdac_sc1502x.c b/src/video/ramdac/vid_ramdac_sc1502x.c index 1c7d4014d..4fc603ee9 100644 --- a/src/video/ramdac/vid_ramdac_sc1502x.c +++ b/src/video/ramdac/vid_ramdac_sc1502x.c @@ -33,65 +33,32 @@ typedef struct sc1502x_ramdac_t { int state; + int use_rs2; uint8_t ctrl; uint8_t idx; uint8_t regs[256]; uint32_t pixel_mask; - uint8_t enable_ext; } sc1502x_ramdac_t; static void -sc1502x_ramdac_bpp(uint8_t val, sc1502x_ramdac_t *ramdac, svga_t *svga) +sc1502x_ramdac_bpp(sc1502x_ramdac_t *ramdac, svga_t *svga) { - int oldbpp = 0; - if (val == 0xff) - return; - ramdac->ctrl = val; - oldbpp = svga->bpp; - switch ((val & 1) | ((val & 0xc0) >> 5)) { - case 0: - svga->bpp = 8; - break; - case 2: - case 3: - switch (val & 0x20) { - case 0x00: - svga->bpp = 32; - break; - case 0x20: - svga->bpp = 24; - break; - - default: - break; - } - break; - case 4: - case 5: - svga->bpp = 15; - break; - case 6: + int oldbpp = svga->bpp; + if (ramdac->ctrl & 0x80) { + if (ramdac->ctrl & 0x40) { svga->bpp = 16; - break; - case 7: - if (val & 4) { - switch (val & 0x20) { - case 0x00: - svga->bpp = 32; - break; - case 0x20: - svga->bpp = 24; - break; - - default: - break; - } - } else - svga->bpp = 16; - break; - - default: - break; + } else + svga->bpp = 15; + } else { + if (ramdac->ctrl & 0x40) { + if (ramdac->regs[0x10] & 0x01) + svga->bpp = 32; + else if (ramdac->ctrl & 0x20) + svga->bpp = 24; + else + svga->bpp = 32; + } else + svga->bpp = 8; } if (oldbpp != svga->bpp) svga_recalctimings(svga); @@ -104,29 +71,30 @@ sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga) switch (addr) { case 0x3C6: - if (ramdac->state == 0) - ramdac->enable_ext = (val == 0x10); - - if (ramdac->state == 4) { + if ((ramdac->state == 4) || (ramdac->ctrl & 0x10)) { ramdac->state = 0; - sc1502x_ramdac_bpp(val, ramdac, svga); + ramdac->ctrl = val; + if (val != 0xff) + sc1502x_ramdac_bpp(ramdac, svga); return; } ramdac->state = 0; + svga_out(addr, val, svga); break; case 0x3C7: - if (ramdac->enable_ext) { + if (ramdac->ctrl & 0x10) ramdac->idx = val; - return; - } + else + svga_out(addr, val, svga); + ramdac->state = 0; break; case 0x3C8: - if (ramdac->enable_ext) { + if (ramdac->ctrl & 0x10) { switch (ramdac->idx) { case 8: - ramdac->regs[ramdac->idx] = val; - svga_set_ramdac_type(svga, (ramdac->regs[ramdac->idx] & 1) ? RAMDAC_8BIT : RAMDAC_6BIT); + ramdac->regs[8] = val; + svga->ramdac_type = (val & 0x01) ? RAMDAC_8BIT : RAMDAC_6BIT; break; case 0x0d: ramdac->pixel_mask = val & svga->dac_mask; @@ -137,24 +105,96 @@ sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga) case 0x0f: ramdac->pixel_mask |= ((val & svga->dac_mask) << 16); break; + case 0x10: + ramdac->regs[0x10] = val; + sc1502x_ramdac_bpp(ramdac, svga); + break; default: ramdac->regs[ramdac->idx] = val; break; } - return; - } + } else + svga_out(addr, val, svga); + ramdac->state = 0; break; case 0x3C9: - if (ramdac->enable_ext) - return; ramdac->state = 0; + svga_out(addr, val, svga); break; default: break; } - svga_out(addr, val, svga); +} + +void +sc1502x_rs2_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga) +{ + sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) priv; + uint8_t rs = (addr & 0x03); + rs |= ((!!rs2) << 2); + + switch (rs) { + case 0x00: + if (ramdac->ctrl & 0x10) { + switch (ramdac->idx) { + case 8: + ramdac->regs[8] = val; + svga->ramdac_type = (val & 0x01) ? RAMDAC_8BIT : RAMDAC_6BIT; + break; + case 0x0d: + ramdac->pixel_mask = val & svga->dac_mask; + break; + case 0x0e: + ramdac->pixel_mask |= ((val & svga->dac_mask) << 8); + break; + case 0x0f: + ramdac->pixel_mask |= ((val & svga->dac_mask) << 16); + break; + case 0x10: + ramdac->regs[0x10] = val; + sc1502x_ramdac_bpp(ramdac, svga); + break; + default: + ramdac->regs[ramdac->idx] = val; + break; + } + } else + svga_out(addr, val, svga); + break; + case 0x01: + svga_out(addr, val, svga); + break; + case 0x02: + if (ramdac->ctrl & 0x10) { + ramdac->ctrl = val; + if (val != 0xff) + sc1502x_ramdac_bpp(ramdac, svga); + } else + svga_out(addr, val, svga); + break; + case 0x03: + if (ramdac->ctrl & 0x10) + ramdac->idx = val; + else + svga_out(addr, val, svga); + break; + case 0x04: + case 0x05: + case 0x07: + svga_out(addr, val, svga); + break; + case 0x06: + ramdac->ctrl = val; + if (val != 0xff) + sc1502x_ramdac_bpp(ramdac, svga); + break; + + default: + svga_out(addr, val, svga); + break; + } } uint8_t @@ -166,8 +206,7 @@ sc1502x_ramdac_in(uint16_t addr, void *priv, svga_t *svga) switch (addr) { case 0x3C6: if (ramdac->state == 4) { - ramdac->state = 0; - temp = ramdac->ctrl; + temp = ramdac->ctrl; break; } ramdac->state++; @@ -176,7 +215,7 @@ sc1502x_ramdac_in(uint16_t addr, void *priv, svga_t *svga) ramdac->state = 0; break; case 0x3C8: - if (ramdac->enable_ext) { + if (ramdac->ctrl & 0x10) { switch (ramdac->idx) { case 9: temp = 0x53; @@ -203,14 +242,72 @@ sc1502x_ramdac_in(uint16_t addr, void *priv, svga_t *svga) temp = ramdac->regs[ramdac->idx]; break; } - } else - ramdac->state = 0; + } + ramdac->state = 0; break; case 0x3C9: - if (ramdac->enable_ext) + if (ramdac->ctrl & 0x10) temp = ramdac->idx; - else - ramdac->state = 0; + + ramdac->state = 0; + break; + + default: + break; + } + + return temp; +} + +uint8_t +sc1502x_rs2_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga) +{ + sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) priv; + uint8_t rs = (addr & 0x03); + uint8_t temp = svga_in(addr, svga); + rs |= ((!!rs2) << 2); + + switch (rs) { + case 0x00: + if (ramdac->ctrl & 0x10) { + switch (ramdac->idx) { + case 9: + temp = 0x53; + break; + case 0x0a: + temp = 0x3a; + break; + case 0x0b: + temp = 0xb1; + break; + case 0x0c: + temp = 0x41; + break; + case 0x0d: + temp = ramdac->pixel_mask & 0xff; + break; + case 0x0e: + temp = ramdac->pixel_mask >> 8; + break; + case 0x0f: + temp = ramdac->pixel_mask >> 16; + break; + default: + temp = ramdac->regs[ramdac->idx]; + break; + } + } + break; + case 0x01: + if (ramdac->ctrl & 0x10) + temp = ramdac->idx; + break; + case 0x02: + if (ramdac->ctrl & 0x10) + temp = ramdac->ctrl; + break; + case 0x06: + temp = ramdac->ctrl; break; default: @@ -221,7 +318,7 @@ sc1502x_ramdac_in(uint16_t addr, void *priv, svga_t *svga) } static void * -sc1502x_ramdac_init(UNUSED(const device_t *info)) +sc1502x_ramdac_init(const device_t *info) { sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) malloc(sizeof(sc1502x_ramdac_t)); memset(ramdac, 0, sizeof(sc1502x_ramdac_t)); @@ -254,3 +351,17 @@ const device_t sc1502x_ramdac_device = { .force_redraw = NULL, .config = NULL }; + +const device_t sc1502x_rs2_ramdac_device = { + .name = "Sierra SC1502x RAMDAC with RS2", + .internal_name = "sc1502x_rs2_ramdac", + .flags = 0, + .local = 1, + .init = sc1502x_ramdac_init, + .close = sc1502x_ramdac_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index fbf329e84..870221742 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -49,6 +49,9 @@ #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_ELSAWIN1KVL_86C928 "roms/video/s3/ELSA_Winner_XHR_1000VL.BIN" +#define ROM_ELSAWIN1KPCI_86C928 "roms/video/s3/ELSA_Winner_10000_PCI_BIOS_3.04.02.BIN" +#define ROM_ELSAWIN2K_86C928 "roms/video/s3/elsa-winner-2000-vga-bios-v1-02-03-66b7554c706d6962736994.bin" #define ROM_SPEA_MERCURY_LITE_PCI "roms/video/s3/SPEAVGA.VBI" #define ROM_SPEA_MIRAGE_86C801 "roms/video/s3/V7MIRAGE.VBI" #define ROM_SPEA_MIRAGE_86C805 "roms/video/s3/86c805pspeavlbus.BIN" @@ -98,6 +101,9 @@ enum { S3_PHOENIX_86C805, S3_ORCHID_86C911, S3_METHEUS_86C928, + S3_ELSAWIN1K_86C928, + S3_ELSAWIN1KPCI_86C928, + S3_ELSAWIN2K_86C928, S3_AMI_86C924, S3_TRIO64V2_DX, S3_TRIO64V2_DX_ONBOARD, @@ -191,8 +197,19 @@ enum { FIFO_OUT_DWORD = (0x06 << 24) }; -typedef struct -{ +typedef enum { + BUILT_IN = 0, + SC1148X, + SC1502X, + ATT49X, + ATT498, + BT48X, + IBM_RGB, + S3_SDAC, + TVP3026 +} s3_ramdac_type; + +typedef struct { uint32_t addr_type; uint32_t val; } fifo_entry_t; @@ -204,6 +221,8 @@ typedef struct s3_t { mem_mapping_t new_mmio_mapping; int elsa_eeprom; + s3_ramdac_type ramdac_type; + uint8_t has_bios; rom_t bios_rom; @@ -1519,14 +1538,17 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xd148: case 0xd2e8: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); s3->accel.ropmix = (s3->accel.ropmix & 0xff00) | val; break; case 0xd149: case 0xd2e9: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); s3->accel.ropmix = (s3->accel.ropmix & 0x00ff) | (val << 8); break; case 0xe548: case 0xe6e8: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->bpp == 3) { if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); @@ -1537,6 +1559,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xe549: case 0xe6e9: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->bpp == 3) { if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24); @@ -1550,6 +1573,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xe54a: case 0xe6ea: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->accel.multifunc[0xe] & 0x200) s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); else if (s3->bpp == 3) { @@ -1561,6 +1585,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xe54b: case 0xe6eb: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->accel.multifunc[0xe] & 0x200) s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24); else if (s3->bpp == 3) { @@ -1578,7 +1603,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xe949: case 0xeae9: - s3->accel.pat_y = (s3->accel.pat_y & 0xff) | ((val & 0x1f) << 8); + s3->accel.pat_y = (s3->accel.pat_y & 0xff) | ((val & 0x0f) << 8); break; case 0xe94a: case 0xeaea: @@ -1586,10 +1611,11 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xe94b: case 0xeaeb: - s3->accel.pat_x = (s3->accel.pat_x & 0xff) | ((val & 0x1f) << 8); + s3->accel.pat_x = (s3->accel.pat_x & 0xff) | ((val & 0x0f) << 8); break; case 0xed48: case 0xeee8: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->bpp == 3) { if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); @@ -1600,6 +1626,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xed49: case 0xeee9: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->bpp == 3) { if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24); @@ -1613,6 +1640,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xed4a: case 0xeeea: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->accel.multifunc[0xe] & 0x200) s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); else if (s3->bpp == 3) { @@ -1624,6 +1652,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xed4b: case 0xeeeb: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->accel.multifunc[0xe] & 0x200) s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24); else if (s3->bpp == 3) { @@ -1977,29 +2006,39 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) break; case 0x8120: + addr = 0xa2e8; + break; case 0x8122: /*BKGD_COLOR*/ - WRITE8(addr, s3->accel.bkgd_color, val); - return; + addr = 0xa2ea; + break; case 0x8124: + addr = 0xa6e8; + break; case 0x8126: /*FRGD_COLOR*/ - WRITE8(addr, s3->accel.frgd_color, val); - return; + addr = 0xa6ea; + break; case 0x8128: + addr = 0xaae8; + break; case 0x812a: /*WRT_MASK*/ - WRITE8(addr, s3->accel.wrt_mask, val); - return; + addr = 0xaaea; + break; case 0x812c: + addr = 0xaee8; + break; case 0x812e: /*RD_MASK*/ - WRITE8(addr, s3->accel.rd_mask, val); - return; + addr = 0xaeea; + break; case 0x8130: + addr = 0xb2e8; + break; case 0x8132: /*COLOR_CMP*/ - WRITE8(addr, s3->accel.color_cmp, val); - return; + addr = 0xb2ea; + break; case 0x8134: addr = 0xb6e8; @@ -2056,9 +2095,11 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) break; case 0x8164: + addr = 0xe6e8; + break; case 0x8166: - WRITE8(addr, s3->accel.pat_bg_color, val); - return; + addr = 0xe6ea; + break; case 0x8168: addr = 0xeae8; @@ -2068,9 +2109,11 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) break; case 0x816c: + addr = 0xeee8; + break; case 0x816e: - WRITE8(addr, s3->accel.pat_fg_color, val); - return; + addr = 0xeeea; + break; default: break; @@ -2235,7 +2278,7 @@ s3_vblank_start(svga_t *svga) static uint32_t s3_hwcursor_convert_addr(svga_t *svga) { - if ((svga->bpp == 8) && (((svga->gdcreg[5] & 0x60) == 0x20) || (svga->crtc[0x3a] & 0x10)) && (svga->crtc[0x45] & 0x10)) { + if ((svga->bpp >= 8) && (((svga->gdcreg[5] & 0x60) == 0x20) || (svga->crtc[0x3a] & 0x10)) && (svga->crtc[0x45] & 0x10)) { if (svga->crtc[0x3a] & 0x10) return ((svga->hwcursor_latch.addr & 0xfffff1ff) | ((svga->hwcursor_latch.addr & 0x200) << 2)) | 0x600; else if ((svga->gdcreg[5] & 0x60) == 0x20) @@ -3019,27 +3062,38 @@ s3_out(uint16_t addr, uint8_t val, void *priv) else rs2 = (svga->crtc[0x55] & 0x01); // rs2 = (svga->crtc[0x55] & 0x01) || !!(svga->crtc[0x43] & 2); - if (s3->chip >= S3_TRIO32) - svga_out(addr, val, svga); - else if ((s3->chip == S3_VISION964 && s3->card_type != S3_ELSAWIN2KPROX_964) || (s3->chip == S3_86C928)) { - rs3 = !!(svga->crtc[0x55] & 0x02); - bt48x_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); - } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_DIAMOND_STEALTH64_968 || s3->card_type == S3_ELSAWIN2KPROX || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771))) - ibm_rgb528_ramdac_out(addr, rs2, val, svga->ramdac, svga); - 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) && (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, rs2, val, svga->ramdac, svga); - } else if (s3->card_type == S3_NUMBER9_9FX_531) - att498_ramdac_out(addr, rs2, val, svga->ramdac, svga); - else if ((s3->chip == S3_86C928PCI) && (s3->card_type == S3_SPEA_MERCURY_LITE_PCI)) - sc1502x_ramdac_out(addr, val, svga->ramdac, svga); - else - sdac_ramdac_out(addr, rs2, val, svga->ramdac, svga); + switch (s3->ramdac_type) { + case BUILT_IN: + default: + svga_out(addr, val, svga); + break; + case SC1148X: + sc1148x_ramdac_out(addr, rs2, val, svga->ramdac, svga); + break; + case SC1502X: + sc1502x_ramdac_out(addr, val, svga->ramdac, svga); + break; + case ATT49X: + att49x_ramdac_out(addr, rs2, val, svga->ramdac, svga); + break; + case ATT498: + att498_ramdac_out(addr, rs2, val, svga->ramdac, svga); + break; + case BT48X: + rs3 = !!(svga->crtc[0x55] & 0x02); + bt48x_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); + break; + case IBM_RGB: + ibm_rgb528_ramdac_out(addr, rs2, val, svga->ramdac, svga); + break; + case S3_SDAC: + sdac_ramdac_out(addr, rs2, val, svga->ramdac, svga); + break; + case TVP3026: + rs3 = !!(svga->crtc[0x55] & 0x02); + tvp3026_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); + break; + } return; case 0x3D4: @@ -3084,7 +3138,7 @@ s3_out(uint16_t addr, uint8_t val, void *priv) case 0x5c: if (s3->elsa_eeprom) nmc93cxx_eeprom_write(s3->eeprom, !!(val & 0x80), !!(val & 0x40), !!(val & 0x10)); - if (s3->card_type == S3_PHOENIX_VISION868 || s3->card_type == S3_PHOENIX_VISION968) { + if ((s3->card_type == S3_PHOENIX_VISION868) || (s3->card_type == S3_PHOENIX_VISION968)) { if ((val & 0x20) && (!(svga->crtc[0x55] & 0x01) && !(svga->crtc[0x43] & 2))) svga->dac_addr |= 0x20; } else if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968) { @@ -3136,6 +3190,7 @@ s3_out(uint16_t addr, uint8_t val, void *priv) if ((s3->chip == S3_VISION964) || (s3->chip == S3_VISION968)) break; svga->hwcursor.ena = val & 1; + s3_log("Write CRTC45=%02x.\n", val); break; case 0x46: case 0x47: @@ -3213,12 +3268,14 @@ s3_out(uint16_t addr, uint8_t val, void *priv) case 0x55: s3_log("[%04X:%08X]: Write CRTC%02x=%02x.\n", CS, cpu_state.pc, svga->crtcreg, svga->crtc[svga->crtcreg]); if (s3->chip == S3_86C928) { - if (val & 0x28) { - svga->hwcursor_draw = NULL; - svga->dac_hwcursor_draw = bt48x_hwcursor_draw; - } else { - svga->hwcursor_draw = s3_hwcursor_draw; - svga->dac_hwcursor_draw = NULL; + if (s3->ramdac_type == BT48X) { + if (val & 0x28) { + svga->hwcursor_draw = NULL; + svga->dac_hwcursor_draw = bt48x_hwcursor_draw; + } else { + svga->hwcursor_draw = s3_hwcursor_draw; + svga->dac_hwcursor_draw = NULL; + } } } break; @@ -3345,32 +3402,43 @@ s3_in(uint16_t addr, void *priv) case 0x3c8: case 0x3c9: rs2 = (svga->crtc[0x55] & 0x01) || !!(svga->crtc[0x43] & 2); - if (s3->chip >= S3_TRIO32) - return svga_in(addr, svga); - else if ((s3->chip == S3_VISION964 && s3->card_type != S3_ELSAWIN2KPROX_964) || (s3->chip == S3_86C928)) { - if (s3->chip == S3_86C928) - rs3 = !!(svga->crtc[0x55] & 0x28) || !!(svga->crtc[0x45] & 0x20) || !!(svga->crtc[0x55] & 0x02); /*Quite insane but Win95's S3 driver wants it set at all costs for 8bpp+ mode*/ - else + switch (s3->ramdac_type) { + case BUILT_IN: + default: + temp = svga_in(addr, svga); + break; + case SC1148X: + temp = sc1148x_ramdac_in(addr, rs2, svga->ramdac, svga); + break; + case SC1502X: + temp = sc1502x_ramdac_in(addr, svga->ramdac, svga); + break; + case ATT49X: + temp = att49x_ramdac_in(addr, rs2, svga->ramdac, svga); + break; + case ATT498: + temp = att498_ramdac_in(addr, rs2, svga->ramdac, svga); + break; + case BT48X: + if (s3->chip == S3_86C928) + rs3 = !!(svga->crtc[0x55] & 0x28) || !!(svga->crtc[0x45] & 0x20) || !!(svga->crtc[0x55] & 0x02); /*Quite insane but Win95's S3 driver wants it set at all costs for 8bpp+ mode*/ + else + rs3 = !!(svga->crtc[0x55] & 0x02); + + temp = bt48x_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); + break; + case IBM_RGB: + temp = ibm_rgb528_ramdac_in(addr, rs2, svga->ramdac, svga); + break; + case S3_SDAC: + temp = sdac_ramdac_in(addr, rs2, svga->ramdac, svga); + break; + case TVP3026: rs3 = !!(svga->crtc[0x55] & 0x02); - temp = bt48x_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); - return temp; - } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_DIAMOND_STEALTH64_968 || s3->card_type == S3_ELSAWIN2KPROX || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771))) - return ibm_rgb528_ramdac_in(addr, rs2, svga->ramdac, svga); - 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) && (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, rs2, svga->ramdac, svga); - else if (s3->card_type == S3_NUMBER9_9FX_531) - return att498_ramdac_in(addr, rs2, svga->ramdac, svga); - else if ((s3->chip == S3_86C928PCI) && (s3->card_type == S3_SPEA_MERCURY_LITE_PCI)) - return sc1502x_ramdac_in(addr, svga->ramdac, svga); - else - return sdac_ramdac_in(addr, rs2, svga->ramdac, svga); - break; + temp = tvp3026_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); + break; + } + return temp; case 0x3d4: return svga->crtcreg; @@ -3650,20 +3718,21 @@ s3_recalctimings(svga_t *svga) svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clk_sel, svga->clock_gen); - if ((s3->chip == S3_VISION964) || (s3->chip == S3_86C928)) { - if (s3->card_type == S3_ELSAWIN2KPROX_964) - ibm_rgb528_recalctimings(svga->ramdac, svga); - else { + switch (s3->ramdac_type) { + case BT48X: bt48x_recalctimings(svga->ramdac, svga); svga->interlace |= (!!(svga->crtc[0x42] & 0x20)); - } - } else if (s3->chip == S3_VISION968) { - if ((s3->card_type == S3_SPEA_MERCURY_P64V) || (s3->card_type == S3_MIROVIDEO40SV_ERGO_968)) - tvp3026_recalctimings(svga->ramdac, svga); - else + break; + case IBM_RGB: ibm_rgb528_recalctimings(svga->ramdac, svga); - } else - svga->interlace = !!(svga->crtc[0x42] & 0x20); + break; + case TVP3026: + tvp3026_recalctimings(svga->ramdac, svga); + break; + default: + svga->interlace = !!(svga->crtc[0x42] & 0x20); + break; + } if (s3->chip >= S3_TRIO32) { switch (svga->crtc[0x67] >> 4) { @@ -3797,13 +3866,127 @@ s3_recalctimings(svga_t *svga) break; } break; - + case S3_ELSAWIN1K_86C928: + case S3_ELSAWIN2K_86C928: + switch (s3->width) { + case 1024: + switch (svga->hdisp) { + case 256: + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + break; + case 512: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + break; + } + break; + case 1280: /*Account for the 1280x1024 resolution*/ + switch (svga->hdisp) { + case 320: + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + break; + case 640: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + break; + } + break; + case 2048: /*Account for the 1280x1024 resolution and the ELSA EEPROM resolutions*/ + switch (svga->hdisp) { + case 320: + case 384: + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + break; + case 576: + case 640: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + if (s3->ramdac_type == BT48X) { + if (!svga->interlace) { + if (svga->dispend >= 1024) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } else { + if (svga->dispend >= 512) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } + } + break; + } + break; + default: + break; + } + break; default: break; } break; case S3_86C928PCI: switch (s3->card_type) { + case S3_ELSAWIN1KPCI_86C928: + switch (s3->width) { + case 1024: + switch (svga->hdisp) { + case 256: + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + break; + case 512: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + break; + } + break; + case 1280: /*Account for the 1280x1024 resolution*/ + switch (svga->hdisp) { + case 320: + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + break; + case 640: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + break; + } + break; + case 2048: /*Account for the 1280x1024 resolution and the ELSA EEPROM resolutions*/ + switch (svga->hdisp) { + case 320: + case 384: + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + break; + case 576: + case 640: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + break; + } + break; + default: + break; + } + break; + case S3_SPEA_MERCURY_LITE_PCI: switch (s3->width) { case 640: @@ -3961,6 +4144,28 @@ s3_recalctimings(svga_t *svga) break; } break; + case S3_ELSAWIN1K_86C928: + case S3_ELSAWIN2K_86C928: + switch (s3->width) { + case 2048: + if (s3->ramdac_type == SC1502X) { + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + } else { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + break; + default: + if (s3->ramdac_type == BT48X) + svga->clock /= 2.0; + else if (s3->ramdac_type == SC1502X) { + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + } + break; + } + break; default: break; @@ -3968,6 +4173,10 @@ s3_recalctimings(svga_t *svga) break; case S3_86C928PCI: switch (s3->card_type) { + case S3_ELSAWIN1KPCI_86C928: + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + break; case S3_SPEA_MERCURY_LITE_PCI: switch (s3->width) { case 640: @@ -4157,6 +4366,28 @@ s3_recalctimings(svga_t *svga) break; } break; + case S3_ELSAWIN1K_86C928: + case S3_ELSAWIN2K_86C928: + switch (s3->width) { + case 2048: + if (s3->ramdac_type == SC1502X) { + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + } else { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + break; + default: + if (s3->ramdac_type == BT48X) + svga->clock /= 2.0; + else if (s3->ramdac_type == SC1502X) { + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + } + break; + } + break; default: break; @@ -4164,6 +4395,10 @@ s3_recalctimings(svga_t *svga) break; case S3_86C928PCI: switch (s3->card_type) { + case S3_ELSAWIN1KPCI_86C928: + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + break; case S3_SPEA_MERCURY_LITE_PCI: switch (s3->width) { case 640: @@ -4365,11 +4600,32 @@ s3_recalctimings(svga_t *svga) case 32: svga->render = svga_render_32bpp_highres; switch (s3->chip) { + case S3_86C928: + switch (s3->card_type) { + case S3_ELSAWIN1K_86C928: + svga->hdisp >>= 2; + svga->dots_per_clock >>= 2; + svga->clock *= 2.0; + break; + default: + break; + } + break; + case S3_86C928PCI: + switch (s3->card_type) { + case S3_ELSAWIN1KPCI_86C928: + svga->hdisp >>= 2; + svga->dots_per_clock >>= 2; + svga->clock *= 2.0; + break; + default: + break; + } + break; case S3_VISION864: svga->hdisp >>= 2; svga->dots_per_clock >>= 2; break; - case S3_VISION868: switch (s3->card_type) { case S3_PHOENIX_VISION868: @@ -4499,7 +4755,8 @@ s3_recalctimings(svga_t *svga) } } - if ((s3->chip == S3_TRIO32) || (s3->chip == S3_TRIO64) || (s3->chip == S3_VISION864) || (s3->chip == S3_VISION868) || (s3->chip == S3_VISION968)) + if ((((s3->card_type == S3_ELSAWIN1K_86C928) || (s3->card_type == S3_ELSAWIN1KPCI_86C928)) && (svga->bpp == 32)) || + (s3->chip == S3_TRIO32) || (s3->chip == S3_TRIO64) || (s3->chip == S3_VISION864) || (s3->chip == S3_VISION868) || (s3->chip == S3_VISION968)) svga->hoverride = 1; else svga->hoverride = 0; @@ -4771,7 +5028,7 @@ s3_updatemapping(s3_t *s3) if (s3->chip >= S3_86C928 && s3->chip <= S3_86C805) { if (s3->vlb) s3->linear_base &= 0x03ffffff; - else + else if (!s3->pci) s3->linear_base &= 0x00ffffff; } if ((svga->crtc[0x58] & 0x10) || (s3->accel.advfunc_cntl & 0x10)) { @@ -7599,6 +7856,7 @@ polygon_setup(s3_t *s3) old_dest_dat = dest_dat; \ ROPMIX_READ(dest_dat, pat_dat, src_dat); \ out = (out & s3->accel.wrt_mask) | (old_dest_dat & ~s3->accel.wrt_mask); \ + out &= 0xFFFFFF; \ } #define WRITE(addr, dat) \ @@ -9543,6 +9801,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi break; case 14: /*ROPBlt (Vision868/968 only)*/ + ; + uint32_t mono_pattern[64] = { 0 }; if (s3->chip != S3_VISION968 && s3->chip != S3_VISION868) break; @@ -9552,11 +9812,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.sy = s3->accel.multifunc[0] & 0xfff; s3->accel.dx = s3->accel.destx_distp & 0xfff; - if (s3->accel.destx_distp & 0x1000) - s3->accel.dx |= ~0xfff; s3->accel.dy = s3->accel.desty_axstp & 0xfff; - if (s3->accel.desty_axstp & 0x1000) - s3->accel.dy |= ~0xfff; s3->accel.cx = s3->accel.cur_x & 0xfff; s3->accel.cy = s3->accel.cur_y & 0xfff; @@ -9567,13 +9823,35 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi 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_log("ROPBLT=%04x, PIXCntl=%04x, Misc1=%04x, PATBKGDCOL=%08x, PATFRGDCOL=%08x, COLBKGDCOL=%08x, COLFRGDCOL=%08x, PX=%d, PY=%d, DX=%d, DY=%d, CX=%d, CY=%d, FRGDSEL=%x, BKGDSEL=%x, RDMASK=%08x, WRTMASK=%08x, ROPMIX=%03x, pitch=%d.\n", s3->accel.cmd, s3->accel.multifunc[0xa], s3->accel.multifunc[0xe], s3->accel.pat_bg_color, s3->accel.pat_fg_color, s3->accel.bkgd_color, s3->accel.frgd_color, s3->accel.px, s3->accel.py, s3->accel.dx, s3->accel.dy, s3->accel.cx, s3->accel.cy, frgd_mix, bkgd_mix, s3->accel.rd_mask, s3->accel.wrt_mask, s3->accel.ropmix, s3->width); } if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ + if (s3->accel.ropmix & 0x100) { + int x; + int y; + switch (s3->accel.cmd & 0x600) { + case 0x000: + case 0x600: + mix_dat &= 0xff; + break; + case 0x200: + mix_dat &= 0xffff; + break; + default: + break; + } + + for (y = 0; y < 8; y++) { + for (x = 0; x < 8; x++) { + mono_pattern[y * 8 + (7 - x)] = (mix_dat & (1 << (x + y * 8))) & 0x80000000; + } + } + } while (count-- && s3->accel.sy >= 0) { - if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b) { + if ((s3->accel.dx >= clip_l) && (s3->accel.dx <= clip_r) && (s3->accel.dy >= clip_t) && (s3->accel.dy <= clip_b)) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: src_dat = s3->accel.bkgd_color; @@ -9592,24 +9870,18 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi break; } - if (s3->accel.ropmix & 0x100) { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + if (s3->accel.ropmix & 0x100) { /*Mono pattern used*/ + switch (mono_pattern[(s3->accel.py & 7) * 8 + (s3->accel.px & 7)] ? (frgd_mix & 1) : (bkgd_mix & 1)) { case 0: pat_dat = s3->accel.pat_bg_color; break; case 1: pat_dat = s3->accel.pat_fg_color; break; - case 2: - pat_dat = cpu_dat; - break; - case 3: - READ(s3->accel.pattern + s3->accel.px, pat_dat); - break; - default: break; } + s3_log("MonoMIX=%08x, PX=%d, PY=%d.\n", mix_dat, s3->accel.px & 7, s3->accel.py & 7); } else { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: @@ -9645,19 +9917,12 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi } else update = 1; - if (s3->bpp == 2) { - src_dat &= 0xff; - pat_dat &= 0xff; - } else if (s3->bpp == 1) { - src_dat &= 0xffff; - pat_dat &= 0xffff; - } - if (update) { READ(s3->accel.dest + s3->accel.dx, dest_dat); ROPMIX + s3_log("Destination=%08x, Source=%08x, Pattern=%08x, OUT=%08x, mix=%08x, count=%d.\n", dest_dat, src_dat, pat_dat, out, mix_dat, count); if (s3->accel.cmd & 0x10) { WRITE(s3->accel.dest + s3->accel.dx, out); } @@ -9666,6 +9931,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi mix_dat <<= 1; mix_dat |= 1; + if (s3->bpp == 0) cpu_dat >>= 8; else @@ -10111,6 +10377,21 @@ s3_init(const device_t *info) else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c801); break; + case S3_ELSAWIN1K_86C928: + bios_fn = ROM_ELSAWIN1KVL_86C928; + chip = S3_86C928; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c805); + break; + case S3_ELSAWIN1KPCI_86C928: + bios_fn = ROM_ELSAWIN1KPCI_86C928; + chip = S3_86C928PCI; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c928pci); + break; + case S3_ELSAWIN2K_86C928: + bios_fn = ROM_ELSAWIN2K_86C928; + chip = S3_86C928; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c801); + break; case S3_SPEA_MERCURY_LITE_PCI: bios_fn = ROM_SPEA_MERCURY_LITE_PCI; chip = S3_86C928PCI; @@ -10482,6 +10763,7 @@ s3_init(const device_t *info) s3->accel_start = s3_accel_start; s3->elsa_eeprom = 0; + s3->ramdac_type = BUILT_IN; switch (s3->card_type) { case S3_ORCHID_86C911: @@ -10494,6 +10776,7 @@ s3_init(const device_t *info) s3->packed_mmio = 0; svga->ramdac = device_add(&sc11483_ramdac_device); + s3->ramdac_type = SC1148X; if (s3->card_type == S3_ORCHID_86C911) { svga->clock_gen = device_add(&av9194_device); svga->getclock = av9194_getclock; @@ -10501,6 +10784,7 @@ s3_init(const device_t *info) /* DCS2824-0 = Diamond ICD2061A-compatible. */ svga->clock_gen = device_add(&icd2061_device); svga->getclock = icd2061_getclock; + icd2061_set_ref_clock(svga->ramdac, svga, 14318184.0f); } break; @@ -10513,6 +10797,7 @@ s3_init(const device_t *info) s3->packed_mmio = 0; svga->ramdac = device_add(&sc11483_ramdac_device); + s3->ramdac_type = SC1148X; svga->clock_gen = device_add(&ics2494an_305_device); svga->getclock = ics2494_getclock; break; @@ -10528,6 +10813,7 @@ s3_init(const device_t *info) svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&gendac_ramdac_device); + s3->ramdac_type = S3_SDAC; svga->clock_gen = svga->ramdac; svga->getclock = sdac_getclock; break; @@ -10544,6 +10830,7 @@ s3_init(const device_t *info) svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&att491_ramdac_device); + s3->ramdac_type = ATT49X; svga->clock_gen = device_add(&av9194_device); svga->getclock = av9194_getclock; if (info->local == S3_WINNER1000_805) @@ -10560,6 +10847,7 @@ s3_init(const device_t *info) svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&att490_ramdac_device); + s3->ramdac_type = ATT49X; svga->clock_gen = device_add(&av9194_device); svga->getclock = av9194_getclock; break; @@ -10575,10 +10863,43 @@ s3_init(const device_t *info) svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&att492_ramdac_device); + s3->ramdac_type = ATT49X; svga->clock_gen = device_add(&av9194_device); svga->getclock = av9194_getclock; break; + case S3_ELSAWIN1K_86C928: + svga->decode_mask = (4 << 20) - 1; + stepping = 0x91; /*86C928D*/ + s3->id = stepping; + s3->id_ext = stepping; + s3->id_ext_pci = 0; + s3->packed_mmio = 0; + svga->crtc[0x5a] = 0x0a; + svga->ramdac = device_add(&sc1502x_ramdac_device); + s3->ramdac_type = SC1502X; + svga->clock_gen = device_add(&icd2061_device); + svga->getclock = icd2061_getclock; + s3->elsa_eeprom = 1; + icd2061_set_ref_clock(svga->ramdac, svga, 28322000.0f); + break; + + case S3_ELSAWIN2K_86C928: + svga->decode_mask = (4 << 20) - 1; + stepping = 0x91; /*86C928D*/ + s3->id = stepping; + s3->id_ext = stepping; + s3->id_ext_pci = 0; + s3->packed_mmio = 0; + svga->crtc[0x5a] = 0x0a; + svga->ramdac = device_add(&bt485_ramdac_device); + s3->ramdac_type = BT48X; + svga->clock_gen = device_add(&ics9161_device); + svga->getclock = ics9161_getclock; + s3->elsa_eeprom = 1; + icd2061_set_ref_clock(svga->ramdac, svga, 28322000.0f); + break; + case S3_METHEUS_86C928: svga->decode_mask = (4 << 20) - 1; stepping = 0x91; /*86C928D*/ @@ -10588,10 +10909,27 @@ s3_init(const device_t *info) s3->packed_mmio = 0; svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&bt485_ramdac_device); + s3->ramdac_type = BT48X; svga->clock_gen = device_add(&ics2494an_305_device); svga->getclock = ics2494_getclock; break; + case S3_ELSAWIN1KPCI_86C928: + svga->decode_mask = (4 << 20) - 1; + stepping = 0xb0; /*86C928PCI*/ + s3->id = stepping; + s3->id_ext = stepping; + s3->id_ext_pci = stepping; + s3->packed_mmio = 0; + svga->crtc[0x5a] = 0x0a; + svga->ramdac = device_add(&sc1502x_ramdac_device); + s3->ramdac_type = SC1502X; + svga->clock_gen = device_add(&icd2061_device); + svga->getclock = icd2061_getclock; + s3->elsa_eeprom = 1; + icd2061_set_ref_clock(svga->ramdac, svga, 28322000.0f); + break; + case S3_SPEA_MERCURY_LITE_PCI: svga->decode_mask = (4 << 20) - 1; stepping = 0xb0; /*86C928PCI*/ @@ -10601,6 +10939,7 @@ s3_init(const device_t *info) s3->packed_mmio = 0; svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&sc1502x_ramdac_device); + s3->ramdac_type = SC1502X; svga->clock_gen = device_add(&av9194_device); svga->getclock = av9194_getclock; break; @@ -10619,6 +10958,7 @@ s3_init(const device_t *info) s3->packed_mmio = 0; svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&sdac_ramdac_device); + s3->ramdac_type = S3_SDAC; svga->clock_gen = svga->ramdac; svga->getclock = sdac_getclock; break; @@ -10636,6 +10976,7 @@ s3_init(const device_t *info) switch (info->local) { case S3_ELSAWIN2KPROX_964: svga->ramdac = device_add(&ibm_rgb528_ramdac_device); + s3->ramdac_type = IBM_RGB; svga->clock_gen = svga->ramdac; svga->getclock = ibm_rgb528_getclock; s3->elsa_eeprom = 1; @@ -10643,8 +10984,10 @@ s3_init(const device_t *info) break; default: svga->ramdac = device_add(&bt485_ramdac_device); + s3->ramdac_type = BT48X; svga->clock_gen = device_add(&icd2061_device); svga->getclock = icd2061_getclock; + icd2061_set_ref_clock(svga->ramdac, svga, 14318184.0f); break; } break; @@ -10678,6 +11021,7 @@ s3_init(const device_t *info) case S3_PHOENIX_VISION968: case S3_NUMBER9_9FX_771: svga->ramdac = device_add(&ibm_rgb528_ramdac_device); + s3->ramdac_type = IBM_RGB; svga->clock_gen = svga->ramdac; svga->getclock = ibm_rgb528_getclock; if (info->local == S3_ELSAWIN2KPROX) { @@ -10690,6 +11034,7 @@ s3_init(const device_t *info) break; default: svga->ramdac = device_add(&tvp3026_ramdac_device); + s3->ramdac_type = TVP3026; svga->clock_gen = svga->ramdac; svga->getclock = tvp3026_getclock; svga->conv_16to32 = tvp3026_conv_16to32; @@ -10718,10 +11063,13 @@ s3_init(const device_t *info) if (info->local == S3_NUMBER9_9FX_531) { svga->ramdac = device_add(&att498_ramdac_device); + s3->ramdac_type = ATT498; svga->clock_gen = device_add(&icd2061_device); svga->getclock = icd2061_getclock; + icd2061_set_ref_clock(svga->ramdac, svga, 14318184.0f); } else { svga->ramdac = device_add(&sdac_ramdac_device); + s3->ramdac_type = S3_SDAC; svga->clock_gen = svga->ramdac; svga->getclock = sdac_getclock; } @@ -10808,6 +11156,24 @@ s3_init(const device_t *info) s3->eeprom_data[0x08] = 0x83d6; snprintf(eeprom_filename, sizeof(eeprom_filename), "eeprom_s3_winner_1k_805_%d.nvr", s3->eeprom_inst); break; + case S3_ELSAWIN1K_86C928: + s3->eeprom_data[0x02] = 0x0912; + s3->eeprom_data[0x07] = 0xa604; + s3->eeprom_data[0x08] = 0xa604; + snprintf(eeprom_filename, sizeof(eeprom_filename), "eeprom_s3_winner_1k_928_vlb_%d.nvr", s3->eeprom_inst); + break; + case S3_ELSAWIN1KPCI_86C928: + s3->eeprom_data[0x02] = 0x0914; + s3->eeprom_data[0x07] = 0xa604; + s3->eeprom_data[0x08] = 0xa604; + snprintf(eeprom_filename, sizeof(eeprom_filename), "eeprom_s3_winner_1k_928_pci_%d.nvr", s3->eeprom_inst); + break; + case S3_ELSAWIN2K_86C928: + s3->eeprom_data[0x02] = 0x0920; + s3->eeprom_data[0x07] = 0xa604; + s3->eeprom_data[0x08] = 0xa604; + snprintf(eeprom_filename, sizeof(eeprom_filename), "eeprom_s3_winner_2k_928_isa_%d.nvr", s3->eeprom_inst); + break; case S3_ELSAWIN2KPROX: s3->eeprom_data[0x02] = 0x094a; s3->eeprom_data[0x07] = 0xf424; @@ -10910,6 +11276,24 @@ s3_mirocrystal_10sd_805_available(void) return rom_present(ROM_MIROCRYSTAL10SD_805); } +static int +s3_elsa_winner1000_86c928_vlb_available(void) +{ + return rom_present(ROM_ELSAWIN1KVL_86C928); +} + +static int +s3_elsa_winner1000_86c928_pci_available(void) +{ + return rom_present(ROM_ELSAWIN1KPCI_86C928); +} + +static int +s3_elsa_winner2000_86c928_available(void) +{ + return rom_present(ROM_ELSAWIN2K_86C928); +} + static int s3_metheus_86c928_available(void) { @@ -11350,7 +11734,7 @@ const device_t s3_spea_mirage_86c801_isa_device = { }; const device_t s3_winner1000_805_isa_device = { - .name = "S3 86c805 ISA (ELSA Winner 1000)", + .name = "S3 86c805 ISA (ELSA Winner 1000 805i)", .internal_name = "winner1000_805_isa", .flags = DEVICE_ISA16, .local = S3_WINNER1000_805, @@ -11447,6 +11831,34 @@ const device_t s3_phoenix_86c805_vlb_device = { .config = s3_9fx_config }; +const device_t s3_elsa_winner1000_86c928_vlb_device = { + .name = "S3 86c928 VLB (ELSA Winner 1000 928)", + .internal_name = "elsawin1k928_vlb", + .flags = DEVICE_VLB, + .local = S3_ELSAWIN1K_86C928, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, + .available = s3_elsa_winner1000_86c928_vlb_available, + .speed_changed = s3_speed_changed, + .force_redraw = s3_force_redraw, + .config = s3_standard_config +}; + +const device_t s3_elsa_winner2000_86c928_isa_device = { + .name = "S3 86c928 ISA (ELSA Winner 2000 928)", + .internal_name = "elsawin2k928_isa", + .flags = DEVICE_ISA16, + .local = S3_ELSAWIN2K_86C928, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, + .available = s3_elsa_winner2000_86c928_available, + .speed_changed = s3_speed_changed, + .force_redraw = s3_force_redraw, + .config = s3_standard_config +}; + const device_t s3_metheus_86c928_isa_device = { .name = "S3 86c928 ISA (Metheus Premier 928)", .internal_name = "metheus928_isa", @@ -11475,6 +11887,21 @@ const device_t s3_metheus_86c928_vlb_device = { .config = s3_standard_config }; +const device_t s3_elsa_winner1000_86c928_pci_device = { + .name = "S3 86c928 PCI (ELSA Winner 1000 928)", + .internal_name = "elsawin1k928_pci", + .flags = DEVICE_PCI, + .local = S3_ELSAWIN1KPCI_86C928, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, + .available = s3_elsa_winner1000_86c928_pci_available, + .speed_changed = s3_speed_changed, + .force_redraw = s3_force_redraw, + .config = s3_standard_config +}; + + const device_t s3_spea_mercury_lite_86c928_pci_device = { .name = "S3 86c928 PCI (SPEA Mercury Lite)", .internal_name = "spea_mercurylite_pci", diff --git a/src/video/vid_table.c b/src/video/vid_table.c index c99f4aad1..20a8f311d 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -91,7 +91,6 @@ video_cards[] = { { .device = &nga_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &nec_sv9000_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &ogc_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &jvga_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &oti037c_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &oti067_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &oti077_device, .flags = VIDEO_FLAG_TYPE_NONE }, @@ -127,10 +126,12 @@ video_cards[] = { { .device = &gd5434_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &gd5434_diamond_speedstar_64_a3_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &inmos_isa_device, .flags = VIDEO_FLAG_TYPE_XGA }, + { .device = &jvga_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &radius_svga_multiview_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_diamond_stealth_vram_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_orchid_86c911_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_ami_86c924_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_elsa_winner2000_86c928_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_metheus_86c928_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_phoenix_86c801_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_spea_mirage_86c801_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, @@ -160,6 +161,7 @@ video_cards[] = { { .device = &gd5430_diamond_speedstar_pro_se_a8_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &gd5430_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &gd5434_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_elsa_winner1000_86c928_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_metheus_86c928_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_mirocrystal_8s_805_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_mirocrystal_10sd_805_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, @@ -199,6 +201,7 @@ video_cards[] = { { .device = &et4000w32p_cardex_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &et4000w32p_noncardex_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &et4000w32p_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_elsa_winner1000_86c928_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_spea_mercury_lite_86c928_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_diamond_stealth64_964_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_elsa_winner2000_pro_x_964_pci_device, .flags = VIDEO_FLAG_TYPE_NONE },