Implemented experimental Headland HT102 chipset based EMS support.

Added Trigem 266M and AMA-932J machines.
Patch from Greatpsycho.
This commit is contained in:
SarahW 2018-11-12 20:32:53 +00:00
commit 461cb221ca
8 changed files with 560 additions and 11 deletions

View file

@ -8,16 +8,173 @@
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];
// 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 };
uint32_t get_headland_addr(uint32_t addr, uint16_t *mr)
{
if (mr && (headland_regs_cr[0] & 2) && (*mr & 0x200))
{
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;
}
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();
}
void headland_memmap_state_update()
{
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);
}
void headland_write(uint16_t addr, uint8_t val, void *priv)
{
if (addr & 1)
uint8_t old_val, index;
uint32_t base_addr, virt_addr;
switch(addr)
{
uint8_t old_val = headland_regs[headland_index];
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;
pclog("Headland write %02X %02X\n",headland_index,val);
//pclog("Headland write %02X %02X at %04X:%04X\n",headland_index,val,CS,cpu_state.oldpc);
if (headland_index == 0x82)
{
shadowbios = val & 0x10;
@ -32,23 +189,350 @@ 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
headland_index = val;
{
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;
}
}
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;
}
}
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;
}
return headland_index;
break;
default:
val = 0xFF;
break;
}
return val;
}
uint16_t headland_readw(uint16_t addr, void *priv)
{
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
void headland_init()
{
int i;
for(i=0; i<8; i++)
headland_regs_cr[i] = 0;
headland_regs_cr[0] = 4;
switch(romset)
{
case ROM_AMI386SX:
// Remark - Previously distributed AMI386 BIOS doesn't seem to be for the Headland chipset.
io_sethandler(0x0022, 0x0002, headland_read, NULL, NULL, headland_write, NULL, NULL, NULL);
break;
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();
}

View file

@ -413,6 +413,7 @@ enum
ROM_IBMAT,
ROM_CMDPC30,
ROM_AMI286,
ROM_TG286M,
ROM_AWARD286,
ROM_GW286CT,
ROM_SPC4200P,
@ -423,6 +424,7 @@ enum
ROM_ACER386,
ROM_KMXC02,
ROM_MEGAPC,
ROM_AMA932J,
ROM_AMI386SX,
ROM_AMI486,
ROM_WIN486,

View file

@ -284,6 +284,17 @@ int loadbios()
romfread(rom,65536,1,f);
fclose(f);
return 1;*/
case ROM_AMA932J:
// f=romfopen("at386/at386.bin","rb");
f=romfopen("ama932j/ami.bin","rb");
if (!f) break;
romfread(rom,65536,1,f);
fclose(f);
f=romfopen("ama932j/oti067.bin","rb");
if (!f) break;
fclose(f);
return 1;
case ROM_AMI386SX:
// f=romfopen("at386/at386.bin","rb");
f=romfopen("ami386/ami386.bin","rb");
@ -332,6 +343,14 @@ int loadbios()
// memset(romext,0x63,0x8000);
return 1;
case ROM_TG286M:
f=romfopen("tg286m/ami.bin","rb");
if (!f) break;
romfread(rom,65536,1,f);
fclose(f);
// memset(romext,0x63,0x8000);
return 1;
case ROM_AWARD286:
f=romfopen("award286/award.bin","rb");
if (!f) break;

View file

@ -157,8 +157,10 @@ MODEL models[] =
{"[286] Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 512, 2048, 128, at_scat_init, NULL},
{"[286] Samsung SPC-4216P", ROM_SPC4216P, "spc4216p", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 5, 1, at_scat_init, NULL},
{"[286] Toshiba T3100e", ROM_T3100E, "t3100e", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_HAS_IDE, 1024, 5120, 256, at_t3100e_init, NULL},
{"[286] Trigem 286M", ROM_TG286M, "tg286m", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512, 8192, 128, at_headland_init, NULL},
{"[386SX] Acer 386SX25/N", ROM_ACER386, "acer386", { {"Intel", cpus_acer}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_acer386sx_init, NULL},
{"[386SX] AMA-932J", ROM_AMA932J, "ama932j", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_HAS_IDE, 512, 8192, 128, at_headland_init, NULL},
{"[386SX] AMI 386SX clone", ROM_AMI386SX, "ami386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512,16384, 128, at_headland_init, NULL},
{"[386SX] Amstrad MegaPC", ROM_MEGAPC, "megapc", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_DISABLE_HW|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL},
{"[386SX] DTK 386SX clone", ROM_DTK386, "dtk386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512,16384, 128, at_neat_init, NULL},

View file

@ -265,6 +265,7 @@ void loadnvr()
case ROM_IBMPS2_M80: f = nvrfopen("ibmps2_m80.nvr", "rb"); break;
case ROM_CMDPC30: f = nvrfopen("cmdpc30.nvr", "rb"); nvrmask = 127; break;
case ROM_AMI286: f = nvrfopen("ami286.nvr", "rb"); nvrmask = 127; break;
case ROM_TG286M: f = nvrfopen("tg286m.nvr", "rb"); nvrmask = 127; break;
case ROM_AWARD286: f = nvrfopen("award286.nvr", "rb"); nvrmask = 127; break;
case ROM_GW286CT: f = nvrfopen("gw286ct.nvr", "rb"); nvrmask = 127; break;
case ROM_SPC4200P: f = nvrfopen("spc4200p.nvr", "rb"); nvrmask = 127; break;
@ -275,6 +276,7 @@ void loadnvr()
case ROM_ACER386: f = nvrfopen("acer386.nvr", "rb"); nvrmask = 127; break;
case ROM_KMXC02: f = nvrfopen("kmxc02.nvr", "rb"); nvrmask = 127; break;
case ROM_MEGAPC: f = nvrfopen("megapc.nvr", "rb"); nvrmask = 127; break;
case ROM_AMA932J: f = nvrfopen("ama932j.nvr", "rb"); nvrmask = 127; break;
case ROM_AMI386SX: f = nvrfopen("ami386.nvr", "rb"); nvrmask = 127; break;
case ROM_AMI486: f = nvrfopen("ami486.nvr", "rb"); nvrmask = 127; break;
case ROM_WIN486: f = nvrfopen("win486.nvr", "rb"); nvrmask = 127; break;
@ -355,6 +357,7 @@ void savenvr()
case ROM_IBMPS2_M80: f = nvrfopen("ibmps2_m80.nvr", "wb"); break;
case ROM_CMDPC30: f = nvrfopen("cmdpc30.nvr", "wb"); break;
case ROM_AMI286: f = nvrfopen("ami286.nvr", "wb"); break;
case ROM_TG286M: f = nvrfopen("tg286m.nvr", "wb"); break;
case ROM_AWARD286: f = nvrfopen("award286.nvr", "wb"); break;
case ROM_GW286CT: f = nvrfopen("gw286ct.nvr", "wb"); break;
case ROM_SPC4200P: f = nvrfopen("spc4200p.nvr", "wb"); break;
@ -365,6 +368,7 @@ void savenvr()
case ROM_ACER386: f = nvrfopen("acer386.nvr", "wb"); break;
case ROM_KMXC02: f = nvrfopen("kmxc02.nvr", "wb"); break;
case ROM_MEGAPC: f = nvrfopen("megapc.nvr", "wb"); break;
case ROM_AMA932J: f = nvrfopen("ama932j.nvr", "wb"); break;
case ROM_AMI386SX: f = nvrfopen("ami386.nvr", "wb"); break;
case ROM_AMI486: f = nvrfopen("ami486.nvr", "wb"); break;
case ROM_WIN486: f = nvrfopen("win486.nvr", "wb"); break;

View file

@ -20,11 +20,14 @@ typedef struct oti067_t
uint8_t regs[32];
uint8_t pos;
uint8_t dipswitch_val;
uint32_t vram_size;
uint32_t vram_mask;
} oti067_t;
static uint8_t oti067_dipswitch_val = 0x18;
void oti067_out(uint16_t addr, uint8_t val, void *p)
{
oti067_t *oti067 = (oti067_t *)p;
@ -111,7 +114,7 @@ uint8_t oti067_in(uint16_t addr, void *p)
temp = oti067->index | (2 << 5);
break;
case 0x3DF:
if (oti067->index==0x10) temp = 0x18;
if (oti067->index==0x10) temp = oti067_dipswitch_val;
else temp = oti067->regs[oti067->index];
break;
@ -192,6 +195,8 @@ void oti067_enable_disable(void *p, int enable)
io_sethandler(0x46e8, 0x0001, oti067_pos_in, NULL, NULL, oti067_pos_out, NULL, NULL, oti067);
mem_mapping_enable(&oti067->svga.mapping);
}
oti067->dipswitch_val = 0x18;
}
void *oti067_init()
@ -209,6 +214,14 @@ void *oti067_acer386_init()
return oti067;
}
void *oti067_ama932j_init()
{
oti067_t *oti067 = oti067_common_init("ama932j/oti067.bin", 512);
oti067->dipswitch_val |= 0x20;
return oti067;
}
static int oti067_available()
{
return rom_present("oti067/bios.bin");
@ -294,3 +307,14 @@ device_t oti067_acer386_device =
oti067_force_redraw,
oti067_add_status_info
};
device_t oti067_ama932j_device =
{
"Oak OTI-067 (AMA-932J)",
0,
oti067_ama932j_init,
oti067_close,
oti067_available,
oti067_speed_changed,
oti067_force_redraw,
oti067_add_status_info
};

View file

@ -1,4 +1,5 @@
extern device_t oti067_device;
extern device_t oti067_acer386_device;
extern device_t oti067_ama932j_device;
void oti067_enable_disable(void *p, int enable);

View file

@ -192,6 +192,9 @@ device_t *video_card_getdevice(int card)
case ROM_ACER386:
return &oti067_acer386_device;
case ROM_AMA932J:
return &oti067_ama932j_device;
case ROM_IBMPS1_2011:
case ROM_IBMPS2_M30_286:
case ROM_IBMPS2_M50:
@ -391,6 +394,7 @@ int video_is_ega_vga()
case ROM_PC3086:
case ROM_MEGAPC:
case ROM_ACER386:
case ROM_AMA932J:
case ROM_IBMPS1_2011:
case ROM_IBMPS2_M30_286:
case ROM_IBMPS2_M50:
@ -523,6 +527,11 @@ void video_updatetiming()
timing = &timing_oti067;
break;
case ROM_AMA932J:
if (gfxcard == GFX_BUILTIN)
timing = &timing_oti067;
break;
case ROM_IBMPS1_2011:
case ROM_IBMPS2_M30_286:
case ROM_IBMPS2_M50:
@ -690,6 +699,10 @@ void video_init()
}
return;
case ROM_AMA932J:
device_add(&oti067_ama932j_device);
return;
case ROM_IBMPS1_2011:
case ROM_IBMPS2_M30_286:
case ROM_IBMPS2_M50: