From f81574b419dfecafc6a14bc00599ee761450a886 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 5 Oct 2018 01:54:54 +0200 Subject: [PATCH] Reworked the RAMDAC and clock chip initialization - now they're all device_t's; Moved the BT48x hardware cursor draw function to the RAMDAC's code where it belongs; Renamed the BT48x RAMDAC code file to vid_bt48x_ramdac.c (was vid_bt485_ramdac.c); Fixed BT48x 64x64 hardware cursor bugs (caused by the index variable being uint8_t when it should have been uint16_t) introduced in the previous commit. --- src/video/vid_ati28800.c | 17 +- src/video/vid_ati68860_ramdac.c | 306 +++++++++------- src/video/vid_ati68860_ramdac.h | 48 ++- src/video/vid_ati_mach64.c | 63 ++-- ...{vid_bt485_ramdac.c => vid_bt48x_ramdac.c} | 238 +++++++++--- ...{vid_bt485_ramdac.h => vid_bt48x_ramdac.h} | 28 +- src/video/vid_cl54xx.c | 11 +- src/video/vid_et4000.c | 9 +- src/video/vid_et4000w32.c | 30 +- src/video/vid_icd2061.c | 57 ++- src/video/vid_icd2061.h | 7 +- src/video/vid_ics2595.c | 102 ++++-- src/video/vid_ics2595.h | 36 +- src/video/vid_s3.c | 160 ++------- src/video/vid_sc1502x_ramdac.c | 196 ++++++---- src/video/vid_sc1502x_ramdac.h | 35 +- src/video/vid_sdac_ramdac.c | 321 ++++++++++------- src/video/vid_sdac_ramdac.h | 41 ++- src/video/vid_stg_ramdac.c | 338 +++++++++++------- src/video/vid_stg_ramdac.h | 36 +- src/video/vid_svga.c | 13 +- src/video/vid_svga.h | 100 +++--- src/video/vid_tgui9440.c | 213 +++++------ src/video/vid_tkd8001_ramdac.c | 134 ++++--- src/video/vid_tkd8001_ramdac.h | 31 +- src/video/vid_tvga.c | 11 +- src/win/Makefile.mingw | 4 +- 27 files changed, 1514 insertions(+), 1071 deletions(-) rename src/video/{vid_bt485_ramdac.c => vid_bt48x_ramdac.c} (63%) rename src/video/{vid_bt485_ramdac.h => vid_bt48x_ramdac.h} (51%) diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index cfb9f2d64..36f5c222d 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -8,7 +8,7 @@ * * ATI 28800 emulation (VGA Charger and Korean VGA) * - * Version: @(#)vid_ati28800.c 1.0.24 2018/10/02 + * Version: @(#)vid_ati28800.c 1.0.25 2018/10/04 * * Authors: Sarah Walker, * Miran Grca, @@ -61,7 +61,6 @@ typedef struct ati28800_t { svga_t svga; ati_eeprom_t eeprom; - sc1502x_ramdac_t ramdac; rom_t bios_rom; @@ -172,9 +171,9 @@ static void ati28800_out(uint16_t addr, uint8_t val, void *p) break; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - sc1502x_ramdac_out(addr, val, &ati28800->ramdac, svga); + sc1502x_ramdac_out(addr, val, svga->ramdac, svga); return; - + case 0x3D4: svga->crtcreg = val & 0x3f; return; @@ -315,8 +314,8 @@ static uint8_t ati28800_in(uint16_t addr, void *p) break; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - return sc1502x_ramdac_in(addr, &ati28800->ramdac, svga); - + return sc1502x_ramdac_in(addr, svga->ramdac, svga); + case 0x3D4: temp = svga->crtcreg; break; @@ -474,6 +473,8 @@ ati28800k_init(const device_t *info) NULL, NULL); + ati28800->svga.ramdac = device_add(&sc1502x_ramdac_device); + io_sethandler(0x01ce, 0x0002, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); io_sethandler(0x03c0, 0x0020, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); @@ -530,7 +531,9 @@ ati28800_init(const device_t *info) ati28800_recalctimings, ati28800_in, ati28800_out, NULL, - NULL); + NULL); + + ati28800->svga.ramdac = device_add(&sc1502x_ramdac_device); io_sethandler(0x01ce, 2, ati28800_in, NULL, NULL, diff --git a/src/video/vid_ati68860_ramdac.c b/src/video/vid_ati68860_ramdac.c index acf654d37..c764d40fe 100644 --- a/src/video/vid_ati68860_ramdac.c +++ b/src/video/vid_ati68860_ramdac.c @@ -28,7 +28,7 @@ * 7 If set can remove "snow" in some cases * (A860_Delay_L ?) ?? * - * Version: @(#)vid_ati68860.c 1.0.4 2018/10/04 + * Version: @(#)vid_ati68860.c 1.0.5 2018/10/04 * * Authors: Sarah Walker, * Miran Grca, @@ -38,9 +38,11 @@ */ #include #include +#include #include #include #include "../86box.h" +#include "../device.h" #include "../mem.h" #include "video.h" #include "vid_svga.h" @@ -48,150 +50,180 @@ #include "vid_svga_render.h" -void ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac, svga_t *svga) +void +ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac, svga_t *svga) { - switch (addr) - { - case 0: - svga_out(0x3c8, val, svga); - break; - case 1: - svga_out(0x3c9, val, svga); - break; - case 2: - svga_out(0x3c6, val, svga); - break; - case 3: - svga_out(0x3c7, val, svga); - break; - default: - ramdac->regs[addr & 0xf] = val; - switch (addr & 0xf) - { - case 0x4: - ramdac->dac_addr = val; - ramdac->dac_pos = 0; - break; - case 0x5: - switch (ramdac->dac_pos) - { - case 0: - ramdac->dac_r = val; - ramdac->dac_pos++; - break; - case 1: - ramdac->dac_g = val; - ramdac->dac_pos++; - break; - case 2: - if (ramdac->dac_addr > 1) - break; - ramdac->pal[ramdac->dac_addr].r = ramdac->dac_r; - ramdac->pal[ramdac->dac_addr].g = ramdac->dac_g; - ramdac->pal[ramdac->dac_addr].b = val; - if (ramdac->ramdac_type == RAMDAC_8BIT) - ramdac->pallook[ramdac->dac_addr] = makecol32(ramdac->pal[ramdac->dac_addr].r, ramdac->pal[ramdac->dac_addr].g, ramdac->pal[ramdac->dac_addr].b); - else - ramdac->pallook[ramdac->dac_addr] = makecol32((ramdac->pal[ramdac->dac_addr].r & 0x3f) * 4, (ramdac->pal[ramdac->dac_addr].g & 0x3f) * 4, (ramdac->pal[ramdac->dac_addr].b & 0x3f) * 4); - ramdac->dac_pos = 0; - ramdac->dac_addr = (ramdac->dac_addr + 1) & 255; - break; - } - break; - - case 0xb: - switch (val) - { - case 0x82: - ramdac->render = svga_render_4bpp_highres; - break; - case 0x83: - ramdac->render = svga_render_8bpp_highres; - break; - case 0xa0: case 0xb0: - ramdac->render = svga_render_15bpp_highres; - break; - case 0xa1: case 0xb1: - ramdac->render = svga_render_16bpp_highres; - break; - case 0xc0: case 0xd0: - ramdac->render = svga_render_24bpp_highres; - break; - case 0xe2: case 0xf7: - ramdac->render = svga_render_32bpp_highres; - break; - case 0xe3: - ramdac->render = svga_render_ABGR8888_highres; - break; - case 0xf2: - ramdac->render = svga_render_RGBA8888_highres; - break; - default: - ramdac->render = svga_render_8bpp_highres; - break; - } - break; - case 0xc: - svga_set_ramdac_type(svga, (val & 1) ? RAMDAC_6BIT : RAMDAC_8BIT); - break; - } - break; - } + switch (addr) { + case 0: + svga_out(0x3c8, val, svga); + break; + case 1: + svga_out(0x3c9, val, svga); + break; + case 2: + svga_out(0x3c6, val, svga); + break; + case 3: + svga_out(0x3c7, val, svga); + break; + default: + ramdac->regs[addr & 0xf] = val; + switch (addr & 0xf) { + case 0x4: + ramdac->dac_addr = val; + ramdac->dac_pos = 0; + break; + case 0x5: + switch (ramdac->dac_pos) { + case 0: + ramdac->dac_r = val; + ramdac->dac_pos++; + break; + case 1: + ramdac->dac_g = val; + ramdac->dac_pos++; + break; + case 2: + if (ramdac->dac_addr > 1) + break; + ramdac->pal[ramdac->dac_addr].r = ramdac->dac_r; + ramdac->pal[ramdac->dac_addr].g = ramdac->dac_g; + ramdac->pal[ramdac->dac_addr].b = val; + if (ramdac->ramdac_type == RAMDAC_8BIT) + ramdac->pallook[ramdac->dac_addr] = makecol32(ramdac->pal[ramdac->dac_addr].r, + ramdac->pal[ramdac->dac_addr].g, + ramdac->pal[ramdac->dac_addr].b); + else + ramdac->pallook[ramdac->dac_addr] = makecol32(video_6to8[ramdac->pal[ramdac->dac_addr].r & 0x3f], + video_6to8[ramdac->pal[ramdac->dac_addr].g & 0x3f], + video_6to8[ramdac->pal[ramdac->dac_addr].b & 0x3f]); + ramdac->dac_pos = 0; + ramdac->dac_addr = (ramdac->dac_addr + 1) & 255; + break; + } + break; + case 0xb: + switch (val) { + case 0x82: + ramdac->render = svga_render_4bpp_highres; + break; + case 0x83: + ramdac->render = svga_render_8bpp_highres; + break; + case 0xa0: case 0xb0: + ramdac->render = svga_render_15bpp_highres; + break; + case 0xa1: case 0xb1: + ramdac->render = svga_render_16bpp_highres; + break; + case 0xc0: case 0xd0: + ramdac->render = svga_render_24bpp_highres; + break; + case 0xe2: case 0xf7: + ramdac->render = svga_render_32bpp_highres; + break; + case 0xe3: + ramdac->render = svga_render_ABGR8888_highres; + break; + case 0xf2: + ramdac->render = svga_render_RGBA8888_highres; + break; + default: + ramdac->render = svga_render_8bpp_highres; + break; + } + break; + case 0xc: + svga_set_ramdac_type(svga, (val & 1) ? RAMDAC_6BIT : RAMDAC_8BIT); + break; + } + break; + } } -uint8_t ati68860_ramdac_in(uint16_t addr, ati68860_ramdac_t *ramdac, svga_t *svga) +uint8_t +ati68860_ramdac_in(uint16_t addr, ati68860_ramdac_t *ramdac, svga_t *svga) { - uint8_t ret = 0; - switch (addr) - { - case 0: - ret = svga_in(0x3c8, svga); - break; - case 1: - ret = svga_in(0x3c9, svga); - break; - case 2: - ret = svga_in(0x3c6, svga); - break; - case 3: - ret = svga_in(0x3c7, svga); - break; - case 4: case 8: - ret = 2; - break; - case 6: case 0xa: - ret = 0x1d; - break; - case 0xf: - ret = 0xd0; - break; - - default: - ret = ramdac->regs[addr & 0xf]; - break; - } - return ret; + uint8_t temp = 0; + + switch (addr) { + case 0: + temp = svga_in(0x3c8, svga); + break; + case 1: + temp = svga_in(0x3c9, svga); + break; + case 2: + temp = svga_in(0x3c6, svga); + break; + case 3: + temp = svga_in(0x3c7, svga); + break; + case 4: case 8: + temp = 2; + break; + case 6: case 0xa: + temp = 0x1d; + break; + case 0xf: + temp = 0xd0; + break; + + default: + temp = ramdac->regs[addr & 0xf]; + break; + } + + return temp; } -void ati68860_ramdac_init(ati68860_ramdac_t *ramdac) + +void +ati68860_set_ramdac_type(ati68860_ramdac_t *ramdac, int type) { - ramdac->render = svga_render_8bpp_highres; + int c; + + if (ramdac->ramdac_type != type) { + ramdac->ramdac_type = type; + + for (c = 0; c < 2; c++) { + if (ramdac->ramdac_type == RAMDAC_8BIT) + ramdac->pallook[c] = makecol32(ramdac->pal[c].r, ramdac->pal[c].g, + ramdac->pal[c].b); + else + ramdac->pallook[c] = makecol32(video_6to8[ramdac->pal[c].r & 0x3f], video_6to8[ramdac->pal[c].g & 0x3f], + video_6to8[ramdac->pal[c].b & 0x3f]); + } + } } -void ati68860_set_ramdac_type(ati68860_ramdac_t *ramdac, int type) + +static void * +ati68860_ramdac_init(const device_t *info) { - int c; - - if (ramdac->ramdac_type != type) - { - ramdac->ramdac_type = type; - - for (c = 0; c < 2; c++) - { - if (ramdac->ramdac_type == RAMDAC_8BIT) - ramdac->pallook[c] = makecol32(ramdac->pal[c].r, ramdac->pal[c].g, ramdac->pal[c].b); - else - ramdac->pallook[c] = makecol32((ramdac->pal[c].r & 0x3f) * 4, (ramdac->pal[c].g & 0x3f) * 4, (ramdac->pal[c].b & 0x3f) * 4); - } - } + ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) malloc(sizeof(ati68860_ramdac_t)); + memset(ramdac, 0, sizeof(ati68860_ramdac_t)); + + ramdac->render = svga_render_8bpp_highres; + + return ramdac; } + + +static void +ati68860_ramdac_close(void *priv) +{ + ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) priv; + + if (ramdac) + free(ramdac); +} + + +const device_t ati68860_ramdac_device = +{ + "ATI-68860 RAMDAC", + 0, 0, + ati68860_ramdac_init, ati68860_ramdac_close, + NULL, NULL, NULL, NULL +}; diff --git a/src/video/vid_ati68860_ramdac.h b/src/video/vid_ati68860_ramdac.h index 27196493e..33e59ebc3 100644 --- a/src/video/vid_ati68860_ramdac.h +++ b/src/video/vid_ati68860_ramdac.h @@ -1,20 +1,36 @@ -/* Copyright holders: Sarah Walker - 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. + * + * ATI 68860 RAMDAC emulation header (for Mach64) + * + * Version: @(#)vid_ati68860.h 1.0.0 2018/10/04 + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + */ typedef struct ati68860_ramdac_t { - uint8_t regs[16]; - void (*render)(struct svga_t *svga); - - int dac_addr, dac_pos; - int dac_r, dac_g; - PALETTE pal; - uint32_t pallook[2]; - - int ramdac_type; + uint8_t regs[16]; + void (*render)(struct svga_t *svga); + + int dac_addr, dac_pos; + int dac_r, dac_g; + PALETTE pal; + uint32_t pallook[2]; + + int ramdac_type; } ati68860_ramdac_t; -void ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac, svga_t *svga); -uint8_t ati68860_ramdac_in(uint16_t addr, ati68860_ramdac_t *ramdac, svga_t *svga); -void ati68860_ramdac_init(ati68860_ramdac_t *ramdac); -void ati68860_set_ramdac_type(ati68860_ramdac_t *ramdac, int type); +extern void ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac, svga_t *svga); +extern uint8_t ati68860_ramdac_in(uint16_t addr, ati68860_ramdac_t *ramdac, svga_t *svga); +extern void ati68860_set_ramdac_type(ati68860_ramdac_t *ramdac, int type); + +extern const device_t ati68860_ramdac_device; diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index 7e014eeef..b34f31251 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -8,7 +8,7 @@ * * ATi Mach64 graphics card emulation. * - * Version: @(#)vid_ati_mach64.c 1.0.24 2018/10/02 + * Version: @(#)vid_ati_mach64.c 1.0.25 2018/10/04 * * Authors: Sarah Walker, * Miran Grca, @@ -85,9 +85,7 @@ typedef struct mach64_t mem_mapping_t mmio_linear_mapping; mem_mapping_t mmio_linear_mapping_2; - ati68860_ramdac_t ramdac; ati_eeprom_t eeprom; - ics2595_t ics2595; svga_t svga; rom_t bios_rom; @@ -386,7 +384,7 @@ void mach64_out(uint16_t addr, uint8_t val, void *p) case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: if (mach64->type == MACH64_GX) - ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, svga); + ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, mach64->svga.ramdac, svga); else svga_out(addr, val, svga); return; @@ -445,7 +443,7 @@ uint8_t mach64_in(uint16_t addr, void *p) case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: if (mach64->type == MACH64_GX) - return ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, svga); + return ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), mach64->svga.ramdac, svga); return svga_in(addr, svga); case 0x3D4: @@ -461,7 +459,9 @@ uint8_t mach64_in(uint16_t addr, void *p) void mach64_recalctimings(svga_t *svga) { mach64_t *mach64 = (mach64_t *)svga->p; - + ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) svga->ramdac; + ics2595_t *clock_gen = (ics2595_t *) svga->clock_gen; + if (((mach64->crtc_gen_cntl >> 24) & 3) == 3) { svga->vtotal = (mach64->crtc_v_total_disp & 2047) + 1; @@ -470,7 +470,7 @@ void mach64_recalctimings(svga_t *svga) svga->hdisp_time = svga->hdisp = ((mach64->crtc_h_total_disp >> 16) & 255) + 1; svga->vsyncstart = (mach64->crtc_v_sync_strt_wid & 2047) + 1; svga->rowoffset = (mach64->crtc_off_pitch >> 22); - svga->clock = cpuclock / mach64->ics2595.output_clock; + svga->clock = cpuclock / clock_gen->output_clock; svga->ma_latch = (mach64->crtc_off_pitch & 0x1fffff) * 2; svga->linedbl = svga->rowcount = 0; svga->split = 0xffffff; @@ -478,7 +478,7 @@ void mach64_recalctimings(svga_t *svga) svga->rowcount = mach64->crtc_gen_cntl & 1; svga->rowoffset <<= 1; if (mach64->type == MACH64_GX) - svga->render = mach64->ramdac.render; + svga->render = ramdac->render; switch ((mach64->crtc_gen_cntl >> 8) & 7) { case 1: @@ -1713,6 +1713,8 @@ static void mach64_vblank_start(svga_t *svga) uint8_t mach64_ext_readb(uint32_t addr, void *p) { mach64_t *mach64 = (mach64_t *)p; + ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) mach64->svga.ramdac; + uint8_t ret; if (!(addr & 0x400)) { @@ -1837,9 +1839,9 @@ uint8_t mach64_ext_readb(uint32_t addr, void *p) case 0xc0: case 0xc1: case 0xc2: case 0xc3: if (mach64->type == MACH64_GX) - ret = ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, &mach64->svga); + ret = ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), ramdac, &mach64->svga); else - ret = ati68860_ramdac_in(addr & 3, &mach64->ramdac, &mach64->svga); + ret = ati68860_ramdac_in(addr & 3, ramdac, &mach64->svga); break; case 0xc4: case 0xc5: case 0xc6: case 0xc7: if (mach64->type == MACH64_VT2) @@ -2133,6 +2135,8 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) { mach64_t *mach64 = (mach64_t *)p; svga_t *svga = &mach64->svga; + ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) svga->ramdac; + ics2595_t *clock_gen = (ics2595_t *) svga->clock_gen; mach64_log("mach64_ext_writeb : addr %08X val %02X\n", addr, val); @@ -2249,12 +2253,12 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) case 0x60: case 0x61: case 0x62: case 0x63: WRITE8(addr, mach64->cur_clr0, val); if (mach64->type == MACH64_VT2) - mach64->ramdac.pallook[0] = makecol32((mach64->cur_clr0 >> 24) & 0xff, (mach64->cur_clr0 >> 16) & 0xff, (mach64->cur_clr0 >> 8) & 0xff); + ramdac->pallook[0] = makecol32((mach64->cur_clr0 >> 24) & 0xff, (mach64->cur_clr0 >> 16) & 0xff, (mach64->cur_clr0 >> 8) & 0xff); break; case 0x64: case 0x65: case 0x66: case 0x67: WRITE8(addr, mach64->cur_clr1, val); if (mach64->type == MACH64_VT2) - mach64->ramdac.pallook[1] = makecol32((mach64->cur_clr1 >> 24) & 0xff, (mach64->cur_clr1 >> 16) & 0xff, (mach64->cur_clr1 >> 8) & 0xff); + ramdac->pallook[1] = makecol32((mach64->cur_clr1 >> 24) & 0xff, (mach64->cur_clr1 >> 16) & 0xff, (mach64->cur_clr1 >> 8) & 0xff); break; case 0x68: case 0x69: case 0x6a: case 0x6b: WRITE8(addr, mach64->cur_offset, val); @@ -2284,11 +2288,11 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) case 0x90: case 0x91: case 0x92: case 0x93: WRITE8(addr, mach64->clock_cntl, val); if (mach64->type == MACH64_GX) - ics2595_write(&mach64->ics2595, val & 0x40, val & 0xf); + ics2595_write(clock_gen, val & 0x40, val & 0xf); else { pll_write(mach64, addr, val); - mach64->ics2595.output_clock = mach64->pll_freq[mach64->clock_cntl & 3]; + clock_gen->output_clock = mach64->pll_freq[mach64->clock_cntl & 3]; } svga_recalctimings(&mach64->svga); break; @@ -2316,14 +2320,14 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) case 0xc0: case 0xc1: case 0xc2: case 0xc3: if (mach64->type == MACH64_GX) - ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, &mach64->svga); + ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, ramdac, &mach64->svga); else - ati68860_ramdac_out(addr & 3, val, &mach64->ramdac, &mach64->svga); + ati68860_ramdac_out(addr & 3, val, ramdac, &mach64->svga); break; case 0xc4: case 0xc5: case 0xc6: case 0xc7: WRITE8(addr, mach64->dac_cntl, val); svga_set_ramdac_type(svga, (mach64->dac_cntl & 0x100) ? RAMDAC_8BIT : RAMDAC_6BIT); - ati68860_set_ramdac_type(&mach64->ramdac, (mach64->dac_cntl & 0x100) ? RAMDAC_8BIT : RAMDAC_6BIT); + ati68860_set_ramdac_type(ramdac, (mach64->dac_cntl & 0x100) ? RAMDAC_8BIT : RAMDAC_6BIT); break; case 0xd0: case 0xd1: case 0xd2: case 0xd3: @@ -2396,7 +2400,9 @@ void mach64_ext_writel(uint32_t addr, uint32_t val, void *p) uint8_t mach64_ext_inb(uint16_t port, void *p) { mach64_t *mach64 = (mach64_t *)p; + ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) mach64->svga.ramdac; uint8_t ret; + switch (port) { case 0x02ec: case 0x02ed: case 0x02ee: case 0x02ef: @@ -2481,9 +2487,9 @@ uint8_t mach64_ext_inb(uint16_t port, void *p) case 0x5eec: case 0x5eed: case 0x5eee: case 0x5eef: if (mach64->type == MACH64_GX) - ret = ati68860_ramdac_in((port & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, &mach64->svga); + ret = ati68860_ramdac_in((port & 3) | ((mach64->dac_cntl & 3) << 2), ramdac, &mach64->svga); else - ret = ati68860_ramdac_in(port & 3, &mach64->ramdac, &mach64->svga); + ret = ati68860_ramdac_in(port & 3, ramdac, &mach64->svga); break; case 0x62ec: case 0x62ed: case 0x62ee: case 0x62ef: @@ -2551,6 +2557,8 @@ uint32_t mach64_ext_inl(uint16_t port, void *p) void mach64_ext_outb(uint16_t port, uint8_t val, void *p) { mach64_t *mach64 = (mach64_t *)p; + ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) mach64->svga.ramdac; + mach64_log("mach64_ext_outb : port %04X val %02X\n", port, val); switch (port) { @@ -2632,9 +2640,9 @@ void mach64_ext_outb(uint16_t port, uint8_t val, void *p) case 0x5eec: case 0x5eed: case 0x5eee: case 0x5eef: if (mach64->type == MACH64_GX) - ati68860_ramdac_out((port & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, &mach64->svga); + ati68860_ramdac_out((port & 3) | ((mach64->dac_cntl & 3) << 2), val, ramdac, &mach64->svga); else - ati68860_ramdac_out(port & 3, val, &mach64->ramdac, &mach64->svga); + ati68860_ramdac_out(port & 3, val, ramdac, &mach64->svga); break; case 0x62ec: case 0x62ed: case 0x62ee: case 0x62ef: @@ -2776,11 +2784,11 @@ uint32_t mach64_readl(uint32_t addr, void *p) void mach64_hwcursor_draw(svga_t *svga, int displine) { - mach64_t *mach64 = (mach64_t *)svga->p; + ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) svga->ramdac; int x, offset; uint8_t dat; - uint32_t col0 = mach64->ramdac.pallook[0]; - uint32_t col1 = mach64->ramdac.pallook[1]; + uint32_t col0 = ramdac->pallook[0]; + uint32_t col1 = ramdac->pallook[1]; int y_add, x_add; y_add = (enable_overscan && !suppress_overscan) ? (overscan_y >> 1) : 0; @@ -3318,9 +3326,10 @@ static void *mach64_common_init(const device_t *info) mach64->pci_regs[0x30] = 0x00; mach64->pci_regs[0x32] = 0x0c; mach64->pci_regs[0x33] = 0x00; - - ati68860_ramdac_init(&mach64->ramdac); - + + mach64->svga.ramdac = device_add(&ati68860_ramdac_device); + mach64->svga.clock_gen = device_add(&ics2595_device); + mach64->dst_cntl = 3; mach64->wake_fifo_thread = thread_create_event(); diff --git a/src/video/vid_bt485_ramdac.c b/src/video/vid_bt48x_ramdac.c similarity index 63% rename from src/video/vid_bt485_ramdac.c rename to src/video/vid_bt48x_ramdac.c index 74b7bec88..021efb9f4 100644 --- a/src/video/vid_bt485_ramdac.c +++ b/src/video/vid_bt48x_ramdac.c @@ -6,10 +6,10 @@ * * This file is part of the 86Box distribution. * - * Emulation of the Brooktree BT485 and BT485A true colour - * RAM DAC's. + * Emulation of the Brooktree BT484-485A true colour RAMDAC + * family. * - * Version: @(#)vid_bt485_ramdac.c 1.0.10 2018/10/04 + * Version: @(#)vid_bt48x_ramdac.c 1.0.11 2018/10/04 * * Authors: Miran Grca, * TheCollector1995, @@ -19,17 +19,28 @@ */ #include #include +#include #include #include #include "../86box.h" +#include "../device.h" #include "../mem.h" #include "video.h" #include "vid_svga.h" -#include "vid_bt485_ramdac.h" +#include "vid_bt48x_ramdac.h" + + +enum { + BT484 = 0, + ATT20C504, + BT485, + ATT20C505, + BT485A +}; static void -bt485_set_bpp(bt485_ramdac_t *ramdac, svga_t *svga) +bt48x_set_bpp(bt48x_ramdac_t *ramdac, svga_t *svga) { if (!(ramdac->cr2 & 0x20)) svga->bpp = 8; @@ -55,32 +66,28 @@ bt485_set_bpp(bt485_ramdac_t *ramdac, svga_t *svga) void -bt485_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt485_ramdac_t *ramdac, svga_t *svga) +bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt48x_ramdac_t *ramdac, svga_t *svga) { uint32_t o32; uint8_t *cd; - uint8_t index; + uint16_t index; uint8_t rs = (addr & 0x03); + uint16_t da_mask = 0x03ff; rs |= (!!rs2 << 2); rs |= (!!rs3 << 3); + if (ramdac->type < BT485) + da_mask = 0x00ff; switch (rs) { case 0x00: /* Palette Write Index Register (RS value = 0000) */ - svga_out(addr, val, svga); - if (ramdac->type >= BT485) - svga->dac_addr |= ((int) (ramdac->cr3 & 0x03) << 8); - break; case 0x03: svga->dac_pos = 0; svga->dac_status = addr & 0x03; svga->dac_addr = val; if (ramdac->type >= BT485) svga->dac_addr |= ((int) (ramdac->cr3 & 0x03) << 8); - svga->dac_addr++; - if (ramdac->type >= BT485) - svga->dac_addr &= 0x3ff; - else - svga->dac_addr &= 0x0ff; + if (svga->dac_status) + svga->dac_addr = (svga->dac_addr + 1) & da_mask; break; case 0x01: /* Palette Data Register (RS value = 0001) */ case 0x02: /* Pixel Read Mask Register (RS value = 0010) */ @@ -114,7 +121,7 @@ bt485_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt485_ramdac_t *r else ramdac->extpallook[index] = makecol32(video_6to8[ramdac->extpal[index].r & 0x3f], video_6to8[ramdac->extpal[index].g & 0x3f], video_6to8[ramdac->extpal[index].b & 0x3f]); - if ((svga->crtc[0x33] & 0x40) && !index) { + if (svga->ext_overscan && !index) { o32 = svga->overscan_color; svga->overscan_color = ramdac->extpallook[0]; if (o32 != svga->overscan_color) @@ -131,12 +138,12 @@ bt485_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt485_ramdac_t *r break; case 0x08: /* Command Register 1 (RS value = 1000) */ ramdac->cr1 = val; - bt485_set_bpp(ramdac, svga); + bt48x_set_bpp(ramdac, svga); break; case 0x09: /* Command Register 2 (RS value = 1001) */ ramdac->cr2 = val; svga->hwcursor.ena = !!(val & 0x03); - bt485_set_bpp(ramdac, svga); + bt48x_set_bpp(ramdac, svga); break; case 0x0a: if ((ramdac->type >= BT485) && (ramdac->cr0 & 0x80)) { @@ -166,19 +173,15 @@ bt485_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt485_ramdac_t *r } break; case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */ - index = svga->dac_addr & 0x03ff; + index = svga->dac_addr & da_mask; if ((ramdac->type >= BT485) && (svga->hwcursor.xsize == 64)) cd = (uint8_t *) ramdac->cursor64_data; - else { - if (ramdac->type < BT485) - index &= 0x00ff; + else cd = (uint8_t *) ramdac->cursor32_data; - } cd[index] = val; - svga->dac_addr++; - svga->dac_addr &= (ramdac->type >= BT485) ? 0x03ff : 0x00ff; + svga->dac_addr = (svga->dac_addr + 1) & da_mask; break; case 0x0c: /* Cursor X Low Register (RS value = 1100) */ ramdac->hwc_x = (ramdac->hwc_x & 0x0f00) | val; @@ -203,14 +206,17 @@ bt485_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt485_ramdac_t *r uint8_t -bt485_ramdac_in(uint16_t addr, int rs2, int rs3, bt485_ramdac_t *ramdac, svga_t *svga) +bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, bt48x_ramdac_t *ramdac, svga_t *svga) { uint8_t temp = 0xff; uint8_t *cd; uint8_t index; uint8_t rs = (addr & 0x03); + uint16_t da_mask = 0x03ff; rs |= (!!rs2 << 2); rs |= (!!rs3 << 3); + if (ramdac->type < BT485) + da_mask = 0x00ff; switch (rs) { case 0x00: /* Palette Write Index Register (RS value = 0000) */ @@ -291,19 +297,15 @@ bt485_ramdac_in(uint16_t addr, int rs2, int rs3, bt485_ramdac_t *ramdac, svga_t temp = ramdac->status | (svga->dac_status ? 0x04 : 0x00); break; case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */ - index = (svga->dac_addr - 1) & 0x03ff; + index = (svga->dac_addr - 1) & da_mask; if ((ramdac->type >= BT485) && (svga->hwcursor.xsize == 64)) cd = (uint8_t *) ramdac->cursor64_data; - else { - if (ramdac->type < BT485) - index &= 0x00ff; + else cd = (uint8_t *) ramdac->cursor32_data; - } temp = cd[index]; - svga->dac_addr++; - svga->dac_addr &= (ramdac->type >= BT485) ? 0x03ff : 0x00ff; + svga->dac_addr = (svga->dac_addr + 1) & da_mask; break; case 0x0c: /* Cursor X Low Register (RS value = 1100) */ temp = ramdac->hwc_x & 0xff; @@ -322,17 +324,116 @@ 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, svga_t *svga, uint8_t type) -{ - memset(ramdac, 0, sizeof(bt485_ramdac_t)); - ramdac->type = type; - if (ramdac->type < BT485) { - /* The BT484 and AT&T 20C504 only have a 32x32 cursor. */ - svga->hwcursor.xsize = svga->hwcursor.ysize = 32; - svga->hwcursor.yoff = 32; +void +bt48x_hwcursor_draw(svga_t *svga, int displine) +{ + int x, xx, comb, b0, b1; + uint16_t dat[2]; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + int y_add, x_add; + int pitch, bppl, mode, x_pos, y_pos; + uint32_t clr1, clr2, clr3, *p; + uint8_t *cd; + bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) svga->ramdac; + + clr1 = ramdac->extpallook[1]; + clr2 = ramdac->extpallook[2]; + clr3 = ramdac->extpallook[3]; + + y_add = (enable_overscan && !suppress_overscan) ? (overscan_y >> 1) : 0; + x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; + + /* The planes come in two parts, and each plane is 1bpp, + so a 32x32 cursor has 4 bytes per line, and a 64x64 + cursor has 8 bytes per line. */ + pitch = (svga->hwcursor_latch.xsize >> 3); /* Bytes per line. */ + /* A 32x32 cursor has 128 bytes per line, and a 64x64 + cursor has 512 bytes per line. */ + bppl = (pitch * svga->hwcursor_latch.ysize); /* Bytes per plane. */ + mode = ramdac->cr2 & 0x03; + + if (svga->interlace && svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += pitch; + + if (svga->hwcursor_latch.xsize == 64) + cd = (uint8_t *) ramdac->cursor64_data; + else + cd = (uint8_t *) ramdac->cursor32_data; + + for (x = 0; x < svga->hwcursor_latch.xsize; x += 16) { + dat[0] = (cd[svga->hwcursor_latch.addr] << 8) | + cd[svga->hwcursor_latch.addr + 1]; + dat[1] = (cd[svga->hwcursor_latch.addr + bppl] << 8) | + cd[svga->hwcursor_latch.addr + bppl + 1]; + + for (xx = 0; xx < 16; xx++) { + b0 = (dat[0] >> (15 - xx)) & 1; + b1 = (dat[1] >> (15 - xx)) & 1; + comb = (b0 | (b1 << 1)); + + y_pos = displine + y_add; + x_pos = offset + 32 + x_add; + p = ((uint32_t *)buffer32->line[y_pos]); + + if (offset >= svga->hwcursor_latch.x) { + switch (mode) { + case 1: /* Three Color */ + switch (comb) { + case 1: + p[x_pos] = clr1; + break; + case 2: + p[x_pos] = clr2; + break; + case 3: + p[x_pos] = clr3; + break; + } + break; + case 2: /* PM/Windows */ + switch (comb) { + case 0: + p[x_pos] = clr1; + break; + case 1: + p[x_pos] = clr2; + break; + case 3: + p[x_pos] ^= 0xffffff; + break; + } + break; + case 3: /* X-Windows */ + switch (comb) { + case 2: + p[x_pos] = clr1; + break; + case 3: + p[x_pos] = clr2; + break; + } + break; + } + } + offset++; + } + svga->hwcursor_latch.addr += 2; } + if (svga->interlace && !svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += pitch; +} + + +void * +bt48x_ramdac_init(const device_t *info) +{ + bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) malloc(sizeof(bt48x_ramdac_t)); + memset(ramdac, 0, sizeof(bt48x_ramdac_t)); + + ramdac->type = info->local; + /* Set the RAM DAC status byte to the correct ID bits. Both the BT484 and BT485 datasheets say this: @@ -355,4 +456,57 @@ void bt485_init(bt485_ramdac_t *ramdac, svga_t *svga, uint8_t type) ramdac->status = 0x20; break; } + + return ramdac; } + + +static void +bt48x_ramdac_close(void *priv) +{ + bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) priv; + + if (ramdac) + free(ramdac); +} + + +const device_t bt484_ramdac_device = +{ + "Brooktree Bt484 RAMDAC", + 0, BT484, + bt48x_ramdac_init, bt48x_ramdac_close, + NULL, NULL, NULL, NULL +}; + +const device_t att20c504_ramdac_device = +{ + "AT&T 20c504 RAMDAC", + 0, ATT20C504, + bt48x_ramdac_init, bt48x_ramdac_close, + NULL, NULL, NULL, NULL +}; + +const device_t bt485_ramdac_device = +{ + "Brooktree Bt485 RAMDAC", + 0, BT485, + bt48x_ramdac_init, bt48x_ramdac_close, + NULL, NULL, NULL, NULL +}; + +const device_t att20c505_ramdac_device = +{ + "AT&T 20c505 RAMDAC", + 0, ATT20C505, + bt48x_ramdac_init, bt48x_ramdac_close, + NULL, NULL, NULL, NULL +}; + +const device_t bt485a_ramdac_device = +{ + "Brooktree Bt485A RAMDAC", + 0, BT485A, + bt48x_ramdac_init, bt48x_ramdac_close, + NULL, NULL, NULL, NULL +}; diff --git a/src/video/vid_bt485_ramdac.h b/src/video/vid_bt48x_ramdac.h similarity index 51% rename from src/video/vid_bt485_ramdac.h rename to src/video/vid_bt48x_ramdac.h index 99924ebbd..18d2d2229 100644 --- a/src/video/vid_bt485_ramdac.h +++ b/src/video/vid_bt48x_ramdac.h @@ -6,10 +6,10 @@ * * This file is part of the 86Box distribution. * - * Header of the emulation of the Brooktree BT485 and BT485A - * true colour RAM DAC's. + * Header of the emulation of the Brooktree BT484-BT485A + * true colour RAMDAC family. * - * Version: @(#)vid_bt485_ramdac.h 1.0.3 2018/10/04 + * Version: @(#)vid_bt485_ramdac.h 1.0.4 2018/10/04 * * Authors: Miran Grca, * TheCollector1995, @@ -17,7 +17,7 @@ * Copyright 2016-2018 Miran Grca. * Copyright 2018 TheCollector1995. */ -typedef struct bt485_ramdac_t +typedef struct { PALETTE extpal; uint32_t extpallook[256]; @@ -32,16 +32,14 @@ typedef struct bt485_ramdac_t uint8_t status; uint8_t type; uint8_t ext_addr; -} bt485_ramdac_t; +} bt48x_ramdac_t; -enum { - BT484 = 0, - ATT20C504, - BT485, - ATT20C505, - BT485A -}; +extern void bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt48x_ramdac_t *ramdac, svga_t *svga); +extern uint8_t bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, bt48x_ramdac_t *ramdac, svga_t *svga); +extern void bt48x_hwcursor_draw(svga_t *svga, int displine); -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, svga_t *svga, uint8_t type); +extern const device_t bt484_ramdac_device; +extern const device_t att20c504_ramdac_device; +extern const device_t bt485_ramdac_device; +extern const device_t att20c505_ramdac_device; +extern const device_t bt485a_ramdac_device; diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 77e2e0f3b..cef1e83d2 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -9,7 +9,7 @@ * Emulation of select Cirrus Logic cards (CL-GD 5428, * CL-GD 5429, CL-GD 5430, CL-GD 5434 and CL-GD 5436 are supported). * - * Version: @(#)vid_cl_54xx.c 1.0.24 2018/10/04 + * Version: @(#)vid_cl_54xx.c 1.0.25 2018/10/04 * * Authors: Sarah Walker, * Barry Rodewald, @@ -126,7 +126,7 @@ typedef struct gd54xx_t { mem_mapping_t mmio_mapping; - mem_mapping_t linear_mapping; + mem_mapping_t linear_mapping; svga_t svga; @@ -301,7 +301,8 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) svga->hwcursor.y = (val << 3) | (svga->seqaddr >> 5); break; case 0x12: - if (val & 0x80) + svga->ext_overscan = !!(val & 0x80); + if (svga->ext_overscan) svga->overscan_color = gd54xx->extpallook[2]; else svga->overscan_color = svga->pallook[svga->attrregs[0x11]]; @@ -358,7 +359,7 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) gd54xx->extpal[index].g = svga->dac_g; gd54xx->extpal[index].b = val; gd54xx->extpallook[index] = makecol32(video_6to8[gd54xx->extpal[index].r & 0x3f], video_6to8[gd54xx->extpal[index].g & 0x3f], video_6to8[gd54xx->extpal[index].b & 0x3f]); - if ((svga->seqregs[0x12] & 0x80) && (index == 2)) { + if (svga->ext_overscan && (index == 2)) { o32 = svga->overscan_color; svga->overscan_color = gd54xx->extpallook[2]; if (o32 != svga->overscan_color) @@ -2265,7 +2266,7 @@ static void svga_init(&gd54xx->svga, gd54xx, gd54xx->vram_size << 20, gd54xx_recalctimings, gd54xx_in, gd54xx_out, gd54xx_hwcursor_draw, NULL); - svga_set_ven_write(&gd54xx->svga, gd54xx_write_modes45); + svga->ven_write = gd54xx_write_modes45; mem_mapping_set_handler(&svga->mapping, gd54xx_read, gd54xx_readw, gd54xx_readl, gd54xx_write, gd54xx_writew, gd54xx_writel); mem_mapping_set_p(&svga->mapping, gd54xx); diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index 3292b774c..9864b0847 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -8,7 +8,7 @@ * * Emulation of the Tseng Labs ET4000. * - * Version: @(#)vid_et4000.c 1.0.19 2018/09/19 + * Version: @(#)vid_et4000.c 1.0.20 2018/10/04 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -65,7 +65,6 @@ typedef struct { int type; svga_t svga; - sc1502x_ramdac_t ramdac; uint8_t pos_regs[8]; @@ -126,7 +125,7 @@ et4000_in(uint16_t addr, void *priv) case 0x3c7: case 0x3c8: case 0x3c9: - return sc1502x_ramdac_in(addr, &dev->ramdac, svga); + return sc1502x_ramdac_in(addr, svga->ramdac, svga); case 0x3cd: /*Banking*/ return dev->banking; @@ -223,7 +222,7 @@ et4000_out(uint16_t addr, uint8_t val, void *priv) case 0x3c7: case 0x3c8: case 0x3c9: - sc1502x_ramdac_out(addr, val, &dev->ramdac, svga); + sc1502x_ramdac_out(addr, val, svga->ramdac, svga); return; case 0x3cd: /*Banking*/ @@ -537,6 +536,8 @@ et4000_init(const device_t *info) break; } + dev->svga.ramdac = device_add(&sc1502x_ramdac_device); + dev->vram_mask = dev->vram_size - 1; rom_init(&dev->bios_rom, (wchar_t *) fn, diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index c311b8608..d6bac4e90 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -10,7 +10,7 @@ * * Known bugs: Accelerator doesn't work in planar modes * - * Version: @(#)vid_et4000w32.c 1.0.19 2018/10/02 + * Version: @(#)vid_et4000w32.c 1.0.20 2018/10/04 * * Authors: Sarah Walker, * Miran Grca, @@ -80,8 +80,6 @@ typedef struct et4000w32p_t rom_t bios_rom; svga_t svga; - stg_ramdac_t ramdac; - icd2061_t icd2061; int index; int pci; @@ -189,11 +187,11 @@ void et4000w32p_out(uint16_t addr, uint8_t val, void *p) { case 0x3c2: if (et4000->type == ET4000W32_DIAMOND) - icd2061_write(&et4000->icd2061, (val >> 2) & 3); + icd2061_write(svga->clock_gen, (val >> 2) & 3); break; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - stg_ramdac_out(addr, val, &et4000->ramdac, svga); + stg_ramdac_out(addr, val, svga->ramdac, svga); return; case 0x3CB: /*Banking extension*/ @@ -305,7 +303,7 @@ uint8_t et4000w32p_in(uint16_t addr, void *p) break; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - return stg_ramdac_in(addr, &et4000->ramdac, svga); + return stg_ramdac_in(addr, svga->ramdac, svga); case 0x3CB: return et4000->banking2; @@ -344,7 +342,6 @@ uint8_t et4000w32p_in(uint16_t addr, void *p) void et4000w32p_recalctimings(svga_t *svga) { - et4000w32p_t *et4000 = (et4000w32p_t *)svga->p; svga->ma_latch |= (svga->crtc[0x33] & 0x7) << 16; if (svga->crtc[0x35] & 0x01) svga->vblankstart += 0x400; if (svga->crtc[0x35] & 0x02) svga->vtotal += 0x400; @@ -355,13 +352,8 @@ void et4000w32p_recalctimings(svga_t *svga) if (svga->crtc[0x3F] & 0x01) svga->htotal += 256; if (svga->attrregs[0x16] & 0x20) svga->hdisp <<= 1; - if (et4000->type == ET4000W32_DIAMOND) - { - svga->clock = cpuclock / icd2061_getclock((svga->miscout >> 2) & 3, &et4000->icd2061); - } - else - svga->clock = cpuclock / stg_getclock((svga->miscout >> 2) & 3, &et4000->ramdac); - + svga->clock = cpuclock / svga->getclock((svga->miscout >> 2) & 3, svga->clock_gen); + switch (svga->bpp) { case 15: case 16: @@ -1245,6 +1237,9 @@ void *et4000w32p_init(const device_t *info) et4000w32p_in, et4000w32p_out, et4000w32p_hwcursor_draw, NULL); + + et4000->svga.ramdac = device_add(&stg_ramdac_device); + et4000->vram_mask = (vram_size << 20) - 1; et4000->type = info->local; @@ -1253,12 +1248,17 @@ void *et4000w32p_init(const device_t *info) case ET4000W32_CARDEX: rom_init(&et4000->bios_rom, BIOS_ROM_PATH_CARDEX, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + + et4000->svga.clock_gen = et4000->svga.ramdac; + et4000->svga.getclock = stg_getclock; break; case ET4000W32_DIAMOND: rom_init(&et4000->bios_rom, BIOS_ROM_PATH_DIAMOND, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - icd2061_init(&et4000->icd2061); + + et4000->svga.clock_gen = device_add(&icd2061_device); + et4000->svga.getclock = icd2061_getclock; break; } et4000->pci = !!(info->flags & DEVICE_PCI); diff --git a/src/video/vid_icd2061.c b/src/video/vid_icd2061.c index 70576d929..47cd5743b 100644 --- a/src/video/vid_icd2061.c +++ b/src/video/vid_icd2061.c @@ -14,7 +14,7 @@ * Used by ET4000w32/p (Diamond Stealth 32) and the S3 * Vision964 family. * - * Version: @(#)vid_icd2061.c 1.0.7 2018/10/03 + * Version: @(#)vid_icd2061.c 1.0.8 2018/10/04 * * Authors: Miran Grca, * @@ -22,9 +22,11 @@ */ #include #include +#include #include #include #include "../86box.h" +#include "../device.h" #include "vid_icd2061.h" void @@ -96,17 +98,6 @@ icd2061_write(icd2061_t *icd2061, int val) } -void -icd2061_init(icd2061_t *icd2061) -{ - memset(icd2061, 0, sizeof(icd2061_t)); - - icd2061->freq[0] = 25175000.0; - icd2061->freq[1] = 28322000.0; - icd2061->freq[2] = 28322000.0; -} - - float icd2061_getclock(int clock, void *p) { @@ -117,3 +108,45 @@ icd2061_getclock(int clock, void *p) return icd2061->freq[clock]; } + + +static void * +icd2061_init(const device_t *info) +{ + icd2061_t *icd2061 = (icd2061_t *) malloc(sizeof(icd2061_t)); + memset(icd2061, 0, sizeof(icd2061_t)); + + icd2061->freq[0] = 25175000.0; + icd2061->freq[1] = 28322000.0; + icd2061->freq[2] = 28322000.0; + + return icd2061; +} + + +static void +icd2061_close(void *priv) +{ + icd2061_t *icd2061 = (icd2061_t *) priv; + + if (icd2061) + free(icd2061); +} + + +const device_t icd2061_device = +{ + "ICD2061 Clock Generator", + 0, 0, + icd2061_init, icd2061_close, + NULL, NULL, NULL, NULL +}; + + +const device_t ics9161_device = +{ + "ICS9161 Clock Generator", + 0, 0, + icd2061_init, icd2061_close, + NULL, NULL, NULL, NULL +}; diff --git a/src/video/vid_icd2061.h b/src/video/vid_icd2061.h index 60bf24b58..5b1c853e3 100644 --- a/src/video/vid_icd2061.h +++ b/src/video/vid_icd2061.h @@ -14,7 +14,7 @@ * Used by ET4000w32/p (Diamond Stealth 32) and the S3 * Vision964 family. * - * Version: @(#)vid_icd2061.h 1.0.2 2018/10/03 + * Version: @(#)vid_icd2061.h 1.0.3 2018/10/04 * * Authors: Miran Grca, * @@ -30,10 +30,11 @@ typedef struct icd2061_t } icd2061_t; void icd2061_write(icd2061_t *icd2061, int val); -void icd2061_init(icd2061_t *icd2061); float icd2061_getclock(int clock, void *p); +extern const device_t icd2061_device; +extern const device_t ics9161_device; + /* 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_ics2595.c b/src/video/vid_ics2595.c index 029999de9..711fb4641 100644 --- a/src/video/vid_ics2595.c +++ b/src/video/vid_ics2595.c @@ -8,19 +8,21 @@ * * ICS2595 clock chip emulation. Used by ATI Mach64. * - * Version: @(#)vid_ics2595.c 1.0.2 2017/11/04 + * Version: @(#)vid_ics2595.c 1.0.3 2018/10/04 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. */ #include #include +#include #include #include #include "../86box.h" +#include "../device.h" #include "vid_ics2595.h" @@ -35,39 +37,67 @@ enum static int ics2595_div[4] = {8, 4, 2, 1}; -void ics2595_write(ics2595_t *ics2595, int strobe, int dat) +void +ics2595_write(ics2595_t *ics2595, int strobe, int dat) { - if (strobe) - { - if ((dat & 8) && !ics2595->oldfs3) /*Data clock*/ - { - switch (ics2595->state) - { - case ICS2595_IDLE: - ics2595->state = (dat & 4) ? ICS2595_WRITE : ICS2595_IDLE; - ics2595->pos = 0; - break; - case ICS2595_WRITE: - ics2595->dat = (ics2595->dat >> 1); - if (dat & 4) - ics2595->dat |= (1 << 19); - ics2595->pos++; - if (ics2595->pos == 20) - { - int d, n, l; - l = (ics2595->dat >> 2) & 0xf; - n = ((ics2595->dat >> 7) & 255) + 257; - d = ics2595_div[(ics2595->dat >> 16) & 3]; + int d, n, l; - ics2595->clocks[l] = (14318181.8 * ((double)n / 46.0)) / (double)d; - ics2595->state = ICS2595_IDLE; - } - break; - } - } - - ics2595->oldfs2 = dat & 4; - ics2595->oldfs3 = dat & 8; - } - ics2595->output_clock = ics2595->clocks[dat]; + if (strobe) { + if ((dat & 8) && !ics2595->oldfs3) { /*Data clock*/ + switch (ics2595->state) { + case ICS2595_IDLE: + ics2595->state = (dat & 4) ? ICS2595_WRITE : ICS2595_IDLE; + ics2595->pos = 0; + break; + case ICS2595_WRITE: + ics2595->dat = (ics2595->dat >> 1); + if (dat & 4) + ics2595->dat |= (1 << 19); + ics2595->pos++; + if (ics2595->pos == 20) { + l = (ics2595->dat >> 2) & 0xf; + n = ((ics2595->dat >> 7) & 255) + 257; + d = ics2595_div[(ics2595->dat >> 16) & 3]; + + ics2595->clocks[l] = (14318181.8 * ((double)n / 46.0)) / (double)d; + ics2595->state = ICS2595_IDLE; + } + break; + } + } + + ics2595->oldfs2 = dat & 4; + ics2595->oldfs3 = dat & 8; + } + + ics2595->output_clock = ics2595->clocks[dat]; } + + +static void * +ics2595_init(const device_t *info) +{ + ics2595_t *ics2595 = (ics2595_t *) malloc(sizeof(ics2595_t)); + memset(ics2595, 0, sizeof(ics2595_t)); + + return ics2595; +} + + +static void +ics2595_close(void *priv) +{ + ics2595_t *ics2595 = (ics2595_t *) priv; + + if (ics2595) + free(ics2595); +} + + +const device_t ics2595_device = +{ + "ICS2595 clock chip", + 0, 0, + ics2595_init, ics2595_close, + NULL, NULL, NULL, NULL +}; diff --git a/src/video/vid_ics2595.h b/src/video/vid_ics2595.h index 5e5f1842d..1453a38ba 100644 --- a/src/video/vid_ics2595.h +++ b/src/video/vid_ics2595.h @@ -1,15 +1,31 @@ -/* Copyright holders: Sarah Walker - 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. + * + * ICS2595 clock chip emulation header. Used by ATI Mach64. + * + * Version: @(#)vid_ics2595.h 1.0.0 2018/10/04 + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + */ typedef struct ics2595_t { - int oldfs3, oldfs2; - int dat; - int pos; - int state; + int oldfs3, oldfs2; + int dat; + int pos, state; - double clocks[16]; - double output_clock; + double clocks[16]; + double output_clock; } ics2595_t; -void ics2595_write(ics2595_t *ics2595, int strobe, int dat); +extern void ics2595_write(ics2595_t *ics2595, int strobe, int dat); + +extern const device_t ics2595_device; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 93972f41b..c7c2040cd 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.24 2018/10/03 + * Version: @(#)vid_s3.c 1.0.25 2018/10/04 * * Authors: Sarah Walker, * Miran Grca, @@ -33,7 +33,7 @@ #include "vid_svga.h" #include "vid_svga_render.h" #include "vid_sdac_ramdac.h" -#include "vid_bt485_ramdac.h" +#include "vid_bt48x_ramdac.h" #include "vid_icd2061.h" #define ROM_PARADISE_BAHAMAS64 L"roms/video/s3/bahamas64.bin" @@ -116,8 +116,6 @@ typedef struct s3_t rom_t bios_rom; svga_t svga; - sdac_ramdac_t ramdac; - bt485_ramdac_t bt485_ramdac; icd2061_t icd2061; uint8_t bank; @@ -142,9 +140,6 @@ typedef struct s3_t uint32_t vram_mask; uint8_t status_9ae8; - - float (*getclock)(int clock, void *p); - void *getclock_p; struct { @@ -1052,9 +1047,9 @@ void s3_out(uint16_t addr, uint8_t val, void *p) rs3 = !!(svga->crtc[0x55] & 0x02); else rs3 = 0; - bt485_ramdac_out(addr, rs2, rs3, val, &s3->bt485_ramdac, svga); + bt48x_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); } else - sdac_ramdac_out(addr, rs2, val, &s3->ramdac, svga); + sdac_ramdac_out(addr, rs2, val, svga->ramdac, svga); return; case 0x3D4: @@ -1214,6 +1209,7 @@ uint8_t s3_in(uint16_t addr, void *p) s3_t *s3 = (s3_t *)p; svga_t *svga = &s3->svga; int rs2, rs3; + uint8_t temp; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; @@ -1236,9 +1232,9 @@ uint8_t s3_in(uint16_t addr, void *p) return svga_in(addr, svga); else if (s3->chip == S3_VISION964) { rs3 = !!(svga->crtc[0x55] & 0x02); - return bt485_ramdac_in(addr, rs2, rs3, &s3->bt485_ramdac, svga); + return bt48x_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); } else - return sdac_ramdac_in(addr, rs2, &s3->ramdac, svga); + return sdac_ramdac_in(addr, rs2, svga->ramdac, svga); break; case 0x3d4: @@ -1254,6 +1250,13 @@ uint8_t s3_in(uint16_t addr, void *p) case 0x35: return (svga->crtc[0x35] & 0xf0) | (s3->bank & 0xf); case 0x45: s3->hwc_col_stack_pos = 0; break; 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] & 0xf0; + if (((svga->miscout >> 2) & 3) == 3) + temp |= svga->crtc[0x42] & 0x0f; + else + temp |= ((svga->miscout >> 2) & 3); + return temp; case 0x69: return s3->ma_ext; case 0x6a: return s3->bank; } @@ -1265,6 +1268,7 @@ uint8_t s3_in(uint16_t addr, void *p) void s3_recalctimings(svga_t *svga) { s3_t *s3 = (s3_t *)svga->p; + bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) svga->ramdac; svga->hdisp = svga->hdisp_old; svga->ma_latch |= (s3->ma_ext << 16); @@ -1284,16 +1288,16 @@ void s3_recalctimings(svga_t *svga) if (!svga->rowoffset) svga->rowoffset = 256; if (s3->chip == S3_VISION964) { - svga->interlace = s3->bt485_ramdac.cr2 & 0x08; - if (s3->bt485_ramdac.cr3 & 0x08) + svga->interlace = ramdac->cr2 & 0x08; + if (ramdac->cr3 & 0x08) svga->hdisp *= 2; /* x2 clock multiplier */ if (((svga->miscout >> 2) & 3) == 3) - svga->clock = cpuclock / s3->getclock(svga->crtc[0x42] & 0x0f, s3->getclock_p); + svga->clock = cpuclock / svga->getclock(svga->crtc[0x42] & 0x0f, svga->clock_gen); else - svga->clock = cpuclock / s3->getclock((svga->miscout >> 2) & 3, s3->getclock_p); + svga->clock = cpuclock / svga->getclock((svga->miscout >> 2) & 3, svga->clock_gen); } else { svga->interlace = svga->crtc[0x42] & 0x20; - svga->clock = cpuclock / s3->getclock((svga->miscout >> 2) & 3, s3->getclock_p); + svga->clock = cpuclock / svga->getclock((svga->miscout >> 2) & 3, svga->clock_gen); } switch (svga->crtc[0x67] >> 4) @@ -2608,105 +2612,6 @@ void s3_hwcursor_draw(svga_t *svga, int displine) svga->hwcursor_latch.addr += 16; } -void s3_bt485_hwcursor_draw(svga_t *svga, int displine) -{ - s3_t *s3 = (s3_t *)svga->p; - int x, xx, comb, b0, b1; - uint16_t dat[2]; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - int y_add, x_add; - int pitch, bppl, mode, x_pos, y_pos; - uint32_t clr1, clr2, clr3, *p; - uint8_t *cd; - - clr1 = s3->bt485_ramdac.extpallook[1]; - clr2 = s3->bt485_ramdac.extpallook[2]; - clr3 = s3->bt485_ramdac.extpallook[3]; - - y_add = (enable_overscan && !suppress_overscan) ? (overscan_y >> 1) : 0; - x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; - - /* The planes come in two parts, and each plane is 1bpp, - so a 32x32 cursor has 4 bytes per line, and a 64x64 - cursor has 8 bytes per line. */ - pitch = (svga->hwcursor_latch.xsize >> 3); /* Bytes per line. */ - /* A 32x32 cursor has 128 bytes per line, and a 64x64 - cursor has 512 bytes per line. */ - bppl = (pitch * svga->hwcursor_latch.ysize); /* Bytes per plane. */ - mode = s3->bt485_ramdac.cr2 & 0x03; - - if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += pitch; - - if (svga->hwcursor_latch.xsize == 64) - cd = (uint8_t *) s3->bt485_ramdac.cursor64_data; - else - cd = (uint8_t *) s3->bt485_ramdac.cursor32_data; - - for (x = 0; x < svga->hwcursor_latch.xsize; x += 16) { - dat[0] = (cd[svga->hwcursor_latch.addr] << 8) | - cd[svga->hwcursor_latch.addr + 1]; - dat[1] = (cd[svga->hwcursor_latch.addr + bppl] << 8) | - cd[svga->hwcursor_latch.addr + bppl + 1]; - - for (xx = 0; xx < 16; xx++) { - b0 = (dat[0] >> (15 - xx)) & 1; - b1 = (dat[1] >> (15 - xx)) & 1; - comb = (b0 | (b1 << 1)); - - y_pos = displine + y_add; - x_pos = offset + 32 + x_add; - p = ((uint32_t *)buffer32->line[y_pos]); - - if (offset >= svga->hwcursor_latch.x) { - switch (mode) { - case 1: /* Three Color */ - switch (comb) { - case 1: - p[x_pos] = clr1; - break; - case 2: - p[x_pos] = clr2; - break; - case 3: - p[x_pos] = clr3; - break; - } - break; - case 2: /* PM/Windows */ - switch (comb) { - case 0: - p[x_pos] = clr1; - break; - case 1: - p[x_pos] = clr2; - break; - case 3: - p[x_pos] ^= 0xffffff; - break; - } - break; - case 3: /* X-Windows */ - switch (comb) { - case 2: - p[x_pos] = clr1; - break; - case 3: - p[x_pos] = clr2; - break; - } - break; - } - } - offset++; - } - svga->hwcursor_latch.addr += 2; - } - - if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += pitch; -} - static void s3_io_remove(s3_t *s3) { io_removehandler(0x03c0, 0x0020, s3_in, NULL, NULL, s3_out, NULL, NULL, s3); @@ -2931,6 +2836,7 @@ static void *s3_init(const device_t *info) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64); break; default: + free(s3); return NULL; } @@ -2967,7 +2873,7 @@ static void *s3_init(const device_t *info) svga_init(&s3->svga, s3, vram_size, s3_recalctimings, s3_in, s3_out, - s3_bt485_hwcursor_draw, + bt48x_hwcursor_draw, NULL); else svga_init(&s3->svga, s3, vram_size, @@ -3044,9 +2950,9 @@ static void *s3_init(const device_t *info) s3->id_ext = s3->id_ext_pci = stepping; s3->packed_mmio = 0; - s3->getclock = sdac_getclock; - s3->getclock_p = &s3->ramdac; - sdac_init(&s3->ramdac); + svga->ramdac = device_add(&sdac_ramdac_device); + svga->clock_gen = svga->ramdac; + svga->getclock = sdac_getclock; break; case S3_DIAMOND_STEALTH64_964: @@ -3057,11 +2963,9 @@ static void *s3_init(const device_t *info) s3->packed_mmio = 1; svga->crtc[0x5a] = 0x0a; - bt485_init(&s3->bt485_ramdac, &s3->svga, BT485); - icd2061_init(&s3->icd2061); - - s3->getclock = icd2061_getclock; - s3->getclock_p = &s3->icd2061; + svga->ramdac = device_add(&bt485_ramdac_device); + svga->clock_gen = device_add(&icd2061_device); + svga->getclock = icd2061_getclock; break; case S3_PHOENIX_TRIO32: @@ -3071,8 +2975,8 @@ static void *s3_init(const device_t *info) s3->id_ext_pci = 0x11; s3->packed_mmio = 1; - s3->getclock = s3_trio64_getclock; - s3->getclock_p = s3; + svga->clock_gen = s3; + svga->getclock = s3_trio64_getclock; break; case S3_PHOENIX_TRIO64: @@ -3088,8 +2992,8 @@ static void *s3_init(const device_t *info) s3->id_ext = s3->id_ext_pci = 0x11; s3->packed_mmio = 1; - s3->getclock = s3_trio64_getclock; - s3->getclock_p = s3; + svga->clock_gen = s3; + svga->getclock = s3_trio64_getclock; break; default: diff --git a/src/video/vid_sc1502x_ramdac.c b/src/video/vid_sc1502x_ramdac.c index 18f78c8b0..992ceea6c 100644 --- a/src/video/vid_sc1502x_ramdac.c +++ b/src/video/vid_sc1502x_ramdac.c @@ -10,102 +10,146 @@ * * Used by the TLIVESA1 driver for ET4000. * - * Version: @(#)vid_sc1502x_ramdac.c 1.0.2 2017/11/04 + * Version: @(#)vid_sc1502x_ramdac.c 1.0.3 2018/10/04 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. */ #include #include +#include #include #include #include "../86box.h" +#include "../device.h" #include "../mem.h" #include "video.h" #include "vid_svga.h" #include "vid_sc1502x_ramdac.h" -void sc1502x_ramdac_out(uint16_t addr, uint8_t val, sc1502x_ramdac_t *ramdac, svga_t *svga) +void +sc1502x_ramdac_out(uint16_t addr, uint8_t val, sc1502x_ramdac_t *ramdac, svga_t *svga) { - int oldbpp = 0; - switch (addr) - { - case 0x3C6: - if (ramdac->state == 4) - { - ramdac->state = 0; - if (val == 0xFF) break; - 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; - } - break; - case 4: case 5: - svga->bpp = 15; - break; - case 6: - svga->bpp = 16; - break; - case 7: - switch (val & 4) - { - case 4: - switch (val & 0x20) - { - case 0x00: svga->bpp = 32; break; - case 0x20: svga->bpp = 24; break; - } - break; - case 0: default: - svga->bpp = 16; - break; - } - case 1: default: + int oldbpp = 0; + + switch (addr) { + case 0x3C6: + if (ramdac->state == 4) { + ramdac->state = 0; + if (val == 0xFF) break; - } - if (oldbpp != svga->bpp) - { - svga_recalctimings(svga); + 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; + } + break; + case 4: + case 5: + svga->bpp = 15; + break; + case 6: + svga->bpp = 16; + break; + case 7: + if (val & 4) { + switch (val & 0x20) { + case 0x00: + svga->bpp = 32; + break; + case 0x20: + svga->bpp = 24; + break; + } + break; + } else { + svga->bpp = 16; + break; + } + break; } - return; - } - ramdac->state = 0; - break; - case 0x3C7: case 0x3C8: case 0x3C9: - ramdac->state = 0; - break; - } - svga_out(addr, val, svga); + if (oldbpp != svga->bpp) + 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 sc1502x_ramdac_in(uint16_t addr, sc1502x_ramdac_t *ramdac, svga_t *svga) + +uint8_t +sc1502x_ramdac_in(uint16_t addr, sc1502x_ramdac_t *ramdac, svga_t *svga) { - switch (addr) - { - case 0x3C6: - if (ramdac->state == 4) - { - ramdac->state = 0; - return ramdac->ctrl; - } - ramdac->state++; - break; - case 0x3C7: case 0x3C8: case 0x3C9: - ramdac->state = 0; - break; - } - return svga_in(addr, svga); + uint8_t temp; + temp = svga_in(addr, svga); + + switch (addr) { + case 0x3C6: + if (ramdac->state == 4) { + ramdac->state = 0; + temp = ramdac->ctrl; + break; + } + ramdac->state++; + break; + case 0x3C7: + case 0x3C8: + case 0x3C9: + ramdac->state = 0; + break; + } + + return temp; } + + +static void * +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)); + + return ramdac; +} + + +static void +sc1502x_ramdac_close(void *priv) +{ + sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) priv; + + if (ramdac) + free(ramdac); +} + + +const device_t sc1502x_ramdac_device = +{ + "Sierra SC1502x RAMDAC", + 0, 0, + sc1502x_ramdac_init, sc1502x_ramdac_close, + NULL, NULL, NULL, NULL +}; diff --git a/src/video/vid_sc1502x_ramdac.h b/src/video/vid_sc1502x_ramdac.h index 2aaccb391..a5dcd234c 100644 --- a/src/video/vid_sc1502x_ramdac.h +++ b/src/video/vid_sc1502x_ramdac.h @@ -1,11 +1,30 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -typedef struct unk_ramdac_t +/* + * 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 a Sierra SC1502X RAMDAC. + * + * Used by the TLIVESA1 driver for ET4000. + * + * Version: @(#)vid_sc1502x_ramdac.h 1.0.0 2018/10/04 + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + */ +typedef struct { - int state; - uint8_t ctrl; + int state; + uint8_t ctrl; } sc1502x_ramdac_t; -void sc1502x_ramdac_out(uint16_t addr, uint8_t val, sc1502x_ramdac_t *ramdac, svga_t *svga); -uint8_t sc1502x_ramdac_in(uint16_t addr, sc1502x_ramdac_t *ramdac, svga_t *svga); +extern void sc1502x_ramdac_out(uint16_t addr, uint8_t val, sc1502x_ramdac_t *ramdac, svga_t *svga); +extern uint8_t sc1502x_ramdac_in(uint16_t addr, sc1502x_ramdac_t *ramdac, svga_t *svga); + +extern const device_t sc1502x_ramdac_device; diff --git a/src/video/vid_sdac_ramdac.c b/src/video/vid_sdac_ramdac.c index 6276b053d..e7ff064a9 100644 --- a/src/video/vid_sdac_ramdac.c +++ b/src/video/vid_sdac_ramdac.c @@ -8,7 +8,7 @@ * * 87C716 'SDAC' true colour RAMDAC emulation. * - * Version: @(#)vid_sdac_ramdac.c 1.0.4 2018/03/21 + * Version: @(#)vid_sdac_ramdac.c 1.0.5 2018/10/04 * * Authors: Sarah Walker, * Miran Grca, @@ -18,166 +18,209 @@ */ #include #include +#include #include #include #include "../86box.h" +#include "../device.h" #include "../mem.h" #include "video.h" #include "vid_svga.h" #include "vid_sdac_ramdac.h" -static void sdac_control_write(sdac_ramdac_t *ramdac, svga_t *svga, uint8_t val) + +static void +sdac_control_write(sdac_ramdac_t *ramdac, svga_t *svga, uint8_t val) { - ramdac->command = val; - switch (val >> 4) - { - case 0x2: case 0x3: case 0xa: svga->bpp = 15; break; - case 0x4: case 0xe: svga->bpp = 24; break; - case 0x5: case 0x6: case 0xc: svga->bpp = 16; break; - case 0x7: svga->bpp = 32; break; - - case 0: case 1: default: svga->bpp = 8; break; - } -} - -static void sdac_reg_write(sdac_ramdac_t *ramdac, int reg, uint8_t val) -{ - if ((reg >= 2 && reg <= 7) || (reg == 0xa) || (reg == 0xe)) - { - if (!ramdac->reg_ff) - ramdac->regs[reg] = (ramdac->regs[reg] & 0xff00) | val; - else - ramdac->regs[reg] = (ramdac->regs[reg] & 0x00ff) | (val << 8); - } - ramdac->reg_ff = !ramdac->reg_ff; - if (!ramdac->reg_ff) - ramdac->windex++; -} - -static uint8_t sdac_reg_read(sdac_ramdac_t *ramdac, int reg) -{ - uint8_t temp; - - if (!ramdac->reg_ff) - temp = ramdac->regs[reg] & 0xff; - else - temp = ramdac->regs[reg] >> 8; - ramdac->reg_ff = !ramdac->reg_ff; - if (!ramdac->reg_ff) - ramdac->rindex++; - - return temp; -} - -void sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga) -{ - switch (addr) - { - case 0x3C6: - if (rs2) - sdac_control_write(ramdac, svga, val); - else { - if (ramdac->magic_count == 4) - sdac_control_write(ramdac, svga, val); - ramdac->magic_count = 0; - } + ramdac->command = val; + switch (val >> 4) { + case 0x2: + case 0x3: + case 0xa: + svga->bpp = 15; break; - - case 0x3C7: - if (rs2) { - ramdac->rindex = val; - ramdac->reg_ff = 0; - } - else + case 0x4: + case 0xe: + svga->bpp = 24; + break; + case 0x5: + case 0x6: + case 0xc: + svga->bpp = 16; + break; + case 0x7: + svga->bpp = 32; + break; + case 0x0: + case 0x1: + default: + svga->bpp = 8; + break; + } +} + + +static void +sdac_reg_write(sdac_ramdac_t *ramdac, int reg, uint8_t val) +{ + if ((reg >= 2 && reg <= 7) || (reg == 0xa) || (reg == 0xe)) { + if (!ramdac->reg_ff) + ramdac->regs[reg] = (ramdac->regs[reg] & 0xff00) | val; + else + ramdac->regs[reg] = (ramdac->regs[reg] & 0x00ff) | (val << 8); + } + ramdac->reg_ff = !ramdac->reg_ff; + if (!ramdac->reg_ff) + ramdac->windex++; +} + + +static uint8_t +sdac_reg_read(sdac_ramdac_t *ramdac, int reg) +{ + uint8_t temp; + + if (!ramdac->reg_ff) + temp = ramdac->regs[reg] & 0xff; + else + temp = ramdac->regs[reg] >> 8; + ramdac->reg_ff = !ramdac->reg_ff; + if (!ramdac->reg_ff) + ramdac->rindex++; + + return temp; +} + + +void +sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga) +{ + uint8_t rs = (addr & 0x03); + rs |= (!!rs2 << 8); + + switch (rs) { + case 0x02: + if (ramdac->magic_count == 4) + sdac_control_write(ramdac, svga, val); + /* Fall through. */ + case 0x00: + case 0x01: + case 0x03: + ramdac->magic_count = 0; + break; + case 0x04: + ramdac->windex = val; + ramdac->reg_ff = 0; + break; + case 0x05: + sdac_reg_write(ramdac, ramdac->windex & 0xff, val); + break; + case 0x06: + sdac_control_write(ramdac, svga, val); + break; + case 0x07: + ramdac->rindex = val; + ramdac->reg_ff = 0; + break; + } + + svga_out(addr, val, svga); +} + + +uint8_t +sdac_ramdac_in(uint16_t addr, int rs2, sdac_ramdac_t *ramdac, svga_t *svga) +{ + uint8_t temp = 0xff; + uint8_t rs = (addr & 0x03); + rs |= (!!rs2 << 8); + + switch (rs) { + case 0x02: + if (ramdac->magic_count < 5) + ramdac->magic_count++; + if (ramdac->magic_count == 4) + temp = 0x70; /*SDAC ID*/ + else if (ramdac->magic_count == 5) { + temp = ramdac->command; ramdac->magic_count = 0; + } else + temp = svga_in(addr, svga); break; - - case 0x3C8: - if (rs2) { - ramdac->windex = val; - ramdac->reg_ff = 0; - } - else - ramdac->magic_count = 0; + case 0x00: + case 0x01: + case 0x03: + ramdac->magic_count=0; + temp = svga_in(addr, svga); break; - - case 0x3C9: - if (rs2) - sdac_reg_write(ramdac, ramdac->windex & 0xff, val); - else - ramdac->magic_count = 0; + case 0x04: + temp = ramdac->windex; break; - } + case 0x05: + temp = sdac_reg_read(ramdac, ramdac->rindex & 0xff); + break; + case 0x06: + temp = ramdac->command; + break; + case 0x07: + temp = ramdac->rindex; + break; + } - svga_out(addr, val, svga); + return temp; } -uint8_t sdac_ramdac_in(uint16_t addr, int rs2, sdac_ramdac_t *ramdac, svga_t *svga) + +float +sdac_getclock(int clock, void *p) { - uint8_t temp; - switch (addr) - { - case 0x3C6: - if (rs2) - return ramdac->command; - else { - if (ramdac->magic_count < 5) - ramdac->magic_count++; - if (ramdac->magic_count == 4) - { - temp = 0x70; /*SDAC ID*/ - } - if (ramdac->magic_count == 5) - { - temp = ramdac->command; - ramdac->magic_count = 0; - } - return temp; - } - break; - - case 0x3C7: - if (rs2) - return ramdac->rindex; - else - ramdac->magic_count=0; - break; - - case 0x3C8: - if (rs2) - return ramdac->windex; - else - ramdac->magic_count=0; - break; - - case 0x3C9: - if (rs2) - return sdac_reg_read(ramdac, ramdac->rindex & 0xff); - else - ramdac->magic_count=0; - break; - } - - return svga_in(addr, svga); + sdac_ramdac_t *ramdac = (sdac_ramdac_t *)p; + float t; + int m, n1, n2; + + if (clock == 0) + return 25175000.0; + if (clock == 1) + return 28322000.0; + + clock ^= 1; /*Clocks 2 and 3 seem to be reversed*/ + m = (ramdac->regs[clock] & 0x7f) + 2; + n1 = ((ramdac->regs[clock] >> 8) & 0x1f) + 2; + n2 = ((ramdac->regs[clock] >> 13) & 0x07); + n2 = (1 << n2); + t = (14318184.0f * (float)m) / (float)(n1 * n2); + + return t; } -float sdac_getclock(int clock, void *p) + +void * +sdac_ramdac_init(const device_t *info) { - sdac_ramdac_t *ramdac = (sdac_ramdac_t *)p; - float t; - int m, n1, n2; - if (clock == 0) return 25175000.0; - if (clock == 1) return 28322000.0; - clock ^= 1; /*Clocks 2 and 3 seem to be reversed*/ - m = (ramdac->regs[clock] & 0x7f) + 2; - n1 = ((ramdac->regs[clock] >> 8) & 0x1f) + 2; - n2 = ((ramdac->regs[clock] >> 13) & 0x07); - t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2); - return t; + sdac_ramdac_t *ramdac = (sdac_ramdac_t *) malloc(sizeof(sdac_ramdac_t)); + memset(ramdac, 0, sizeof(sdac_ramdac_t)); + + ramdac->regs[0] = 0x6128; + ramdac->regs[1] = 0x623d; + + return ramdac; } -void sdac_init(sdac_ramdac_t *ramdac) + +static void +sdac_ramdac_close(void *priv) { - ramdac->regs[0] = 0x6128; - ramdac->regs[1] = 0x623d; + sdac_ramdac_t *ramdac = (sdac_ramdac_t *) priv; + + if (ramdac) + free(ramdac); } + + +const device_t sdac_ramdac_device = +{ + "S3 SDAC 86c716 RAMDAC", + 0, 0, + sdac_ramdac_init, sdac_ramdac_close, + NULL, NULL, NULL, NULL +}; diff --git a/src/video/vid_sdac_ramdac.h b/src/video/vid_sdac_ramdac.h index c8c5e7d57..001b8727f 100644 --- a/src/video/vid_sdac_ramdac.h +++ b/src/video/vid_sdac_ramdac.h @@ -1,19 +1,32 @@ -/* Copyright holders: Sarah Walker, 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. + * + * 87C716 'SDAC' true colour RAMDAC emulation header. + * + * Version: @(#)vid_sdac_ramdac.h 1.0.0 2018/10/04 + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + */ typedef struct sdac_ramdac_t { - int magic_count; - uint8_t command; - int windex, rindex; - uint16_t regs[256]; - int reg_ff; - int rs2; + uint16_t regs[256]; + int magic_count, + windex, rindex, + reg_ff, rs2; + uint8_t command; } sdac_ramdac_t; -void sdac_init(sdac_ramdac_t *ramdac); +extern void sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga); +extern uint8_t sdac_ramdac_in(uint16_t addr, int rs2, sdac_ramdac_t *ramdac, svga_t *svga); +extern float sdac_getclock(int clock, void *p); -void sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga); -uint8_t sdac_ramdac_in(uint16_t addr, int rs2, sdac_ramdac_t *ramdac, svga_t *svga); - -float sdac_getclock(int clock, void *p); +extern const device_t sdac_ramdac_device; diff --git a/src/video/vid_stg_ramdac.c b/src/video/vid_stg_ramdac.c index 37b1b5a2a..2bbeee85e 100644 --- a/src/video/vid_stg_ramdac.c +++ b/src/video/vid_stg_ramdac.c @@ -8,7 +8,7 @@ * * STG1702 true colour RAMDAC emulation. * - * Version: @(#)vid_stg_ramdac.c 1.0.4 2018/01/25 + * Version: @(#)vid_stg_ramdac.c 1.0.5 2018/10/04 * * Authors: Sarah Walker, * Miran Grca, @@ -18,9 +18,11 @@ */ #include #include +#include #include #include #include "../86box.h" +#include "../device.h" #include "../mem.h" #include "video.h" #include "vid_svga.h" @@ -31,151 +33,213 @@ static int stg_state_read[2][8] = {{1,2,3,4,0,0,0,0}, {1,2,3,4,5,6,7,7}}; static int stg_state_write[8] = {0,0,0,0,0,6,7,7}; -void stg_ramdac_set_bpp(svga_t *svga, stg_ramdac_t *ramdac) +void +stg_ramdac_set_bpp(svga_t *svga, stg_ramdac_t *ramdac) { - if (ramdac->command & 0x8) - { - switch (ramdac->regs[3]) - { - case 0: case 5: case 7: svga->bpp = 8; break; - case 1: case 2: case 8: svga->bpp = 15; break; - case 3: case 6: svga->bpp = 16; break; - case 4: case 9: svga->bpp = 24; break; - default: svga->bpp = 8; break; - } + if (ramdac->command & 0x8) { + switch (ramdac->regs[3]) { + case 0: + case 5: + case 7: + default: + svga->bpp = 8; + break; + case 1: + case 2: + case 8: + svga->bpp = 15; + break; + case 3: + case 6: + svga->bpp = 16; + break; + case 4: + case 9: + svga->bpp = 24; + break; } - else - { - switch (ramdac->command >> 5) - { - case 0: svga->bpp = 8; break; - case 5: svga->bpp = 15; break; - case 6: svga->bpp = 16; break; - case 7: svga->bpp = 24; break; - default: svga->bpp = 8; break; - } + } else { + switch (ramdac->command >> 5) { + case 0: + default: + svga->bpp = 8; + break; + case 5: + svga->bpp = 15; + break; + case 6: + svga->bpp = 16; + break; + case 7: + svga->bpp = 24; + break; } - svga_recalctimings(svga); + } + + svga_recalctimings(svga); } -void stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *svga) + +void +stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *svga) { - int didwrite, old; - switch (addr) - { - case 0x3c6: - switch (ramdac->magic_count) - { + int didwrite, old; + + switch (addr) { + case 0x3c6: + switch (ramdac->magic_count) { /* 0 = PEL mask register */ - case 0: case 1: case 2: case 3: - break; - case 4: /* REG06 */ - old = ramdac->command; - ramdac->command = val; - if ((old ^ val) & 8) - { - stg_ramdac_set_bpp(svga, ramdac); - } - else - { - if ((old ^ val) & 0xE0) - { - stg_ramdac_set_bpp(svga, ramdac); - } - } - break; - case 5: - ramdac->index = (ramdac->index & 0xff00) | val; - break; - case 6: - ramdac->index = (ramdac->index & 0xff) | (val << 8); - break; - case 7: - if (ramdac->index < 0x100) - { - ramdac->regs[ramdac->index] = val; - } - if ((ramdac->index == 3) && (ramdac->command & 8)) stg_ramdac_set_bpp(svga, ramdac); - ramdac->index++; - break; - } - didwrite = (ramdac->magic_count >= 4); - ramdac->magic_count = stg_state_write[ramdac->magic_count & 7]; - if (didwrite) return; - break; - case 0x3c7: case 0x3c8: case 0x3c9: - ramdac->magic_count=0; - break; - } - svga_out(addr, val, svga); -} - -uint8_t stg_ramdac_in(uint16_t addr, stg_ramdac_t *ramdac, svga_t *svga) -{ - uint8_t temp = 0xff; - switch (addr) - { - case 0x3c6: - switch (ramdac->magic_count) - { - case 0: case 1: case 2: case 3: - temp = 0xff; - break; - case 4: - temp = ramdac->command; - break; - case 5: - temp = ramdac->index & 0xff; - break; - case 6: - temp = ramdac->index >> 8; - break; - case 7: - switch (ramdac->index) - { - case 0: - temp = 0x44; - break; - case 1: - temp = 0x03; - break; - case 7: - temp = 0x88; + case 0: + case 1: + case 2: + case 3: break; - default: - if (ramdac->index < 0x100) temp = ramdac->regs[ramdac->index]; - else temp = 0xff; - break; - } - ramdac->index++; - break; - } - ramdac->magic_count = stg_state_read[(ramdac->command & 0x10) ? 1 : 0][ramdac->magic_count & 7]; - return temp; - case 0x3c7: case 0x3c8: case 0x3c9: - ramdac->magic_count=0; - break; - } - return svga_in(addr, svga); + case 4: /* REG06 */ + old = ramdac->command; + ramdac->command = val; + if ((old ^ val) & 8) + stg_ramdac_set_bpp(svga, ramdac); + else { + if ((old ^ val) & 0xE0) + stg_ramdac_set_bpp(svga, ramdac); + } + break; + case 5: + ramdac->index = (ramdac->index & 0xff00) | val; + break; + case 6: + ramdac->index = (ramdac->index & 0xff) | (val << 8); + break; + case 7: + if (ramdac->index < 0x100) + ramdac->regs[ramdac->index] = val; + if ((ramdac->index == 3) && (ramdac->command & 8)) + stg_ramdac_set_bpp(svga, ramdac); + ramdac->index++; + break; + } + didwrite = (ramdac->magic_count >= 4); + ramdac->magic_count = stg_state_write[ramdac->magic_count & 7]; + if (didwrite) + return; + break; + case 0x3c7: + case 0x3c8: + case 0x3c9: + ramdac->magic_count=0; + break; + } + + svga_out(addr, val, svga); } -float stg_getclock(int clock, void *p) + +uint8_t +stg_ramdac_in(uint16_t addr, stg_ramdac_t *ramdac, svga_t *svga) { - stg_ramdac_t *ramdac = (stg_ramdac_t *)p; - float t; - int m, n, n2; - float b, n1, d; - uint16_t *c; - if (clock == 0) return 25175000.0; - if (clock == 1) return 28322000.0; - clock ^= 1; /*Clocks 2 and 3 seem to be reversed*/ - c = (uint16_t *) &ramdac->regs[0x20 + (clock << 1)]; - m = (*c & 0xff) + 2; /* B+2 */ - n = ((*c >> 8) & 0x1f) + 2; /* N1+2 */ - n2 = ((*c >> 13) & 0x07); /* D */ - b = (float) m; - n1 = (float) n; - d = (double) (1 << n2); - t = (14318184.0 * (b / d)) / n1; - return t; + uint8_t temp = 0xff; + + switch (addr) { + case 0x3c6: + switch (ramdac->magic_count) { + case 0: + case 1: + case 2: + case 3: + temp = 0xff; + break; + case 4: + temp = ramdac->command; + break; + case 5: + temp = ramdac->index & 0xff; + break; + case 6: + temp = ramdac->index >> 8; + break; + case 7: + switch (ramdac->index) { + case 0: + temp = 0x44; + break; + case 1: + temp = 0x03; + break; + case 7: + temp = 0x88; + break; + default: + if (ramdac->index < 0x100) + temp = ramdac->regs[ramdac->index]; + else + temp = 0xff; + break; + } + ramdac->index++; + break; + } + ramdac->magic_count = stg_state_read[(ramdac->command & 0x10) ? 1 : 0][ramdac->magic_count & 7]; + return temp; + case 0x3c7: + case 0x3c8: + case 0x3c9: + ramdac->magic_count=0; + break; + } + + return svga_in(addr, svga); } + + +float +stg_getclock(int clock, void *p) +{ + stg_ramdac_t *ramdac = (stg_ramdac_t *)p; + float t; + int m, n, n2; + uint16_t *c; + + if (clock == 0) + return 25175000.0; + if (clock == 1) + return 28322000.0; + + clock ^= 1; /*Clocks 2 and 3 seem to be reversed*/ + c = (uint16_t *) &ramdac->regs[0x20 + (clock << 1)]; + m = (*c & 0xff) + 2; /* B+2 */ + n = ((*c >> 8) & 0x1f) + 2; /* N1+2 */ + n2 = ((*c >> 13) & 0x07); /* D */ + n2 = (1 << n2); + t = (14318184.0f * (float)m) / (float)(n * n2); + + return t; +} + + +static void * +stg_ramdac_init(const device_t *info) +{ + stg_ramdac_t *ramdac = (stg_ramdac_t *) malloc(sizeof(stg_ramdac_t)); + memset(ramdac, 0, sizeof(stg_ramdac_t)); + + return ramdac; +} + + +static void +stg_ramdac_close(void *priv) +{ + stg_ramdac_t *ramdac = (stg_ramdac_t *) priv; + + if (ramdac) + free(ramdac); +} + + +const device_t stg_ramdac_device = +{ + "SGS-Thompson STG170x RAMDAC", + 0, 0, + stg_ramdac_init, stg_ramdac_close, + NULL, NULL, NULL, NULL +}; diff --git a/src/video/vid_stg_ramdac.h b/src/video/vid_stg_ramdac.h index 8e383ea17..76dbfcd3e 100644 --- a/src/video/vid_stg_ramdac.h +++ b/src/video/vid_stg_ramdac.h @@ -1,14 +1,30 @@ -/* Copyright holders: Sarah Walker, 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. + * + * STG1702 true colour RAMDAC emulation header. + * + * Version: @(#)vid_stg_ramdac.h 1.0.0 2018/10/04 + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + */ typedef struct stg_ramdac_t { - int magic_count; - uint8_t command; - int index; - uint8_t regs[256]; + int magic_count, index; + uint8_t regs[256]; + uint8_t command; } stg_ramdac_t; -void stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *svga); -uint8_t stg_ramdac_in(uint16_t addr, stg_ramdac_t *ramdac, svga_t *svga); -float stg_getclock(int clock, void *p); +extern void stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *svga); +extern uint8_t stg_ramdac_in(uint16_t addr, stg_ramdac_t *ramdac, svga_t *svga); +extern float stg_getclock(int clock, void *p); + +extern const device_t stg_ramdac_device; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 742566e9a..1621c48f0 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -11,7 +11,7 @@ * This is intended to be used by another SVGA driver, * and not as a card in it's own right. * - * Version: @(#)vid_svga.c 1.0.32 2018/10/04 + * Version: @(#)vid_svga.c 1.0.33 2018/10/04 * * Authors: Sarah Walker, * Miran Grca, @@ -75,14 +75,6 @@ svga_set_override(svga_t *svga, int val) } -/* Used to add custom write modes, eg. by the CL-GD 54xx to add write modes 4 and 5. */ -void -svga_set_ven_write(svga_t *svga, void (*ven_write)(struct svga_t *svga, uint8_t val, uint32_t addr)) -{ - svga->ven_write = ven_write; -} - - void svga_out(uint16_t addr, uint8_t val, void *p) { @@ -803,6 +795,9 @@ svga_init(svga_t *svga, void *p, int memsize, svga->hwcursor_draw = hwcursor_draw; svga->overlay_draw = overlay_draw; + svga->hwcursor.xsize = svga->hwcursor.ysize = 32; + svga->hwcursor.yoff = 32; + mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, diff --git a/src/video/vid_svga.h b/src/video/vid_svga.h index 7aee461f4..4b498cb31 100644 --- a/src/video/vid_svga.h +++ b/src/video/vid_svga.h @@ -8,7 +8,7 @@ * * Generic SVGA handling. * - * Version: @(#)vid_svga.h 1.0.14 2018/10/04 + * Version: @(#)vid_svga.h 1.0.15 2018/10/04 * * Authors: Sarah Walker, * Miran Grca, @@ -28,57 +28,14 @@ typedef struct svga_t { mem_mapping_t mapping; - int enabled; - - uint8_t crtcreg, crtc[128], - gdcaddr, gdcreg[64], - attrff, attr_palette_enable, - attraddr, attrregs[32], - seqaddr, seqregs[64], - miscout, cgastat, - plane_mask, writemask, - colourcompare, colournocare, - scrblank, egapal[16], - *vram, *changedvram; - - int vidclock, fb_only, - fast; - - /*The three variables below allow us to implement memory maps like that seen on a 1MB Trio64 : - 0MB-1MB - VRAM - 1MB-2MB - VRAM mirror - 2MB-4MB - open bus - 4MB-xMB - mirror of above - - For the example memory map, decode_mask would be 4MB-1 (4MB address space), vram_max would be 2MB - (present video memory only responds to first 2MB), vram_mask would be 1MB-1 (video memory wraps at 1MB) - */ - uint32_t decode_mask; - uint32_t vram_max; - uint32_t vram_mask; - - uint8_t dac_mask, dac_status; - int dac_addr, dac_pos, - dac_r, dac_g, - ramdac_type; - - int readmode, writemode, - readplane, extvram, + int enabled, fast, vidclock, fb_only, + dac_addr, dac_pos, dac_r, dac_g, + ramdac_type, ext_overscan, + readmode, writemode, readplane, extvram, chain4, chain2_write, chain2_read, oddeven_page, oddeven_chain, - set_reset_disabled; - - uint32_t charseta, charsetb, - latch, ma_latch, - ma, maback, - write_bank, read_bank, - banked_mask, - ca, overscan_color, - pallook[256]; - - PALETTE vgapal; - - int vtotal, dispend, vsyncstart, split, vblankstart, + set_reset_disabled, + vtotal, dispend, vsyncstart, split, vblankstart, hdisp, hdisp_old, htotal, hdisp_time, rowoffset, lowres, interlace, linedbl, rowcount, bpp, dispon, hdisp_on, @@ -91,11 +48,32 @@ typedef struct svga_t hwcursor_on, overlay_on, hwcursor_oddeven, overlay_oddeven; - double clock; + /*The three variables below allow us to implement memory maps like that seen on a 1MB Trio64 : + 0MB-1MB - VRAM + 1MB-2MB - VRAM mirror + 2MB-4MB - open bus + 4MB-xMB - mirror of above + + For the example memory map, decode_mask would be 4MB-1 (4MB address space), vram_max would be 2MB + (present video memory only responds to first 2MB), vram_mask would be 1MB-1 (video memory wraps at 1MB) + */ + uint32_t decode_mask, vram_max, + vram_mask, + charseta, charsetb, + latch, ma_latch, + ma, maback, + write_bank, read_bank, + banked_mask, + ca, overscan_color, + pallook[256]; + + PALETTE vgapal; int64_t dispontime, dispofftime, vidtime; + double clock; + hwcursor_t hwcursor, hwcursor_latch, overlay, overlay_latch; @@ -112,13 +90,26 @@ typedef struct svga_t void (*vblank_start)(struct svga_t *svga); void (*ven_write)(struct svga_t *svga, uint8_t val, uint32_t addr); + float (*getclock)(int clock, void *p); /*If set then another device is driving the monitor output and the SVGA card should not attempt to display anything */ int override; void *p; - - uint8_t ksc5601_sbyte_mask; + + uint8_t crtc[128], gdcreg[64], attrregs[32], seqregs[64], + egapal[16], + *vram, *changedvram; + + uint8_t crtcreg, gdcaddr, + attrff, attr_palette_enable, attraddr, seqaddr, + miscout, cgastat, scrblank, + plane_mask, writemask, + colourcompare, colournocare, + dac_mask, dac_status, + ksc5601_sbyte_mask; + + void *ramdac, *clock_gen; } svga_t; @@ -156,9 +147,6 @@ uint8_t svga_in(uint16_t addr, void *p); svga_t *svga_get_pri(); void svga_set_override(svga_t *svga, int val); -void svga_set_ven_write(svga_t *svga, - void (*ven_write)(struct svga_t *svga, uint8_t val, uint32_t addr)); - void svga_set_ramdac_type(svga_t *svga, int type); void svga_close(svga_t *svga); diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index e95780796..53c05725c 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -47,7 +47,7 @@ * access size or host data has any affect, but the Windows 3.1 * driver always reads bytes and write words of 0xffff. * - * Version: @(#)vid_tgui9440.c 1.0.8 2018/09/19 + * Version: @(#)vid_tgui9440.c 1.0.9 2018/10/04 * * Authors: Sarah Walker, * Miran Grca, @@ -105,6 +105,9 @@ writes out 16 bytes. I don't think the access size or host data has any affect, but the Windows 3.1 driver always reads bytes and write words of 0xffff.*/ +#define ROM_TGUI_9400CXI L"roms/video/tgui9440/9400CXI.vbi" +#define ROM_TGUI_9440 L"roms/video/tgui9440/9440.vbi" + #define EXT_CTRL_16BIT 0x01 #define EXT_CTRL_MONO_EXPANSION 0x02 #define EXT_CTRL_MONO_TRANSPARENT 0x04 @@ -152,8 +155,6 @@ typedef struct tgui_t svga_t svga; int pci; - tkd8001_ramdac_t ramdac; /*TGUI9400CXi*/ - int type; struct @@ -282,7 +283,7 @@ void tgui_out(uint16_t addr, uint8_t val, void *p) case 0x3C6: if (tgui->type == TGUI_9400CXI) { - tkd8001_ramdac_out(addr, val, &tgui->ramdac, svga); + tkd8001_ramdac_out(addr, val, svga->ramdac, svga); return; } if (tgui->ramdac_state == 4) @@ -309,7 +310,7 @@ void tgui_out(uint16_t addr, uint8_t val, void *p) case 0x3C7: case 0x3C8: case 0x3C9: if (tgui->type == TGUI_9400CXI) { - tkd8001_ramdac_out(addr, val, &tgui->ramdac, svga); + tkd8001_ramdac_out(addr, val, svga->ramdac, svga); return; } tgui->ramdac_state = 0; @@ -463,14 +464,14 @@ uint8_t tgui_in(uint16_t addr, void *p) break; case 0x3C6: if (tgui->type == TGUI_9400CXI) - return tkd8001_ramdac_in(addr, &tgui->ramdac, svga); + return tkd8001_ramdac_in(addr, svga->ramdac, svga); if (tgui->ramdac_state == 4) return tgui->ramdac_ctrl; tgui->ramdac_state++; break; case 0x3C7: case 0x3C8: case 0x3C9: if (tgui->type == TGUI_9400CXI) - return tkd8001_ramdac_in(addr, &tgui->ramdac, svga); + return tkd8001_ramdac_in(addr, svga->ramdac, svga); tgui->ramdac_state = 0; break; case 0x3CF: @@ -777,94 +778,6 @@ void tgui_pci_write(int func, int addr, uint8_t val, void *p) } } -static void *tgui_init(const device_t *info, wchar_t *bios_fn, int type) -{ - tgui_t *tgui = malloc(sizeof(tgui_t)); - memset(tgui, 0, sizeof(tgui_t)); - - tgui->vram_size = device_get_config_int("memory") << 20; - tgui->vram_mask = tgui->vram_size - 1; - - tgui->type = type; - - tgui->pci = !!(info->flags & DEVICE_PCI); - - rom_init(&tgui->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tgui); - - svga_init(&tgui->svga, tgui, tgui->vram_size, - tgui_recalctimings, - tgui_in, tgui_out, - tgui_hwcursor_draw, - NULL); - - mem_mapping_add(&tgui->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, tgui_accel_write_fb_b, tgui_accel_write_fb_w, tgui_accel_write_fb_l, NULL, 0, &tgui->svga); - mem_mapping_add(&tgui->accel_mapping, 0xbc000, 0x4000, tgui_accel_read, tgui_accel_read_w, tgui_accel_read_l, tgui_accel_write, tgui_accel_write_w, tgui_accel_write_l, NULL, 0, tgui); - mem_mapping_disable(&tgui->accel_mapping); - - io_sethandler(0x03c0, 0x0020, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); - if (tgui->type >= TGUI_9440) - io_sethandler(0x43c8, 0x0002, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); - - if ((info->flags & DEVICE_PCI) && (tgui->type >= TGUI_9440)) - pci_add_card(PCI_ADD_VIDEO, tgui_pci_read, tgui_pci_write, tgui); - - tgui->wake_fifo_thread = thread_create_event(); - tgui->fifo_not_full_event = thread_create_event(); - tgui->fifo_thread = thread_create(fifo_thread, tgui); - - return tgui; -} - -static void *tgui9400cxi_init(const device_t *info) -{ - return tgui_init(info, L"roms/video/tgui9440/9400CXI.vbi", TGUI_9400CXI); -} - -static void *tgui9440_init(const device_t *info) -{ - return tgui_init(info, L"roms/video/tgui9440/9440.vbi", TGUI_9440); -} - -static int tgui9400cxi_available() -{ - return rom_present(L"roms/video/tgui9440/9400CXI.vbi"); -} - -static int tgui9440_available() -{ - return rom_present(L"roms/video/tgui9440/9440.vbi"); -} - -void tgui_close(void *p) -{ - tgui_t *tgui = (tgui_t *)p; - - svga_close(&tgui->svga); - - thread_kill(tgui->fifo_thread); - thread_destroy_event(tgui->wake_fifo_thread); - thread_destroy_event(tgui->fifo_not_full_event); - - free(tgui); -} - -void tgui_speed_changed(void *p) -{ - tgui_t *tgui = (tgui_t *)p; - - svga_recalctimings(&tgui->svga); -} - -void tgui_force_redraw(void *p) -{ - tgui_t *tgui = (tgui_t *)p; - - tgui->svga.fullchange = changeframecount; -} - - static uint8_t tgui_ext_linear_read(uint32_t addr, void *p) { svga_t *svga = (svga_t *)p; @@ -1734,6 +1647,102 @@ void tgui_accel_write_fb_l(uint32_t addr, uint32_t val, void *p) svga_writel_linear(addr, val, svga); } +static void *tgui_init(const device_t *info) +{ + const wchar_t *bios_fn; + int type = info->local; + + tgui_t *tgui = malloc(sizeof(tgui_t)); + memset(tgui, 0, sizeof(tgui_t)); + + tgui->vram_size = device_get_config_int("memory") << 20; + tgui->vram_mask = tgui->vram_size - 1; + + tgui->type = type; + + tgui->pci = !!(info->flags & DEVICE_PCI); + + switch(info->local) { + case TGUI_9400CXI: + bios_fn = ROM_TGUI_9400CXI; + break; + case TGUI_9440: + bios_fn = ROM_TGUI_9440; + break; + default: + free(tgui); + return NULL; + } + + rom_init(&tgui->bios_rom, (wchar_t *) bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tgui); + + svga_init(&tgui->svga, tgui, tgui->vram_size, + tgui_recalctimings, + tgui_in, tgui_out, + tgui_hwcursor_draw, + NULL); + + if (tgui->type == TGUI_9400CXI) + tgui->svga.ramdac = device_add(&tkd8001_ramdac_device); + + mem_mapping_add(&tgui->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, tgui_accel_write_fb_b, tgui_accel_write_fb_w, tgui_accel_write_fb_l, NULL, 0, &tgui->svga); + mem_mapping_add(&tgui->accel_mapping, 0xbc000, 0x4000, tgui_accel_read, tgui_accel_read_w, tgui_accel_read_l, tgui_accel_write, tgui_accel_write_w, tgui_accel_write_l, NULL, 0, tgui); + mem_mapping_disable(&tgui->accel_mapping); + + io_sethandler(0x03c0, 0x0020, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); + if (tgui->type >= TGUI_9440) + io_sethandler(0x43c8, 0x0002, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); + + if ((info->flags & DEVICE_PCI) && (tgui->type >= TGUI_9440)) + pci_add_card(PCI_ADD_VIDEO, tgui_pci_read, tgui_pci_write, tgui); + + tgui->wake_fifo_thread = thread_create_event(); + tgui->fifo_not_full_event = thread_create_event(); + tgui->fifo_thread = thread_create(fifo_thread, tgui); + + return tgui; +} + +static int tgui9400cxi_available() +{ + return rom_present(L"roms/video/tgui9440/9400CXI.vbi"); +} + +static int tgui9440_available() +{ + return rom_present(L"roms/video/tgui9440/9440.vbi"); +} + +void tgui_close(void *p) +{ + tgui_t *tgui = (tgui_t *)p; + + svga_close(&tgui->svga); + + thread_kill(tgui->fifo_thread); + thread_destroy_event(tgui->wake_fifo_thread); + thread_destroy_event(tgui->fifo_not_full_event); + + free(tgui); +} + +void tgui_speed_changed(void *p) +{ + tgui_t *tgui = (tgui_t *)p; + + svga_recalctimings(&tgui->svga); +} + +void tgui_force_redraw(void *p) +{ + tgui_t *tgui = (tgui_t *)p; + + tgui->svga.fullchange = changeframecount; +} + + static const device_config_t tgui9440_config[] = { { @@ -1765,8 +1774,8 @@ const device_t tgui9400cxi_device = { "Trident TGUI 9400CXi", DEVICE_VLB, - 0, - tgui9400cxi_init, + TGUI_9400CXI, + tgui_init, tgui_close, NULL, tgui9400cxi_available, @@ -1779,8 +1788,8 @@ const device_t tgui9440_vlb_device = { "Trident TGUI 9440 VLB", DEVICE_VLB, - 0, - tgui9440_init, + TGUI_9440, + tgui_init, tgui_close, NULL, tgui9440_available, @@ -1793,12 +1802,12 @@ const device_t tgui9440_pci_device = { "Trident TGUI 9440 PCI", DEVICE_PCI, - 0, - tgui9440_init, + TGUI_9440, + tgui_init, tgui_close, NULL, tgui9440_available, tgui_speed_changed, tgui_force_redraw, tgui9440_config -}; \ No newline at end of file +}; diff --git a/src/video/vid_tkd8001_ramdac.c b/src/video/vid_tkd8001_ramdac.c index e2d266cac..8f0c306fa 100644 --- a/src/video/vid_tkd8001_ramdac.c +++ b/src/video/vid_tkd8001_ramdac.c @@ -8,73 +8,109 @@ * * Trident TKD8001 RAMDAC emulation. * - * Version: @(#)vid_tkd8001_ramdac.c 1.0.2 2017/11/04 + * Version: @(#)vid_tkd8001_ramdac.c 1.0.3 2018/10/04 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. */ #include #include +#include #include #include #include "../86box.h" +#include "../device.h" #include "../mem.h" #include "video.h" #include "vid_svga.h" #include "vid_tkd8001_ramdac.h" -void tkd8001_ramdac_out(uint16_t addr, uint8_t val, tkd8001_ramdac_t *ramdac, svga_t *svga) +void +tkd8001_ramdac_out(uint16_t addr, uint8_t val, tkd8001_ramdac_t *ramdac, svga_t *svga) { - switch (addr) - { - case 0x3C6: - if (ramdac->state == 4) - { - ramdac->state = 0; - ramdac->ctrl = val; - switch (val >> 5) - { - case 0: case 1: case 2: case 3: - svga->bpp = 8; - break; - case 5: - svga->bpp = 15; - break; - case 6: - svga->bpp = 24; - break; - case 7: - svga->bpp = 16; - break; - } - return; - } - break; - case 0x3C7: case 0x3C8: case 0x3C9: - ramdac->state = 0; - break; - } - svga_out(addr, val, svga); + switch (addr) { + case 0x3C6: + if (ramdac->state == 4) { + ramdac->state = 0; + ramdac->ctrl = val; + switch (val >> 5) { + case 0: + case 1: + case 2: + case 3: + svga->bpp = 8; + break; + case 5: + svga->bpp = 15; + break; + case 6: + svga->bpp = 24; + break; + case 7: + svga->bpp = 16; + break; + } + return; + } + break; + case 0x3C7: + case 0x3C8: + case 0x3C9: + ramdac->state = 0; + break; + } + + svga_out(addr, val, svga); } -uint8_t tkd8001_ramdac_in(uint16_t addr, tkd8001_ramdac_t *ramdac, svga_t *svga) + +uint8_t +tkd8001_ramdac_in(uint16_t addr, tkd8001_ramdac_t *ramdac, svga_t *svga) { - switch (addr) - { - case 0x3C6: - if (ramdac->state == 4) - { - return ramdac->ctrl; - } - ramdac->state++; - break; - case 0x3C7: case 0x3C8: case 0x3C9: - ramdac->state = 0; - break; - } - return svga_in(addr, svga); + switch (addr) { + case 0x3C6: + if (ramdac->state == 4) + return ramdac->ctrl; + ramdac->state++; + break; + case 0x3C7: + case 0x3C8: + case 0x3C9: + ramdac->state = 0; + break; + } + return svga_in(addr, svga); } + + +static void * +tkd8001_ramdac_init(const device_t *info) +{ + tkd8001_ramdac_t *ramdac = (tkd8001_ramdac_t *) malloc(sizeof(tkd8001_ramdac_t)); + memset(ramdac, 0, sizeof(tkd8001_ramdac_t)); + + return ramdac; +} + + +static void +tkd8001_ramdac_close(void *priv) +{ + tkd8001_ramdac_t *ramdac = (tkd8001_ramdac_t *) priv; + + if (ramdac) + free(ramdac); +} + + +const device_t tkd8001_ramdac_device = +{ + "Trident TKD8001 RAMDAC", + 0, 0, + tkd8001_ramdac_init, tkd8001_ramdac_close, + NULL, NULL, NULL, NULL +}; diff --git a/src/video/vid_tkd8001_ramdac.h b/src/video/vid_tkd8001_ramdac.h index f83ba978d..3cfa166b0 100644 --- a/src/video/vid_tkd8001_ramdac.h +++ b/src/video/vid_tkd8001_ramdac.h @@ -1,11 +1,28 @@ -/* Copyright holders: Sarah Walker - 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. + * + * Trident TKD8001 RAMDAC emulation header. + * + * Version: @(#)vid_tkd8001_ramdac.h 1.0.0 2018/10/04 + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + */ typedef struct tkd8001_ramdac_t { - int state; - uint8_t ctrl; + int state; + uint8_t ctrl; } tkd8001_ramdac_t; -void tkd8001_ramdac_out(uint16_t addr, uint8_t val, tkd8001_ramdac_t *ramdac, svga_t *svga); -uint8_t tkd8001_ramdac_in(uint16_t addr, tkd8001_ramdac_t *ramdac, svga_t *svga); +extern void tkd8001_ramdac_out(uint16_t addr, uint8_t val, tkd8001_ramdac_t *ramdac, svga_t *svga); +extern uint8_t tkd8001_ramdac_in(uint16_t addr, tkd8001_ramdac_t *ramdac, svga_t *svga); + +extern const device_t tkd8001_ramdac_device; diff --git a/src/video/vid_tvga.c b/src/video/vid_tvga.c index 199d140e4..77c8236f5 100644 --- a/src/video/vid_tvga.c +++ b/src/video/vid_tvga.c @@ -8,7 +8,7 @@ * * Trident TVGA (8900D) emulation. * - * Version: @(#)vid_tvga.c 1.0.7 2018/09/19 + * Version: @(#)vid_tvga.c 1.0.8 2018/10/04 * * Authors: Sarah Walker, * Miran Grca, @@ -39,8 +39,7 @@ typedef struct tvga_t mem_mapping_t accel_mapping; svga_t svga; - tkd8001_ramdac_t ramdac; - + rom_t bios_rom; uint8_t tvga_3d8, tvga_3d9; @@ -111,7 +110,7 @@ void tvga_out(uint16_t addr, uint8_t val, void *p) break; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - tkd8001_ramdac_out(addr, val, &tvga->ramdac, svga); + tkd8001_ramdac_out(addr, val, svga->ramdac, svga); return; case 0x3CF: @@ -199,7 +198,7 @@ uint8_t tvga_in(uint16_t addr, void *p) } break; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - return tkd8001_ramdac_in(addr, &tvga->ramdac, svga); + return tkd8001_ramdac_in(addr, svga->ramdac, svga); case 0x3D4: return svga->crtcreg; case 0x3D5: @@ -311,6 +310,8 @@ static void *tvga8900d_init(const device_t *info) tvga_in, tvga_out, NULL, NULL); + + tvga->svga.ramdac = device_add(&tkd8001_ramdac_device); io_sethandler(0x03c0, 0x0020, tvga_in, NULL, NULL, tvga_out, NULL, NULL, tvga); diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index fbf3c7949..fc46ff2ed 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -8,7 +8,7 @@ # # Makefile for Win32 (MinGW32) environment. # -# Version: @(#)Makefile.mingw 1.0.127 2018/09/30 +# Version: @(#)Makefile.mingw 1.0.128 2018/10/04 # # Authors: Miran Grca, # Fred N. van Kempen, @@ -530,7 +530,7 @@ VIDOBJ := video.o \ vid_ati_eeprom.o \ vid_ati18800.o vid_ati28800.o \ vid_ati_mach64.o vid_ati68860_ramdac.o \ - vid_bt485_ramdac.o \ + vid_bt48x_ramdac.o \ vid_icd2061.o vid_ics2595.o \ vid_cl54xx.o \ vid_et4000.o vid_sc1502x_ramdac.o \