Added Kasan Hangulmadang-16 emulation. Patch from Greatpsycho.
This commit is contained in:
parent
ed30e17128
commit
87941f2903
8 changed files with 290 additions and 8 deletions
256
src/vid_et4000.c
256
src/vid_et4000.c
|
|
@ -25,6 +25,11 @@ typedef struct et4000_t
|
|||
int get_korean_font_enabled;
|
||||
int get_korean_font_index;
|
||||
uint16_t get_korean_font_base;
|
||||
|
||||
uint8_t kasan_cfg_index;
|
||||
uint8_t kasan_cfg_regs[16];
|
||||
uint16_t kasan_access_addr;
|
||||
uint8_t kasan_font_data[4];
|
||||
} et4000_t;
|
||||
|
||||
static uint8_t crtc_mask[0x40] =
|
||||
|
|
@ -39,6 +44,9 @@ static uint8_t crtc_mask[0x40] =
|
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
void et4000_kasan_out(uint16_t addr, uint8_t val, void *p);
|
||||
uint8_t et4000_kasan_in(uint16_t addr, void *p);
|
||||
|
||||
void et4000_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
et4000_t *et4000 = (et4000_t *)p;
|
||||
|
|
@ -137,6 +145,118 @@ void et4000k_out(uint16_t addr, uint8_t val, void *p)
|
|||
et4000->port_32cb_val = val;
|
||||
svga_recalctimings(&et4000->svga);
|
||||
break;
|
||||
default:
|
||||
et4000_out(addr, val, p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void et4000_kasan_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
et4000_t *et4000 = (et4000_t *)p;
|
||||
|
||||
// pclog("ET4000k out %04X %02X\n", addr, val);
|
||||
|
||||
|
||||
if(addr == 0x258)
|
||||
{
|
||||
//pclog("Write port %04X to %02X at %04X:%04X\n", addr, val, CS, cpu_state.oldpc);
|
||||
et4000->kasan_cfg_index = val;
|
||||
}
|
||||
else if(addr == 0x259)
|
||||
{
|
||||
//pclog("Write port %04X to %02X at %04X:%04X\n", addr, val, CS, cpu_state.oldpc);
|
||||
if(et4000->kasan_cfg_index >= 0xF0)
|
||||
{
|
||||
switch(et4000->kasan_cfg_index - 0xF0)
|
||||
{
|
||||
case 0:
|
||||
if(et4000->kasan_cfg_regs[4] & 8)
|
||||
val = (val & 0xFC) | (et4000->kasan_cfg_regs[0] & 3);
|
||||
et4000->kasan_cfg_regs[0] = val;
|
||||
svga_recalctimings(&et4000->svga);
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
et4000->kasan_cfg_regs[et4000->kasan_cfg_index - 0xF0] = val;
|
||||
io_removehandler(et4000->kasan_access_addr, 0x0008, et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, et4000);
|
||||
et4000->kasan_access_addr = (et4000->kasan_cfg_regs[2] << 8) | et4000->kasan_cfg_regs[1];
|
||||
io_sethandler(et4000->kasan_access_addr, 0x0008, et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, et4000);
|
||||
//pclog("Set font access address to %04X\n", et4000->kasan_access_addr);
|
||||
break;
|
||||
case 4:
|
||||
if(et4000->kasan_cfg_regs[0] & 0x20)
|
||||
val |= 0x80;
|
||||
et4000->svga.ksc5601_swap_mode = (val & 4) >> 2;
|
||||
et4000->kasan_cfg_regs[4] = val;
|
||||
svga_recalctimings(&et4000->svga);
|
||||
break;
|
||||
case 5:
|
||||
et4000->kasan_cfg_regs[5] = val;
|
||||
et4000->svga.ksc5601_english_font_type = 0x100 | val;
|
||||
case 6:
|
||||
case 7:
|
||||
et4000->svga.ksc5601_udc_area_msb[et4000->kasan_cfg_index - 0xF6] = val;
|
||||
default:
|
||||
et4000->kasan_cfg_regs[et4000->kasan_cfg_index - 0xF0] = val;
|
||||
svga_recalctimings(&et4000->svga);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(addr >= et4000->kasan_access_addr && addr < et4000->kasan_access_addr + 8)
|
||||
{
|
||||
switch (addr - ((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1])))
|
||||
{
|
||||
case 0:
|
||||
if(et4000->kasan_cfg_regs[0] & 2)
|
||||
{
|
||||
et4000->get_korean_font_index = ((val & 1) << 4) | ((val & 0x1E) >> 1);
|
||||
et4000->get_korean_font_base = (et4000->get_korean_font_base & ~7) | (val >> 5);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if(et4000->kasan_cfg_regs[0] & 2)
|
||||
{
|
||||
et4000->get_korean_font_base = (et4000->get_korean_font_base & ~0x7F8) | (val << 3);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if(et4000->kasan_cfg_regs[0] & 2)
|
||||
{
|
||||
et4000->get_korean_font_base = (et4000->get_korean_font_base & ~0x7F800) | ((val & 7) << 11);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
if(et4000->kasan_cfg_regs[0] & 1)
|
||||
{
|
||||
et4000->kasan_font_data[addr - (((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1])) + 3)] = val;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
if((et4000->kasan_cfg_regs[0] & 1) && (et4000->kasan_font_data[3] & !val & 0x80) && (et4000->get_korean_font_base & 0x7F) >= 0x20 && (et4000->get_korean_font_base & 0x7F) < 0x7F)
|
||||
{
|
||||
if(((et4000->get_korean_font_base >> 7) & 0x7F) == (et4000->svga.ksc5601_udc_area_msb[0] & 0x7F) && (et4000->svga.ksc5601_udc_area_msb[0] & 0x80))
|
||||
{
|
||||
fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20][et4000->get_korean_font_index] = et4000->kasan_font_data[2];
|
||||
}
|
||||
else if(((et4000->get_korean_font_base >> 7) & 0x7F) == (et4000->svga.ksc5601_udc_area_msb[1] & 0x7F) && (et4000->svga.ksc5601_udc_area_msb[1] & 0x80))
|
||||
{
|
||||
fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20][et4000->get_korean_font_index] = et4000->kasan_font_data[2];
|
||||
}
|
||||
}
|
||||
et4000->kasan_font_data[3] = val;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
//pclog("Write port %04X at %04X:%04X\n", addr, CS, cpu_state.oldpc);
|
||||
}
|
||||
else
|
||||
{
|
||||
et4000_out(addr, val, p);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -220,7 +340,60 @@ uint8_t et4000k_in(uint16_t addr, void *p)
|
|||
return et4000->port_32cb_val;
|
||||
}
|
||||
|
||||
return 0xff;
|
||||
return et4000_in(addr, p);
|
||||
}
|
||||
|
||||
uint8_t et4000_kasan_in(uint16_t addr, void *p)
|
||||
{
|
||||
uint8_t val = 0xFF;
|
||||
et4000_t *et4000 = (et4000_t *)p;
|
||||
|
||||
if(addr == 0x258)
|
||||
{
|
||||
//pclog("Read port %04X at %04X:%04X\n", addr, CS, cpu_state.oldpc);
|
||||
val = et4000->kasan_cfg_index;
|
||||
}
|
||||
else if(addr == 0x259)
|
||||
{
|
||||
//pclog("Read port %04X at %04X:%04X\n", addr, CS, cpu_state.oldpc);
|
||||
if (et4000->kasan_cfg_index >= 0xF0)
|
||||
{
|
||||
val = et4000->kasan_cfg_regs[et4000->kasan_cfg_index - 0xF0];
|
||||
if(et4000->kasan_cfg_index == 0xF4 && et4000->kasan_cfg_regs[0] & 0x20)
|
||||
val |= 0x80;
|
||||
}
|
||||
}
|
||||
else if(addr >= et4000->kasan_access_addr && addr < et4000->kasan_access_addr + 8)
|
||||
{
|
||||
switch (addr - ((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1])))
|
||||
{
|
||||
case 2:
|
||||
val = 0;
|
||||
break;
|
||||
case 5:
|
||||
if(((et4000->get_korean_font_base >> 7) & 0x7F) == (et4000->svga.ksc5601_udc_area_msb[0] & 0x7F) && (et4000->svga.ksc5601_udc_area_msb[0] & 0x80))
|
||||
{
|
||||
val = fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20][et4000->get_korean_font_index];
|
||||
}
|
||||
else if(((et4000->get_korean_font_base >> 7) & 0x7F) == (et4000->svga.ksc5601_udc_area_msb[1] & 0x7F) && (et4000->svga.ksc5601_udc_area_msb[1] & 0x80))
|
||||
{
|
||||
val = fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20][et4000->get_korean_font_index];
|
||||
}
|
||||
else
|
||||
{
|
||||
val = fontdatksc5601[et4000->get_korean_font_base][et4000->get_korean_font_index];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
//pclog(stderr, "Read port %04X at %04X:%04X\n", addr, CS, cpu_state.oldpc);
|
||||
}
|
||||
else
|
||||
{
|
||||
val = et4000_in(addr, p);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
void et4000_recalctimings(svga_t *svga)
|
||||
|
|
@ -276,6 +449,22 @@ void et4000k_recalctimings(svga_t *svga)
|
|||
}
|
||||
}
|
||||
|
||||
void et4000_kasan_recalctimings(svga_t *svga)
|
||||
{
|
||||
et4000_t *et4000 = (et4000_t *)svga->p;
|
||||
|
||||
et4000_recalctimings(svga);
|
||||
|
||||
if (svga->render == svga_render_text_80 && (et4000->kasan_cfg_regs[0] & 8))
|
||||
{
|
||||
svga->ma_latch -= 3;
|
||||
svga->ca_adj = (et4000->kasan_cfg_regs[0] >> 6) - 3;
|
||||
svga->ksc5601_sbyte_mask = (et4000->kasan_cfg_regs[0] & 4) << 5;
|
||||
if((et4000->kasan_cfg_regs[0] & 0x23) == 0x20 && (et4000->kasan_cfg_regs[4] & 0x80) && ((svga->crtc[0x37] & 0x0B) == 0x0A))
|
||||
svga->render = svga_render_text_80_ksc5601;
|
||||
}
|
||||
}
|
||||
|
||||
void *et4000_init()
|
||||
{
|
||||
et4000_t *et4000 = malloc(sizeof(et4000_t));
|
||||
|
|
@ -317,6 +506,54 @@ void *et4000k_init()
|
|||
NULL);
|
||||
|
||||
et4000->svga.ksc5601_sbyte_mask = 0x80;
|
||||
et4000->svga.ksc5601_udc_area_msb[0] = 0xC9;
|
||||
et4000->svga.ksc5601_udc_area_msb[1] = 0xFE;
|
||||
et4000->svga.ksc5601_swap_mode = 0;
|
||||
et4000->svga.ksc5601_english_font_type = 0;
|
||||
|
||||
return et4000;
|
||||
}
|
||||
|
||||
void *et4000_kasan_init()
|
||||
{
|
||||
int i;
|
||||
et4000_t *et4000 = malloc(sizeof(et4000_t));
|
||||
memset(et4000, 0, sizeof(et4000_t));
|
||||
|
||||
rom_init(&et4000->bios_rom, "et4000_kasan16.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
loadfont("kasan_ksc5601.rom", 6);
|
||||
|
||||
io_sethandler(0x03c0, 0x0020, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000);
|
||||
|
||||
io_sethandler(0x0258, 0x0002, et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, et4000);
|
||||
|
||||
svga_init(&et4000->svga, et4000, 1 << 20, /*1mb*/
|
||||
et4000_kasan_recalctimings,
|
||||
et4000_in, et4000_out,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
et4000->svga.ksc5601_sbyte_mask = 0;
|
||||
et4000->kasan_cfg_index = 0;
|
||||
for(i=0; i<16; i++)
|
||||
et4000->kasan_cfg_regs[i] = 0;
|
||||
for(i=0; i<4; i++)
|
||||
et4000->kasan_font_data[i] = 0;
|
||||
et4000->kasan_cfg_regs[1] = 0x50;
|
||||
et4000->kasan_cfg_regs[2] = 2;
|
||||
et4000->kasan_cfg_regs[3] = 6;
|
||||
et4000->kasan_cfg_regs[4] = 0x78;
|
||||
et4000->kasan_cfg_regs[5] = 0xFF;
|
||||
et4000->kasan_cfg_regs[6] = 0xC9;
|
||||
et4000->kasan_cfg_regs[7] = 0xFE;
|
||||
et4000->kasan_access_addr = 0x250;
|
||||
io_sethandler(0x250, 0x0008, et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, et4000);
|
||||
|
||||
et4000->svga.ksc5601_sbyte_mask = 0;
|
||||
et4000->svga.ksc5601_udc_area_msb[0] = 0xC9;
|
||||
et4000->svga.ksc5601_udc_area_msb[1] = 0xFE;
|
||||
et4000->svga.ksc5601_swap_mode = 0;
|
||||
et4000->svga.ksc5601_english_font_type = 0x1FF;
|
||||
|
||||
return et4000;
|
||||
}
|
||||
|
|
@ -331,6 +568,11 @@ static int et4000k_available()
|
|||
return rom_present("tgkorvga.bin") && rom_present("tg_ksc5601.rom");;
|
||||
}
|
||||
|
||||
static int et4000_kasan_available()
|
||||
{
|
||||
return rom_present("et4000_kasan16.bin") && rom_present("kasan_ksc5601.rom");;
|
||||
}
|
||||
|
||||
void et4000_close(void *p)
|
||||
{
|
||||
et4000_t *et4000 = (et4000_t *)p;
|
||||
|
|
@ -384,3 +626,15 @@ device_t et4000k_device =
|
|||
et4000_force_redraw,
|
||||
et4000_add_status_info
|
||||
};
|
||||
|
||||
device_t et4000_kasan_device =
|
||||
{
|
||||
"Kasan Hangulmadang-16(Tseng Labs ET4000AX)",
|
||||
0,
|
||||
et4000_kasan_init,
|
||||
et4000_close,
|
||||
et4000_kasan_available,
|
||||
et4000_speed_changed,
|
||||
et4000_force_redraw,
|
||||
et4000_add_status_info
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue