Fixes for the (S)VGA common DAC and some card-specific DAT's (ATi 68860, BT48x family, and the Cirrus Logic DAC), fixes Star Control II among other things.

This commit is contained in:
OBattler
2018-10-04 01:19:43 +02:00
parent 6b938d63c3
commit ed92602dad
883 changed files with 444853 additions and 88 deletions

176
src/video/startblit.fnd Normal file
View File

@@ -0,0 +1,176 @@
---------- STARTBLIT.FND
---------- VIDEO.C
---------- VIDEO.H
---------- VID_ATI18800.C
---------- VID_ATI18800.H
---------- VID_ATI28800.C
---------- VID_ATI28800.H
---------- VID_ATI68860_RAMDAC.C
---------- VID_ATI68860_RAMDAC.H
---------- VID_ATI_EEPROM.C
---------- VID_ATI_EEPROM.H
---------- VID_ATI_MACH64.C
---------- VID_ATI_MACH64.H
---------- VID_BT485_RAMDAC.C
---------- VID_BT485_RAMDAC.H
---------- VID_CGA.C
---------- VID_CGA.H
---------- VID_CGA_COMP.C
---------- VID_CGA_COMP.H
---------- VID_CL54XX.C
---------- VID_CL54XX.H
---------- VID_COLORPLUS.C
---------- VID_COLORPLUS.H
---------- VID_COMPAQ_CGA.C
---------- VID_COMPAQ_CGA.H
---------- VID_EGA.C
---------- VID_EGA.H
---------- VID_EGA_RENDER.C
---------- VID_EGA_RENDER.H
---------- VID_ET4000.C
---------- VID_ET4000.H
---------- VID_ET4000W32.C
---------- VID_ET4000W32.H
---------- VID_ET4000W32I.C
---------- VID_GENIUS.C
---------- VID_GENIUS.H
---------- VID_HERCULES.C
---------- VID_HERCULES.H
---------- VID_HERCULESPLUS.C
---------- VID_HERCULESPLUS.H
---------- VID_ICD2061.C
---------- VID_ICD2061.H
---------- VID_ICS2595.C
---------- VID_ICS2595.H
---------- VID_INCOLOR.C
---------- VID_INCOLOR.H
---------- VID_MDA.C
---------- VID_MDA.H
---------- VID_NVIDIA.C
---------- VID_NVIDIA.H
---------- VID_NV_RIVA128.C
---------- VID_NV_RIVA128.H
---------- VID_OAK_OTI.C
---------- VID_OAK_OTI.H
---------- VID_PARADISE.C
---------- VID_PARADISE.H
---------- VID_S3.C
---------- VID_S3.H
---------- VID_S3_VIRGE.C
---------- VID_S3_VIRGE.H
---------- VID_SC1502X_RAMDAC.C
---------- VID_SC1502X_RAMDAC.H
---------- VID_SDAC_RAMDAC.C
---------- VID_SDAC_RAMDAC.H
---------- VID_STG_RAMDAC.C
---------- VID_STG_RAMDAC.H
---------- VID_SVGA.C
---------- VID_SVGA.H
---------- VID_SVGA_RENDER.C
---------- VID_SVGA_RENDER.H
---------- VID_TABLE.C
---------- VID_TGUI9440.C
---------- VID_TGUI9440.H
---------- VID_TI_CF62011.C
---------- VID_TI_CF62011.H
---------- VID_TKD8001_RAMDAC.C
---------- VID_TKD8001_RAMDAC.H
---------- VID_TVGA.C
---------- VID_TVGA.H
---------- VID_VGA.C
---------- VID_VGA.H
---------- VID_VOODOO.C
---------- VID_VOODOO.H
---------- VID_VOODOO_CODEGEN_X86-64.H
---------- VID_VOODOO_CODEGEN_X86.H
---------- VID_VOODOO_DITHER.H
---------- VID_WY700.C
---------- VID_WY700.H

View File

@@ -0,0 +1,197 @@
/*
* 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 (for Mach64)
*
* ATI 68860/68880 Truecolor DACs:
* REG08 (R/W):
* bit 0-? Always 2 ??
*
* REG0A (R/W):
* bit 0-? Always 1Dh ??
*
* REG0B (R/W): (GMR ?)
* bit 0-7 Mode. 82h: 4bpp, 83h: 8bpp,
* A0h: 15bpp, A1h: 16bpp, C0h: 24bpp,
* E3h: 32bpp (80h for VGA modes ?)
*
* REG0C (R/W): Device Setup Register A
* bit 0 Controls 6/8bit DAC. 0: 8bit DAC/LUT, 1: 6bit DAC/LUT
* 2-3 Depends on Video memory (= VRAM width ?) .
* 1: Less than 1Mb, 2: 1Mb, 3: > 1Mb
* 5-6 Always set ?
* 7 If set can remove "snow" in some cases
* (A860_Delay_L ?) ??
*
* Version: @(#)vid_ati68860.c 1.0.3 2017/11/04
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016,2017 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <wchar.h>
#include "../86box.h"
#include "../mem.h"
#include "video.h"
#include "vid_svga.h"
#include "vid_ati68860_ramdac.h"
#include "vid_svga_render.h"
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_write = 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_write > 1)
break;
ramdac->pal[ramdac->dac_write].r = ramdac->dac_r;
ramdac->pal[ramdac->dac_write].g = ramdac->dac_g;
ramdac->pal[ramdac->dac_write].b = val;
if (ramdac->ramdac_type == RAMDAC_8BIT)
ramdac->pallook[ramdac->dac_write] = makecol32(ramdac->pal[ramdac->dac_write].r, ramdac->pal[ramdac->dac_write].g, ramdac->pal[ramdac->dac_write].b);
else
ramdac->pallook[ramdac->dac_write] = makecol32((ramdac->pal[ramdac->dac_write].r & 0x3f) * 4, (ramdac->pal[ramdac->dac_write].g & 0x3f) * 4, (ramdac->pal[ramdac->dac_write].b & 0x3f) * 4);
ramdac->dac_pos = 0;
ramdac->dac_write = (ramdac->dac_write + 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 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;
}
void ati68860_ramdac_init(ati68860_ramdac_t *ramdac)
{
ramdac->render = svga_render_8bpp_highres;
}
void ati68860_set_ramdac_type(ati68860_ramdac_t *ramdac, int type)
{
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);
}
}
}

View File

@@ -0,0 +1,197 @@
/*
* 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 (for Mach64)
*
* ATI 68860/68880 Truecolor DACs:
* REG08 (R/W):
* bit 0-? Always 2 ??
*
* REG0A (R/W):
* bit 0-? Always 1Dh ??
*
* REG0B (R/W): (GMR ?)
* bit 0-7 Mode. 82h: 4bpp, 83h: 8bpp,
* A0h: 15bpp, A1h: 16bpp, C0h: 24bpp,
* E3h: 32bpp (80h for VGA modes ?)
*
* REG0C (R/W): Device Setup Register A
* bit 0 Controls 6/8bit DAC. 0: 8bit DAC/LUT, 1: 6bit DAC/LUT
* 2-3 Depends on Video memory (= VRAM width ?) .
* 1: Less than 1Mb, 2: 1Mb, 3: > 1Mb
* 5-6 Always set ?
* 7 If set can remove "snow" in some cases
* (A860_Delay_L ?) ??
*
* Version: @(#)vid_ati68860.c 1.0.3 2017/11/04
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016,2017 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <wchar.h>
#include "../86box.h"
#include "../mem.h"
#include "video.h"
#include "vid_svga.h"
#include "vid_ati68860_ramdac.h"
#include "vid_svga_render.h"
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_write = 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_write > 1)
break;
ramdac->pal[ramdac->dac_write].r = ramdac->dac_r;
ramdac->pal[ramdac->dac_write].g = ramdac->dac_g;
ramdac->pal[ramdac->dac_write].b = val;
if (ramdac->ramdac_type == RAMDAC_8BIT)
ramdac->pallook[ramdac->dac_write] = makecol32(ramdac->pal[ramdac->dac_write].r, ramdac->pal[ramdac->dac_write].g, ramdac->pal[ramdac->dac_write].b);
else
ramdac->pallook[ramdac->dac_write] = makecol32((ramdac->pal[ramdac->dac_write].r & 0x3f) * 4, (ramdac->pal[ramdac->dac_write].g & 0x3f) * 4, (ramdac->pal[ramdac->dac_write].b & 0x3f) * 4);
ramdac->dac_pos = 0;
ramdac->dac_write = (ramdac->dac_write + 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 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;
}
void ati68860_ramdac_init(ati68860_ramdac_t *ramdac)
{
ramdac->render = svga_render_8bpp_highres;
}
void ati68860_set_ramdac_type(ati68860_ramdac_t *ramdac, int type)
{
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);
}
}
}

View File

@@ -0,0 +1,197 @@
/*
* 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 (for Mach64)
*
* ATI 68860/68880 Truecolor DACs:
* REG08 (R/W):
* bit 0-? Always 2 ??
*
* REG0A (R/W):
* bit 0-? Always 1Dh ??
*
* REG0B (R/W): (GMR ?)
* bit 0-7 Mode. 82h: 4bpp, 83h: 8bpp,
* A0h: 15bpp, A1h: 16bpp, C0h: 24bpp,
* E3h: 32bpp (80h for VGA modes ?)
*
* REG0C (R/W): Device Setup Register A
* bit 0 Controls 6/8bit DAC. 0: 8bit DAC/LUT, 1: 6bit DAC/LUT
* 2-3 Depends on Video memory (= VRAM width ?) .
* 1: Less than 1Mb, 2: 1Mb, 3: > 1Mb
* 5-6 Always set ?
* 7 If set can remove "snow" in some cases
* (A860_Delay_L ?) ??
*
* Version: @(#)vid_ati68860.c 1.0.3 2017/11/04
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016,2017 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <wchar.h>
#include "../86box.h"
#include "../mem.h"
#include "video.h"
#include "vid_svga.h"
#include "vid_ati68860_ramdac.h"
#include "vid_svga_render.h"
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_write = 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_write > 1)
break;
ramdac->pal[ramdac->dac_write].r = ramdac->dac_r;
ramdac->pal[ramdac->dac_write].g = ramdac->dac_g;
ramdac->pal[ramdac->dac_write].b = val;
if (ramdac->ramdac_type == RAMDAC_8BIT)
ramdac->pallook[ramdac->dac_write] = makecol32(ramdac->pal[ramdac->dac_write].r, ramdac->pal[ramdac->dac_write].g, ramdac->pal[ramdac->dac_write].b);
else
ramdac->pallook[ramdac->dac_write] = makecol32((ramdac->pal[ramdac->dac_write].r & 0x3f) * 4, (ramdac->pal[ramdac->dac_write].g & 0x3f) * 4, (ramdac->pal[ramdac->dac_write].b & 0x3f) * 4);
ramdac->dac_pos = 0;
ramdac->dac_write = (ramdac->dac_write + 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 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;
}
void ati68860_ramdac_init(ati68860_ramdac_t *ramdac)
{
ramdac->render = svga_render_8bpp_highres;
}
void ati68860_set_ramdac_type(ati68860_ramdac_t *ramdac, int type)
{
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);
}
}
}

View File

@@ -0,0 +1,20 @@
/* Copyright holders: Sarah Walker
see COPYING for more details
*/
typedef struct ati68860_ramdac_t
{
uint8_t regs[16];
void (*render)(struct svga_t *svga);
int dac_write, 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);

View File

@@ -28,13 +28,13 @@
* 7 If set can remove "snow" in some cases
* (A860_Delay_L ?) ??
*
* Version: @(#)vid_ati68860.c 1.0.3 2017/11/04
* Version: @(#)vid_ati68860.c 1.0.4 2018/10/04
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016,2017 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
@@ -69,7 +69,7 @@ void ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac,
switch (addr & 0xf)
{
case 0x4:
ramdac->dac_write = val;
ramdac->dac_addr = val;
ramdac->dac_pos = 0;
break;
case 0x5:
@@ -84,17 +84,17 @@ void ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac,
ramdac->dac_pos++;
break;
case 2:
if (ramdac->dac_write > 1)
if (ramdac->dac_addr > 1)
break;
ramdac->pal[ramdac->dac_write].r = ramdac->dac_r;
ramdac->pal[ramdac->dac_write].g = ramdac->dac_g;
ramdac->pal[ramdac->dac_write].b = val;
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_write] = makecol32(ramdac->pal[ramdac->dac_write].r, ramdac->pal[ramdac->dac_write].g, ramdac->pal[ramdac->dac_write].b);
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_write] = makecol32((ramdac->pal[ramdac->dac_write].r & 0x3f) * 4, (ramdac->pal[ramdac->dac_write].g & 0x3f) * 4, (ramdac->pal[ramdac->dac_write].b & 0x3f) * 4);
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_write = (ramdac->dac_write + 1) & 255;
ramdac->dac_addr = (ramdac->dac_addr + 1) & 255;
break;
}
break;

View File

@@ -6,7 +6,7 @@ typedef struct ati68860_ramdac_t
uint8_t regs[16];
void (*render)(struct svga_t *svga);
int dac_write, dac_pos;
int dac_addr, dac_pos;
int dac_r, dac_g;
PALETTE pal;
uint32_t pallook[2];

View File

@@ -0,0 +1,348 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Emulation of the Brooktree BT485 and BT485A true colour
* RAM DAC's.
*
* Version: @(#)vid_bt485_ramdac.c 1.0.11 2018/10/03
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* TheCollector1995,
*
* Copyright 2016-2018 Miran Grca.
* Copyright 2018 TheCollector1995.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <wchar.h>
#include "../86box.h"
#include "../mem.h"
#include "video.h"
#include "vid_svga.h"
#include "vid_bt485_ramdac.h"
static void
bt485_set_bpp(bt485_ramdac_t *ramdac, svga_t *svga)
{
if (!(ramdac->cr2 & 0x20))
svga->bpp = 8;
else switch ((ramdac->cr1 >> 5) & 0x03) {
case 0:
svga->bpp = 32;
break;
case 1:
if (ramdac->cr1 & 0x08)
svga->bpp = 16;
else
svga->bpp = 15;
break;
case 2:
svga->bpp = 8;
break;
case 3:
svga->bpp = 4;
break;
}
svga_recalctimings(svga);
}
void
bt485_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt485_ramdac_t *ramdac, svga_t *svga)
{
uint32_t o32;
uint8_t *cd;
uint8_t index;
uint8_t rs = (addr & 0x03);
rs |= (!!rs2 << 2);
rs |= (!!rs3 << 3);
switch (rs) {
case 0x00: /* Palette Write Index Register (RS value = 0000) */
case 0x03: /* Palette Read Index Register (RS value = 0011) */
svga_out(addr, val, svga);
if ((ramdac->type >= BT485) && (svga->hwcursor.xsize == 64)) {
svga->dac_read |= ((int) (ramdac->cr3 & 0x03) << 8);
svga->dac_write |= ((int) (ramdac->cr3 & 0x03) << 8);
}
break;
case 0x01: /* Palette Data Register (RS value = 0001) */
case 0x02: /* Pixel Read Mask Register (RS value = 0010) */
svga_out(addr, val, svga);
break;
case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */
ramdac->ext_write = val;
svga->dac_pos = 0;
svga->dac_status = 0;
ramdac->ext_read = (val - 1) & 0xff;
break;
case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */
ramdac->ext_read = val;
svga->dac_pos = 0;
svga->dac_status = 3;
ramdac->ext_write = (val + 1) & 0xff;
break;
case 0x05: /* Ext Palette Data Register (RS value = 0101) */
svga->dac_status = 0;
svga->fullchange = changeframecount;
switch (svga->dac_pos) {
case 0:
svga->dac_r = val;
svga->dac_pos++;
break;
case 1:
svga->dac_g = val;
svga->dac_pos++;
break;
case 2:
index = ramdac->ext_write & 3;
ramdac->extpal[index].r = svga->dac_r;
ramdac->extpal[index].g = svga->dac_g;
ramdac->extpal[index].b = val;
if (svga->ramdac_type == RAMDAC_8BIT)
ramdac->extpallook[index] = makecol32(ramdac->extpal[index].r, ramdac->extpal[index].g, ramdac->extpal[index].b);
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) {
o32 = svga->overscan_color;
svga->overscan_color = ramdac->extpallook[0];
if (o32 != svga->overscan_color)
svga_recalctimings(svga);
}
ramdac->ext_write = (ramdac->ext_write + 1);
svga->dac_pos = 0;
break;
}
break;
case 0x06: /* Command Register 0 (RS value = 0110) */
ramdac->cr0 = val;
svga->ramdac_type = (val & 0x02) ? RAMDAC_8BIT : RAMDAC_6BIT;
break;
case 0x08: /* Command Register 1 (RS value = 1000) */
ramdac->cr1 = val;
bt485_set_bpp(ramdac, svga);
break;
case 0x09: /* Command Register 2 (RS value = 1001) */
ramdac->cr2 = val;
svga->hwcursor.ena = !!(val & 0x03);
pclog("Hardware cursor is now %s\n", svga->hwcursor.ena ? "ON" : "OFF");
bt485_set_bpp(ramdac, svga);
break;
case 0x0a:
if ((ramdac->type >= BT485) && (ramdac->cr0 & 0x80)) {
switch ((svga->dac_write & 0xff)) {
case 0x01:
/* Command Register 3 (RS value = 1010) */
ramdac->cr3 = val;
svga->hwcursor.xsize = svga->hwcursor.ysize = (val & 4) ? 64 : 32;
svga->hwcursor.yoff = (svga->hwcursor.ysize == 32) ? 32 : 0;
svga->hwcursor.x = ramdac->hwc_x - svga->hwcursor.xsize;
svga->hwcursor.y = ramdac->hwc_y - svga->hwcursor.ysize;
if (svga->hwcursor.xsize == 64)
svga->dac_write = (svga->dac_write & 0x00ff) | ((val & 0x03) << 8);
svga_recalctimings(svga);
break;
case 0x02:
case 0x20:
case 0x21:
case 0x22:
if (ramdac->type != BT485A)
break;
else if (svga->dac_write == 2) {
ramdac->cr4 = val;
break;
}
break;
}
}
break;
case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */
if (svga->hwcursor.xsize == 64)
cd = (uint8_t *) ramdac->cursor64_data;
else
cd = (uint8_t *) ramdac->cursor32_data;
cd[svga->dac_write] = val;
svga->dac_write++;
svga->dac_write &= ((svga->hwcursor.xsize == 64) ? 0x03ff : 0x00ff);
break;
case 0x0c: /* Cursor X Low Register (RS value = 1100) */
ramdac->hwc_x = (ramdac->hwc_x & 0x0f00) | val;
svga->hwcursor.x = ramdac->hwc_x - svga->hwcursor.xsize;
break;
case 0x0d: /* Cursor X High Register (RS value = 1101) */
ramdac->hwc_x = (ramdac->hwc_x & 0x00ff) | ((val & 0x0f) << 8);
svga->hwcursor.x = ramdac->hwc_x - svga->hwcursor.xsize;
break;
case 0x0e: /* Cursor Y Low Register (RS value = 1110) */
ramdac->hwc_y = (ramdac->hwc_y & 0x0f00) | val;
svga->hwcursor.y = ramdac->hwc_y - svga->hwcursor.ysize;
break;
case 0x0f: /* Cursor Y High Register (RS value = 1111) */
ramdac->hwc_y = (ramdac->hwc_y & 0x00ff) | ((val & 0x0f) << 8);
svga->hwcursor.y = ramdac->hwc_y - svga->hwcursor.ysize;
break;
}
return;
}
uint8_t
bt485_ramdac_in(uint16_t addr, int rs2, int rs3, bt485_ramdac_t *ramdac, svga_t *svga)
{
uint8_t temp = 0xff;
uint8_t *cd;
uint8_t index;
uint8_t rs = (addr & 0x03);
rs |= (!!rs2 << 2);
rs |= (!!rs3 << 3);
switch (rs) {
case 0x00: /* Palette Write Index Register (RS value = 0000) */
case 0x01: /* Palette Data Register (RS value = 0001) */
case 0x02: /* Pixel Read Mask Register (RS value = 0010) */
temp = svga_in(addr, svga);
break;
case 0x03: /* Palette Read Index Register (RS value = 0011) */
temp = svga->dac_read & 0xff;
break;
case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */
temp = ramdac->ext_write;
break;
case 0x05: /* Ext Palette Data Register (RS value = 0101) */
index = ramdac->ext_read & 3;
svga->dac_status = 3;
switch (svga->dac_pos) {
case 0:
svga->dac_pos++;
if (svga->ramdac_type == RAMDAC_8BIT)
temp = ramdac->extpal[index].r;
else
temp = ramdac->extpal[index].r & 0x3f;
case 1:
svga->dac_pos++;
if (svga->ramdac_type == RAMDAC_8BIT)
temp = ramdac->extpal[index].g;
else
temp = ramdac->extpal[index].g & 0x3f;
case 2:
svga->dac_pos=0;
ramdac->ext_read = ramdac->ext_read + 1;
if (svga->ramdac_type == RAMDAC_8BIT)
temp = ramdac->extpal[index].b;
else
temp = ramdac->extpal[index].b & 0x3f;
}
break;
case 0x06: /* Command Register 0 (RS value = 0110) */
temp = ramdac->cr0;
break;
case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */
temp = ramdac->ext_read;
break;
case 0x08: /* Command Register 1 (RS value = 1000) */
temp = ramdac->cr1;
break;
case 0x09: /* Command Register 2 (RS value = 1001) */
temp = ramdac->cr2;
break;
case 0x0a:
if ((ramdac->type >= BT485) && (ramdac->cr0 & 0x80)) {
switch ((svga->dac_write & 0xff)) {
case 0x00:
temp = ramdac->status | (svga->dac_status ? 0x04 : 0x00);
break;
case 0x01:
temp = ramdac->cr3;
break;
case 0x02:
case 0x20:
case 0x21:
case 0x22:
if (ramdac->type != BT485A)
break;
else if (svga->dac_write == 2) {
temp = ramdac->cr4;
break;
} else {
/* TODO: Red, Green, and Blue Signature Analysis Registers */
temp = 0xff;
break;
}
break;
}
} else
temp = ramdac->status | (svga->dac_status ? 0x04 : 0x00);
break;
case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */
if (svga->hwcursor.xsize == 64)
cd = (uint8_t *) ramdac->cursor64_data;
else
cd = (uint8_t *) ramdac->cursor32_data;
temp = cd[svga->dac_read];
svga->dac_read++;
svga->dac_read &= ((svga->hwcursor.xsize == 64) ? 0x03ff : 0x00ff);
break;
case 0x0c: /* Cursor X Low Register (RS value = 1100) */
temp = ramdac->hwc_x & 0xff;
break;
case 0x0d: /* Cursor X High Register (RS value = 1101) */
temp = (ramdac->hwc_x >> 8) & 0xff;
break;
case 0x0e: /* Cursor Y Low Register (RS value = 1110) */
temp = ramdac->hwc_y & 0xff;
break;
case 0x0f: /* Cursor Y High Register (RS value = 1111) */
temp = (ramdac->hwc_y >> 8) & 0xff;
break;
}
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;
}
/* Set the RAM DAC status byte to the correct ID bits.
Both the BT484 and BT485 datasheets say this:
SR7-SR6: These bits are identification values. SR7=0 and SR6=1.
But all other sources seem to assume SR7=1 and SR6=0. */
switch (ramdac->type) {
case BT484:
ramdac->status = 0x40;
break;
case ATT20C504:
ramdac->status = 0x40;
break;
case BT485:
ramdac->status = 0x60;
break;
case ATT20C505:
ramdac->status = 0xd0;
break;
case BT485A:
ramdac->status = 0x20;
break;
}
}

View File

@@ -0,0 +1,47 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Header of the emulation of the Brooktree BT485 and BT485A
* true colour RAM DAC's.
*
* Version: @(#)vid_bt485_ramdac.h 1.0.3 2018/10/03
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* TheCollector1995,
*
* Copyright 2016-2018 Miran Grca.
* Copyright 2018 TheCollector1995.
*/
typedef struct bt485_ramdac_t
{
PALETTE extpal;
uint32_t extpallook[256];
uint8_t cursor32_data[256];
uint8_t cursor64_data[1024];
int hwc_y, hwc_x;
uint8_t cr0;
uint8_t cr1;
uint8_t cr2;
uint8_t cr3;
uint8_t cr4;
uint8_t status;
uint8_t type;
uint8_t ext_read, ext_write;
} bt485_ramdac_t;
enum {
BT484 = 0,
ATT20C504,
BT485,
ATT20C505,
BT485A
};
extern void bt485_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt485_ramdac_t *ramdac, svga_t *svga);
extern uint8_t bt485_ramdac_in(uint16_t addr, int rs2, int rs3, bt485_ramdac_t *ramdac, svga_t *svga);
extern void bt485_init(bt485_ramdac_t *ramdac, svga_t *svga, uint8_t type);

View File

@@ -9,7 +9,7 @@
* Emulation of the Brooktree BT485 and BT485A true colour
* RAM DAC's.
*
* Version: @(#)vid_bt485_ramdac.c 1.0.9 2018/10/03
* Version: @(#)vid_bt485_ramdac.c 1.0.10 2018/10/04
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* TheCollector1995,
@@ -66,17 +66,32 @@ bt485_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt485_ramdac_t *r
switch (rs) {
case 0x00: /* Palette Write Index Register (RS value = 0000) */
case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */
svga_out(addr, val, svga);
if ((ramdac->type >= BT485) && (svga->hwcursor.xsize == 64))
svga->dac_write |= ((int) (ramdac->cr3 & 0x03) << 8);
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;
break;
case 0x01: /* Palette Data Register (RS value = 0001) */
case 0x02: /* Pixel Read Mask Register (RS value = 0010) */
case 0x03: /* Palette Read Index Register (RS value = 0011) */
case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */
svga_out(addr, val, svga);
break;
case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */
case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */
svga->dac_pos = 0;
svga->dac_status = rs & 0x03;
ramdac->ext_addr = (val + (rs & 0x01)) & 255;
break;
case 0x05: /* Ext Palette Data Register (RS value = 0101) */
svga->dac_status = 0;
svga->fullchange = changeframecount;
@@ -90,7 +105,7 @@ bt485_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt485_ramdac_t *r
svga->dac_pos++;
break;
case 2:
index = svga->dac_write & 3;
index = ramdac->ext_addr & 3;
ramdac->extpal[index].r = svga->dac_r;
ramdac->extpal[index].g = svga->dac_g;
ramdac->extpal[index].b = val;
@@ -105,7 +120,7 @@ bt485_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt485_ramdac_t *r
if (o32 != svga->overscan_color)
svga_recalctimings(svga);
}
svga->dac_write = (svga->dac_write + 1);
ramdac->ext_addr = (ramdac->ext_addr + 1) & 0xff;
svga->dac_pos = 0;
break;
}
@@ -125,7 +140,7 @@ bt485_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt485_ramdac_t *r
break;
case 0x0a:
if ((ramdac->type >= BT485) && (ramdac->cr0 & 0x80)) {
switch ((svga->dac_write & 0xff)) {
switch ((svga->dac_addr & 0xff)) {
case 0x01:
/* Command Register 3 (RS value = 1010) */
ramdac->cr3 = val;
@@ -133,8 +148,7 @@ bt485_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt485_ramdac_t *r
svga->hwcursor.yoff = (svga->hwcursor.ysize == 32) ? 32 : 0;
svga->hwcursor.x = ramdac->hwc_x - svga->hwcursor.xsize;
svga->hwcursor.y = ramdac->hwc_y - svga->hwcursor.ysize;
if (svga->hwcursor.xsize == 64)
svga->dac_write = (svga->dac_write & 0x00ff) | ((val & 0x03) << 8);
svga->dac_addr = (svga->dac_addr & 0x00ff) | ((val & 0x03) << 8);
svga_recalctimings(svga);
break;
case 0x02:
@@ -143,7 +157,7 @@ bt485_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, bt485_ramdac_t *r
case 0x22:
if (ramdac->type != BT485A)
break;
else if (svga->dac_write == 2) {
else if (svga->dac_addr == 2) {
ramdac->cr4 = val;
break;
}
@@ -152,15 +166,19 @@ 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) */
if (svga->hwcursor.xsize == 64)
index = svga->dac_addr & 0x03ff;
if ((ramdac->type >= BT485) && (svga->hwcursor.xsize == 64))
cd = (uint8_t *) ramdac->cursor64_data;
else
else {
if (ramdac->type < BT485)
index &= 0x00ff;
cd = (uint8_t *) ramdac->cursor32_data;
}
cd[svga->dac_write] = val;
cd[index] = val;
svga->dac_write++;
svga->dac_write &= ((svga->hwcursor.xsize == 64) ? 0x03ff : 0x00ff);
svga->dac_addr++;
svga->dac_addr &= (ramdac->type >= BT485) ? 0x03ff : 0x00ff;
break;
case 0x0c: /* Cursor X Low Register (RS value = 1100) */
ramdac->hwc_x = (ramdac->hwc_x & 0x0f00) | val;
@@ -198,13 +216,16 @@ bt485_ramdac_in(uint16_t addr, int rs2, int rs3, bt485_ramdac_t *ramdac, svga_t
case 0x00: /* Palette Write Index Register (RS value = 0000) */
case 0x01: /* Palette Data Register (RS value = 0001) */
case 0x02: /* Pixel Read Mask Register (RS value = 0010) */
case 0x03: /* Palette Read Index Register (RS value = 0011) */
case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */
case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */
temp = svga_in(addr, svga);
break;
case 0x03: /* Palette Read Index Register (RS value = 0011) */
temp = svga->dac_addr & 0xff;
break;
case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */
temp = ramdac->ext_addr;
break;
case 0x05: /* Ext Palette Data Register (RS value = 0101) */
index = svga->dac_read & 3;
index = (ramdac->ext_addr - 1) & 3;
svga->dac_status = 3;
switch (svga->dac_pos) {
case 0:
@@ -221,7 +242,7 @@ bt485_ramdac_in(uint16_t addr, int rs2, int rs3, bt485_ramdac_t *ramdac, svga_t
temp = ramdac->extpal[index].g & 0x3f;
case 2:
svga->dac_pos=0;
svga->dac_read = svga->dac_read + 1;
ramdac->ext_addr = ramdac->ext_addr + 1;
if (svga->ramdac_type == RAMDAC_8BIT)
temp = ramdac->extpal[index].b;
else
@@ -231,6 +252,9 @@ bt485_ramdac_in(uint16_t addr, int rs2, int rs3, bt485_ramdac_t *ramdac, svga_t
case 0x06: /* Command Register 0 (RS value = 0110) */
temp = ramdac->cr0;
break;
case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */
temp = ramdac->ext_addr;
break;
case 0x08: /* Command Register 1 (RS value = 1000) */
temp = ramdac->cr1;
break;
@@ -239,12 +263,13 @@ bt485_ramdac_in(uint16_t addr, int rs2, int rs3, bt485_ramdac_t *ramdac, svga_t
break;
case 0x0a:
if ((ramdac->type >= BT485) && (ramdac->cr0 & 0x80)) {
switch ((svga->dac_write & 0xff)) {
switch ((svga->dac_addr & 0xff)) {
case 0x00:
temp = ramdac->status;
temp = ramdac->status | (svga->dac_status ? 0x04 : 0x00);
break;
case 0x01:
temp = ramdac->cr3;
temp = ramdac->cr3 & 0xfc;
temp |= (svga->dac_addr & 0x300) >> 8;
break;
case 0x02:
case 0x20:
@@ -252,7 +277,7 @@ bt485_ramdac_in(uint16_t addr, int rs2, int rs3, bt485_ramdac_t *ramdac, svga_t
case 0x22:
if (ramdac->type != BT485A)
break;
else if (svga->dac_write == 2) {
else if (svga->dac_addr == 2) {
temp = ramdac->cr4;
break;
} else {
@@ -263,18 +288,22 @@ bt485_ramdac_in(uint16_t addr, int rs2, int rs3, bt485_ramdac_t *ramdac, svga_t
break;
}
} else
temp = ramdac->status;
temp = ramdac->status | (svga->dac_status ? 0x04 : 0x00);
break;
case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */
if (svga->hwcursor.xsize == 64)
index = (svga->dac_addr - 1) & 0x03ff;
if ((ramdac->type >= BT485) && (svga->hwcursor.xsize == 64))
cd = (uint8_t *) ramdac->cursor64_data;
else
else {
if (ramdac->type < BT485)
index &= 0x00ff;
cd = (uint8_t *) ramdac->cursor32_data;
}
temp = cd[svga->dac_write];
temp = cd[index];
svga->dac_write++;
svga->dac_write &= ((svga->hwcursor.xsize == 64) ? 0x03ff : 0x00ff);
svga->dac_addr++;
svga->dac_addr &= (ramdac->type >= BT485) ? 0x03ff : 0x00ff;
break;
case 0x0c: /* Cursor X Low Register (RS value = 1100) */
temp = ramdac->hwc_x & 0xff;

View File

@@ -9,7 +9,7 @@
* Header of the emulation of the Brooktree BT485 and BT485A
* true colour RAM DAC's.
*
* Version: @(#)vid_bt485_ramdac.h 1.0.2 2018/10/03
* Version: @(#)vid_bt485_ramdac.h 1.0.3 2018/10/04
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* TheCollector1995,
@@ -31,6 +31,7 @@ typedef struct bt485_ramdac_t
uint8_t cr4;
uint8_t status;
uint8_t type;
uint8_t ext_addr;
} bt485_ramdac_t;
enum {

File diff suppressed because it is too large Load Diff

View File

@@ -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.23 2018/10/03
* Version: @(#)vid_cl_54xx.c 1.0.24 2018/10/04
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Barry Rodewald,
@@ -351,26 +351,26 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p)
svga->dac_pos++;
break;
case 2:
index = svga->dac_addr & 0xff;
if (svga->seqregs[0x12] & 2) {
index = svga->dac_write & 0x0f;
index &= 0x0f;
gd54xx->extpal[index].r = svga->dac_r;
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) && ((svga->dac_write & 15) == 2)) {
if ((svga->seqregs[0x12] & 0x80) && (index == 2)) {
o32 = svga->overscan_color;
svga->overscan_color = gd54xx->extpallook[2];
if (o32 != svga->overscan_color)
svga_recalctimings(svga);
}
svga->dac_write = (svga->dac_write + 1);
} else {
svga->vgapal[svga->dac_write].r = svga->dac_r;
svga->vgapal[svga->dac_write].g = svga->dac_g;
svga->vgapal[svga->dac_write].b = val;
svga->pallook[svga->dac_write] = makecol32(video_6to8[svga->vgapal[svga->dac_write].r & 0x3f], video_6to8[svga->vgapal[svga->dac_write].g & 0x3f], video_6to8[svga->vgapal[svga->dac_write].b & 0x3f]);
svga->dac_write = (svga->dac_write + 1) & 255;
svga->vgapal[index].r = svga->dac_r;
svga->vgapal[index].g = svga->dac_g;
svga->vgapal[index].b = val;
svga->pallook[index] = makecol32(video_6to8[svga->vgapal[index].r & 0x3f], video_6to8[svga->vgapal[index].g & 0x3f], video_6to8[svga->vgapal[index].b & 0x3f]);
}
svga->dac_addr = (svga->dac_addr + 1) & 255;
svga->dac_pos = 0;
break;
}
@@ -596,7 +596,9 @@ gd54xx_in(uint16_t addr, void *p)
break;
case 0x3c9:
svga->dac_status = 3;
index = svga->dac_read & 0x0f;
index = (svga->dac_addr - 1) & 0xff;
if (svga->seqregs[0x12] & 2)
index &= 0x0f;
switch (svga->dac_pos) {
case 0:
svga->dac_pos++;
@@ -612,11 +614,11 @@ gd54xx_in(uint16_t addr, void *p)
return svga->vgapal[index].g & 0x3f;
case 2:
svga->dac_pos=0;
svga->dac_read = (svga->dac_read + 1) & 255;
svga->dac_addr = (svga->dac_addr + 1) & 255;
if (svga->seqregs[0x12] & 2)
return gd54xx->extpal[index].b & 0x3f;
else
return svga->vgapal[(svga->dac_read - 1) & 255].b & 0x3f;
return svga->vgapal[index].b & 0x3f;
}
return 0xFF;
case 0x3C6:

592
src/video/vid_et4000_bak.c Normal file
View File

@@ -0,0 +1,592 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Emulation of the Tseng Labs ET4000.
*
* Version: @(#)vid_et4000.c 1.0.15 2018/08/26
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#include "../86box.h"
#include "../io.h"
#include "../mca.h"
#include "../mem.h"
#include "../rom.h"
#include "../device.h"
#include "video.h"
#include "vid_svga.h"
#include "vid_svga_render.h"
#include "vid_sc1502x_ramdac.h"
#include "vid_et4000.h"
#define BIOS_ROM_PATH L"roms/video/et4000/et4000.bin"
#define KOREAN_BIOS_ROM_PATH L"roms/video/et4000/tgkorvga.bin"
#define KOREAN_FONT_ROM_PATH L"roms/video/et4000/tg_ksc5601.rom"
typedef struct et4000_t
{
svga_t svga;
sc1502x_ramdac_t ramdac;
rom_t bios_rom;
uint8_t banking;
uint8_t pos_regs[8];
int is_mca;
uint8_t port_22cb_val;
uint8_t port_32cb_val;
int get_korean_font_enabled;
int get_korean_font_index;
uint16_t get_korean_font_base;
uint32_t vram_mask;
uint8_t hcr, mcr;
} et4000_t;
static uint8_t crtc_mask[0x40] =
{
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
uint8_t et4000_in(uint16_t addr, void *p);
void et4000_out(uint16_t addr, uint8_t val, void *p)
{
et4000_t *et4000 = (et4000_t *)p;
svga_t *svga = &et4000->svga;
uint8_t old;
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1))
addr ^= 0x60;
switch (addr)
{
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
sc1502x_ramdac_out(addr, val, &et4000->ramdac, svga);
return;
case 0x3CD: /*Banking*/
if (!(svga->crtc[0x36] & 0x10) && !(svga->gdcreg[6] & 0x08)) {
svga->write_bank = (val & 0xf) * 0x10000;
svga->read_bank = ((val >> 4) & 0xf) * 0x10000;
}
et4000->banking = val;
return;
case 0x3cf:
if ((svga->gdcaddr & 15) == 6) {
if (!(svga->crtc[0x36] & 0x10) && !(val & 0x08)) {
svga->write_bank = (et4000->banking & 0xf) * 0x10000;
svga->read_bank = ((et4000->banking >> 4) & 0xf) * 0x10000;
} else
svga->write_bank = svga->read_bank = 0;
}
break;
case 0x3D4:
svga->crtcreg = val & 0x3f;
return;
case 0x3D5:
if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80))
return;
if ((svga->crtcreg == 0x35) && (svga->crtc[0x11] & 0x80))
return;
if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80))
val = (svga->crtc[7] & ~0x10) | (val & 0x10);
old = svga->crtc[svga->crtcreg];
val &= crtc_mask[svga->crtcreg];
svga->crtc[svga->crtcreg] = val;
if (svga->crtcreg == 0x36) {
if (!(val & 0x10) && !(svga->gdcreg[6] & 0x08)) {
svga->write_bank = (et4000->banking & 0xf) * 0x10000;
svga->read_bank = ((et4000->banking >> 4) & 0xf) * 0x10000;
} else
svga->write_bank = svga->read_bank = 0;
}
if (old != val)
{
if (svga->crtcreg < 0xE || svga->crtcreg > 0x10)
{
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}
/*Note - Silly hack to determine video memory size automatically by ET4000 BIOS.*/
if ((svga->crtcreg == 0x37) && !et4000->is_mca)
{
switch(val & 0x0B)
{
case 0x00:
case 0x01:
if(svga->vram_max == 64 * 1024)
mem_mapping_enable(&svga->mapping);
else
mem_mapping_disable(&svga->mapping);
break;
case 0x02:
if(svga->vram_max == 128 * 1024)
mem_mapping_enable(&svga->mapping);
else
mem_mapping_disable(&svga->mapping);
break;
case 0x03:
case 0x08:
case 0x09:
if (svga->vram_max == 256 * 1024)
mem_mapping_enable(&svga->mapping);
else
mem_mapping_disable(&svga->mapping);
break;
case 0x0A:
if (svga->vram_max == 512 * 1024)
mem_mapping_enable(&svga->mapping);
else
mem_mapping_disable(&svga->mapping);
break;
case 0x0B:
if (svga->vram_max == 1024 * 1024)
mem_mapping_enable(&svga->mapping);
else
mem_mapping_disable(&svga->mapping);
break;
default:
mem_mapping_enable(&svga->mapping);
break;
}
}
break;
}
svga_out(addr, val, svga);
}
uint8_t et4000_in(uint16_t addr, void *p)
{
et4000_t *et4000 = (et4000_t *)p;
svga_t *svga = &et4000->svga;
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1))
addr ^= 0x60;
switch (addr)
{
case 0x3c2:
if (et4000->is_mca)
{
if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x4e)
return 0;
else
return 0x10;
}
break;
case 0x3C5:
if ((svga->seqaddr & 0xf) == 7) return svga->seqregs[svga->seqaddr & 0xf] | 4;
break;
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
return sc1502x_ramdac_in(addr, &et4000->ramdac, svga);
case 0x3CD: /*Banking*/
return et4000->banking;
case 0x3D4:
return svga->crtcreg;
case 0x3D5:
return svga->crtc[svga->crtcreg];
}
return svga_in(addr, svga);
}
void et4000k_out(uint16_t addr, uint8_t val, void *p)
{
et4000_t *et4000 = (et4000_t *)p;
// pclog("ET4000k out %04X %02X\n", addr, val);
switch (addr)
{
case 0x22CB:
et4000->port_22cb_val = (et4000->port_22cb_val & 0xF0) | (val & 0x0F);
et4000->get_korean_font_enabled = val & 7;
if (et4000->get_korean_font_enabled == 3)
et4000->get_korean_font_index = 0;
break;
case 0x22CF:
switch(et4000->get_korean_font_enabled)
{
case 1:
et4000->get_korean_font_base = ((val & 0x7F) << 7) | (et4000->get_korean_font_base & 0x7F);
break;
case 2:
et4000->get_korean_font_base = (et4000->get_korean_font_base & 0x3F80) | (val & 0x7F) | (((val ^ 0x80) & 0x80) << 8);
break;
case 3:
if((et4000->port_32cb_val & 0x30) == 0x20 && (et4000->get_korean_font_base & 0x7F) > 0x20 && (et4000->get_korean_font_base & 0x7F) < 0x7F)
{
switch(et4000->get_korean_font_base & 0x3F80)
{
case 0x2480:
if(et4000->get_korean_font_index < 16)
fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20].chr[et4000->get_korean_font_index] = val;
else if(et4000->get_korean_font_index >= 24 && et4000->get_korean_font_index < 40)
fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20].chr[et4000->get_korean_font_index - 8] = val;
break;
case 0x3F00:
if(et4000->get_korean_font_index < 16)
fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20].chr[et4000->get_korean_font_index] = val;
else if(et4000->get_korean_font_index >= 24 && et4000->get_korean_font_index < 40)
fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20].chr[et4000->get_korean_font_index - 8] = val;
break;
default:
break;
}
et4000->get_korean_font_index++;
}
break;
default:
break;
}
break;
case 0x32CB:
et4000->port_32cb_val = val;
svga_recalctimings(&et4000->svga);
break;
default:
et4000_out(addr, val, p);
break;
}
}
uint8_t et4000k_in(uint16_t addr, void *p)
{
uint8_t val = 0xFF;
et4000_t *et4000 = (et4000_t *)p;
// if (addr != 0x3da) pclog("IN ET4000 %04X\n", addr);
switch (addr)
{
case 0x22CB:
return et4000->port_22cb_val;
case 0x22CF:
val = 0;
switch(et4000->get_korean_font_enabled)
{
case 3:
if((et4000->port_32cb_val & 0x30) == 0x30)
{
val = fontdatksc5601[et4000->get_korean_font_base].chr[et4000->get_korean_font_index++];
et4000->get_korean_font_index &= 0x1F;
}
else if((et4000->port_32cb_val & 0x30) == 0x20 && (et4000->get_korean_font_base & 0x7F) > 0x20 && (et4000->get_korean_font_base & 0x7F) < 0x7F)
{
switch(et4000->get_korean_font_base & 0x3F80)
{
case 0x2480:
if(et4000->get_korean_font_index < 16)
val = fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20].chr[et4000->get_korean_font_index];
else if(et4000->get_korean_font_index >= 24 && et4000->get_korean_font_index < 40)
val = fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20].chr[et4000->get_korean_font_index - 8];
break;
case 0x3F00:
if(et4000->get_korean_font_index < 16)
val = fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20].chr[et4000->get_korean_font_index];
else if(et4000->get_korean_font_index >= 24 && et4000->get_korean_font_index < 40)
val = fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20].chr[et4000->get_korean_font_index - 8];
break;
default:
break;
}
et4000->get_korean_font_index++;
et4000->get_korean_font_index %= 72;
}
break;
case 4:
val = 0x0F;
break;
default:
break;
}
return val;
case 0x32CB:
return et4000->port_32cb_val;
default:
return et4000_in(addr, p);
}
}
void et4000_recalctimings(svga_t *svga)
{
svga->ma_latch |= (svga->crtc[0x33]&3)<<16;
if (svga->crtc[0x35] & 1) svga->vblankstart += 0x400;
if (svga->crtc[0x35] & 2) svga->vtotal += 0x400;
if (svga->crtc[0x35] & 4) svga->dispend += 0x400;
if (svga->crtc[0x35] & 8) svga->vsyncstart += 0x400;
if (svga->crtc[0x35] & 0x10) svga->split += 0x400;
if (!svga->rowoffset) svga->rowoffset = 0x100;
if (svga->crtc[0x3f] & 1) svga->htotal += 256;
if (svga->attrregs[0x16] & 0x20) svga->hdisp <<= 1;
switch (((svga->miscout >> 2) & 3) | ((svga->crtc[0x34] << 1) & 4))
{
case 0: case 1: break;
case 3: svga->clock = cpuclock / 40000000.0; break;
case 5: svga->clock = cpuclock / 65000000.0; break;
default: svga->clock = cpuclock / 36000000.0; break;
}
switch (svga->bpp)
{
case 15: case 16:
svga->hdisp /= 2;
break;
case 24:
svga->hdisp /= 3;
break;
}
}
void et4000k_recalctimings(svga_t *svga)
{
et4000_t *et4000 = (et4000_t *)svga->p;
et4000_recalctimings(svga);
if (svga->render == svga_render_text_80 && ((svga->crtc[0x37] & 0x0A) == 0x0A))
{
if((et4000->port_32cb_val & 0xB4) == ((svga->crtc[0x37] & 3) == 2 ? 0xB4 : 0xB0))
{
svga->render = svga_render_text_80_ksc5601;
}
}
}
void *et4000_isa_init(const device_t *info)
{
et4000_t *et4000 = malloc(sizeof(et4000_t));
memset(et4000, 0, sizeof(et4000_t));
et4000->is_mca = 0;
rom_init(&et4000->bios_rom, BIOS_ROM_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
io_sethandler(0x03c0, 0x0020, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000);
svga_init(&et4000->svga, et4000, device_get_config_int("memory") << 10, /*1mb default*/
et4000_recalctimings,
et4000_in, et4000_out,
NULL,
NULL);
et4000->vram_mask = (device_get_config_int("memory") << 10) - 1;
return et4000;
}
void *et4000k_isa_init(const device_t *info)
{
et4000_t *et4000 = malloc(sizeof(et4000_t));
memset(et4000, 0, sizeof(et4000_t));
rom_init(&et4000->bios_rom, KOREAN_BIOS_ROM_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
loadfont(KOREAN_FONT_ROM_PATH, 6);
io_sethandler(0x03c0, 0x0020, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000);
io_sethandler(0x22cb, 0x0001, et4000k_in, NULL, NULL, et4000k_out, NULL, NULL, et4000);
io_sethandler(0x22cf, 0x0001, et4000k_in, NULL, NULL, et4000k_out, NULL, NULL, et4000);
io_sethandler(0x32cb, 0x0001, et4000k_in, NULL, NULL, et4000k_out, NULL, NULL, et4000);
et4000->port_22cb_val = 0x60;
et4000->port_32cb_val = 0;
svga_init(&et4000->svga, et4000, device_get_config_int("memory") << 10,
et4000k_recalctimings,
et4000k_in, et4000k_out,
NULL,
NULL);
et4000->vram_mask = (device_get_config_int("memory") << 10) - 1;
et4000->svga.ksc5601_sbyte_mask = 0x80;
return et4000;
}
static uint8_t
et4000_mca_read(int port, void *priv)
{
et4000_t *et4000 = (et4000_t *)priv;
return(et4000->pos_regs[port & 7]);
}
static void
et4000_mca_write(int port, uint8_t val, void *priv)
{
et4000_t *et4000 = (et4000_t *)priv;
/* MCA does not write registers below 0x0100. */
if (port < 0x0102) return;
/* Save the MCA register value. */
et4000->pos_regs[port & 7] = val;
}
void *et4000_mca_init(const device_t *info)
{
et4000_t *et4000 = malloc(sizeof(et4000_t));
memset(et4000, 0, sizeof(et4000_t));
et4000->is_mca = 1;
/* Enable MCA. */
et4000->pos_regs[0] = 0xF2; /* ET4000 MCA board ID */
et4000->pos_regs[1] = 0x80;
mca_add(et4000_mca_read, et4000_mca_write, et4000);
rom_init(&et4000->bios_rom, BIOS_ROM_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
svga_init(&et4000->svga, et4000, 1 << 20, /*1mb*/
et4000_recalctimings,
et4000_in, et4000_out,
NULL,
NULL);
et4000->vram_mask = (1 << 20) - 1;
io_sethandler(0x03c0, 0x0020, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000);
return et4000;
}
static int et4000_available(void)
{
return rom_present(BIOS_ROM_PATH);
}
static int et4000k_available()
{
return rom_present(KOREAN_BIOS_ROM_PATH) && rom_present(KOREAN_FONT_ROM_PATH);
}
void et4000_close(void *p)
{
et4000_t *et4000 = (et4000_t *)p;
svga_close(&et4000->svga);
free(et4000);
}
void et4000_speed_changed(void *p)
{
et4000_t *et4000 = (et4000_t *)p;
svga_recalctimings(&et4000->svga);
}
void et4000_force_redraw(void *p)
{
et4000_t *et4000 = (et4000_t *)p;
et4000->svga.fullchange = changeframecount;
}
static device_config_t et4000_config[] =
{
{
.name = "memory",
.description = "Memory size",
.type = CONFIG_SELECTION,
.selection =
{
{
.description = "256 kB",
.value = 256
},
{
.description = "512 kB",
.value = 512
},
{
.description = "1 MB",
.value = 1024
},
{
.description = ""
}
},
.default_int = 1024
},
{
.type = -1
}
};
const device_t et4000_isa_device =
{
"Tseng Labs ET4000AX (ISA)",
DEVICE_ISA, 0,
et4000_isa_init, et4000_close, NULL,
et4000_available,
et4000_speed_changed,
et4000_force_redraw,
et4000_config
};
const device_t et4000k_isa_device =
{
"Trigem Korean VGA (Tseng Labs ET4000AX Korean)",
DEVICE_ISA, 0,
et4000k_isa_init, et4000_close, NULL,
et4000k_available,
et4000_speed_changed,
et4000_force_redraw,
et4000_config
};
const device_t et4000k_tg286_isa_device =
{
"Trigem Korean VGA (Trigem 286M)",
DEVICE_ISA, 0,
et4000k_isa_init, et4000_close, NULL,
et4000k_available,
et4000_speed_changed,
et4000_force_redraw,
et4000_config
};
const device_t et4000_mca_device =
{
"Tseng Labs ET4000AX (MCA)",
DEVICE_MCA, 0,
et4000_mca_init, et4000_close, NULL,
et4000_available,
et4000_speed_changed,
et4000_force_redraw,
NULL
};

View File

@@ -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.31 2018/05/26
* Version: @(#)vid_svga.c 1.0.32 2018/10/04
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -88,7 +88,7 @@ svga_out(uint16_t addr, uint8_t val, void *p)
{
svga_t *svga = (svga_t *)p;
int c;
uint8_t o;
uint8_t o, index;
switch (addr) {
case 0x3c0:
@@ -182,17 +182,13 @@ svga_out(uint16_t addr, uint8_t val, void *p)
case 0x3c6:
svga->dac_mask = val;
break;
case 0x3C7:
svga->dac_read = val;
svga->dac_pos = 0;
break;
case 0x3c8:
svga->dac_write = val;
svga->dac_read = val - 1;
svga->dac_pos = 0;
case 0x3c7:
case 0x3c8:
svga->dac_pos = 0;
svga->dac_status = addr & 0x03;
svga->dac_addr = (val + (addr & 0x01)) & 255;
break;
case 0x3c9:
svga->dac_status = 0;
svga->fullchange = changeframecount;
switch (svga->dac_pos) {
case 0:
@@ -204,15 +200,16 @@ svga_out(uint16_t addr, uint8_t val, void *p)
svga->dac_pos++;
break;
case 2:
svga->vgapal[svga->dac_write].r = svga->dac_r;
svga->vgapal[svga->dac_write].g = svga->dac_g;
svga->vgapal[svga->dac_write].b = val;
index = svga->dac_addr & 255;
svga->vgapal[index].r = svga->dac_r;
svga->vgapal[index].g = svga->dac_g;
svga->vgapal[index].b = val;
if (svga->ramdac_type == RAMDAC_8BIT)
svga->pallook[svga->dac_write] = makecol32(svga->vgapal[svga->dac_write].r, svga->vgapal[svga->dac_write].g, svga->vgapal[svga->dac_write].b);
svga->pallook[index] = makecol32(svga->vgapal[index].r, svga->vgapal[index].g, svga->vgapal[index].b);
else
svga->pallook[svga->dac_write] = makecol32(video_6to8[svga->vgapal[svga->dac_write].r & 0x3f], video_6to8[svga->vgapal[svga->dac_write].g & 0x3f], video_6to8[svga->vgapal[svga->dac_write].b & 0x3f]);
svga->pallook[index] = makecol32(video_6to8[svga->vgapal[index].r & 0x3f], video_6to8[svga->vgapal[index].g & 0x3f], video_6to8[svga->vgapal[index].b & 0x3f]);
svga->dac_pos = 0;
svga->dac_write = (svga->dac_write + 1) & 255;
svga->dac_addr = (svga->dac_addr + 1) & 255;
break;
}
break;
@@ -274,7 +271,7 @@ uint8_t
svga_in(uint16_t addr, void *p)
{
svga_t *svga = (svga_t *)p;
uint8_t ret = 0xff;
uint8_t index, ret = 0xff;
switch (addr) {
case 0x3c0:
@@ -302,32 +299,32 @@ svga_in(uint16_t addr, void *p)
ret = svga->dac_status;
break;
case 0x3c8:
ret = svga->dac_write;
ret = svga->dac_addr;
break;
case 0x3c9:
svga->dac_status = 3;
index = (svga->dac_addr - 1) & 255;
switch (svga->dac_pos) {
case 0:
svga->dac_pos++;
if (svga->ramdac_type == RAMDAC_8BIT)
ret = svga->vgapal[svga->dac_read].r;
ret = svga->vgapal[index].r;
else
ret = svga->vgapal[svga->dac_read].r & 0x3f;
ret = svga->vgapal[index].r & 0x3f;
break;
case 1:
svga->dac_pos++;
if (svga->ramdac_type == RAMDAC_8BIT)
ret = svga->vgapal[svga->dac_read].g;
ret = svga->vgapal[index].g;
else
ret = svga->vgapal[svga->dac_read].g & 0x3f;
ret = svga->vgapal[index].g & 0x3f;
break;
case 2:
svga->dac_pos=0;
svga->dac_read = (svga->dac_read + 1) & 255;
svga->dac_addr = (svga->dac_addr + 1) & 255;
if (svga->ramdac_type == RAMDAC_8BIT)
ret = svga->vgapal[(svga->dac_read - 1) & 255].b;
ret = svga->vgapal[index].b;
else
ret = svga->vgapal[(svga->dac_read - 1) & 255].b & 0x3f;
ret = svga->vgapal[index].b & 0x3f;
break;
}
break;

1372
src/video/vid_svga.c.good Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@
*
* Generic SVGA handling.
*
* Version: @(#)vid_svga.h 1.0.13 2018/08/14
* Version: @(#)vid_svga.h 1.0.14 2018/10/04
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -58,9 +58,9 @@ typedef struct svga_t
uint32_t vram_mask;
uint8_t dac_mask, dac_status;
int dac_read, dac_write,
dac_pos, ramdac_type,
dac_r, dac_g;
int dac_addr, dac_pos,
dac_r, dac_g,
ramdac_type;
int readmode, writemode,
readplane, extvram,

818
src/video/video - Cópia.c Normal file
View File

@@ -0,0 +1,818 @@
/*
* 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.
*
* Main video-rendering module.
*
* Video timing settings -
*
* 8-bit - 1mb/sec
* B = 8 ISA clocks
* W = 16 ISA clocks
* L = 32 ISA clocks
*
* Slow 16-bit - 2mb/sec
* B = 6 ISA clocks
* W = 8 ISA clocks
* L = 16 ISA clocks
*
* Fast 16-bit - 4mb/sec
* B = 3 ISA clocks
* W = 3 ISA clocks
* L = 6 ISA clocks
*
* Slow VLB/PCI - 8mb/sec (ish)
* B = 4 bus clocks
* W = 8 bus clocks
* L = 16 bus clocks
*
* Mid VLB/PCI -
* B = 4 bus clocks
* W = 5 bus clocks
* L = 10 bus clocks
*
* Fast VLB/PCI -
* B = 3 bus clocks
* W = 3 bus clocks
* L = 4 bus clocks
*
* Version: @(#)video.c 1.0.26 2018/09/19
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#include <math.h>
#include "../86box.h"
#include "../cpu/cpu.h"
#include "../machine/machine.h"
#include "../io.h"
#include "../mem.h"
#include "../rom.h"
#include "../config.h"
#include "../timer.h"
#include "../plat.h"
#include "video.h"
#include "vid_svga.h"
bitmap_t *screen = NULL,
*buffer = NULL,
*buffer32 = NULL;
uint8_t fontdat[2048][8]; /* IBM CGA font */
uint8_t fontdatm[2048][16]; /* IBM MDA font */
uint8_t fontdatw[512][32]; /* Wyse700 font */
uint8_t fontdat8x12[256][16]; /* MDSI Genius font */
dbcs_font_t *fontdatksc5601 = NULL; /* Korean KSC-5601 font */
dbcs_font_t *fontdatksc5601_user = NULL; /* Korean KSC-5601 user defined font */
uint32_t pal_lookup[256];
int xsize = 1,
ysize = 1;
int cga_palette = 0;
uint32_t *video_6to8 = NULL,
*video_15to32 = NULL,
*video_16to32 = NULL;
int egareads = 0,
egawrites = 0,
changeframecount = 2;
uint8_t rotatevga[8][256];
int frames = 0;
int fullchange = 0;
uint8_t edatlookup[4][4];
int overscan_x = 0,
overscan_y = 0;
int video_timing_read_b = 0,
video_timing_read_w = 0,
video_timing_read_l = 0;
int video_timing_write_b = 0,
video_timing_write_w = 0,
video_timing_write_l = 0;
int video_res_x = 0,
video_res_y = 0,
video_bpp = 0;
static int video_force_resize;
int invert_display = 0;
int video_grayscale = 0;
int video_graytype = 0;
static int vid_type;
static const video_timings_t *vid_timings;
PALETTE cgapal = {
{0,0,0}, {0,42,0}, {42,0,0}, {42,21,0},
{0,0,0}, {0,42,42}, {42,0,42}, {42,42,42},
{0,0,0}, {21,63,21}, {63,21,21}, {63,63,21},
{0,0,0}, {21,63,63}, {63,21,63}, {63,63,63},
{0,0,0}, {0,0,42}, {0,42,0}, {0,42,42},
{42,0,0}, {42,0,42}, {42,21,00}, {42,42,42},
{21,21,21}, {21,21,63}, {21,63,21}, {21,63,63},
{63,21,21}, {63,21,63}, {63,63,21}, {63,63,63},
{0,0,0}, {0,21,0}, {0,0,42}, {0,42,42},
{42,0,21}, {21,10,21}, {42,0,42}, {42,0,63},
{21,21,21}, {21,63,21}, {42,21,42}, {21,63,63},
{63,0,0}, {42,42,0}, {63,21,42}, {41,41,41},
{0,0,0}, {0,42,42}, {42,0,0}, {42,42,42},
{0,0,0}, {0,42,42}, {42,0,0}, {42,42,42},
{0,0,0}, {0,63,63}, {63,0,0}, {63,63,63},
{0,0,0}, {0,63,63}, {63,0,0}, {63,63,63},
};
PALETTE cgapal_mono[6] = {
{ /* 0 - green, 4-color-optimized contrast. */
{0x00,0x00,0x00},{0x00,0x0d,0x03},{0x01,0x17,0x05},
{0x01,0x1a,0x06},{0x02,0x28,0x09},{0x02,0x2c,0x0a},
{0x03,0x39,0x0d},{0x03,0x3c,0x0e},{0x00,0x07,0x01},
{0x01,0x13,0x04},{0x01,0x1f,0x07},{0x01,0x23,0x08},
{0x02,0x31,0x0b},{0x02,0x35,0x0c},{0x05,0x3f,0x11},{0x0d,0x3f,0x17},
},
{ /* 1 - green, 16-color-optimized contrast. */
{0x00,0x00,0x00},{0x00,0x0d,0x03},{0x01,0x15,0x05},
{0x01,0x17,0x05},{0x01,0x21,0x08},{0x01,0x24,0x08},
{0x02,0x2e,0x0b},{0x02,0x31,0x0b},{0x01,0x22,0x08},
{0x02,0x28,0x09},{0x02,0x30,0x0b},{0x02,0x32,0x0c},
{0x03,0x39,0x0d},{0x03,0x3b,0x0e},{0x09,0x3f,0x14},{0x0d,0x3f,0x17},
},
{ /* 2 - amber, 4-color-optimized contrast. */
{0x00,0x00,0x00},{0x15,0x05,0x00},{0x20,0x0b,0x00},
{0x24,0x0d,0x00},{0x33,0x18,0x00},{0x37,0x1b,0x00},
{0x3f,0x26,0x01},{0x3f,0x2b,0x06},{0x0b,0x02,0x00},
{0x1b,0x08,0x00},{0x29,0x11,0x00},{0x2e,0x14,0x00},
{0x3b,0x1e,0x00},{0x3e,0x21,0x00},{0x3f,0x32,0x0a},{0x3f,0x38,0x0d},
},
{ /* 3 - amber, 16-color-optimized contrast. */
{0x00,0x00,0x00},{0x15,0x05,0x00},{0x1e,0x09,0x00},
{0x21,0x0b,0x00},{0x2b,0x12,0x00},{0x2f,0x15,0x00},
{0x38,0x1c,0x00},{0x3b,0x1e,0x00},{0x2c,0x13,0x00},
{0x32,0x17,0x00},{0x3a,0x1e,0x00},{0x3c,0x1f,0x00},
{0x3f,0x27,0x01},{0x3f,0x2a,0x04},{0x3f,0x36,0x0c},{0x3f,0x38,0x0d},
},
{ /* 4 - grey, 4-color-optimized contrast. */
{0x00,0x00,0x00},{0x0e,0x0f,0x10},{0x15,0x17,0x18},
{0x18,0x1a,0x1b},{0x24,0x25,0x25},{0x27,0x28,0x28},
{0x33,0x34,0x32},{0x37,0x38,0x35},{0x09,0x0a,0x0b},
{0x11,0x12,0x13},{0x1c,0x1e,0x1e},{0x20,0x22,0x22},
{0x2c,0x2d,0x2c},{0x2f,0x30,0x2f},{0x3c,0x3c,0x38},{0x3f,0x3f,0x3b},
},
{ /* 5 - grey, 16-color-optimized contrast. */
{0x00,0x00,0x00},{0x0e,0x0f,0x10},{0x13,0x14,0x15},
{0x15,0x17,0x18},{0x1e,0x20,0x20},{0x20,0x22,0x22},
{0x29,0x2a,0x2a},{0x2c,0x2d,0x2c},{0x1f,0x21,0x21},
{0x23,0x25,0x25},{0x2b,0x2c,0x2b},{0x2d,0x2e,0x2d},
{0x34,0x35,0x33},{0x37,0x37,0x34},{0x3e,0x3e,0x3a},{0x3f,0x3f,0x3b},
}
};
const uint32_t shade[5][256] =
{
{0}, // RGB Color (unused)
{0}, // RGB Grayscale (unused)
{ // Amber monitor
0x000000, 0x060000, 0x090000, 0x0d0000, 0x100000, 0x120100, 0x150100, 0x170100, 0x1a0100, 0x1c0100, 0x1e0200, 0x210200, 0x230200, 0x250300, 0x270300, 0x290300,
0x2b0400, 0x2d0400, 0x2f0400, 0x300500, 0x320500, 0x340500, 0x360600, 0x380600, 0x390700, 0x3b0700, 0x3d0700, 0x3f0800, 0x400800, 0x420900, 0x440900, 0x450a00,
0x470a00, 0x480b00, 0x4a0b00, 0x4c0c00, 0x4d0c00, 0x4f0d00, 0x500d00, 0x520e00, 0x530e00, 0x550f00, 0x560f00, 0x581000, 0x591000, 0x5b1100, 0x5c1200, 0x5e1200,
0x5f1300, 0x601300, 0x621400, 0x631500, 0x651500, 0x661600, 0x671600, 0x691700, 0x6a1800, 0x6c1800, 0x6d1900, 0x6e1a00, 0x701a00, 0x711b00, 0x721c00, 0x741c00,
0x751d00, 0x761e00, 0x781e00, 0x791f00, 0x7a2000, 0x7c2000, 0x7d2100, 0x7e2200, 0x7f2300, 0x812300, 0x822400, 0x832500, 0x842600, 0x862600, 0x872700, 0x882800,
0x8a2900, 0x8b2900, 0x8c2a00, 0x8d2b00, 0x8e2c00, 0x902c00, 0x912d00, 0x922e00, 0x932f00, 0x953000, 0x963000, 0x973100, 0x983200, 0x993300, 0x9b3400, 0x9c3400,
0x9d3500, 0x9e3600, 0x9f3700, 0xa03800, 0xa23900, 0xa33a00, 0xa43a00, 0xa53b00, 0xa63c00, 0xa73d00, 0xa93e00, 0xaa3f00, 0xab4000, 0xac4000, 0xad4100, 0xae4200,
0xaf4300, 0xb14400, 0xb24500, 0xb34600, 0xb44700, 0xb54800, 0xb64900, 0xb74a00, 0xb94a00, 0xba4b00, 0xbb4c00, 0xbc4d00, 0xbd4e00, 0xbe4f00, 0xbf5000, 0xc05100,
0xc15200, 0xc25300, 0xc45400, 0xc55500, 0xc65600, 0xc75700, 0xc85800, 0xc95900, 0xca5a00, 0xcb5b00, 0xcc5c00, 0xcd5d00, 0xce5e00, 0xcf5f00, 0xd06000, 0xd26101,
0xd36201, 0xd46301, 0xd56401, 0xd66501, 0xd76601, 0xd86701, 0xd96801, 0xda6901, 0xdb6a01, 0xdc6b01, 0xdd6c01, 0xde6d01, 0xdf6e01, 0xe06f01, 0xe17001, 0xe27201,
0xe37301, 0xe47401, 0xe57501, 0xe67602, 0xe77702, 0xe87802, 0xe97902, 0xeb7a02, 0xec7b02, 0xed7c02, 0xee7e02, 0xef7f02, 0xf08002, 0xf18103, 0xf28203, 0xf38303,
0xf48403, 0xf58503, 0xf68703, 0xf78803, 0xf88903, 0xf98a04, 0xfa8b04, 0xfb8c04, 0xfc8d04, 0xfd8f04, 0xfe9005, 0xff9105, 0xff9205, 0xff9305, 0xff9405, 0xff9606,
0xff9706, 0xff9806, 0xff9906, 0xff9a07, 0xff9b07, 0xff9d07, 0xff9e08, 0xff9f08, 0xffa008, 0xffa109, 0xffa309, 0xffa409, 0xffa50a, 0xffa60a, 0xffa80a, 0xffa90b,
0xffaa0b, 0xffab0c, 0xffac0c, 0xffae0d, 0xffaf0d, 0xffb00e, 0xffb10e, 0xffb30f, 0xffb40f, 0xffb510, 0xffb610, 0xffb811, 0xffb912, 0xffba12, 0xffbb13, 0xffbd14,
0xffbe14, 0xffbf15, 0xffc016, 0xffc217, 0xffc317, 0xffc418, 0xffc619, 0xffc71a, 0xffc81b, 0xffca1c, 0xffcb1d, 0xffcc1e, 0xffcd1f, 0xffcf20, 0xffd021, 0xffd122,
0xffd323, 0xffd424, 0xffd526, 0xffd727, 0xffd828, 0xffd92a, 0xffdb2b, 0xffdc2c, 0xffdd2e, 0xffdf2f, 0xffe031, 0xffe133, 0xffe334, 0xffe436, 0xffe538, 0xffe739
},
{ // Green monitor
0x000000, 0x000400, 0x000700, 0x000900, 0x000b00, 0x000d00, 0x000f00, 0x001100, 0x001300, 0x001500, 0x001600, 0x001800, 0x001a00, 0x001b00, 0x001d00, 0x001e00,
0x002000, 0x002100, 0x002300, 0x002400, 0x002601, 0x002701, 0x002901, 0x002a01, 0x002b01, 0x002d01, 0x002e01, 0x002f01, 0x003101, 0x003201, 0x003301, 0x003401,
0x003601, 0x003702, 0x003802, 0x003902, 0x003b02, 0x003c02, 0x003d02, 0x003e02, 0x004002, 0x004102, 0x004203, 0x004303, 0x004403, 0x004503, 0x004703, 0x004803,
0x004903, 0x004a03, 0x004b04, 0x004c04, 0x004d04, 0x004e04, 0x005004, 0x005104, 0x005205, 0x005305, 0x005405, 0x005505, 0x005605, 0x005705, 0x005806, 0x005906,
0x005a06, 0x005b06, 0x005d06, 0x005e07, 0x005f07, 0x006007, 0x006107, 0x006207, 0x006308, 0x006408, 0x006508, 0x006608, 0x006708, 0x006809, 0x006909, 0x006a09,
0x006b09, 0x016c0a, 0x016d0a, 0x016e0a, 0x016f0a, 0x01700b, 0x01710b, 0x01720b, 0x01730b, 0x01740c, 0x01750c, 0x01760c, 0x01770c, 0x01780d, 0x01790d, 0x017a0d,
0x017b0d, 0x017b0e, 0x017c0e, 0x017d0e, 0x017e0f, 0x017f0f, 0x01800f, 0x018110, 0x028210, 0x028310, 0x028410, 0x028511, 0x028611, 0x028711, 0x028812, 0x028912,
0x028a12, 0x028a13, 0x028b13, 0x028c13, 0x028d14, 0x028e14, 0x038f14, 0x039015, 0x039115, 0x039215, 0x039316, 0x039416, 0x039417, 0x039517, 0x039617, 0x039718,
0x049818, 0x049918, 0x049a19, 0x049b19, 0x049c19, 0x049c1a, 0x049d1a, 0x049e1b, 0x059f1b, 0x05a01b, 0x05a11c, 0x05a21c, 0x05a31c, 0x05a31d, 0x05a41d, 0x06a51e,
0x06a61e, 0x06a71f, 0x06a81f, 0x06a920, 0x06aa20, 0x07aa21, 0x07ab21, 0x07ac21, 0x07ad22, 0x07ae22, 0x08af23, 0x08b023, 0x08b024, 0x08b124, 0x08b225, 0x09b325,
0x09b426, 0x09b526, 0x09b527, 0x0ab627, 0x0ab728, 0x0ab828, 0x0ab929, 0x0bba29, 0x0bba2a, 0x0bbb2a, 0x0bbc2b, 0x0cbd2b, 0x0cbe2c, 0x0cbf2c, 0x0dbf2d, 0x0dc02d,
0x0dc12e, 0x0ec22e, 0x0ec32f, 0x0ec42f, 0x0fc430, 0x0fc530, 0x0fc631, 0x10c731, 0x10c832, 0x10c932, 0x11c933, 0x11ca33, 0x11cb34, 0x12cc35, 0x12cd35, 0x12cd36,
0x13ce36, 0x13cf37, 0x13d037, 0x14d138, 0x14d139, 0x14d239, 0x15d33a, 0x15d43a, 0x16d43b, 0x16d53b, 0x17d63c, 0x17d73d, 0x17d83d, 0x18d83e, 0x18d93e, 0x19da3f,
0x19db40, 0x1adc40, 0x1adc41, 0x1bdd41, 0x1bde42, 0x1cdf43, 0x1ce043, 0x1de044, 0x1ee145, 0x1ee245, 0x1fe346, 0x1fe446, 0x20e447, 0x20e548, 0x21e648, 0x22e749,
0x22e74a, 0x23e84a, 0x23e94b, 0x24ea4c, 0x25ea4c, 0x25eb4d, 0x26ec4e, 0x27ed4e, 0x27ee4f, 0x28ee50, 0x29ef50, 0x29f051, 0x2af152, 0x2bf153, 0x2cf253, 0x2cf354,
0x2df455, 0x2ef455, 0x2ff556, 0x2ff657, 0x30f758, 0x31f758, 0x32f859, 0x32f95a, 0x33fa5a, 0x34fa5b, 0x35fb5c, 0x36fc5d, 0x37fd5d, 0x38fd5e, 0x38fe5f, 0x39ff60
},
{ // White monitor
0x000000, 0x010102, 0x020203, 0x020304, 0x030406, 0x040507, 0x050608, 0x060709, 0x07080a, 0x08090c, 0x080a0d, 0x090b0e, 0x0a0c0f, 0x0b0d10, 0x0c0e11, 0x0d0f12,
0x0e1013, 0x0f1115, 0x101216, 0x111317, 0x121418, 0x121519, 0x13161a, 0x14171b, 0x15181c, 0x16191d, 0x171a1e, 0x181b1f, 0x191c20, 0x1a1d21, 0x1b1e22, 0x1c1f23,
0x1d2024, 0x1e2125, 0x1f2226, 0x202327, 0x212428, 0x222529, 0x22262b, 0x23272c, 0x24282d, 0x25292e, 0x262a2f, 0x272b30, 0x282c30, 0x292d31, 0x2a2e32, 0x2b2f33,
0x2c3034, 0x2d3035, 0x2e3136, 0x2f3237, 0x303338, 0x313439, 0x32353a, 0x33363b, 0x34373c, 0x35383d, 0x36393e, 0x373a3f, 0x383b40, 0x393c41, 0x3a3d42, 0x3b3e43,
0x3c3f44, 0x3d4045, 0x3e4146, 0x3f4247, 0x404348, 0x414449, 0x42454a, 0x43464b, 0x44474c, 0x45484d, 0x46494d, 0x474a4e, 0x484b4f, 0x484c50, 0x494d51, 0x4a4e52,
0x4b4f53, 0x4c5054, 0x4d5155, 0x4e5256, 0x4f5357, 0x505458, 0x515559, 0x52565a, 0x53575b, 0x54585b, 0x55595c, 0x565a5d, 0x575b5e, 0x585c5f, 0x595d60, 0x5a5e61,
0x5b5f62, 0x5c6063, 0x5d6164, 0x5e6265, 0x5f6366, 0x606466, 0x616567, 0x626668, 0x636769, 0x64686a, 0x65696b, 0x666a6c, 0x676b6d, 0x686c6e, 0x696d6f, 0x6a6e70,
0x6b6f70, 0x6c7071, 0x6d7172, 0x6f7273, 0x707374, 0x707475, 0x717576, 0x727677, 0x747778, 0x757879, 0x767979, 0x777a7a, 0x787b7b, 0x797c7c, 0x7a7d7d, 0x7b7e7e,
0x7c7f7f, 0x7d8080, 0x7e8181, 0x7f8281, 0x808382, 0x818483, 0x828584, 0x838685, 0x848786, 0x858887, 0x868988, 0x878a89, 0x888b89, 0x898c8a, 0x8a8d8b, 0x8b8e8c,
0x8c8f8d, 0x8d8f8e, 0x8e908f, 0x8f9190, 0x909290, 0x919391, 0x929492, 0x939593, 0x949694, 0x959795, 0x969896, 0x979997, 0x989a98, 0x999b98, 0x9a9c99, 0x9b9d9a,
0x9c9e9b, 0x9d9f9c, 0x9ea09d, 0x9fa19e, 0xa0a29f, 0xa1a39f, 0xa2a4a0, 0xa3a5a1, 0xa4a6a2, 0xa6a7a3, 0xa7a8a4, 0xa8a9a5, 0xa9aaa5, 0xaaaba6, 0xabaca7, 0xacada8,
0xadaea9, 0xaeafaa, 0xafb0ab, 0xb0b1ac, 0xb1b2ac, 0xb2b3ad, 0xb3b4ae, 0xb4b5af, 0xb5b6b0, 0xb6b7b1, 0xb7b8b2, 0xb8b9b2, 0xb9bab3, 0xbabbb4, 0xbbbcb5, 0xbcbdb6,
0xbdbeb7, 0xbebfb8, 0xbfc0b8, 0xc0c1b9, 0xc1c2ba, 0xc2c3bb, 0xc3c4bc, 0xc5c5bd, 0xc6c6be, 0xc7c7be, 0xc8c8bf, 0xc9c9c0, 0xcacac1, 0xcbcbc2, 0xccccc3, 0xcdcdc3,
0xcecec4, 0xcfcfc5, 0xd0d0c6, 0xd1d1c7, 0xd2d2c8, 0xd3d3c9, 0xd4d4c9, 0xd5d5ca, 0xd6d6cb, 0xd7d7cc, 0xd8d8cd, 0xd9d9ce, 0xdadacf, 0xdbdbcf, 0xdcdcd0, 0xdeddd1,
0xdfded2, 0xe0dfd3, 0xe1e0d4, 0xe2e1d4, 0xe3e2d5, 0xe4e3d6, 0xe5e4d7, 0xe6e5d8, 0xe7e6d9, 0xe8e7d9, 0xe9e8da, 0xeae9db, 0xebeadc, 0xecebdd, 0xedecde, 0xeeeddf,
0xefeedf, 0xf0efe0, 0xf1f0e1, 0xf2f1e2, 0xf3f2e3, 0xf4f3e3, 0xf6f3e4, 0xf7f4e5, 0xf8f5e6, 0xf9f6e7, 0xfaf7e8, 0xfbf8e9, 0xfcf9e9, 0xfdfaea, 0xfefbeb, 0xfffcec
}
};
static struct {
int x, y, y1, y2, w, h;
int busy;
int buffer_in_use;
thread_t *blit_thread;
event_t *wake_blit_thread;
event_t *blit_complete;
event_t *buffer_not_in_use;
} blit_data;
static void (*blit_func)(int x, int y, int y1, int y2, int w, int h);
static
void blit_thread(void *param)
{
while (1) {
thread_wait_event(blit_data.wake_blit_thread, -1);
thread_reset_event(blit_data.wake_blit_thread);
if (blit_func)
blit_func(blit_data.x, blit_data.y,
blit_data.y1, blit_data.y2,
blit_data.w, blit_data.h);
blit_data.busy = 0;
thread_set_event(blit_data.blit_complete);
}
}
void
video_setblit(void(*blit)(int,int,int,int,int,int))
{
blit_func = blit;
}
void
video_blit_complete(void)
{
blit_data.buffer_in_use = 0;
thread_set_event(blit_data.buffer_not_in_use);
}
void
video_wait_for_blit(void)
{
while (blit_data.busy)
thread_wait_event(blit_data.blit_complete, -1);
thread_reset_event(blit_data.blit_complete);
}
void
video_wait_for_buffer(void)
{
while (blit_data.buffer_in_use)
thread_wait_event(blit_data.buffer_not_in_use, -1);
thread_reset_event(blit_data.buffer_not_in_use);
}
void
video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h)
{
if (h <= 0) return;
video_wait_for_blit();
blit_data.busy = 1;
blit_data.buffer_in_use = 1;
blit_data.x = x;
blit_data.y = y;
blit_data.y1 = y1;
blit_data.y2 = y2;
blit_data.w = w;
blit_data.h = h;
thread_set_event(blit_data.wake_blit_thread);
}
void
video_blit_memtoscreen_8(int x, int y, int y1, int y2, int w, int h)
{
int yy, xx;
if (h <= 0) return;
for (yy = 0; yy < h; yy++)
{
if ((y + yy) >= 0 && (y + yy) < buffer->h)
{
for (xx = 0; xx < w; xx++)
*(uint32_t *) &(buffer32->line[y + yy][(x + xx) << 2]) = pal_lookup[buffer->line[y + yy][x + xx]];
}
}
video_blit_memtoscreen(x, y, y1, y2, w, h);
}
void
cgapal_rebuild(void)
{
int c;
/* We cannot do this (yet) if we have not been enabled yet. */
if (video_6to8 == NULL) return;
for (c=0; c<256; c++) {
pal_lookup[c] = makecol(video_6to8[cgapal[c].r],
video_6to8[cgapal[c].g],
video_6to8[cgapal[c].b]);
}
if ((cga_palette > 1) && (cga_palette < 8)) {
if (vid_cga_contrast != 0) {
for (c=0; c<16; c++) {
pal_lookup[c] = makecol(video_6to8[cgapal_mono[cga_palette - 2][c].r],
video_6to8[cgapal_mono[cga_palette - 2][c].g],
video_6to8[cgapal_mono[cga_palette - 2][c].b]);
pal_lookup[c+16] = makecol(video_6to8[cgapal_mono[cga_palette - 2][c].r],
video_6to8[cgapal_mono[cga_palette - 2][c].g],
video_6to8[cgapal_mono[cga_palette - 2][c].b]);
pal_lookup[c+32] = makecol(video_6to8[cgapal_mono[cga_palette - 2][c].r],
video_6to8[cgapal_mono[cga_palette - 2][c].g],
video_6to8[cgapal_mono[cga_palette - 2][c].b]);
pal_lookup[c+48] = makecol(video_6to8[cgapal_mono[cga_palette - 2][c].r],
video_6to8[cgapal_mono[cga_palette - 2][c].g],
video_6to8[cgapal_mono[cga_palette - 2][c].b]);
}
} else {
for (c=0; c<16; c++) {
pal_lookup[c] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r],
video_6to8[cgapal_mono[cga_palette - 1][c].g],
video_6to8[cgapal_mono[cga_palette - 1][c].b]);
pal_lookup[c+16] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r],
video_6to8[cgapal_mono[cga_palette - 1][c].g],
video_6to8[cgapal_mono[cga_palette - 1][c].b]);
pal_lookup[c+32] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r],
video_6to8[cgapal_mono[cga_palette - 1][c].g],
video_6to8[cgapal_mono[cga_palette - 1][c].b]);
pal_lookup[c+48] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r],
video_6to8[cgapal_mono[cga_palette - 1][c].g],
video_6to8[cgapal_mono[cga_palette - 1][c].b]);
}
}
}
if (cga_palette == 8)
pal_lookup[0x16] = makecol(video_6to8[42],video_6to8[42],video_6to8[0]);
}
void
video_inform(int type, const video_timings_t *ptr)
{
vid_type = type;
vid_timings = ptr;
}
int
video_get_type(void)
{
return vid_type;
}
void
video_update_timing(void)
{
if (!vid_timings)
pclog("WARNING: vid_timings is NULL\n");
if (vid_timings->type == VIDEO_ISA) {
video_timing_read_b = ISA_CYCLES(vid_timings->read_b);
video_timing_read_w = ISA_CYCLES(vid_timings->read_w);
video_timing_read_l = ISA_CYCLES(vid_timings->read_l);
video_timing_write_b = ISA_CYCLES(vid_timings->write_b);
video_timing_write_w = ISA_CYCLES(vid_timings->write_w);
video_timing_write_l = ISA_CYCLES(vid_timings->write_l);
} else {
video_timing_read_b = (int)(bus_timing * vid_timings->read_b);
video_timing_read_w = (int)(bus_timing * vid_timings->read_w);
video_timing_read_l = (int)(bus_timing * vid_timings->read_l);
video_timing_write_b = (int)(bus_timing * vid_timings->write_b);
video_timing_write_w = (int)(bus_timing * vid_timings->write_w);
video_timing_write_l = (int)(bus_timing * vid_timings->write_l);
}
if (cpu_16bitbus) {
video_timing_read_l = video_timing_read_w * 2;
video_timing_write_l = video_timing_write_w * 2;
}
}
int
calc_6to8(int c)
{
int ic, i8;
double d8;
ic = c;
if (ic == 64)
ic = 63;
else
ic &= 0x3f;
d8 = (ic / 63.0) * 255.0;
i8 = (int) d8;
return(i8 & 0xff);
}
int
calc_15to32(int c)
{
int b, g, r;
double db, dg, dr;
b = (c & 31);
g = ((c >> 5) & 31);
r = ((c >> 10) & 31);
db = (((double) b) / 31.0) * 255.0;
dg = (((double) g) / 31.0) * 255.0;
dr = (((double) r) / 31.0) * 255.0;
b = (int) db;
g = ((int) dg) << 8;
r = ((int) dr) << 16;
return(b | g | r);
}
int
calc_16to32(int c)
{
int b, g, r;
double db, dg, dr;
b = (c & 31);
g = ((c >> 5) & 63);
r = ((c >> 11) & 31);
db = (((double) b) / 31.0) * 255.0;
dg = (((double) g) / 63.0) * 255.0;
dr = (((double) r) / 31.0) * 255.0;
b = (int) db;
g = ((int) dg) << 8;
r = ((int) dr) << 16;
return(b | g | r);
}
void
hline(bitmap_t *b, int x1, int y, int x2, uint32_t col)
{
if (y < 0 || y >= buffer->h)
return;
if (b == buffer)
memset(&b->line[y][x1], col, x2 - x1);
else
memset(&((uint32_t *)b->line[y])[x1], col, (x2 - x1) * 4);
}
void
blit(bitmap_t *src, bitmap_t *dst, int x1, int y1, int x2, int y2, int xs, int ys)
{
}
void
stretch_blit(bitmap_t *src, bitmap_t *dst, int x1, int y1, int xs1, int ys1, int x2, int y2, int xs2, int ys2)
{
}
void
rectfill(bitmap_t *b, int x1, int y1, int x2, int y2, uint32_t col)
{
}
void
set_palette(PALETTE p)
{
}
void
destroy_bitmap(bitmap_t *b)
{
if (b->dat != NULL)
free(b->dat);
free(b);
}
bitmap_t *
create_bitmap(int x, int y)
{
bitmap_t *b = malloc(sizeof(bitmap_t) + (y * sizeof(uint8_t *)));
int c;
b->dat = malloc(x * y * 4);
for (c = 0; c < y; c++)
b->line[c] = b->dat + (c * x * 4);
b->w = x;
b->h = y;
return(b);
}
void
video_init(void)
{
int c, d, e;
/* Account for overscan. */
buffer32 = create_bitmap(2048, 2048);
buffer = create_bitmap(2048, 2048);
for (c = 0; c < 64; c++) {
cgapal[c + 64].r = (((c & 4) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21;
cgapal[c + 64].g = (((c & 2) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21;
cgapal[c + 64].b = (((c & 1) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21;
if ((c & 0x17) == 6)
cgapal[c + 64].g >>= 1;
}
for (c = 0; c < 64; c++) {
cgapal[c + 128].r = (((c & 4) ? 2 : 0) | ((c & 0x20) ? 1 : 0)) * 21;
cgapal[c + 128].g = (((c & 2) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21;
cgapal[c + 128].b = (((c & 1) ? 2 : 0) | ((c & 0x08) ? 1 : 0)) * 21;
}
for (c = 0; c < 256; c++) {
e = c;
for (d = 0; d < 8; d++) {
rotatevga[d][c] = e;
e = (e >> 1) | ((e & 1) ? 0x80 : 0);
}
}
for (c = 0; c < 4; c++) {
for (d = 0; d < 4; d++) {
edatlookup[c][d] = 0;
if (c & 1) edatlookup[c][d] |= 1;
if (d & 1) edatlookup[c][d] |= 2;
if (c & 2) edatlookup[c][d] |= 0x10;
if (d & 2) edatlookup[c][d] |= 0x20;
}
}
video_6to8 = malloc(4 * 256);
for (c = 0; c < 256; c++)
video_6to8[c] = calc_6to8(c);
video_15to32 = malloc(4 * 65536);
#if 0
for (c = 0; c < 65536; c++)
video_15to32[c] = ((c & 31) << 3) | (((c >> 5) & 31) << 11) | (((c >> 10) & 31) << 19);
#endif
for (c = 0; c < 65536; c++)
video_15to32[c] = calc_15to32(c);
video_16to32 = malloc(4 * 65536);
#if 0
for (c = 0; c < 65536; c++)
video_16to32[c] = ((c & 31) << 3) | (((c >> 5) & 63) << 10) | (((c >> 11) & 31) << 19);
#endif
for (c = 0; c < 65536; c++)
video_16to32[c] = calc_16to32(c);
blit_data.wake_blit_thread = thread_create_event();
blit_data.blit_complete = thread_create_event();
blit_data.buffer_not_in_use = thread_create_event();
blit_data.blit_thread = thread_create(blit_thread, NULL);
}
void
video_close(void)
{
thread_kill(blit_data.blit_thread);
thread_destroy_event(blit_data.buffer_not_in_use);
thread_destroy_event(blit_data.blit_complete);
thread_destroy_event(blit_data.wake_blit_thread);
free(video_6to8);
free(video_15to32);
free(video_16to32);
destroy_bitmap(buffer);
destroy_bitmap(buffer32);
if (fontdatksc5601) {
free(fontdatksc5601);
fontdatksc5601 = NULL;
}
if (fontdatksc5601_user) {
free(fontdatksc5601_user);
fontdatksc5601_user = NULL;
}
}
uint8_t
video_force_resize_get(void)
{
return video_force_resize;
}
void
video_force_resize_set(uint8_t res)
{
video_force_resize = res;
}
void
loadfont(wchar_t *s, int format)
{
FILE *f;
int c,d;
f = rom_fopen(s, L"rb");
if (f == NULL)
return;
switch (format) {
case 0: /* MDA */
for (c=0; c<256; c++)
for (d=0; d<8; d++)
fontdatm[c][d] = fgetc(f);
for (c=0; c<256; c++)
for (d=0; d<8; d++)
fontdatm[c][d+8] = fgetc(f);
(void)fseek(f, 4096+2048, SEEK_SET);
for (c=0; c<256; c++)
for (d=0; d<8; d++)
fontdat[c][d] = fgetc(f);
break;
case 1: /* PC200 */
for (c=0; c<256; c++)
for (d=0; d<8; d++)
fontdatm[c][d] = fgetc(f);
for (c=0; c<256; c++)
for (d=0; d<8; d++)
fontdatm[c][d+8] = fgetc(f);
(void)fseek(f, 4096, SEEK_SET);
for (c=0; c<256; c++) {
for (d=0; d<8; d++)
fontdat[c][d] = fgetc(f);
for (d=0; d<8; d++) (void)fgetc(f);
}
break;
default:
case 2: /* CGA */
for (c=0; c<256; c++)
for (d=0; d<8; d++)
fontdat[c][d] = fgetc(f);
break;
case 3: /* Wyse 700 */
for (c=0; c<512; c++)
for (d=0; d<32; d++)
fontdatw[c][d] = fgetc(f);
break;
case 4: /* MDSI Genius */
for (c=0; c<256; c++)
for (d=0; d<16; d++)
fontdat8x12[c][d] = fgetc(f);
break;
case 5: /* Toshiba 3100e */
for (d = 0; d < 2048; d += 512) /* Four languages... */
{
for (c = d; c < d+256; c++)
{
fread(&fontdatm[c][8], 1, 8, f);
}
for (c = d+256; c < d+512; c++)
{
fread(&fontdatm[c][8], 1, 8, f);
}
for (c = d; c < d+256; c++)
{
fread(&fontdatm[c][0], 1, 8, f);
}
for (c = d+256; c < d+512; c++)
{
fread(&fontdatm[c][0], 1, 8, f);
}
fseek(f, 4096, SEEK_CUR); /* Skip blank section */
for (c = d; c < d+256; c++)
{
fread(&fontdat[c][0], 1, 8, f);
}
for (c = d+256; c < d+512; c++)
{
fread(&fontdat[c][0], 1, 8, f);
}
}
break;
case 6: /* Korean KSC-5601 */
if (!fontdatksc5601)
fontdatksc5601 = malloc(16384 * sizeof(dbcs_font_t));
if (!fontdatksc5601_user)
fontdatksc5601_user = malloc(192 * sizeof(dbcs_font_t));
for (c = 0; c < 16384; c++)
{
for (d = 0; d < 32; d++)
fontdatksc5601[c].chr[d]=getc(f);
}
break;
}
(void)fclose(f);
}
uint32_t
video_color_transform(uint32_t color)
{
uint8_t *clr8 = (uint8_t *) &color;
/* if (!video_grayscale && !invert_display)
return color; */
if (video_grayscale) {
if (video_graytype) {
if (video_graytype == 1)
color = ((54 * (uint32_t)clr8[2]) + (183 * (uint32_t)clr8[1]) + (18 * (uint32_t)clr8[0])) / 255;
else
color = ((uint32_t)clr8[2] + (uint32_t)clr8[1] + (uint32_t)clr8[0]) / 3;
} else
color = ((76 * (uint32_t)clr8[2]) + (150 * (uint32_t)clr8[1]) + (29 * (uint32_t)clr8[0])) / 255;
switch (video_grayscale) {
case 2: case 3: case 4:
color = (uint32_t) shade[video_grayscale][color];
break;
default:
clr8[3] = 0;
clr8[0] = color;
clr8[1] = clr8[2] = clr8[0];
break;
}
}
if (invert_display)
color ^= 0x00ffffff;
return color;
}
void
video_transform_copy(uint32_t *dst, uint32_t *src, int len)
{
int i;
for (i = 0; i < len; i++) {
*dst = video_color_transform(*src);
dst++;
src++;
}
}

283
src/video/video - Cópia.h Normal file
View File

@@ -0,0 +1,283 @@
/*
* 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.
*
* Definitions for the video controller module.
*
* Version: @(#)video.h 1.0.35 2018/09/19
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
* Copyright 2017,2018 Fred N. van Kempen.
*/
#ifndef EMU_VIDEO_H
# define EMU_VIDEO_H
#define makecol(r, g, b) ((b) | ((g) << 8) | ((r) << 16))
#define makecol32(r, g, b) ((b) | ((g) << 8) | ((r) << 16))
enum {
GFX_NONE = 0,
GFX_INTERNAL,
GFX_CGA,
GFX_COMPAQ_CGA, /* Compaq CGA */
GFX_COMPAQ_CGA_2, /* Compaq CGA 2 */
GFX_COLORPLUS, /* Plantronics ColorPlus */
GFX_WY700, /* Wyse 700 */
GFX_MDA,
GFX_GENIUS, /* MDSI Genius */
GFX_HERCULES,
GFX_HERCULESPLUS,
GFX_INCOLOR, /* Hercules InColor */
GFX_EGA, /* Using IBM EGA BIOS */
GFX_COMPAQ_EGA, /* Compaq EGA */
GFX_SUPER_EGA, /* Using Chips & Technologies SuperEGA BIOS */
GFX_VGA, /* IBM VGA */
GFX_TVGA, /* Using Trident TVGA8900D BIOS */
GFX_ET4000_ISA, /* Tseng ET4000 */
GFX_ET4000_MCA, /* Tseng ET4000 */
GFX_TGKOREANVGA, /*Trigem Korean VGA(Tseng ET4000AX)*/
GFX_ET4000W32_CARDEX_VLB, /* Tseng ET4000/W32p (Cardex) VLB */
GFX_ET4000W32_CARDEX_PCI, /* Tseng ET4000/W32p (Cardex) PCI */
#if defined(DEV_BRANCH) && defined(USE_STEALTH32)
GFX_ET4000W32_VLB, /* Tseng ET4000/W32p (Diamond Stealth 32) VLB */
GFX_ET4000W32_PCI, /* Tseng ET4000/W32p (Diamond Stealth 32) PCI */
#endif
GFX_BAHAMAS64_VLB, /* S3 Vision864 (Paradise Bahamas 64) VLB */
GFX_BAHAMAS64_PCI, /* S3 Vision864 (Paradise Bahamas 64) PCI */
GFX_N9_9FX_VLB, /* S3 764/Trio64 (Number Nine 9FX) VLB */
GFX_N9_9FX_PCI, /* S3 764/Trio64 (Number Nine 9FX) PCI */
GFX_TGUI9400CXI, /* Trident TGUI9400CXi VLB */
GFX_TGUI9440_VLB, /* Trident TGUI9440AGi VLB */
GFX_TGUI9440_PCI, /* Trident TGUI9440AGi PCI */
GFX_ATIKOREANVGA, /*ATI Korean VGA (28800-5)*/
GFX_VGA88, /* ATI VGA-88 (18800-1) */
GFX_VGAEDGE16, /* ATI VGA Edge-16 (18800-1) */
GFX_VGACHARGER, /* ATI VGA Charger (28800-5) */
#if defined(DEV_BRANCH) && defined(USE_VGAWONDER)
GFX_VGAWONDER, /* Compaq ATI VGA Wonder (18800) */
#endif
GFX_VGAWONDERXL, /* Compaq ATI VGA Wonder XL (28800-5) */
#if defined(DEV_BRANCH) && defined(USE_XL24)
GFX_VGAWONDERXL24, /* Compaq ATI VGA Wonder XL24 (28800-6) */
#endif
GFX_MACH64GX_ISA, /* ATI Graphics Pro Turbo (Mach64) ISA */
GFX_MACH64GX_VLB, /* ATI Graphics Pro Turbo (Mach64) VLB */
GFX_MACH64GX_PCI, /* ATI Graphics Pro Turbo (Mach64) PCI */
GFX_MACH64VT2, /* ATI Mach64 VT2 */
GFX_CL_GD5424_ISA, /* Cirrus Logic CL-GD 5424 ISA */
GFX_CL_GD5424_VLB, /* Cirrus Logic CL-GD 5424 VLB */
GFX_CL_GD5426_VLB, /* Diamond SpeedStar PRO (Cirrus Logic CL-GD 5426) VLB */
GFX_CL_GD5428_ISA, /* Cirrus Logic CL-GD 5428 ISA */
GFX_CL_GD5428_VLB, /* Cirrus Logic CL-GD 5428 VLB */
GFX_CL_GD5429_ISA, /* Cirrus Logic CL-GD 5429 ISA */
GFX_CL_GD5429_VLB, /* Cirrus Logic CL-GD 5429 VLB */
GFX_CL_GD5430_VLB, /* Diamond SpeedStar PRO SE (Cirrus Logic CL-GD 5430) VLB */
GFX_CL_GD5430_PCI, /* Cirrus Logic CL-GD 5430 PCI */
GFX_CL_GD5434_ISA, /* Cirrus Logic CL-GD 5434 ISA */
GFX_CL_GD5434_VLB, /* Cirrus Logic CL-GD 5434 VLB */
GFX_CL_GD5434_PCI, /* Cirrus Logic CL-GD 5434 PCI */
GFX_CL_GD5436_PCI, /* Cirrus Logic CL-GD 5436 PCI */
GFX_CL_GD5440_PCI, /* Cirrus Logic CL-GD 5440 PCI */
GFX_CL_GD5446_PCI, /* Cirrus Logic CL-GD 5446 PCI */
GFX_CL_GD5446_STB_PCI, /* STB Nitro 64V (Cirrus Logic CL-GD 5446) PCI */
GFX_CL_GD5480_PCI, /* Cirrus Logic CL-GD 5480 PCI */
GFX_EXPERTCOLOR_VLB, /* S3 Vision868 (ExpertColor DSV3868P CF55) VLB */
GFX_EXPERTCOLOR_PCI, /* S3 Vision868 (ExpertColor DSV3868P CF55) PCI */
GFX_OTI037C, /* Oak OTI-037C */
GFX_OTI067, /* Oak OTI-067 */
GFX_OTI077, /* Oak OTI-077 */
GFX_PVGA1A, /* Paradise PVGA1A Standalone */
GFX_WD90C11, /* Paradise WD90C11-LR Standalone */
GFX_WD90C30, /* Paradise WD90C30-LR Standalone */
GFX_PHOENIX_VISION864_VLB, /* S3 Vision864 (Phoenix) VLB */
GFX_PHOENIX_VISION864_PCI, /* S3 Vision864 (Phoenix) PCI */
GFX_PHOENIX_TRIO32_VLB, /* S3 732/Trio32 (Phoenix) VLB */
GFX_PHOENIX_TRIO32_PCI, /* S3 732/Trio32 (Phoenix) PCI */
GFX_PHOENIX_TRIO64_VLB, /* S3 764/Trio64 (Phoenix) VLB */
GFX_PHOENIX_TRIO64_PCI, /* S3 764/Trio64 (Phoenix) PCI */
GFX_STEALTH64_VLB, /* S3 Trio64 (Diamond Stealth 64) VLB */
GFX_STEALTH64_PCI, /* S3 Trio64 (Diamond Stealth 64) PCI */
#if defined(DEV_BRANCH) && defined(USE_TI)
GFX_TICF62011, /* TI CF62011 */
#endif
GFX_VIRGE_VLB, /* S3 Virge VLB */
GFX_VIRGE_PCI, /* S3 Virge PCI */
GFX_VIRGEDX_VLB, /* S3 Virge/DX VLB */
GFX_VIRGEDX_PCI, /* S3 Virge/DX PCI */
GFX_VIRGEDX4_VLB, /* S3 Virge/DX (VBE 2.0) VLB */
GFX_VIRGEDX4_PCI, /* S3 Virge/DX (VBE 2.0) PCI */
GFX_VIRGEVX_VLB, /* S3 Virge/VX VLB */
GFX_VIRGEVX_PCI, /* S3 Virge/VX PCI */
GFX_MAX
};
enum {
FULLSCR_SCALE_FULL = 0,
FULLSCR_SCALE_43,
FULLSCR_SCALE_SQ,
FULLSCR_SCALE_INT,
FULLSCR_SCALE_KEEPRATIO
};
#ifdef __cplusplus
extern "C" {
#endif
enum {
VIDEO_ISA = 0,
VIDEO_MCA,
VIDEO_BUS
};
#define VIDEO_FLAG_TYPE_CGA 0
#define VIDEO_FLAG_TYPE_MDA 1
#define VIDEO_FLAG_TYPE_SPECIAL 2
#define VIDEO_FLAG_TYPE_MASK 3
typedef struct {
int type;
int write_b, write_w, write_l;
int read_b, read_w, read_l;
} video_timings_t;
typedef struct {
int w, h;
uint8_t *dat;
uint8_t *line[2048];
} bitmap_t;
typedef struct {
uint8_t r, g, b;
} rgb_t;
typedef struct {
uint8_t chr[32];
} dbcs_font_t;
typedef rgb_t PALETTE[256];
extern int gfx_present[GFX_MAX];
extern int egareads,
egawrites;
extern int changeframecount;
extern bitmap_t *screen,
*buffer,
*buffer32;
extern PALETTE cgapal,
cgapal_mono[6];
extern uint32_t pal_lookup[256];
extern int video_fullscreen,
video_fullscreen_scale,
video_fullscreen_first;
extern int fullchange;
extern uint8_t fontdat[2048][8];
extern uint8_t fontdatm[2048][16];
extern dbcs_font_t *fontdatksc5601;
extern dbcs_font_t *fontdatksc5601_user;
extern uint32_t *video_6to8,
*video_15to32,
*video_16to32;
extern int xsize,ysize;
extern int enable_overscan;
extern int overscan_x,
overscan_y;
extern int force_43;
extern int video_timing_read_b,
video_timing_read_w,
video_timing_read_l;
extern int video_timing_write_b,
video_timing_write_w,
video_timing_write_l;
extern int video_res_x,
video_res_y,
video_bpp;
extern int vid_resize;
extern int cga_palette;
extern int vid_cga_contrast;
extern int video_grayscale;
extern int video_graytype;
extern float cpuclock;
extern int emu_fps,
frames;
extern int readflash;
/* Function handler pointers. */
extern void (*video_recalctimings)(void);
/* Table functions. */
extern int video_card_available(int card);
extern char *video_card_getname(int card);
#ifdef EMU_DEVICE_H
extern const device_t *video_card_getdevice(int card);
#endif
extern int video_card_has_config(int card);
extern int video_card_getid(char *s);
extern int video_old_to_new(int card);
extern int video_new_to_old(int card);
extern char *video_get_internal_name(int card);
extern int video_get_video_from_internal_name(char *s);
extern int video_is_mda(void);
extern int video_is_cga(void);
extern int video_is_ega_vga(void);
extern void video_inform(int type, const video_timings_t *ptr);
extern int video_get_type(void);
extern void video_setblit(void(*blit)(int,int,int,int,int,int));
extern void video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h);
extern void video_blit_memtoscreen_8(int x, int y, int y1, int y2, int w, int h);
extern void video_blit_complete(void);
extern void video_wait_for_blit(void);
extern void video_wait_for_buffer(void);
extern bitmap_t *create_bitmap(int w, int h);
extern void destroy_bitmap(bitmap_t *b);
extern void cgapal_rebuild(void);
extern void hline(bitmap_t *b, int x1, int y, int x2, uint32_t col);
extern void updatewindowsize(int x, int y);
extern void video_init(void);
extern void video_close(void);
extern void video_font_reset(void);
extern void video_reset(int card);
extern uint8_t video_force_resize_get(void);
extern void video_force_resize_set(uint8_t res);
extern void video_update_timing(void);
extern void loadfont(wchar_t *s, int format);
extern int get_actual_size_x(void);
extern int get_actual_size_y(void);
#ifdef ENABLE_VRAM_DUMP
extern void svga_dump_vram(void);
#endif
extern uint32_t video_color_transform(uint32_t color);
extern void video_transform_copy(uint32_t *dst, uint32_t *src, int len);
#ifdef __cplusplus
}
#endif
#endif /*EMU_VIDEO_H*/