From 83b6756b95bc4b27293f12032a4f27f7b360e615 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 1 Oct 2018 23:36:52 +0200 Subject: [PATCH] Rewrote the BT485 RAM DAC emulation - now it's cleaner and follows the correct (BT485 non-A) datasheet. --- src/video/vid_bt485_ramdac.c | 426 +++++++++++++++-------------------- 1 file changed, 176 insertions(+), 250 deletions(-) diff --git a/src/video/vid_bt485_ramdac.c b/src/video/vid_bt485_ramdac.c index c47598eab..32eaa9c6e 100644 --- a/src/video/vid_bt485_ramdac.c +++ b/src/video/vid_bt485_ramdac.c @@ -9,7 +9,7 @@ * Brooktree BT485 true colour RAMDAC emulation. * * - * Version: @(#)vid_bt485_ramdac.c 1.0.4 2018/09/30 + * Version: @(#)vid_bt485_ramdac.c 1.0.5 2018/01/10 * * Authors: Miran Grca, * TheCollector1995, @@ -33,179 +33,138 @@ bt485_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt485_ramdac_t *r { uint32_t o32; uint8_t *cd; + uint8_t rs = (addr & 0x03); + rs |= (!!rs2 << 2); + rs |= (!!rs3 << 3); - switch (addr) { - case 0x3C6: - if (rs2) { - if (rs3) { /*REG0E, Hardware Cursor Y-position*/ - ramdac->hwc_y = (ramdac->hwc_y & 0x0f00) | val; - svga->hwcursor.y = ramdac->hwc_y - svga->hwcursor.ysize; - /* pclog("BT485 0E Y=%d\n", ramdac->hwc_y); */ + switch (rs) { + case 0x00: /* Palette Write Index Register (RS value = 0000) */ + case 0x01: /* Palette Data Register (RS value = 0001) */ + case 0x02: /* Pixel Read Mask Register (RS value = 0010) */ + case 0x03: /* Palette Read Index Register (RS value = 0011) */ + case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */ + case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */ + svga_out(addr, val, svga); + break; + case 0x05: /* Ext Palette Data Register (RS value = 0101) */ + svga->dac_status = 0; + svga->fullchange = changeframecount; + switch (svga->dac_pos) { + case 0: + svga->dac_r = val; + svga->dac_pos++; break; - } else { /*REG06, Command Reg 0*/ - ramdac->cr0 = val; - svga->ramdac_type = (val & 0x01) ? RAMDAC_8BIT : RAMDAC_6BIT; + case 1: + svga->dac_g = val; + svga->dac_pos++; break; - } - } else { - if (rs3) { /*REG0A*/ - switch (ramdac->set_reg0a) { - case 0: /*Status, read-only*/ - break; - - case 1: /*Command Reg 3*/ - ramdac->cr3 = val; - svga->hwcursor.xsize = svga->hwcursor.ysize = (val & 4) ? 64 : 32; - svga->hwcursor.yoff = (svga->hwcursor.ysize == 32) ? 32 : 0; - svga->hwcursor.x = ramdac->hwc_x - svga->hwcursor.xsize; - svga->hwcursor.y = ramdac->hwc_y - svga->hwcursor.ysize; - if (svga->hwcursor.xsize == 64) - svga->dac_pos = (svga->dac_pos & 0x00ff) | ((val & 0x03) << 8); + case 2: + ramdac->extpal[svga->dac_write & 3].r = svga->dac_r; + ramdac->extpal[svga->dac_write & 3].g = svga->dac_g; + ramdac->extpal[svga->dac_write & 3].b = val; + if (svga->ramdac_type == RAMDAC_8BIT) + ramdac->extpallook[svga->dac_write & 3] = makecol32(ramdac->extpal[svga->dac_write].r & 0x3f, ramdac->extpal[svga->dac_write].g & 0x3f, ramdac->extpal[svga->dac_write].b & 0x3f); + else + ramdac->extpallook[svga->dac_write & 3] = makecol32(video_6to8[ramdac->extpal[svga->dac_write].r & 0x3f], video_6to8[ramdac->extpal[svga->dac_write].g & 0x3f], video_6to8[ramdac->extpal[svga->dac_write].b & 0x3f]); + + if ((svga->crtc[0x33] & 0x40) && ((svga->dac_write & 3) == 0)) { + o32 = svga->overscan_color; + svga->overscan_color = ramdac->extpallook[0]; + if (o32 != svga->overscan_color) svga_recalctimings(svga); - break; } - break; - } else { /*REG02*/ - svga_out(addr, val, svga); - break; - } - } - break; - - case 0x3C7: - if (!rs2 && !rs3) { /*REG03*/ - svga_out(addr, val, svga); - break; - } else if (rs2 && !rs3) { /*REG07, Cursor/Overscan Read Address*/ - svga->dac_read = val; - svga->dac_pos = 0; - break; - } else if (!rs2 && rs3) { /*REG0B, Cursor Ram Data*/ - if (svga->hwcursor.xsize == 64) - cd = (uint8_t *) ramdac->cursor64_data; - else - cd = (uint8_t *) ramdac->cursor32_data; - - cd[svga->dac_pos] = val; - svga->dac_pos++; - if (svga->hwcursor.xsize == 32) - svga->dac_pos &= 0x00ff; - else - svga->dac_pos &= 0x03ff; - break; - } else { /*REG0F, Hardware Cursor Y-position*/ - ramdac->hwc_y = (ramdac->hwc_y & 0x00ff) | ((val & 0x0f) << 8); - svga->hwcursor.y = ramdac->hwc_y - svga->hwcursor.ysize; - /* pclog("BT485 0F Y=%d\n", ramdac->hwc_y); */ - break; - } - break; - - case 0x3C8: - ramdac->set_reg0a = (ramdac->cr0 & 0x80) ? 1 : 0; - if (rs2) { - if (rs3) { /*REG0C, Hardware Cursor X-position*/ - ramdac->hwc_x = (ramdac->hwc_x & 0x0f00) | val; - svga->hwcursor.x = ramdac->hwc_x - svga->hwcursor.xsize; - /* pclog("BT485 0C X=%d\n", ramdac->hwc_x); */ - break; - } - else { /*REG04, Cursor/Overscan Write Address*/ - svga->dac_write = val; - svga->dac_read = val - 1; + svga->dac_write = (svga->dac_write + 1) & 15; svga->dac_pos = 0; break; - } - } else { - if (rs3) { /*REG08, Command Reg 1*/ - ramdac->cr1 = val; - switch (val >> 5) { - case 0: - if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) - svga->bpp = 32; - else - svga->bpp = 8; - break; - - case 1: - if (ramdac->cr1 & 8) - svga->bpp = 16; - else - svga->bpp = 15; - break; - - case 2: - svga->bpp = 8; - break; - - case 3: - svga->bpp = 4; - break; - } - svga_recalctimings(svga); - break; - } - else { /*REG00*/ - svga_out(addr, val, svga); - break; - } } break; - - case 0x3C9: - if (rs2) { - if (rs3) { /*REG0D, Hardware Cursor X-position*/ - ramdac->hwc_x = (ramdac->hwc_x & 0x00ff) | ((val & 0x0f) << 8); - svga->hwcursor.x = ramdac->hwc_x - svga->hwcursor.xsize; - /* pclog("BT485 0D X=%d\n", ramdac->hwc_x); */ + 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) */ + ramdac->cr1 = val; + switch ((val >> 5) & 0x03) { + case 0: + if (val & 0x10) + svga->bpp = 32; + else + svga->bpp = 8; + break; + + case 1: + if (val & 0x10) { + if (val & 0x08) + svga->bpp = 16; + else + svga->bpp = 15; + } else + svga->bpp = 8; + break; + + case 2: + svga->bpp = 8; + break; + + case 3: + svga->bpp = 4; break; - } else { /*REG05, Cursor/Overscan Data*/ - svga->dac_status = 0; - svga->fullchange = changeframecount; - switch (svga->dac_pos) { - case 0: - svga->dac_r = val; - svga->dac_pos++; - break; - case 1: - svga->dac_g = val; - svga->dac_pos++; - break; - case 2: - ramdac->extpal[svga->dac_write].r = svga->dac_r; - ramdac->extpal[svga->dac_write].g = svga->dac_g; - ramdac->extpal[svga->dac_write].b = val; - if (svga->ramdac_type == RAMDAC_8BIT) - ramdac->extpallook[svga->dac_write & 3] = makecol32(ramdac->extpal[svga->dac_write].r & 0x3f, ramdac->extpal[svga->dac_write].g & 0x3f, ramdac->extpal[svga->dac_write].b & 0x3f); - else - ramdac->extpallook[svga->dac_write & 3] = makecol32(video_6to8[ramdac->extpal[svga->dac_write].r & 0x3f], video_6to8[ramdac->extpal[svga->dac_write].g & 0x3f], video_6to8[ramdac->extpal[svga->dac_write].b & 0x3f]); - - if ((svga->crtc[0x33] & 0x40) && ((svga->dac_write & 3) == 0)) { - o32 = svga->overscan_color; - svga->overscan_color = ramdac->extpallook[0]; - if (o32 != svga->overscan_color) - svga_recalctimings(svga); - } - svga->dac_write = (svga->dac_write + 1) & 15; - svga->dac_pos = 0; - break; - } - break; - } } - else { - if (rs3) { /*REG09, Command Reg 2*/ - ramdac->cr2 = val; - svga->hwcursor.ena = ramdac->cr2 & 0x03; + svga_recalctimings(svga); + break; + case 0x09: /* Command Register 2 (RS value = 1001) */ + ramdac->cr2 = val; + svga->hwcursor.ena = !!(val & 0x03); + svga_recalctimings(svga); + break; + case 0x0a: + switch (ramdac->set_reg0a) { + case 0: /* Status Register (RS value = 1010) */ + break; + + case 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; + svga->hwcursor.x = ramdac->hwc_x - svga->hwcursor.xsize; + svga->hwcursor.y = ramdac->hwc_y - svga->hwcursor.ysize; + if (svga->hwcursor.xsize == 64) + svga->dac_pos = (svga->dac_pos & 0x00ff) | ((val & 0x03) << 8); svga_recalctimings(svga); break; - } else { /*REG01*/ - svga_out(addr, val, svga); - break; - } } break; + case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */ + if (svga->hwcursor.xsize == 64) + cd = (uint8_t *) ramdac->cursor64_data; + else + cd = (uint8_t *) ramdac->cursor32_data; + cd[svga->dac_pos] = val; + svga->dac_pos++; + if (svga->hwcursor.xsize == 32) + svga->dac_pos &= 0x00ff; + else + svga->dac_pos &= 0x03ff; + break; + case 0x0c: /* Cursor X Low Register (RS value = 1100) */ + ramdac->hwc_x = (ramdac->hwc_x & 0x0f00) | val; + svga->hwcursor.x = ramdac->hwc_x - svga->hwcursor.xsize; + break; + case 0x0d: /* Cursor X High Register (RS value = 1101) */ + ramdac->hwc_x = (ramdac->hwc_x & 0x00ff) | ((val & 0x0f) << 8); + svga->hwcursor.x = ramdac->hwc_x - svga->hwcursor.xsize; + break; + case 0x0e: /* Cursor Y Low Register (RS value = 1110) */ + ramdac->hwc_y = (ramdac->hwc_y & 0x0f00) | val; + svga->hwcursor.y = ramdac->hwc_y - svga->hwcursor.ysize; + break; + case 0x0f: /* Cursor Y High Register (RS value = 1111) */ + ramdac->hwc_y = (ramdac->hwc_y & 0x00ff) | ((val & 0x0f) << 8); + svga->hwcursor.y = ramdac->hwc_y - svga->hwcursor.ysize; + break; } + return; } @@ -215,105 +174,72 @@ bt485_ramdac_in(uint16_t addr, int rs2, int rs3, bt485_ramdac_t *ramdac, svga_t { uint8_t temp = 0xff; uint8_t *cd; + uint8_t rs = (addr & 0x03); + rs |= (!!rs2 << 2); + rs |= (!!rs3 << 3); - switch (addr) { - case 0x3C6: - if (rs2) { - if (rs3) /*REG0E, Hardware Cursor Y-position, write only*/ - return 0xff; - else /*REG06, Command Reg 0*/ - return ramdac->cr0; - } else { - if (rs3) { /*REG0A*/ - switch (ramdac->set_reg0a) { - case 0: /*Status, read-only*/ - return 0x0b; /*Bt485*/ - - case 1: /*Command Reg 3*/ - if (ramdac->cr2 & 4) { - if (ramdac->cr3 & 2) - temp = 0xa9; - else - temp = 0xa8; - } else - temp = ramdac->cr3; - temp &= 0xfc; - if (svga->hwcursor.xsize == 64) - temp |= (svga->dac_pos >> 8) & 0x03; - return temp; - } - return 0xff; - } else /*REG02*/ - return svga_in(addr, svga); - } + switch (rs) { + case 0x00: /* Palette Write Index Register (RS value = 0000) */ + case 0x01: /* Palette Data Register (RS value = 0001) */ + case 0x02: /* Pixel Read Mask Register (RS value = 0010) */ + case 0x03: /* Palette Read Index Register (RS value = 0011) */ + case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */ + case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */ + temp = svga_in(addr, svga); break; - - case 0x3C7: - if (rs2) { - if (rs3) /*REG0F, Hardware Cursor Y-position, write only*/ - return 0xff; - else /*REG07, Cursor/Overscan Read Address*/ - return svga->dac_status; - } else { - if (rs3) { /*REG0B, Cursor Ram Data*/ - if (svga->hwcursor.xsize == 64) - cd = (uint8_t *) ramdac->cursor64_data; - else - cd = (uint8_t *) ramdac->cursor32_data; - - temp = cd[svga->dac_pos]; + case 0x05: /* Ext Palette Data Register (RS value = 0101) */ + svga->dac_status = 0; + switch (svga->dac_pos) { + case 0: svga->dac_pos++; - if (svga->hwcursor.xsize == 32) - svga->dac_pos &= 0x00ff; - else - svga->dac_pos &= 0x03ff; - return temp; - } else /*REG03*/ - return svga_in(addr, svga); + temp = ramdac->extpal[svga->dac_read].r & 0x3f; + case 1: + svga->dac_pos++; + temp = ramdac->extpal[svga->dac_read].g & 0x3f; + case 2: + svga->dac_pos=0; + svga->dac_read = (svga->dac_read + 1) & 15; + temp = ramdac->extpal[(svga->dac_read - 1) & 15].b & 0x3f; } break; - - case 0x3C8: - if (rs2) { - if (rs3) /*REG0C, Hardware Cursor X-position, write only*/ - return 0xff; - else /*REG04, Cursor/Overscan Write Address*/ - return svga->dac_write; - } else { - if (rs3) /*REG08, Command Reg 1*/ - return ramdac->cr1; - else /*REG00*/ - return svga_in(addr, svga); - } + case 0x06: /* Command Register 0 (RS value = 0110) */ + temp = ramdac->cr0; break; + case 0x08: /* Command Register 1 (RS value = 1000) */ + temp = ramdac->cr1; + break; + case 0x09: /* Command Register 2 (RS value = 1001) */ + temp = ramdac->cr2; + break; + case 0x0a: + if (ramdac->set_reg0a) + temp = ramdac->cr3; + else + temp = 0x60; /*Bt485*/ + /* Datasheet says bits 7,6 = 01, bits 5,4 = revision */ + break; + case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */ + if (svga->hwcursor.xsize == 64) + cd = (uint8_t *) ramdac->cursor64_data; + else + cd = (uint8_t *) ramdac->cursor32_data; - case 0x3C9: - if (rs2) { - if (rs3) /*REG0D, Hardware Cursor X-position, write only*/ - return 0xff; - else { /*REG05, Cursor/Overscan Data*/ - svga->dac_status = 0; - switch (svga->dac_pos) { - case 0: - svga->dac_pos++; - return ramdac->extpal[svga->dac_read].r & 0x3f; - case 1: - svga->dac_pos++; - return ramdac->extpal[svga->dac_read].g & 0x3f; - case 2: - svga->dac_pos=0; - svga->dac_read = (svga->dac_read + 1) & 15; - return ramdac->extpal[(svga->dac_read - 1) & 15].b & 0x3f; - - } - return 0xff; - } - } else { - if (rs3) /*REG09, Command Reg 2*/ - return ramdac->cr2; - else /*REG01*/ - return svga_in(addr, svga); - } + temp = cd[svga->dac_pos]; + svga->dac_pos++; + + svga->dac_pos &= ((svga->hwcursor.xsize == 64) ? 0x03ff : 0x00ff); + break; + case 0x0c: /* Cursor X Low Register (RS value = 1100) */ + temp = ramdac->hwc_x & 0xff; + break; + case 0x0d: /* Cursor X High Register (RS value = 1101) */ + temp = (ramdac->hwc_x >> 8) & 0xff; + break; + case 0x0e: /* Cursor Y Low Register (RS value = 1110) */ + temp = ramdac->hwc_y & 0xff; + break; + case 0x0f: /* Cursor Y High Register (RS value = 1111) */ + temp = (ramdac->hwc_y >> 8) & 0xff; break; }