diff --git a/src/ibm.h b/src/ibm.h index 4bab0e3..50f59b8 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -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)*/ diff --git a/src/vid_ati28800.c b/src/vid_ati28800.c index 275432d..845b0ee 100644 --- a/src/vid_ati28800.c +++ b/src/vid_ati28800.c @@ -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); diff --git a/src/vid_et4000.c b/src/vid_et4000.c index f24acbc..174fbdd 100644 --- a/src/vid_et4000.c +++ b/src/vid_et4000.c @@ -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 +}; diff --git a/src/vid_et4000.h b/src/vid_et4000.h index cc7e161..b5b0170 100644 --- a/src/vid_et4000.h +++ b/src/vid_et4000.h @@ -1 +1,2 @@ extern device_t et4000_device; +extern device_t et4000k_device; diff --git a/src/vid_svga.h b/src/vid_svga.h index db5f817..852010f 100644 --- a/src/vid_svga.h +++ b/src/vid_svga.h @@ -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, diff --git a/src/vid_svga_render.c b/src/vid_svga_render.c index 6df365e..92d177c 100644 --- a/src/vid_svga_render.c +++ b/src/vid_svga_render.c @@ -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++) diff --git a/src/video.c b/src/video.c index b004e7e..dfe8e68 100644 --- a/src/video.c +++ b/src/video.c @@ -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}},