diff --git a/src/headland.c b/src/headland.c index b3bc4d0..8af4a5d 100644 --- a/src/headland.c +++ b/src/headland.c @@ -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 + { + 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; } - else - headland_index = val; } 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; +} + +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() { - io_sethandler(0x0022, 0x0002, headland_read, NULL, NULL, headland_write, NULL, NULL, NULL); + 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(); } diff --git a/src/ibm.h b/src/ibm.h index 549acc2..ccddb88 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -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, diff --git a/src/mem_bios.c b/src/mem_bios.c index dc5a904..26603e2 100644 --- a/src/mem_bios.c +++ b/src/mem_bios.c @@ -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; diff --git a/src/model.c b/src/model.c index 55be58b..3546d2d 100644 --- a/src/model.c +++ b/src/model.c @@ -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}, diff --git a/src/nvr.c b/src/nvr.c index 32510aa..045f373 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -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; diff --git a/src/vid_oti067.c b/src/vid_oti067.c index 1b7c20d..400fcf2 100644 --- a/src/vid_oti067.c +++ b/src/vid_oti067.c @@ -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 +}; diff --git a/src/vid_oti067.h b/src/vid_oti067.h index cf1fa1b..8376b38 100644 --- a/src/vid_oti067.h +++ b/src/vid_oti067.h @@ -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); diff --git a/src/video.c b/src/video.c index ab0ff7f..49c8ea0 100644 --- a/src/video.c +++ b/src/video.c @@ -191,6 +191,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: @@ -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: @@ -522,6 +526,11 @@ void video_updatetiming() if (gfxcard == GFX_BUILTIN) timing = &timing_oti067; break; + + case ROM_AMA932J: + if (gfxcard == GFX_BUILTIN) + timing = &timing_oti067; + break; case ROM_IBMPS1_2011: case ROM_IBMPS2_M30_286: @@ -689,6 +698,10 @@ void video_init() break; } return; + + case ROM_AMA932J: + device_add(&oti067_ama932j_device); + return; case ROM_IBMPS1_2011: case ROM_IBMPS2_M30_286: