diff --git a/src/machine/m_at_headland.c b/src/machine/m_at_headland.c index b8f707d4e..1d1f6c641 100644 --- a/src/machine/m_at_headland.c +++ b/src/machine/m_at_headland.c @@ -9,26 +9,187 @@ #include "../cpu/cpu.h" #include "../cpu/x86.h" #include "../io.h" +#include "../mem.h" +#include "../rom.h" #include "../device.h" #include "../keyboard.h" -#include "../mem.h" #include "../floppy/fdd.h" #include "../floppy/fdc.h" #include "machine.h" +#include "../video/video.h" +#include "../video/vid_oak_oti.h" static int headland_index; static uint8_t headland_regs[256]; +static uint8_t headland_port_92 = 0xFC, headland_ems_mar = 0, headland_cri = 0; +static uint8_t headland_regs_cr[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; +static uint16_t headland_ems_mr[64]; +static mem_mapping_t headland_low_mapping; +static mem_mapping_t headland_ems_mapping[64]; +static mem_mapping_t headland_mid_mapping; +static mem_mapping_t headland_high_mapping; +static mem_mapping_t headland_4000_9FFF_mapping[24]; -static void headland_write(uint16_t addr, uint8_t val, void *priv) +// TODO - Headland chipset's memory address mapping emulation isn't fully implemented yet, so memory configuration is hardcoded now. +static int headland_mem_conf_cr0[41] = { 0x00, 0x00, 0x20, 0x40, 0x60, 0xA0, 0x40, 0xE0, + 0xA0, 0xC0, 0xE0, 0xE0, 0xC0, 0xE0, 0xE0, 0xE0, + 0xE0, 0x20, 0x40, 0x40, 0xA0, 0xC0, 0xE0, 0xE0, + 0xC0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, + 0x20, 0x40, 0x60, 0x60, 0xC0, 0xE0, 0xE0, 0xE0, + 0xE0 }; +static int headland_mem_conf_cr1[41] = { 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, + 0x00, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x40 }; + +static uint32_t +get_headland_addr(uint32_t addr, uint16_t *mr) { - uint8_t old_val; - - if (addr & 1) + if (mr && (headland_regs_cr[0] & 2) && (*mr & 0x200)) { - old_val = headland_regs[headland_index]; + addr = (addr & 0x3fff) | ((*mr & 0x1F) << 14); + if(headland_regs_cr[1] & 0x40) + { + if((headland_regs_cr[4] & 0x80) && (headland_regs_cr[6] & 1)) + { + if(headland_regs_cr[0] & 0x80) + { + addr |= (*mr & 0x60) << 14; + if(*mr & 0x100) + addr += ((*mr & 0xC00) << 13) + (((*mr & 0x80) + 0x80) << 15); + else + addr += (*mr & 0x80) << 14; + } + else if(*mr & 0x100) + addr += ((*mr & 0xC00) << 13) + (((*mr & 0x80) + 0x20) << 15); + else + addr += (*mr & 0x80) << 12; + } + else if(headland_regs_cr[0] & 0x80) + addr |= (*mr & 0x100) ? ((*mr & 0x80) + 0x400) << 12 : (*mr & 0xE0) << 14; + else + addr |= (*mr & 0x100) ? ((*mr & 0xE0) + 0x40) << 14 : (*mr & 0x80) << 12; + } + else + { + if((headland_regs_cr[4] & 0x80) && (headland_regs_cr[6] & 1)) + { + if(headland_regs_cr[0] & 0x80) + { + addr |= ((*mr & 0x60) << 14); + if(*mr & 0x180) + addr += ((*mr & 0xC00) << 13) + (((*mr & 0x180) - 0x60) << 16); + } + else + addr |= ((*mr & 0x60) << 14) | ((*mr & 0x180) << 16) | ((*mr & 0xC00) << 13); + } + else if(headland_regs_cr[0] & 0x80) + addr |= (*mr & 0x1E0) << 14; + else + addr |= (*mr & 0x180) << 12; + } + } + else if(mr == NULL && (headland_regs_cr[0] & 4) == 0 && mem_size >= 1024 && addr >= 0x100000) + addr -= 0x60000; + + return addr; +} + +static void +headland_set_global_EMS_state(int state) +{ + + int i; + uint32_t base_addr, virt_addr; + + for(i=0; i<32; i++) + { + base_addr = (i + 16) << 14; + if(i >= 24) + base_addr += 0x20000; + if((state & 2) && (headland_ems_mr[((state & 1) << 5) | i] & 0x200)) + { + virt_addr = get_headland_addr(base_addr, &headland_ems_mr[((state & 1) << 5) | i]); + if(i < 24) mem_mapping_disable(&headland_4000_9FFF_mapping[i]); + mem_mapping_disable(&headland_ems_mapping[(((state ^ 1) & 1) << 5) | i]); + mem_mapping_enable(&headland_ems_mapping[((state & 1) << 5) | i]); + if(virt_addr < (mem_size << 10)) mem_mapping_set_exec(&headland_ems_mapping[((state & 1) << 5) | i], ram + virt_addr); + else mem_mapping_set_exec(&headland_ems_mapping[((state & 1) << 5) | i], NULL); + } + else + { + mem_mapping_set_exec(&headland_ems_mapping[((state & 1) << 5) | i], ram + base_addr); + mem_mapping_disable(&headland_ems_mapping[(((state ^ 1) & 1) << 5) | i]); + mem_mapping_disable(&headland_ems_mapping[((state & 1) << 5) | i]); + + if(i < 24) + mem_mapping_enable(&headland_4000_9FFF_mapping[i]); + } + } + flushmmucache(); +} + +static void +headland_memmap_state_update(void) +{ + int i; + uint32_t addr; + + for(i=0;i<24;i++) + { + addr = get_headland_addr(0x40000 + (i << 14), NULL); + mem_mapping_set_exec(&headland_4000_9FFF_mapping[i], addr < (mem_size << 10) ? ram + addr : NULL); + //pclog("headland_memmap_state_update : Address %06X to %06X\n", 0x40000 + (i << 14), addr); + } + + mem_set_mem_state(0xA0000, 0x40000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + + if (mem_size > 640) + { + if ((headland_regs_cr[0] & 4) == 0) + { + mem_mapping_set_addr(&headland_mid_mapping, 0x100000, mem_size > 1024 ? 0x60000 : (mem_size - 640) << 10); + mem_mapping_set_exec(&headland_mid_mapping, ram + 0xA0000); + if (mem_size > 1024) + { + mem_mapping_set_addr(&headland_high_mapping, 0x160000, (mem_size - 1024) << 10); + mem_mapping_set_exec(&headland_high_mapping, ram + 0x100000); + } + } + else + { + mem_mapping_set_addr(&headland_mid_mapping, 0xA0000, mem_size > 1024 ? 0x60000 : (mem_size - 640) << 10); + mem_mapping_set_exec(&headland_mid_mapping, ram + 0xA0000); + if (mem_size > 1024) + { + mem_mapping_set_addr(&headland_high_mapping, 0x100000, (mem_size - 1024) << 10); + mem_mapping_set_exec(&headland_high_mapping, ram + 0x100000); + } + } + } + + headland_set_global_EMS_state(headland_regs_cr[0] & 3); +} + +static void +headland_write(uint16_t addr, uint8_t val, void *priv) +{ + uint8_t old_val, index; + uint32_t base_addr, virt_addr; + + switch(addr) + { + case 0x22: + headland_index = val; + break; + + case 0x23: + old_val = headland_regs[headland_index]; if (headland_index == 0xc1 && !is486) val = 0; headland_regs[headland_index] = val; if (headland_index == 0x82) @@ -45,27 +206,358 @@ static void headland_write(uint16_t addr, uint8_t val, void *priv) if ((val & 1) && !(old_val & 1)) softresetx86(); } + break; + + case 0x92: + if ((mem_a20_alt ^ val) & 2) + { + mem_a20_alt = val & 2; + mem_a20_recalc(); + } + if ((~headland_port_92 & val) & 1) + { + softresetx86(); + cpu_set_edx(); + } + headland_port_92 = val | 0xFC; + break; + + case 0x1EC: + //pclog("Set EMS Map Register to %02X(actually FF%02X) at %04X:%04X\n", val, val, CS, cpu_state.oldpc); + headland_ems_mr[headland_ems_mar & 0x3F] = val | 0xFF00; + index = headland_ems_mar & 0x1F; + base_addr = (index + 16) << 14; + if(index >= 24) + base_addr += 0x20000; + if((headland_regs_cr[0] & 2) && ((headland_regs_cr[0] & 1) == ((headland_ems_mar & 0x20) >> 5))) + { + virt_addr = get_headland_addr(base_addr, &headland_ems_mr[headland_ems_mar & 0x3F]); + if(index < 24) mem_mapping_disable(&headland_4000_9FFF_mapping[index]); + if(virt_addr < (mem_size << 10)) mem_mapping_set_exec(&headland_ems_mapping[headland_ems_mar & 0x3F], ram + virt_addr); + else mem_mapping_set_exec(&headland_ems_mapping[headland_ems_mar & 0x3F], NULL); + mem_mapping_enable(&headland_ems_mapping[headland_ems_mar & 0x3F]); + pclog("Map page %d(address %05X) to address %06X\n", index, base_addr, virt_addr); + flushmmucache(); + } + if(headland_ems_mar & 0x80) headland_ems_mar++; + break; + + case 0x1ED: + //pclog("Set Control Register Index to %02X at %04X:%04X\n", val, CS, cpu_state.oldpc); + headland_cri = val; + break; + + case 0x1EE: + //pclog("Set EMS Map Address Register to %02X at %04X:%04X\n", val, CS, cpu_state.oldpc); + headland_ems_mar = val; + break; + + case 0x1EF: + //pclog("Set Control Register %1X to %02X at %04X:%04X\n", headland_cri, val, CS, cpu_state.oldpc); + old_val = headland_regs_cr[headland_cri]; + switch(headland_cri) + { + case 0: + headland_regs_cr[0] = (val & 0x1F) | headland_mem_conf_cr0[(mem_size > 640 ? mem_size : mem_size - 128) >> 9]; + mem_set_mem_state(0xE0000, 0x10000, (val & 8 ? MEM_READ_INTERNAL : MEM_READ_EXTERNAL) | MEM_WRITE_DISABLED); + mem_set_mem_state(0xF0000, 0x10000, (val & 0x10 ? MEM_READ_INTERNAL: MEM_READ_EXTERNAL) | MEM_WRITE_DISABLED); + headland_memmap_state_update(); + break; + case 1: + headland_regs_cr[1] = (val & 0xBF) | headland_mem_conf_cr1[(mem_size > 640 ? mem_size : mem_size - 128) >> 9]; + headland_memmap_state_update(); + break; + case 2: + case 3: + case 5: + headland_regs_cr[headland_cri] = val; + headland_memmap_state_update(); + break; + case 4: + headland_regs_cr[4] = (headland_regs_cr[4] & 0xF0) | (val & 0x0F); + if(val & 1) + { + mem_mapping_disable(&bios_mapping[0]); + mem_mapping_disable(&bios_mapping[1]); + mem_mapping_disable(&bios_mapping[2]); + mem_mapping_disable(&bios_mapping[3]); + } + else + { + mem_mapping_enable(&bios_mapping[0]); + mem_mapping_enable(&bios_mapping[1]); + mem_mapping_enable(&bios_mapping[2]); + mem_mapping_enable(&bios_mapping[3]); + } + break; + case 6: + if(headland_regs_cr[4] & 0x80) + { + headland_regs_cr[headland_cri] = (val & 0xFE) | (mem_size > 8192 ? 1 : 0); + headland_memmap_state_update(); + } + break; + default: + break; + } + break; + + default: + break; + } +} + +static void +headland_writew(uint16_t addr, uint16_t val, void *priv) +{ + uint8_t index; + uint32_t base_addr, virt_addr; + + switch(addr) + { + case 0x1EC: + //pclog("Set EMS Map Register to %04X at %04X:%04X\n", val, CS, cpu_state.oldpc); + headland_ems_mr[headland_ems_mar & 0x3F] = val; + index = headland_ems_mar & 0x1F; + base_addr = (index + 16) << 14; + if(index >= 24) + base_addr += 0x20000; + if((headland_regs_cr[0] & 2) && (headland_regs_cr[0] & 1) == ((headland_ems_mar & 0x20) >> 5)) + { + if(val & 0x200) + { + virt_addr = get_headland_addr(base_addr, &headland_ems_mr[headland_ems_mar & 0x3F]); + if(index < 24) mem_mapping_disable(&headland_4000_9FFF_mapping[index]); + if(virt_addr < (mem_size << 10)) mem_mapping_set_exec(&headland_ems_mapping[headland_ems_mar & 0x3F], ram + virt_addr); + else mem_mapping_set_exec(&headland_ems_mapping[headland_ems_mar & 0x3F], NULL); + mem_mapping_enable(&headland_ems_mapping[headland_ems_mar & 0x3F]); + //pclog("Map page %d(address %05X) to address %07X(val=%04X)\n", index, base_addr, virt_addr, val); + } + else + { + mem_mapping_set_exec(&headland_ems_mapping[headland_ems_mar & 0x3F], ram + base_addr); + mem_mapping_disable(&headland_ems_mapping[headland_ems_mar & 0x3F]); + if(index < 24) mem_mapping_enable(&headland_4000_9FFF_mapping[index]); + //pclog("Unmap page %d(address %05X)\n", index, base_addr); + } + flushmmucache(); + } + if(headland_ems_mar & 0x80) headland_ems_mar++; + break; + + default: + break; } - else - headland_index = val; } static uint8_t headland_read(uint16_t addr, void *priv) { - if (addr & 1) + uint8_t val; + + switch(addr) { + case 0x22: + val = headland_index; + break; + + case 0x23: if ((headland_index >= 0xc0 || headland_index == 0x20) && cpu_iscyrix) - return 0xff; /*Don't conflict with Cyrix config registers*/ - return headland_regs[headland_index]; + val = 0xff; /*Don't conflict with Cyrix config registers*/ + else + val = headland_regs[headland_index]; + break; + + case 0x92: + val = headland_port_92 | 0xFC; + break; + + case 0x1EC: + val = headland_ems_mr[headland_ems_mar & 0x3F]; + if(headland_ems_mar & 0x80) headland_ems_mar++; + break; + + case 0x1ED: + val = headland_cri; + break; + + case 0x1EE: + val = headland_ems_mar; + break; + + case 0x1EF: + switch(headland_cri) + { + case 0: + val = (headland_regs_cr[0] & 0x1F) | headland_mem_conf_cr0[(mem_size > 640 ? mem_size : mem_size - 128) >> 9]; + break; + case 1: + val = (headland_regs_cr[1] & 0xBF) | headland_mem_conf_cr1[(mem_size > 640 ? mem_size : mem_size - 128) >> 9]; + break; + case 6: + if(headland_regs_cr[4] & 0x80) + val = (headland_regs_cr[6] & 0xFE) | (mem_size > 8192 ? 1 : 0); + else + val = 0; + break; + default: + val = headland_regs_cr[headland_cri]; + break; + } + break; + + default: + val = 0xFF; + break; } - return headland_index; + return val; } - -static void headland_init(void) +static uint16_t +headland_readw(uint16_t addr, void *priv) { - io_sethandler(0x0022, 0x0002, headland_read, NULL, NULL, headland_write, NULL, NULL, NULL); + uint16_t val; + + switch(addr) + { + case 0x1EC: + val = headland_ems_mr[headland_ems_mar & 0x3F] | ((headland_regs_cr[4] & 0x80) ? 0xF000 : 0xFC00); + if(headland_ems_mar & 0x80) headland_ems_mar++; + break; + + default: + val = 0xFFFF; + break; + } + + return val; +} + +static uint8_t +mem_read_headlandb(uint32_t addr, void *priv) +{ + uint8_t val = 0xff; + + addr = get_headland_addr(addr, priv); + if (addr < (mem_size << 10)) + val = ram[addr]; + + return val; +} + +static uint16_t +mem_read_headlandw(uint32_t addr, void *priv) +{ + uint16_t val = 0xffff; + + //if((addr & 0x3FFF) == 0x3FFF) pclog("mem_read_headlandw(%08X, %p) called.\n", addr, priv); + addr = get_headland_addr(addr, priv); + if (addr < (mem_size << 10)) + val = *(uint16_t *)&ram[addr]; + + return val; +} + +static uint32_t +mem_read_headlandl(uint32_t addr, void *priv) +{ + uint32_t val = 0xffffffff; + + //if((addr & 0x3FFF) > 0x3FFC) pclog("mem_read_headlandl(%08X, %p) called.\n", addr, priv); + addr = get_headland_addr(addr, priv); + if (addr < (mem_size << 10)) + val = *(uint32_t *)&ram[addr]; + + return val; +} + +static void +mem_write_headlandb(uint32_t addr, uint8_t val, void *priv) +{ + addr = get_headland_addr(addr, priv); + if (addr < (mem_size << 10)) + ram[addr] = val; +} + +static void +mem_write_headlandw(uint32_t addr, uint16_t val, void *priv) +{ + //if((addr & 0x3FFF) == 0x3FFF) pclog("mem_write_headlandw(%08X, %04X, %p) called.\n", addr, val, priv); + addr = get_headland_addr(addr, priv); + if (addr < (mem_size << 10)) + *(uint16_t *)&ram[addr] = val; +} + +static void +mem_write_headlandl(uint32_t addr, uint32_t val, void *priv) +{ + //if((addr & 0x3FFF) > 0x3FFC) pclog("mem_write_headland(%08X, %08X, %p) called.\n", addr, val, priv); + addr = get_headland_addr(addr, priv); + if (addr < (mem_size << 10)) + *(uint32_t *)&ram[addr] = val; +} + +static void +headland_init(void) +{ + int i; + + for(i=0; i<8; i++) + headland_regs_cr[i] = 0; + headland_regs_cr[0] = 4; + + switch(romset) + { + case ROM_AMI386SX: + case ROM_AMA932J: + headland_regs_cr[4] = 0x20; + io_sethandler(0x0092, 0x0001, headland_read, NULL, NULL, headland_write, NULL, NULL, NULL); + break; + default: + headland_regs_cr[4] = 0; + break; + } + + io_sethandler(0x01EC, 0x0001, headland_read, headland_readw, NULL, headland_write, headland_writew, NULL, NULL); + io_sethandler(0x01ED, 0x0003, headland_read, NULL, NULL, headland_write, NULL, NULL, NULL); + + for(i=0; i<64; i++) + headland_ems_mr[i] = 0; + + mem_mapping_disable(&ram_low_mapping); + mem_mapping_disable(&ram_mid_mapping); + mem_mapping_disable(&ram_high_mapping); + + mem_mapping_add(&headland_low_mapping, 0, 0x40000, mem_read_headlandb, mem_read_headlandw, mem_read_headlandl, mem_write_headlandb, mem_write_headlandw, mem_write_headlandl, ram, MEM_MAPPING_INTERNAL, NULL); + + if(mem_size > 640) + { + mem_mapping_add(&headland_mid_mapping, 0xA0000, 0x60000, mem_read_headlandb, mem_read_headlandw, mem_read_headlandl, mem_write_headlandb, mem_write_headlandw, mem_write_headlandl, ram + 0xA0000, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_enable(&headland_mid_mapping); + } + + if(mem_size > 1024) + { + mem_mapping_add(&headland_high_mapping, 0x100000, ((mem_size - 1024) * 1024), mem_read_headlandb, mem_read_headlandw, mem_read_headlandl, mem_write_headlandb, mem_write_headlandw, mem_write_headlandl, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_enable(&headland_high_mapping); + } + + for (i = 0; i < 24; i++) + { + mem_mapping_add(&headland_4000_9FFF_mapping[i], 0x40000 + (i << 14), 0x4000, mem_read_headlandb, mem_read_headlandw, mem_read_headlandl, mem_write_headlandb, mem_write_headlandw, mem_write_headlandl, mem_size > 256 + (i << 4) ? ram + 0x40000 + (i << 14) : NULL, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_enable(&headland_4000_9FFF_mapping[i]); + } + + for (i = 0; i < 64; i++) + { + headland_ems_mr[i] = 0; + mem_mapping_add(&headland_ems_mapping[i], ((i & 31) + ((i & 31) >= 24 ? 24 : 16)) << 14, 0x04000, mem_read_headlandb, mem_read_headlandw, mem_read_headlandl, mem_write_headlandb, mem_write_headlandw, mem_write_headlandl, ram + (((i & 31) + ((i & 31) >= 24 ? 24 : 16)) << 14), 0, &headland_ems_mr[i]); + mem_mapping_disable(&headland_ems_mapping[i]); + } + + for(i=4;i<10;i++) isram[i] = 0; + + headland_memmap_state_update(); } @@ -74,8 +566,21 @@ machine_at_headland_init(const machine_t *model) { machine_at_common_ide_init(model); - device_add(&keyboard_at_ami_device); - device_add(&fdc_at_device); + device_add(&keyboard_at_ami_device); + device_add(&fdc_at_device); headland_init(); + + if (romset == ROM_AMA932J) + { + if (gfxcard == GFX_INTERNAL) { + device_add(&oti067_ama932j_device); + } + } +} + +const device_t * +at_headland_get_device(void) +{ + return &oti067_ama932j_device; } diff --git a/src/machine/m_xt_t1000.c b/src/machine/m_xt_t1000.c index 917e9219e..294ef7c6f 100644 --- a/src/machine/m_xt_t1000.c +++ b/src/machine/m_xt_t1000.c @@ -51,7 +51,7 @@ * NOTE: Still need to figure out a way to load/save ConfigSys and * HardRAM stuff. Needs to be linked in to the NVR code. * - * Version: @(#)m_xt_t1000.c 1.0.8 2018/08/15 + * Version: @(#)m_xt_t1000.c 1.0.9 2018/08/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -419,7 +419,7 @@ ems_set_hardram(t1000_t *sys, uint8_t val) #if 0 t1000_log("EMS base set to %02x\n", val); #endif - sys->ems_pages = 48 - 4 * sys->ems_base; + sys->ems_pages = ((mem_size - 512) / 16) - 4 * sys->ems_base; if (sys->ems_pages < 0) sys->ems_pages = 0; /* Recalculate EMS mappings */ @@ -653,6 +653,15 @@ write_ctl(uint16_t addr, uint8_t val, void *priv) } break; + /* It looks as if the T1200, like the T3100, can disable + * its builtin video chipset if it detects the presence of + * another video card. */ + case 6: if (romset == ROM_T1200) + { + t1000_video_enable(val & 0x01 ? 0 : 1); + } + break; + case 0x0f: /* EMS control */ switch (sys->sys_ctl[0x0e]) { case 0x50: @@ -904,7 +913,8 @@ machine_xt_t1000_init(const machine_t *model) tc8521_init(&t1000.nvr, model->nvrmask + 1); - device_add(&t1000_video_device); + if (gfxcard == GFX_INTERNAL) + device_add(&t1000_video_device); } @@ -957,7 +967,8 @@ machine_xt_t1200_init(const machine_t *model) tc8521_init(&t1000.nvr, model->nvrmask + 1); - device_add(&t1200_video_device); + if (gfxcard == GFX_INTERNAL) + device_add(&t1200_video_device); } diff --git a/src/machine/m_xt_t1000.h b/src/machine/m_xt_t1000.h index 3a345fcbc..d76b792e1 100644 --- a/src/machine/m_xt_t1000.h +++ b/src/machine/m_xt_t1000.h @@ -8,7 +8,7 @@ * * Definitions for the Toshiba T1000/T1200 machines. * - * Version: @(#)m_xt_t1000.h 1.0.4 2018/03/19 + * Version: @(#)m_xt_t1000.h 1.0.5 2018/08/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -45,6 +45,7 @@ extern const device_t t1200_video_device; extern void t1000_video_options_set(uint8_t options); +extern void t1000_video_enable(uint8_t enabled); extern void t1000_display_set(uint8_t internal); extern void t1000_syskey(uint8_t amask, uint8_t omask, uint8_t xmask); diff --git a/src/machine/m_xt_t1000_vid.c b/src/machine/m_xt_t1000_vid.c index 01b184fde..1eb7e3d24 100644 --- a/src/machine/m_xt_t1000_vid.c +++ b/src/machine/m_xt_t1000_vid.c @@ -9,7 +9,7 @@ * Implementation of the Toshiba T1000 plasma display, which * has a fixed resolution of 640x200 pixels. * - * Version: @(#)m_xt_t1000_vid.c 1.0.7 2018/04/29 + * Version: @(#)m_xt_t1000_vid.c 1.0.8 2018/08/15 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -72,6 +72,7 @@ static uint8_t language; * Bit 0: Thin font */ static uint8_t st_video_options; +static uint8_t st_enabled = 1; static int8_t st_display_internal = -1; void t1000_video_options_set(uint8_t options) @@ -80,6 +81,11 @@ void t1000_video_options_set(uint8_t options) st_video_options |= language; } +void t1000_video_enable(uint8_t enabled) +{ + st_enabled = enabled; +} + void t1000_display_set(uint8_t internal) { st_display_internal = (int8_t)internal; @@ -457,12 +463,19 @@ static void t1000_poll(void *p) { t1000_t *t1000 = (t1000_t *)p; - if (t1000->video_options != st_video_options) + if (t1000->video_options != st_video_options || + t1000->enabled != st_enabled) { t1000->video_options = st_video_options; + t1000->enabled = st_enabled; /* Set the font used for the external display */ t1000->cga.fontbase = ((t1000->video_options & 3) * 256); + + if (t1000->enabled) /* Disable internal chipset */ + mem_mapping_enable(&t1000->mapping); + else + mem_mapping_disable(&t1000->mapping); } /* Switch between internal plasma and external CRT display. */ if (st_display_internal != -1 && st_display_internal != t1000->internal) @@ -684,7 +697,7 @@ static void *t1000_init(const device_t *info) t1000->enabled = 1; t1000->video_options = 0x01; language = device_get_config_int("display_language") ? 2 : 0; - return t1000; + return t1000; } static void t1000_close(void *p) diff --git a/src/machine/machine.h b/src/machine/machine.h index 89228c5eb..aa8921b1c 100644 --- a/src/machine/machine.h +++ b/src/machine/machine.h @@ -8,7 +8,7 @@ * * Handling of the emulated machines. * - * Version: @(#)machine.h 1.0.24 2018/05/10 + * Version: @(#)machine.h 1.0.25 2018/08/16 * * Authors: Sarah Walker, * Miran Grca, @@ -211,6 +211,8 @@ extern const device_t *t1000_get_device(void); extern const device_t *t1200_get_device(void); extern const device_t *at_endeavor_get_device(void); + +extern const device_t *at_headland_get_device(void); #endif diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 8798fdce5..1f08bab0d 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -11,7 +11,7 @@ * NOTES: OpenAT wip for 286-class machine with open BIOS. * PS2_M80-486 wip, pending receipt of TRM's for machine. * - * Version: @(#)machine_table.c 1.0.30 2018/05/26 + * Version: @(#)machine_table.c 1.0.31 2018/08/15 * * Authors: Sarah Walker, * Miran Grca, @@ -46,7 +46,7 @@ const machine_t machines[] = { { "[8088] Schneider EuroPC", ROM_EUROPC, "europc", {{"Siemens",cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_HDC | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 15, machine_europc_init, NULL }, { "[8088] Tandy 1000", ROM_TANDY, "tandy", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA, 128, 640, 128, 0, machine_tandy1k_init, tandy1k_get_device }, { "[8088] Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA, 256, 640, 128, 0, machine_tandy1k_init, tandy1k_hx_get_device }, - { "[8088] Toshiba T1000", ROM_T1000, "t1000", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO, 512, 1280, 768, 63, machine_xt_t1000_init, NULL }, + { "[8088] Toshiba T1000", ROM_T1000, "t1000", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO, 512, 1280, 768, 63, machine_xt_t1000_init, t1000_get_device }, #if defined(DEV_BRANCH) && defined(USE_LASERXT) { "[8088] VTech Laser Turbo XT", ROM_LTXT, "ltxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 512, 512, 256, 0, machine_xt_laserxt_init, NULL }, #endif @@ -59,7 +59,7 @@ const machine_t machines[] = { { "[8086] Amstrad PC20(0)", ROM_PC200, "pc200", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 63, machine_amstrad_init, NULL }, { "[8086] Olivetti M24", ROM_OLIM24, "olivetti_m24", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 128, 640, 128, 0, machine_olim24_init, NULL }, { "[8086] Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA, 512, 768, 128, 0, machine_tandy1k_init, NULL }, - { "[8086] Toshiba T1200", ROM_T1200, "t1200", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO, 1024, 2048,1024, 63, machine_xt_t1200_init, NULL }, + { "[8086] Toshiba T1200", ROM_T1200, "t1200", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO, 1024, 2048,1024, 63, machine_xt_t1200_init, t1200_get_device }, #if defined(DEV_BRANCH) && defined(USE_LASERXT) { "[8086] VTech Laser XT3", ROM_LXT3, "lxt3", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 256, 512, 256, 0, machine_xt_laserxt_init, NULL }, #endif @@ -83,9 +83,11 @@ const machine_t machines[] = { { "[286 ISA] OpenAT 286", ROM_OPENAT, "open_at", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512, 4096, 128, 127, machine_at_init, NULL }, #endif { "[286 ISA] Toshiba T3100e", ROM_T3100E, "t3100e", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1024, 5120, 256, 63, machine_at_t3100e_init, NULL }, - + { "[286 ISA] Trigem 286M", ROM_TG286M, "tg286m", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512, 8192, 128, 127, machine_at_headland_init, NULL }, + { "[286 MCA] IBM PS/2 model 50", ROM_IBMPS2_M50, "ibmps2_m50", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2 | MACHINE_VIDEO, 1, 10, 1, 63, machine_ps2_model_50_init, NULL }, + { "[386SX ISA] AMA-932J", ROM_AMA932J, "ama932j", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO, 512, 8192, 128, 127, machine_at_headland_init, at_headland_get_device }, { "[386SX ISA] AMI 386SX clone", ROM_AMI386SX, "ami386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_headland_init, NULL }, { "[386SX ISA] Amstrad MegaPC", ROM_MEGAPC, "megapc", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC, 1, 16, 1, 127, machine_at_wd76c10_init, NULL }, { "[386SX ISA] Award 386SX clone", ROM_AWARD386SX_OPTI495, "award386sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_init, NULL }, diff --git a/src/rom.c b/src/rom.c index 0fbb102a4..49bb7dc4b 100644 --- a/src/rom.c +++ b/src/rom.c @@ -13,7 +13,7 @@ * - c386sx16 BIOS fails checksum * - the loadfont() calls should be done elsewhere * - * Version: @(#)rom.c 1.0.37 2018/05/20 + * Version: @(#)rom.c 1.0.38 2018/08/16 * * Authors: Sarah Walker, * Miran Grca, @@ -537,6 +537,18 @@ rom_load_bios(int rom_id) biosmask = 0x7fff; return(1); + case ROM_TG286M: + if (rom_load_linear( + L"roms/machines/tg286m/ami.bin", + 0x000000, 65536, 0, rom)) return(1); + break; + + case ROM_AMA932J: + if (rom_load_linear( + L"roms/machines/ama932j/ami.bin", + 0x000000, 65536, 0, rom)) return(1); + break; + case ROM_AMI386SX: if (rom_load_linear( L"roms/machines/ami386/ami386.bin", diff --git a/src/rom.h b/src/rom.h index 095ddb1d3..b911820fc 100644 --- a/src/rom.h +++ b/src/rom.h @@ -8,7 +8,7 @@ * * Definitions for the ROM image handler. * - * Version: @(#)rom.h 1.0.17 2018/05/10 + * Version: @(#)rom.h 1.0.18 2018/08/16 * * Author: Fred N. van Kempen, * Copyright 2018 Fred N. van Kempen. @@ -74,6 +74,7 @@ enum { ROM_AMI286, ROM_AWARD286, ROM_CMDPC30, + ROM_TG286M, ROM_PORTABLEII, #if defined(DEV_BRANCH) && defined(USE_PORTABLE3) ROM_PORTABLEIII, @@ -92,6 +93,7 @@ enum { ROM_IBMPS2_M50, + ROM_AMA932J, ROM_AMI386SX, ROM_KMXC02, ROM_MEGAPC, diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index e8fda8302..dc45ae143 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.19 2018/05/20 + * Version: @(#)vid_ati28800.c 1.0.20 2018/08/14 * * Authors: Sarah Walker, * Miran Grca, @@ -130,9 +130,12 @@ 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 (val & 1) + pclog("Extended 0xB6 bit 0 enabled\n"); + + if((old ^ val) & 0x10) svga_recalctimings(svga); + break; case 0xb8: if((old ^ val) & 0x40) svga_recalctimings(svga); break; @@ -247,14 +250,14 @@ static uint8_t ati28800_in(uint16_t addr, void *p) case 0x1cf: switch (ati28800->index) { - case 0xb0: - if (ati28800->memory == 256) - return 0x08; - else if (ati28800->memory == 512) - return 0x10; - else - return 0x18; - break; + case 0xb0: + if (ati28800->memory == 256) + return 0x08; + else if (ati28800->memory == 512) + return 0x10; + else + return 0x18; + break; case 0xb7: temp = ati28800->regs[ati28800->index] & ~8; @@ -422,6 +425,7 @@ ati28800k_init(const device_t *info) 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, L"atikorvga.nvr", 0); @@ -479,7 +483,23 @@ ati28800_init(const device_t *info) ati->svga.miscout = 1; - ati_eeprom_load(&ati->eeprom, L"ati28800.nvr", 0); + switch (info->local) + { + case GFX_VGAWONDERXL: + ati_eeprom_load(&ati->eeprom, L"ati28800xl.nvr", 0); + break; + +#if defined(DEV_BRANCH) && defined(USE_XL24) + case GFX_VGAWONDERXL24: + ati_eeprom_load(&ati->eeprom, L"ati28800xl24.nvr", 0); + break; +#endif + + default: + ati_eeprom_load(&ati->eeprom, L"ati28800.nvr", 0); + break; + } + return(ati); } @@ -556,7 +576,7 @@ static const device_config_t ati28800_config[] = "512 kB", 512 }, { - "1024 kB", 1024 + "1 MB", 1024 }, { "" diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index 329b854dd..2f9a8bb61 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -8,7 +8,7 @@ * * Emulation of the Tseng Labs ET4000. * - * Version: @(#)vid_et4000.c 1.0.7 2018/07/19 + * Version: @(#)vid_et4000.c 1.0.8 2018/08/14 * * Authors: Sarah Walker, * Miran Grca, @@ -29,11 +29,14 @@ #include "../device.h" #include "video.h" #include "vid_svga.h" +#include "vid_svga_render.h" #include "vid_sc1502x_ramdac.h" #include "vid_et4000.h" -#define BIOS_ROM_PATH L"roms/video/et4000/et4000.bin" +#define BIOS_ROM_PATH L"roms/video/et4000/et4000.bin" +#define KOREAN_BIOS_ROM_PATH L"roms/video/et4000/tgkorvga.bin" +#define KOREAN_FONT_ROM_PATH L"roms/video/et4000/tg_ksc5601.rom" typedef struct et4000_t @@ -48,6 +51,12 @@ typedef struct et4000_t uint8_t pos_regs[8]; int is_mca; + + 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] = @@ -102,6 +111,50 @@ void et4000_out(uint16_t addr, uint8_t val, void *p) svga_recalctimings(svga); } } + + /*Note - Silly hack to determine video memory size automatically by ET4000 BIOS.*/ + if(svga->crtcreg == 0x37 && !et4000->is_mca) + { + switch(val & 0x0B) + { + case 0x00: + case 0x01: + if(svga->vram_max == 64 * 1024) + mem_mapping_enable(&svga->mapping); + else + mem_mapping_disable(&svga->mapping); + break; + case 0x02: + if(svga->vram_max == 128 * 1024) + mem_mapping_enable(&svga->mapping); + else + mem_mapping_disable(&svga->mapping); + break; + case 0x03: + case 0x08: + case 0x09: + if(svga->vram_max == 256 * 1024) + mem_mapping_enable(&svga->mapping); + else + mem_mapping_disable(&svga->mapping); + break; + case 0x0A: + if(svga->vram_max == 512 * 1024) + mem_mapping_enable(&svga->mapping); + else + mem_mapping_disable(&svga->mapping); + break; + case 0x0B: + if(svga->vram_max == 1024 * 1024) + mem_mapping_enable(&svga->mapping); + else + mem_mapping_disable(&svga->mapping); + break; + default: + mem_mapping_enable(&svga->mapping); + break; + } + } break; } svga_out(addr, val, svga); @@ -144,6 +197,124 @@ uint8_t et4000_in(uint16_t addr, void *p) return svga_in(addr, 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].chr[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].chr[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].chr[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].chr[et4000->get_korean_font_index - 8] = val; + break; + default: + break; + } + et4000->get_korean_font_index++; + } + break; + default: + break; + } + break; + case 0x32CB: + et4000->port_32cb_val = val; + svga_recalctimings(&et4000->svga); + break; + default: + et4000_out(addr, val, p); + break; + } +} + +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].chr[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].chr[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].chr[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].chr[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].chr[et4000->get_korean_font_index - 8]; + break; + default: + break; + } + et4000->get_korean_font_index++; + et4000->get_korean_font_index %= 72; + } + break; + case 4: + val = 0x0F; + break; + default: + break; + } + return val; + case 0x32CB: + return et4000->port_32cb_val; + default: + return et4000_in(addr, p); + } +} + void et4000_recalctimings(svga_t *svga) { svga->ma_latch |= (svga->crtc[0x33]&3)<<16; @@ -175,6 +346,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_isa_init(const device_t *info) { et4000_t *et4000 = malloc(sizeof(et4000_t)); @@ -186,7 +372,7 @@ void *et4000_isa_init(const device_t *info) io_sethandler(0x03c0, 0x0020, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000); - svga_init(&et4000->svga, et4000, 1 << 20, /*1mb*/ + svga_init(&et4000->svga, et4000, device_get_config_int("memory") << 10, /*1mb default*/ et4000_recalctimings, et4000_in, et4000_out, NULL, @@ -195,6 +381,33 @@ void *et4000_isa_init(const device_t *info) return et4000; } +void *et4000k_isa_init(const device_t *info) +{ + et4000_t *et4000 = malloc(sizeof(et4000_t)); + memset(et4000, 0, sizeof(et4000_t)); + + rom_init(&et4000->bios_rom, KOREAN_BIOS_ROM_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + loadfont(KOREAN_FONT_ROM_PATH, 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, device_get_config_int("memory") << 10, + et4000k_recalctimings, + et4000k_in, et4000k_out, + NULL, + NULL); + + et4000->svga.ksc5601_sbyte_mask = 0x80; + + return et4000; +} + static uint8_t et4000_mca_read(int port, void *priv) { @@ -245,6 +458,11 @@ static int et4000_available(void) return rom_present(BIOS_ROM_PATH); } +static int et4000k_available() +{ + return rom_present(KOREAN_BIOS_ROM_PATH) && rom_present(KOREAN_FONT_ROM_PATH); +} + void et4000_close(void *p) { et4000_t *et4000 = (et4000_t *)p; @@ -268,6 +486,33 @@ void et4000_force_redraw(void *p) et4000->svga.fullchange = changeframecount; } +static device_config_t et4000_config[] = +{ + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "512 kB", + .value = 512 + }, + { + .description = "1 MB", + .value = 1024 + }, + { + .description = "" + } + }, + .default_int = 1024 + }, + { + .type = -1 + } +}; + const device_t et4000_isa_device = { "Tseng Labs ET4000AX (ISA)", @@ -276,7 +521,18 @@ const device_t et4000_isa_device = et4000_available, et4000_speed_changed, et4000_force_redraw, - NULL + et4000_config +}; + +const device_t et4000k_isa_device = +{ + "Trigem Korean VGA (Tseng Labs ET4000AX Korean)", + DEVICE_ISA, 0, + et4000k_isa_init, et4000_close, NULL, + et4000k_available, + et4000_speed_changed, + et4000_force_redraw, + et4000_config }; const device_t et4000_mca_device = diff --git a/src/video/vid_et4000.h b/src/video/vid_et4000.h index bb9ba03c2..3cd8ec99b 100644 --- a/src/video/vid_et4000.h +++ b/src/video/vid_et4000.h @@ -8,7 +8,7 @@ * * Emulation of the Tseng Labs ET4000. * - * Version: @(#)vid_et4000.c 1.0.7 2018/07/19 + * Version: @(#)vid_et4000.c 1.0.8 2018/08/14 * * Authors: Sarah Walker, * Miran Grca, @@ -20,6 +20,7 @@ # define EMU_VID_ET4000_H extern const device_t et4000_isa_device; +extern const device_t et4000k_isa_device; extern const device_t et4000_mca_device; #endif /*EMU_VID_ET4000_H*/ \ No newline at end of file diff --git a/src/video/vid_oak_oti.c b/src/video/vid_oak_oti.c index 9d166d6e0..93a6aa8f7 100644 --- a/src/video/vid_oak_oti.c +++ b/src/video/vid_oak_oti.c @@ -8,7 +8,7 @@ * * Oak OTI037C/67/077 emulation. * - * Version: @(#)vid_oak_oti.c 1.0.12 2018/04/26 + * Version: @(#)vid_oak_oti.c 1.0.12 2018/08/14 * * Authors: Sarah Walker, * Miran Grca, @@ -29,9 +29,11 @@ #include "video.h" #include "vid_oak_oti.h" #include "vid_svga.h" +#include "../machine/machine.h" -#define BIOS_37C_PATH L"roms/video/oti/bios.bin" -#define BIOS_77_PATH L"roms/video/oti/oti077.vbi" +#define BIOS_37C_PATH L"roms/video/oti/bios.bin" +#define BIOS_67_AMA932J_PATH L"roms/machines/ama932j/oti067.bin" +#define BIOS_77_PATH L"roms/video/oti/oti077.vbi" typedef struct { @@ -271,6 +273,11 @@ oti_init(const device_t *info) break; case 2: + if (romset == ROM_AMA932J) /*In case of any other future board uses another variant*/ + { + romfn = BIOS_67_AMA932J_PATH; + break; + } case 5: romfn = BIOS_77_PATH; break; @@ -281,7 +288,7 @@ oti_init(const device_t *info) oti->vram_size = device_get_config_int("memory"); oti->vram_mask = (oti->vram_size << 10) - 1; - + svga_init(&oti->svga, oti, oti->vram_size << 10, oti_recalctimings, oti_in, oti_out, NULL, NULL); @@ -332,6 +339,11 @@ oti037c_available(void) return(rom_present(BIOS_37C_PATH)); } +static int +oti067_ama932j_available(void) +{ + return(rom_present(BIOS_67_AMA932J_PATH)); +} static int oti067_077_available(void) @@ -410,6 +422,18 @@ const device_t oti067_device = oti067_config }; +const device_t oti067_ama932j_device = +{ + "Oak OTI-067 (AMA-932J)", + DEVICE_ISA, + 2, + oti_init, oti_close, NULL, + oti067_ama932j_available, + oti_speed_changed, + oti_force_redraw, + oti067_config +}; + const device_t oti077_device = { "Oak OTI-077", diff --git a/src/video/vid_oak_oti.h b/src/video/vid_oak_oti.h index 6a4d3cb1f..e59d6bcc7 100644 --- a/src/video/vid_oak_oti.h +++ b/src/video/vid_oak_oti.h @@ -4,4 +4,5 @@ extern const device_t oti037c_device; extern const device_t oti067_device; extern const device_t oti067_acer386_device; +extern const device_t oti067_ama932j_device; extern const device_t oti077_device; diff --git a/src/video/vid_svga.h b/src/video/vid_svga.h index 214e62a13..5fb6ebd93 100644 --- a/src/video/vid_svga.h +++ b/src/video/vid_svga.h @@ -8,7 +8,7 @@ * * Generic SVGA handling. * - * Version: @(#)vid_svga.h 1.0.12 2018/05/26 + * Version: @(#)vid_svga.h 1.0.13 2018/08/14 * * Authors: Sarah Walker, * Miran Grca, @@ -117,6 +117,8 @@ typedef struct svga_t card should not attempt to display anything */ int override; void *p; + + uint8_t ksc5601_sbyte_mask; } svga_t; diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 3e920bd1e..fcb7e4486 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.11 2018/05/26 + * Version: @(#)vid_svga_render.c 1.0.12 2018/08/14 * * Authors: Sarah Walker, * Miran Grca, @@ -235,12 +235,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].chr[svga->sc]; - else + else if(nextchr & 0x80) dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)].chr[svga->sc]; + else + dat = 0xff; } else { @@ -266,7 +268,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]; @@ -289,8 +291,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].chr[svga->sc + 16]; - else + else if(nextchr & 0x80) dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)].chr[svga->sc + 16]; + else + dat = 0xFF; if (svga->seqregs[1] & 1) { for (xx = 0; xx < 8; xx++) diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 76af3629c..7f49f74c5 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -8,7 +8,7 @@ * * Define all known video cards. * - * Version: @(#)vid_table.c 1.0.31 2018/08/01 + * Version: @(#)vid_table.c 1.0.32 2018/08/16 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -121,7 +121,8 @@ video_cards[] = { { "[ISA] TI CF62011 SVGA", "ti_cf62011", &ti_cf62011_device, GFX_TICF62011, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, #endif {"[ISA] Trident TVGA8900D", "tvga8900d", &tvga8900d_device, GFX_TVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}, - {"[ISA] Tseng ET4000AX", "et4000ax", &et4000_isa_device, GFX_ET4000_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, + {"[ISA] Trigem Korean VGA (ET4000AX)", "tgkorvga", &et4000k_isa_device, GFX_TGKOREANVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, + {"[ISA] Tseng ET4000AX", "et4000ax", &et4000_isa_device, GFX_ET4000_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, {"[ISA] VGA", "vga", &vga_device, GFX_VGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"[ISA] Wyse 700", "wy700", &wy700_device, GFX_WY700, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"[MCA] Tseng ET4000AX", "et4000mca", &et4000_mca_device, GFX_ET4000_MCA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 3, 6, 5, 5, 10}}, @@ -337,6 +338,7 @@ int video_is_mda(void) case ROM_OLIM24: case ROM_PC2086: case ROM_PC3086: + case ROM_AMA932J: case ROM_MEGAPC: case ROM_MEGAPCDX: case ROM_IBMPS1_2011: @@ -370,6 +372,7 @@ int video_is_cga(void) case ROM_PC1640: case ROM_PC2086: case ROM_PC3086: + case ROM_AMA932J: case ROM_MEGAPC: case ROM_MEGAPCDX: case ROM_IBMPS1_2011: @@ -402,6 +405,7 @@ int video_is_ega_vga(void) case ROM_PC1640: case ROM_PC2086: case ROM_PC3086: + case ROM_AMA932J: case ROM_MEGAPC: case ROM_MEGAPCDX: case ROM_IBMPS1_2011: diff --git a/src/video/video.c b/src/video/video.c index ae7085e96..a296f16ef 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -408,6 +408,7 @@ static video_timings_t timing_m24 = {VIDEO_ISA, 8,16,32, 8,16,32}; static video_timings_t timing_t1000 = {VIDEO_ISA, 8,16,32, 8,16,32}; static video_timings_t timing_pvga1a = {VIDEO_ISA, 6, 8,16, 6, 8,16}; static video_timings_t timing_wd90c11 = {VIDEO_ISA, 3, 3, 6, 5, 5,10}; +static video_timings_t timing_oti067 = {VIDEO_ISA, 6, 8,16, 6, 8,16}; static video_timings_t timing_vga = {VIDEO_ISA, 8,16,32, 8,16,32}; static video_timings_t timing_ps1_svga = {VIDEO_ISA, 6, 8,16, 6, 8,16}; static video_timings_t timing_t3100e = {VIDEO_ISA, 8,16,32, 8,16,32}; @@ -448,6 +449,9 @@ video_update_timing(void) case ROM_T1200: timing = &timing_t1000; break; + case ROM_AMA932J: + timing = &timing_oti067; + break; case ROM_MEGAPC: case ROM_MEGAPCDX: timing = &timing_wd90c11; diff --git a/src/video/video.h b/src/video/video.h index 8d326f893..fdf3cc34b 100644 --- a/src/video/video.h +++ b/src/video/video.h @@ -8,7 +8,7 @@ * * Definitions for the video controller module. * - * Version: @(#)video.h 1.0.31 2018/08/01 + * Version: @(#)video.h 1.0.32 2018/08/16 * * Authors: Sarah Walker, * Miran Grca, @@ -46,6 +46,7 @@ enum { GFX_TVGA, /* Using Trident TVGA8900D BIOS */ GFX_ET4000_ISA, /* Tseng ET4000 */ GFX_ET4000_MCA, /* Tseng ET4000 */ + GFX_TGKOREANVGA, /*Trigem Korean VGA(Tseng ET4000AX)*/ GFX_ET4000W32_CARDEX_VLB, /* Tseng ET4000/W32p (Cardex) VLB */ GFX_ET4000W32_CARDEX_PCI, /* Tseng ET4000/W32p (Cardex) PCI */ #if defined(DEV_BRANCH) && defined(USE_STEALTH32)