diff --git a/src/video/vid_bt485_ramdac.c b/src/video/vid_bt485_ramdac.c index fefba5a42..f6cbfd7ec 100644 --- a/src/video/vid_bt485_ramdac.c +++ b/src/video/vid_bt485_ramdac.c @@ -6,10 +6,10 @@ * * This file is part of the 86Box distribution. * - * Brooktree BT485 true colour RAMDAC emulation. + * Emulation of the Brooktree BT485 and BT485A true colour + * RAM DAC's. * - * - * Version: @(#)vid_bt485_ramdac.c 1.0.6 2018/10/02 + * Version: @(#)vid_bt485_ramdac.c 1.0.7 2018/10/03 * * Authors: Miran Grca, * TheCollector1995, @@ -106,7 +106,6 @@ bt485_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt485_ramdac_t *r break; case 0x06: /* Command Register 0 (RS value = 0110) */ ramdac->cr0 = val; - ramdac->set_reg0a = !!(val & 0x80); svga->ramdac_type = (val & 0x01) ? RAMDAC_8BIT : RAMDAC_6BIT; break; case 0x08: /* Command Register 1 (RS value = 1000) */ @@ -119,11 +118,9 @@ bt485_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt485_ramdac_t *r bt485_set_bpp(ramdac, svga); break; case 0x0a: - switch (ramdac->set_reg0a) { - case 0: /* Status Register (RS value = 1010) */ - break; - - case 1: /* Command Register 3 (RS value = 1010) */ + if (ramdac->cr0 & 0x80) { + if ((ramdac->type == BT485) || (svga->dac_pos == 1)) { + /* Command Register 3 (RS value = 1010) */ ramdac->cr3 = val; svga->hwcursor.xsize = svga->hwcursor.ysize = (val & 4) ? 64 : 32; svga->hwcursor.yoff = (svga->hwcursor.ysize == 32) ? 32 : 0; @@ -132,7 +129,8 @@ bt485_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt485_ramdac_t *r if (svga->hwcursor.xsize == 64) svga->dac_pos = (svga->dac_pos & 0x00ff) | ((val & 0x03) << 8); svga_recalctimings(svga); - break; + } else if (svga->dac_pos == 2) + ramdac->cr4 = val; } break; case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */ @@ -212,10 +210,20 @@ bt485_ramdac_in(uint16_t addr, int rs2, int rs3, bt485_ramdac_t *ramdac, svga_t temp = ramdac->cr2; break; case 0x0a: - if (ramdac->set_reg0a) - temp = ramdac->cr3; - else - temp = 0x60; /*Bt485*/ + if (ramdac->cr0 & 0x80) { + if ((ramdac->type == BT485) || (svga->dac_pos == 1)) + temp = ramdac->cr3; + else if (svga->dac_pos == 2) + temp = ramdac->cr4; + else if ((svga->dac_pos & 0xf0) == 0x20) { + /* TODO: Red, Green, and Blue Signature Analysis Registers */ + temp = 0xff; + } + } else + if (ramdac->type == BT485) + temp = 0x60; /*Bt485*/ + else + temp = 0x20; /*Bt485A*/ /* Datasheet says bits 7,6 = 01, bits 5,4 = revision */ break; case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */ @@ -245,3 +253,9 @@ bt485_ramdac_in(uint16_t addr, int rs2, int rs3, bt485_ramdac_t *ramdac, svga_t return temp; } + +void bt485_init(bt485_ramdac_t *ramdac, uint8_t type) +{ + memset(ramdac, 0, sizeof(bt485_ramdac_t)); + ramdac->type = type; +} diff --git a/src/video/vid_bt485_ramdac.h b/src/video/vid_bt485_ramdac.h index 14ec3eae3..dbd899101 100644 --- a/src/video/vid_bt485_ramdac.h +++ b/src/video/vid_bt485_ramdac.h @@ -1,20 +1,42 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ +/* + * 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. + * + * Header of the emulation of the Brooktree BT485 and BT485A + * true colour RAM DAC's. + * + * Version: @(#)vid_bt485_ramdac.h 1.0.0 2018/10/03 + * + * Authors: Miran Grca, + * TheCollector1995, + * + * Copyright 2016-2018 Miran Grca. + * Copyright 2018 TheCollector1995. + */ typedef struct bt485_ramdac_t { PALETTE extpal; uint32_t extpallook[256]; uint8_t cursor32_data[256]; uint8_t cursor64_data[1024]; - int set_reg0a; int hwc_y, hwc_x; uint8_t cr0; uint8_t cr1; uint8_t cr2; uint8_t cr3; + uint8_t cr4; + uint8_t type; } bt485_ramdac_t; -void bt485_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt485_ramdac_t *ramdac, svga_t *svga); -uint8_t bt485_ramdac_in(uint16_t addr, int rs2, int rs3, bt485_ramdac_t *ramdac, svga_t *svga); +enum { + BT485 = 0, + BT485A +}; +extern void bt485_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt485_ramdac_t *ramdac, svga_t *svga); +extern uint8_t bt485_ramdac_in(uint16_t addr, int rs2, int rs3, bt485_ramdac_t *ramdac, svga_t *svga); +extern void bt485_init(bt485_ramdac_t *ramdac, uint8_t type); diff --git a/src/video/vid_icd2061.c b/src/video/vid_icd2061.c index 82d55242f..70576d929 100644 --- a/src/video/vid_icd2061.c +++ b/src/video/vid_icd2061.c @@ -7,10 +7,14 @@ * This file is part of the 86Box distribution. * * ICD2061 clock generator emulation. + * Also emulates the ICS9161 which is the same as the ICD2016, + * but without the need for tuning (which is irrelevant in + * emulation anyway). * - * Used by ET4000w32/p (Diamond Stealth 32) + * Used by ET4000w32/p (Diamond Stealth 32) and the S3 + * Vision964 family. * - * Version: @(#)vid_icd2061.c 1.0.6 2018/10/02 + * Version: @(#)vid_icd2061.c 1.0.7 2018/10/03 * * Authors: Miran Grca, * @@ -27,7 +31,7 @@ void icd2061_write(icd2061_t *icd2061, int val) { int /*od, */nd, oc, nc; - int a/*, i*/, qa, q, pa, p, m; + int a/*, i*/, qa, q, pa, p, m, ps; #if 0 od = (icd2061->state & 2) >> 1; /* Old data. */ @@ -67,17 +71,16 @@ icd2061_write(icd2061_t *icd2061, int val) #if 0 i = ((icd2061->data >> 18) & 0x0f); /* I */ #endif - pa = ((icd2061->data >> 11) & 0x7f); /* P' */ - m = ((icd2061->data >> 8) & 0x07); /* M */ - qa = ((icd2061->data >> 1) & 0x7f); /* Q' */ + pa = ((icd2061->data >> 11) & 0x7f); /* P' (ICD2061) / N' (ICS9161) */ + m = ((icd2061->data >> 8) & 0x07); /* M (ICD2061) / R (ICS9161) */ + qa = ((icd2061->data >> 1) & 0x7f); /* Q' (ICD2061) / M' (ICS9161) */ - p = pa + 3; /* P */ + p = pa + 3; /* P (ICD2061) / N (ICS9161) */ m = 1 << m; - q = qa + 2; /* Q */ + q = qa + 2; /* Q (ICD2061) / M (ICS9161) */ + ps = (icd2061->ctrl & (1 << a)) ? 4 : 2; /* Prescale */ - if (icd2061->ctrl & (1 << a)) - p <<= 1; - icd2061->freq[a] = ((float)p / (float)q) * 2.0 * 14318184.0 / (float)m; + icd2061->freq[a] = ((float)(p * ps) / (float)(q * m)) * 14318184.0f; /* pclog("P = %02X, M = %01X, Q = %02X, freq[%i] = %f\n", p, m, q, a, icd2061->freq[a]); */ } else if (a == 6) { diff --git a/src/video/vid_icd2061.h b/src/video/vid_icd2061.h index b3be37211..60bf24b58 100644 --- a/src/video/vid_icd2061.h +++ b/src/video/vid_icd2061.h @@ -7,10 +7,14 @@ * This file is part of the 86Box distribution. * * ICD2061 clock generator emulation header. + * Also emulates the ICS9161 which is the same as the ICD2016, + * but without the need for tuning (which is irrelevant in + * emulation anyway). * - * Used by ET4000w32/p (Diamond Stealth 32) + * Used by ET4000w32/p (Diamond Stealth 32) and the S3 + * Vision964 family. * - * Version: @(#)vid_icd2061.h 1.0.1 2018/10/02 + * Version: @(#)vid_icd2061.h 1.0.2 2018/10/03 * * Authors: Miran Grca, * @@ -28,3 +32,8 @@ typedef struct icd2061_t void icd2061_write(icd2061_t *icd2061, int val); void icd2061_init(icd2061_t *icd2061); float icd2061_getclock(int clock, void *p); + +/* The code is the same, the #define's are so that the correct name can be used. */ +#define ics9161_write icd2061_write +#define ics9161_init icd2061_init +#define ics9161_getclock icd2061_getclock diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index c039dbc35..5e0729668 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -8,7 +8,7 @@ * * S3 emulation. * - * Version: @(#)vid_s3.c 1.0.22 2018/10/02 + * Version: @(#)vid_s3.c 1.0.23 2018/10/03 * * Authors: Sarah Walker, * Miran Grca, @@ -3057,7 +3057,9 @@ static void *s3_init(const device_t *info) s3->packed_mmio = 1; svga->crtc[0x5a] = 0x0a; + bt485_init(&s3->bt485_ramdac, BT485); icd2061_init(&s3->icd2061); + s3->getclock = icd2061_getclock; s3->getclock_p = &s3->icd2061; break;