Applied the ATI Korean VGA patch from greatpsycho.

This commit is contained in:
OBattler
2018-03-12 15:19:36 +01:00
parent 1e25dc24e3
commit 67f6649a26
4 changed files with 198 additions and 110 deletions

View File

@@ -8,7 +8,7 @@
*
* ATI 28800 emulation (VGA Charger and Korean VGA)
*
* Version: @(#)vid_ati28800.c 1.0.9 2018/03/05
* Version: @(#)vid_ati28800.c 1.0.10 2018/03/12
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -59,7 +59,7 @@ typedef struct ati28800_t
uint8_t regs[256];
int index;
uint32_t memory;
uint32_t memory;
} ati28800_t;
@@ -69,7 +69,7 @@ int in_get_korean_font_kind_set;
int get_korean_font_enabled;
int get_korean_font_index;
uint16_t get_korean_font_base;
extern int dbcs_mode_enabled;
int ksc5601_mode_enabled;
static void ati28800_out(uint16_t addr, uint8_t val, void *p)
@@ -106,9 +106,14 @@ static void ati28800_out(uint16_t addr, uint8_t val, void *p)
case 0xb3:
ati_eeprom_write(&ati28800->eeprom, val & 8, val & 2, val & 1);
break;
case 0xb6:
if((old ^ val) & 0x10) svga_recalctimings(svga);
break;
case 0xb6:
if((old ^ val) & 0x10) svga_recalctimings(svga);
break;
case 0xb8:
if((old ^ val) & 0x40) svga_recalctimings(svga);
break;
case 0xb9:
if((old ^ val) & 2) svga_recalctimings(svga);
}
break;
@@ -149,7 +154,7 @@ void ati28800k_out(uint16_t addr, uint8_t val, void *p)
case 0x1CF:
if(ati28800->index == 0xBF && ((ati28800->regs[0xBF] ^ val) & 0x20))
{
dbcs_mode_enabled = val & 0x20;
ksc5601_mode_enabled = val & 0x20;
svga_recalctimings(svga);
}
@@ -291,13 +296,44 @@ static void ati28800_recalctimings(svga_t *svga)
{
ati28800_t *ati28800 = (ati28800_t *)svga->p;
if (ati28800->regs[0xb6] & 0x10)
{
switch(((ati28800->regs[0xbe] & 0x10) >> 1) | ((ati28800->regs[0xb9] & 2) << 1) | ((svga->miscout & 0x0C) >> 2))
{
case 0x00: svga->clock = cpuclock / 42954000.0; break;
case 0x01: svga->clock = cpuclock / 48771000.0; break;
case 0x03: svga->clock = cpuclock / 36000000.0; break;
case 0x04: svga->clock = cpuclock / 50350000.0; break;
case 0x05: svga->clock = cpuclock / 56640000.0; break;
case 0x07: svga->clock = cpuclock / 44900000.0; break;
case 0x08: svga->clock = cpuclock / 30240000.0; break;
case 0x09: svga->clock = cpuclock / 32000000.0; break;
case 0x0A: svga->clock = cpuclock / 37500000.0; break;
case 0x0B: svga->clock = cpuclock / 39000000.0; break;
case 0x0C: svga->clock = cpuclock / 40000000.0; break;
case 0x0D: svga->clock = cpuclock / 56644000.0; break;
case 0x0E: svga->clock = cpuclock / 75000000.0; break;
case 0x0F: svga->clock = cpuclock / 65000000.0; break;
default: break;
}
if(ati28800->regs[0xb8] & 0x40) svga->clock *= 2;
if (ati28800->regs[0xb6] & 0x10)
{
svga->hdisp <<= 1;
svga->htotal <<= 1;
svga->rowoffset <<= 1;
}
}
if(svga->crtc[0x17] & 4)
{
svga->vtotal <<= 1;
svga->dispend <<= 1;
svga->vsyncstart <<= 1;
svga->split <<= 1;
svga->vblankstart <<= 1;
}
if (!svga->scrblank && (ati28800->regs[0xb0] & 0x20)) /*Extended 256 colour modes*/
{
svga->render = svga_render_8bpp_highres;
@@ -307,6 +343,16 @@ static void ati28800_recalctimings(svga_t *svga)
}
}
void ati28800k_recalctimings(svga_t *svga)
{
ati28800_recalctimings(svga);
if (svga->render == svga_render_text_80 && ksc5601_mode_enabled)
{
svga->render = svga_render_text_80_ksc5601;
}
}
void *
ati28800k_init(device_t *info)
{
@@ -321,13 +367,13 @@ ati28800k_init(device_t *info)
get_korean_font_enabled = 0;
get_korean_font_kind = 0;
in_get_korean_font_kind_set = 0;
dbcs_mode_enabled = 0;
ksc5601_mode_enabled = 0;
rom_init(&ati28800->bios_rom, BIOS_ATIKOR_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
loadfont(FONT_ATIKOR_PATH, 6);
svga_init(&ati28800->svga, ati28800, ati28800->memory << 10, /*Memory size, default 512KB*/
ati28800_recalctimings,
ati28800k_recalctimings,
ati28800k_in, ati28800k_out,
NULL,
NULL);
@@ -457,6 +503,17 @@ ati28800_force_redraw(void *priv)
ati->svga.fullchange = changeframecount;
}
void ati28800k_add_status_info(char *s, int max_len, void *p)
{
ati28800_t *ati28800 = (ati28800_t *)p;
char temps[128];
svga_add_status_info(s, max_len, &ati28800->svga);
sprintf(temps, "Korean SVGA mode enabled : %s\n\n", ksc5601_mode_enabled ? "Yes" : "No");
strncat(s, temps, max_len);
}
static void ati28800_add_status_info(char *s, int max_len, void *priv)
{
ati28800_t *ati = (ati28800_t *)priv;
@@ -537,7 +594,7 @@ device_t ati28800k_device =
ati28800k_available,
ati28800_speed_changed,
ati28800_force_redraw,
ati28800_add_status_info,
ati28800k_add_status_info,
ati28800_config
};

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.24 2018/03/11
* Version: @(#)vid_svga.c 1.0.25 2018/03/12
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -385,15 +385,6 @@ void svga_recalctimings(svga_t *svga)
if (svga->crtc[9] & 0x20) svga->vblankstart |= 0x200;
svga->vblankstart++;
if(svga->crtc[0x17] & 4)
{
svga->vtotal <<= 1;
svga->dispend <<= 1;
svga->vsyncstart <<= 1;
svga->split <<= 1;
svga->vblankstart <<= 1;
}
svga->hdisp = svga->crtc[1];
svga->hdisp++;

View File

@@ -8,7 +8,7 @@
*
* SVGA renderers.
*
* Version: @(#)vid_svga_render.c 1.0.7 2018/03/05
* Version: @(#)vid_svga_render.c 1.0.8 2018/03/12
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
@@ -92,9 +92,6 @@ uint32_t shade[5][256] =
}
};
int dbcs_mode_enabled = 0;
void svga_render_blank(svga_t *svga)
{
int x, xx;
@@ -208,7 +205,7 @@ void svga_render_text_80(svga_t *svga)
uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[32 + x_add];
int x, xx;
int drawcursor;
uint8_t chr, attr, dat, nextchr;
uint8_t chr, attr, dat;
uint32_t charaddr;
int fg, bg;
int xinc = (svga->seqregs[1] & 1) ? 8 : 9;
@@ -220,83 +217,6 @@ void svga_render_text_80(svga_t *svga)
attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask];
if(dbcs_mode_enabled && x + xinc < svga->hdisp && chr & 0x80)
{
nextchr = svga->vram[((svga->ma + 4) << 1) & svga->vram_display_mask];
if(nextchr & 0x80)
{
if (drawcursor)
{
bg = svga->pallook[svga->egapal[attr & 15]];
fg = svga->pallook[svga->egapal[attr >> 4]];
}
else
{
fg = svga->pallook[svga->egapal[attr & 15]];
bg = svga->pallook[svga->egapal[attr >> 4]];
if (attr & 0x80 && svga->attrregs[0x10] & 8)
{
bg = svga->pallook[svga->egapal[(attr >> 4) & 7]];
if (svga->blink & 16)
fg = bg;
}
}
dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)][svga->sc];
if (svga->seqregs[1] & 1)
{
for (xx = 0; xx < 8; xx++)
p[xx] = (dat & (0x80 >> xx)) ? fg : bg;
}
else
{
for (xx = 0; xx < 8; xx++)
p[xx] = (dat & (0x80 >> xx)) ? fg : bg;
if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4))
p[8] = bg;
else
p[8] = (dat & 1) ? fg : bg;
}
attr = svga->vram[(((svga->ma + 4) << 1) + 1) & svga->vram_display_mask];
if (drawcursor)
{
bg = svga->pallook[svga->egapal[attr & 15]];
fg = svga->pallook[svga->egapal[attr >> 4]];
}
else
{
fg = svga->pallook[svga->egapal[attr & 15]];
bg = svga->pallook[svga->egapal[attr >> 4]];
if (attr & 0x80 && svga->attrregs[0x10] & 8)
{
bg = svga->pallook[svga->egapal[(attr >> 4) & 7]];
if (svga->blink & 16)
fg = bg;
}
}
dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)][svga->sc + 16];
if (svga->seqregs[1] & 1)
{
for (xx = 0; xx < 8; xx++)
p[xx+8] = (dat & (0x80 >> xx)) ? fg : bg;
}
else
{
for (xx = 0; xx < 8; xx++)
p[xx+9] = (dat & (0x80 >> xx)) ? fg : bg;
if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4))
p[17] = bg;
else
p[17] = (dat & 1) ? fg : bg;
}
svga->ma += 8;
p += xinc * 2;
continue;
}
}
if (attr & 8) charaddr = svga->charsetb + (chr * 128);
else charaddr = svga->charseta + (chr * 128);
@@ -342,6 +262,127 @@ void svga_render_text_80(svga_t *svga)
}
}
void svga_render_text_80_ksc5601(svga_t *svga)
{
int y_add = enable_overscan ? (overscan_y >> 1) : 0;
int x_add = enable_overscan ? 8 : 0;
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
if (svga->fullchange)
{
uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[32 + x_add];
int x, xx;
int drawcursor;
uint8_t chr, attr, dat, nextchr;
uint32_t charaddr;
int fg, bg;
int xinc = (svga->seqregs[1] & 1) ? 8 : 9;
for (x = 0; x < svga->hdisp; x += xinc)
{
drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron);
chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask];
nextchr = svga->vram[((svga->ma + 4) << 1) & svga->vram_display_mask];
attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask];
if (drawcursor)
{
bg = svga->pallook[svga->egapal[attr & 15]];
fg = svga->pallook[svga->egapal[attr >> 4]];
}
else
{
fg = svga->pallook[svga->egapal[attr & 15]];
bg = svga->pallook[svga->egapal[attr >> 4]];
if (attr & 0x80 && svga->attrregs[0x10] & 8)
{
bg = svga->pallook[svga->egapal[(attr >> 4) & 7]];
if (svga->blink & 16)
fg = bg;
}
}
fg = svga_color_transform(fg);
bg = svga_color_transform(bg);
if(x + xinc < svga->hdisp && (chr & nextchr & 0x80))
{
dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)][svga->sc];
}
else
{
if (attr & 8) charaddr = svga->charsetb + (chr * 128);
else charaddr = svga->charseta + (chr * 128);
dat = svga->vram[charaddr + (svga->sc << 2)];
}
if (svga->seqregs[1] & 1)
{
for (xx = 0; xx < 8; xx++)
p[xx] = (dat & (0x80 >> xx)) ? fg : bg;
}
else
{
for (xx = 0; xx < 8; xx++)
p[xx] = (dat & (0x80 >> xx)) ? fg : bg;
if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4))
p[8] = bg;
else
p[8] = (dat & 1) ? fg : bg;
}
svga->ma += 4;
p += xinc;
if(x + xinc < svga->hdisp && (chr & nextchr & 0x80))
{
attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask];
if (drawcursor)
{
bg = svga->pallook[svga->egapal[attr & 15]];
fg = svga->pallook[svga->egapal[attr >> 4]];
}
else
{
fg = svga->pallook[svga->egapal[attr & 15]];
bg = svga->pallook[svga->egapal[attr >> 4]];
if (attr & 0x80 && svga->attrregs[0x10] & 8)
{
bg = svga->pallook[svga->egapal[(attr >> 4) & 7]];
if (svga->blink & 16)
fg = bg;
}
}
dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)][svga->sc + 16];
if (svga->seqregs[1] & 1)
{
for (xx = 0; xx < 8; xx++)
p[xx] = (dat & (0x80 >> xx)) ? fg : bg;
}
else
{
for (xx = 0; xx < 8; xx++)
p[xx] = (dat & (0x80 >> xx)) ? fg : bg;
if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4))
p[8] = bg;
else
p[8] = (dat & 1) ? fg : bg;
}
svga->ma += 4;
p += xinc;
x += xinc;
}
}
svga->ma &= svga->vram_display_mask;
}
}
void svga_render_2bpp_lowres(svga_t *svga)
{
int changed_offset;

View File

@@ -8,12 +8,12 @@
*
* SVGA renderers.
*
* Version: @(#)vid_svga_render.h 1.0.0 2017/05/30
* Version: @(#)vid_svga_render.h 1.0.1 2018/03/12
*
* Author: 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.
*/
extern int firstline_draw, lastline_draw;
@@ -29,9 +29,8 @@ extern uint8_t edatlookup[4][4];
void svga_render_blank(svga_t *svga);
void svga_render_text_40(svga_t *svga);
void svga_render_text_40_12(svga_t *svga);
void svga_render_text_80(svga_t *svga);
void svga_render_text_80_12(svga_t *svga);
void svga_render_text_80_ksc5601(svga_t *svga);
void svga_render_2bpp_lowres(svga_t *svga);
void svga_render_2bpp_highres(svga_t *svga);