From 67f6649a2689c0ecb282433a9e7348035707c4ac Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 12 Mar 2018 15:19:36 +0100 Subject: [PATCH] Applied the ATI Korean VGA patch from greatpsycho. --- src/video/vid_ati28800.c | 83 ++++++++++++--- src/video/vid_svga.c | 11 +- src/video/vid_svga_render.c | 205 +++++++++++++++++++++--------------- src/video/vid_svga_render.h | 9 +- 4 files changed, 198 insertions(+), 110 deletions(-) diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index cc6be6487..5a9c7093f 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -8,7 +8,7 @@ * * ATI 28800 emulation (VGA Charger and Korean VGA) * - * Version: @(#)vid_ati28800.c 1.0.9 2018/03/05 + * Version: @(#)vid_ati28800.c 1.0.10 2018/03/12 * * Authors: Sarah Walker, * Miran Grca, @@ -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 }; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 695644c5e..92b17be32 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -11,7 +11,7 @@ * This is intended to be used by another SVGA driver, * and not as a card in it's own right. * - * Version: @(#)vid_svga.c 1.0.24 2018/03/11 + * Version: @(#)vid_svga.c 1.0.25 2018/03/12 * * Authors: Sarah Walker, * Miran Grca, @@ -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++; diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 5f24264d0..818e25d57 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -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, * Miran Grca, @@ -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; diff --git a/src/video/vid_svga_render.h b/src/video/vid_svga_render.h index cfad3585d..4bbc43272 100644 --- a/src/video/vid_svga_render.h +++ b/src/video/vid_svga_render.h @@ -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, * Miran Grca, - * 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);