Applied the ATI Korean VGA patch from greatpsycho.
This commit is contained in:
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -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++;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user