From ba89af057c623f81b513f17402fc722ac25a21ac Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 25 Jun 2020 13:18:29 +0200 Subject: [PATCH] Added the Sierra SC11483 and SC11487 ramdac's. Made the S3 911 use the SC11483 plus a few minor changes to the S3 code itself. --- src/include/86box/vid_svga.h | 5 ++ src/video/vid_s3.c | 25 +++--- src/video/vid_sc1148x_ramdac.c | 143 +++++++++++++++++++++++++++++++++ src/win/Makefile.mingw | 3 +- 4 files changed, 161 insertions(+), 15 deletions(-) create mode 100644 src/video/vid_sc1148x_ramdac.c diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index acdea041c..d63af24c9 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -226,6 +226,9 @@ extern void ics2595_write(void *p, int strobe, int dat); extern double ics2595_getclock(void *p); extern void ics2595_setclock(void *p, double clock); +extern void sc1148x_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga); +extern uint8_t sc1148x_ramdac_in(uint16_t addr, void *p, svga_t *svga); + extern void sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga); extern uint8_t sc1502x_ramdac_in(uint16_t addr, void *p, svga_t *svga); @@ -255,6 +258,8 @@ extern const device_t gendac_ramdac_device; extern const device_t ics2595_device; extern const device_t icd2061_device; extern const device_t ics9161_device; +extern const device_t sc11483_ramdac_device; +extern const device_t sc11487_ramdac_device; extern const device_t sc1502x_ramdac_device; extern const device_t sdac_ramdac_device; extern const device_t stg_ramdac_device; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 551229513..dc152ed7c 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -1316,8 +1316,10 @@ void s3_out(uint16_t addr, uint8_t val, void *p) else rs3 = 0; bt48x_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); - } else if (s3->chip == S3_86C801 || s3->chip == S3_86C805 || s3->chip == S3_86C911) + } else if (s3->chip == S3_86C801 || s3->chip == S3_86C805) att49x_ramdac_out(addr, val, svga->ramdac, svga); + else if (s3->chip == S3_86C911) + sc1148x_ramdac_out(addr, val, svga->ramdac, svga); else sdac_ramdac_out(addr, rs2, val, svga->ramdac, svga); return; @@ -1440,7 +1442,7 @@ void s3_out(uint16_t addr, uint8_t val, void *p) s3->hwc_fg_col = (s3->hwc_fg_col & 0x00ffff) | (val << 16); break; } - s3->hwc_col_stack_pos = (s3->hwc_col_stack_pos + 1) % 3; + s3->hwc_col_stack_pos = (s3->hwc_col_stack_pos + 1) & 3; break; case 0x4b: switch (s3->hwc_col_stack_pos) @@ -1455,7 +1457,7 @@ void s3_out(uint16_t addr, uint8_t val, void *p) s3->hwc_bg_col = (s3->hwc_bg_col & 0x00ffff) | (val << 16); break; } - s3->hwc_col_stack_pos = (s3->hwc_col_stack_pos + 1) % 3; + s3->hwc_col_stack_pos = (s3->hwc_col_stack_pos + 1) & 3; break; case 0x53: @@ -1553,8 +1555,10 @@ uint8_t s3_in(uint16_t addr, void *p) else if (s3->chip == S3_VISION964 || s3->chip == S3_86C928) { rs3 = !!(svga->crtc[0x55] & 0x02); return bt48x_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); - } else if (s3->chip == S3_86C801 || s3->chip == S3_86C805 || s3->chip == S3_86C911) + } else if (s3->chip == S3_86C801 || s3->chip == S3_86C805) return att49x_ramdac_in(addr, svga->ramdac, svga); + else if (s3->chip == S3_86C911) + sc1148x_ramdac_in(addr, svga->ramdac, svga); else return sdac_ramdac_in(addr, rs2, svga->ramdac, svga); break; @@ -1641,7 +1645,7 @@ void s3_recalctimings(svga_t *svga) break; case 15: svga->render = svga_render_15bpp_highres; - if (s3->chip != S3_VISION964 && s3->chip != S3_86C801 && s3->chip != S3_86C928) + if (s3->chip != S3_VISION964 && s3->chip != S3_86C801 && s3->chip != S3_86C928 && s3->chip != S3_86C911) svga->hdisp /= 2; break; case 16: @@ -1735,10 +1739,7 @@ void s3_updatemapping(s3_t *s3) break; case 3: /*8mb*/ switch (s3->chip) { - case S3_TRIO32: case S3_TRIO64: - case S3_86C801: - case S3_86C805: case S3_86C928: s3->linear_size = 0x400000; break; @@ -1767,7 +1768,6 @@ void s3_updatemapping(s3_t *s3) /* Memory mapped I/O. */ if ((svga->crtc[0x53] & 0x10) || (s3->accel.advfunc_cntl & 0x20)) { /* Old MMIO. */ - mem_mapping_disable(&svga->mapping); mem_mapping_enable(&s3->mmio_mapping); } else mem_mapping_disable(&s3->mmio_mapping); @@ -3432,7 +3432,7 @@ static void *s3_init(const device_t *info) if (chip == S3_VISION964) svga->dac_hwcursor_draw = bt48x_hwcursor_draw; - if (s3->chip >= S3_VISION864) { + if (chip >= S3_VISION864) { switch (vram) { case 0: /* 512 kB */ svga->vram_mask = (1 << 19) - 1; @@ -3502,7 +3502,7 @@ static void *s3_init(const device_t *info) s3->packed_mmio = 0; s3->width = 1024; - svga->ramdac = device_add(&att490_ramdac_device); + svga->ramdac = device_add(&sc11483_ramdac_device); svga->clock_gen = device_add(&av9194_device); svga->getclock = av9194_getclock; break; @@ -3800,9 +3800,6 @@ static const device_config_t s3_config[] = { "4 MB", 4 }, - { - "8 MB", 8 - }, { "" } diff --git a/src/video/vid_sc1148x_ramdac.c b/src/video/vid_sc1148x_ramdac.c new file mode 100644 index 000000000..b786629ab --- /dev/null +++ b/src/video/vid_sc1148x_ramdac.c @@ -0,0 +1,143 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of Sierra SC11483 and SC11487 RAMDACs. + * + * Used by the S3 911 and 924 chips. + * + * + * + * Authors: TheCollector1995, + * + * Copyright 2020 TheCollector1995. + */ +#include +#include +#include +#include +#include +#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> + + +typedef struct +{ + int type; + int state; + uint8_t ctrl; +} sc1148x_ramdac_t; + + +void +sc1148x_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) +{ + sc1148x_ramdac_t *ramdac = (sc1148x_ramdac_t *) p; + + switch (addr) { + case 0x3C6: + if (ramdac->state == 4) { + ramdac->state = 0; + ramdac->ctrl = val; + if (ramdac->ctrl & 0x80) { + if (ramdac->ctrl & 0x40) + svga->bpp = 16; + else + svga->bpp = 15; + } else { + svga->bpp = 8; + } + svga_recalctimings(svga); + return; + } + ramdac->state = 0; + break; + case 0x3C7: + case 0x3C8: + case 0x3C9: + ramdac->state = 0; + break; + } + + svga_out(addr, val, svga); +} + + +uint8_t +sc1148x_ramdac_in(uint16_t addr, void *p, svga_t *svga) +{ + sc1148x_ramdac_t *ramdac = (sc1148x_ramdac_t *) p; + uint8_t temp = svga_in(addr, svga); + + switch (addr) { + case 0x3C6: + if (ramdac->state == 4) { + ramdac->state = 0; + temp = ramdac->ctrl; + + if (ramdac->type == 1) { + if (ramdac->ctrl & 0x80) + temp |= 1; + else + temp &= ~1; + } + break; + } + + ramdac->state++; + break; + case 0x3C7: + case 0x3C8: + case 0x3C9: + ramdac->state = 0; + break; + } + + return temp; +} + + +static void * +sc1148x_ramdac_init(const device_t *info) +{ + sc1148x_ramdac_t *ramdac = (sc1148x_ramdac_t *) malloc(sizeof(sc1148x_ramdac_t)); + memset(ramdac, 0, sizeof(sc1148x_ramdac_t)); + + ramdac->type = info->local; + + return ramdac; +} + + +static void +sc1148x_ramdac_close(void *priv) +{ + sc1148x_ramdac_t *ramdac = (sc1148x_ramdac_t *) priv; + + if (ramdac) + free(ramdac); +} + +const device_t sc11483_ramdac_device = +{ + "Sierra SC11483 RAMDAC", + 0, 0, + sc1148x_ramdac_init, sc1148x_ramdac_close, + NULL, NULL, NULL, NULL +}; + +const device_t sc11487_ramdac_device = +{ + "Sierra SC11487 RAMDAC", + 0, 1, + sc1148x_ramdac_init, sc1148x_ramdac_close, + NULL, NULL, NULL, NULL +}; diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 122ed8daf..bd90c39fe 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -690,7 +690,8 @@ VIDOBJ := video.o \ vid_av9194.o \ vid_icd2061.o vid_ics2595.o \ vid_cl54xx.o \ - vid_et4000.o vid_sc1502x_ramdac.o \ + vid_et4000.o vid_sc1148x_ramdac.o \ + vid_sc1502x_ramdac.o \ vid_et4000w32.o vid_stg_ramdac.o \ vid_ht216.o \ vid_oak_oti.o \