Added Trigem Korean VGA emulation. Patch from Greatpsycho.

This commit is contained in:
SarahW 2018-11-26 17:36:47 +00:00
commit c034381797
7 changed files with 186 additions and 4 deletions

View file

@ -481,6 +481,7 @@ enum
GFX_EGA, /*Using IBM EGA BIOS*/
GFX_TVGA, /*Using Trident TVGA8900D BIOS*/
GFX_ET4000, /*Tseng ET4000*/
GFX_TGKOREANVGA, /*Trigem Korean VGA(Tseng ET4000AX)*/
GFX_ET4000W32, /*Tseng ET4000/W32p (Diamond Stealth 32)*/
GFX_BAHAMAS64, /*S3 Vision864 (Paradise Bahamas 64)*/
GFX_N9_9FX, /*S3 764/Trio64 (Number Nine 9FX)*/

View file

@ -376,6 +376,7 @@ void *ati28800k_init()
io_sethandler(0x03c0, 0x0020, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800);
ati28800->svga.miscout = 1;
ati28800->svga.ksc5601_sbyte_mask = 0;
ati_eeprom_load(&ati28800->eeprom, "atikorvga.nvr", 0);

View file

@ -7,6 +7,7 @@
#include "rom.h"
#include "video.h"
#include "vid_svga.h"
#include "vid_svga_render.h"
#include "vid_unk_ramdac.h"
#include "vid_et4000.h"
@ -19,6 +20,11 @@ typedef struct et4000_t
rom_t bios_rom;
uint8_t banking;
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;
} et4000_t;
static uint8_t crtc_mask[0x40] =
@ -81,6 +87,59 @@ void et4000_out(uint16_t addr, uint8_t val, void *p)
svga_out(addr, val, 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][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][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][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][et4000->get_korean_font_index - 8] = val;
break;
}
et4000->get_korean_font_index++;
}
break;
}
break;
case 0x32CB:
et4000->port_32cb_val = val;
svga_recalctimings(&et4000->svga);
break;
}
}
uint8_t et4000_in(uint16_t addr, void *p)
{
et4000_t *et4000 = (et4000_t *)p;
@ -110,6 +169,60 @@ uint8_t et4000_in(uint16_t addr, void *p)
return svga_in(addr, svga);
}
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][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][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][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][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][et4000->get_korean_font_index - 8];
break;
}
et4000->get_korean_font_index++;
et4000->get_korean_font_index %= 72;
}
break;
case 4:
val = 0x0F;
break;
}
return val;
case 0x32CB:
return et4000->port_32cb_val;
}
return 0xff;
}
void et4000_recalctimings(svga_t *svga)
{
svga->ma_latch |= (svga->crtc[0x33]&3)<<16;
@ -143,6 +256,21 @@ void et4000_recalctimings(svga_t *svga)
}
}
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_init()
{
et4000_t *et4000 = malloc(sizeof(et4000_t));
@ -161,11 +289,43 @@ void *et4000_init()
return et4000;
}
void *et4000k_init()
{
et4000_t *et4000 = malloc(sizeof(et4000_t));
memset(et4000, 0, sizeof(et4000_t));
rom_init(&et4000->bios_rom, "tgkorvga.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
loadfont("tg_ksc5601.rom", 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, 1 << 20, /*1mb*/
et4000k_recalctimings,
et4000k_in, et4000k_out,
NULL,
NULL);
et4000->svga.ksc5601_sbyte_mask = 0x80;
return et4000;
}
static int et4000_available()
{
return rom_present("et4000.bin");
}
static int et4000k_available()
{
return rom_present("tgkorvga.bin") && rom_present("tg_ksc5601.rom");;
}
void et4000_close(void *p)
{
et4000_t *et4000 = (et4000_t *)p;
@ -207,3 +367,15 @@ device_t et4000_device =
et4000_force_redraw,
et4000_add_status_info
};
device_t et4000k_device =
{
"Trigem Korean VGA(Tseng Labs ET4000AX)",
0,
et4000k_init,
et4000_close,
et4000k_available,
et4000_speed_changed,
et4000_force_redraw,
et4000_add_status_info
};

View file

@ -1 +1,2 @@
extern device_t et4000_device;
extern device_t et4000k_device;

View file

@ -127,6 +127,8 @@ typedef struct svga_t
card should not attempt to display anything */
int override;
void *p;
uint8_t ksc5601_sbyte_mask;
} svga_t;
extern int svga_init(svga_t *svga, void *p, int memsize,

View file

@ -201,12 +201,14 @@ void svga_render_text_80_ksc5601(svga_t *svga)
}
}
if(x + xinc < svga->hdisp && (chr & nextchr & 0x80))
if(x + xinc < svga->hdisp && (chr & (nextchr | svga->ksc5601_sbyte_mask) & 0x80))
{
if((chr == 0xc9 || chr == 0xfe) && (nextchr > 0xa0 && nextchr < 0xff))
dat = fontdatksc5601_user[(chr == 0xfe ? 96 : 0) + (nextchr & 0x7F) - 0x20][svga->sc];
else
else if(nextchr & 0x80)
dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)][svga->sc];
else
dat = 0xFF;
}
else
{
@ -232,7 +234,7 @@ void svga_render_text_80_ksc5601(svga_t *svga)
svga->ma += 4;
p += xinc;
if(x + xinc < svga->hdisp && (chr & nextchr & 0x80))
if(x + xinc < svga->hdisp && (chr & (nextchr | svga->ksc5601_sbyte_mask) & 0x80))
{
attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask];
@ -255,8 +257,10 @@ void svga_render_text_80_ksc5601(svga_t *svga)
if((chr == 0xc9 || chr == 0xfe) && (nextchr > 0xa0 && nextchr < 0xff))
dat = fontdatksc5601_user[(chr == 0xfe ? 96 : 0) + (nextchr & 0x7F) - 0x20][svga->sc + 16];
else
else if(nextchr & 0x80)
dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)][svga->sc + 16];
else
dat = 0xFF;
if (svga->seqregs[1] & 1)
{
for (xx = 0; xx < 8; xx++)

View file

@ -106,6 +106,7 @@ static VIDEO_CARD video_cards[] =
{"S3 ViRGE/DX", "virge375", &s3_virge_375_device, GFX_VIRGEDX, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}},
{"Sigma Color 400", "sigma400", &sigma_device, GFX_SIGMA400, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
{"Trident TVGA8900D", "tvga8900d", &tvga8900d_device, GFX_TVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}},
{"Trigem Korean VGA (Tseng ET4000AX)", "tgkorvga", &et4000k_device, GFX_TGKOREANVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}},
{"Tseng ET4000AX", "et4000ax", &et4000_device, GFX_ET4000, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}},
{"Trident TGUI9400CXi", "tgui9400cxi", &tgui9400cxi_device, GFX_TGUI9400CXI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}},
{"Trident TGUI9440", "tgui9440", &tgui9440_device, GFX_TGUI9440, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}},