diff --git a/src/CPU/x86seg.c b/src/CPU/x86seg.c index 399b6826f..e7d873cd6 100644 --- a/src/CPU/x86seg.c +++ b/src/CPU/x86seg.c @@ -1191,6 +1191,14 @@ void loadcscall(uint16_t seg) } break; + case 0x100: /*286 Task gate*/ + case 0x900: /*386 Task gate*/ + cpu_state.pc=oxpc; + cpl_override=1; + taskswitch286(seg,segdat,segdat[2]&0x800); + cpl_override=0; + break; + default: x86gpf(NULL,seg&~3); return; @@ -1593,7 +1601,7 @@ void pmodeint(int num, int soft) } else { - addr = 2 + tr.base + (DPL2 * 8); + addr = 2 + tr.base + (DPL2 * 4); newss=readmemw(0,addr+2); newsp=readmemw(0,addr); } @@ -2127,43 +2135,32 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) base=segdat[1]|((segdat[2]&0xFF)<<16); limit=segdat[0]; - if (is32) + if(is386) { base |= (segdat[3]>>8)<<24; limit |= (segdat[3]&0xF)<<16; + } - new_cr3=readmeml(base,0x1C); - new_pc=readmeml(base,0x20); - new_flags=readmeml(base,0x24); - - new_eax=readmeml(base,0x28); - new_ecx=readmeml(base,0x2C); - new_edx=readmeml(base,0x30); - new_ebx=readmeml(base,0x34); - new_esp=readmeml(base,0x38); - new_ebp=readmeml(base,0x3C); - new_esi=readmeml(base,0x40); - new_edi=readmeml(base,0x44); - - new_es=readmemw(base,0x48); - new_cs=readmemw(base,0x4C); - new_ss=readmemw(base,0x50); - new_ds=readmemw(base,0x54); - new_fs=readmemw(base,0x58); - new_gs=readmemw(base,0x5C); - new_ldt=readmemw(base,0x60); - - if (cpu_state.abrt) return; - if (optype==JMP || optype==OPTYPE_INT) + if (is32) + { + if (limit < 103) { - if (tr.seg&4) tempw=readmemw(ldt.base,(tr.seg&~7)+4); - else tempw=readmemw(gdt.base,(tr.seg&~7)+4); - if (cpu_state.abrt) return; - tempw&=~0x200; - if (tr.seg&4) writememw(ldt.base,(tr.seg&~7)+4,tempw); - else writememw(gdt.base,(tr.seg&~7)+4,tempw); + pclog("32-bit TSS %04X limit less than 103.\n", seg); + x86ts(NULL, seg); + return; } - + + if (optype==JMP || optype==CALL || optype==OPTYPE_INT) + { + if (tr.seg&4) tempw=readmemw(ldt.base,(seg&~7)+4); + else tempw=readmemw(gdt.base,(seg&~7)+4); + if (cpu_state.abrt) return; + tempw|=0x200; + if (tr.seg&4) writememw(ldt.base,(seg&~7)+4,tempw); + else writememw(gdt.base,(seg&~7)+4,tempw); + } + if (cpu_state.abrt) return; + if (optype==IRET) flags&=~NT_FLAG; cpu_386_flags_rebuild(); @@ -2186,26 +2183,48 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) writememl(tr.base,0x54,DS); writememl(tr.base,0x58,FS); writememl(tr.base,0x5C,GS); - writememl(tr.base,0x60,ldt.seg); - if (optype==OPTYPE_INT) + if (optype==JMP || optype==IRET) + { + if (tr.seg&4) tempw=readmemw(ldt.base,(tr.seg&~7)+4); + else tempw=readmemw(gdt.base,(tr.seg&~7)+4); + if (cpu_state.abrt) return; + tempw&=~0x200; + if (tr.seg&4) writememw(ldt.base,(tr.seg&~7)+4,tempw); + else writememw(gdt.base,(tr.seg&~7)+4,tempw); + } + if (cpu_state.abrt) return; + + if (optype==OPTYPE_INT || optype==CALL) { writememl(base,0,tr.seg); new_flags|=NT_FLAG; } if (cpu_state.abrt) return; - if (optype==JMP || optype==OPTYPE_INT) - { - if (tr.seg&4) tempw=readmemw(ldt.base,(seg&~7)+4); - else tempw=readmemw(gdt.base,(seg&~7)+4); - if (cpu_state.abrt) return; - tempw|=0x200; - if (tr.seg&4) writememw(ldt.base,(seg&~7)+4,tempw); - else writememw(gdt.base,(seg&~7)+4,tempw); - } - - + + new_cr3=readmeml(base,0x1C); + new_pc=readmeml(base,0x20); + new_flags=readmeml(base,0x24); + new_eax=readmeml(base,0x28); + new_ecx=readmeml(base,0x2C); + new_edx=readmeml(base,0x30); + new_ebx=readmeml(base,0x34); + new_esp=readmeml(base,0x38); + new_ebp=readmeml(base,0x3C); + new_esi=readmeml(base,0x40); + new_edi=readmeml(base,0x44); + + new_es=readmemw(base,0x48); + new_cs=readmemw(base,0x4C); + new_ss=readmemw(base,0x50); + new_ds=readmemw(base,0x54); + new_fs=readmemw(base,0x58); + new_gs=readmemw(base,0x5C); + new_ldt=readmemw(base,0x60); + + cr0 |= 8; + cr3=new_cr3; flushmmucache(); @@ -2232,7 +2251,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) if (!(new_cs&~3)) { - x86gpf(NULL,0); + x86ts(NULL,0); return; } addr=new_cs&~7; @@ -2240,7 +2259,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) { if (addr>=ldt.limit) { - x86gpf(NULL,0); + x86ts(NULL,new_cs&~3); return; } addr+=ldt.base; @@ -2249,7 +2268,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) { if (addr>=gdt.limit) { - x86gpf(NULL,0); + x86ts(NULL,new_cs&~3); return; } addr+=gdt.base; @@ -2268,19 +2287,19 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/ if ((new_cs&3) != DPL2) { - x86gpf(NULL,new_cs&~3); + x86ts(NULL,new_cs&~3); return; } break; case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/ if ((new_cs&3) < DPL2) { - x86gpf(NULL,new_cs&~3); + x86ts(NULL,new_cs&~3); return; } break; default: - x86gpf(NULL,new_cs&~3); + x86ts(NULL,new_cs&~3); return; } @@ -2313,35 +2332,24 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) } else { - new_pc=readmemw(base,0x0E); - new_flags=readmemw(base,0x10); - - new_eax=readmemw(base,0x12); - new_ecx=readmemw(base,0x14); - new_edx=readmemw(base,0x16); - new_ebx=readmemw(base,0x18); - new_esp=readmemw(base,0x1A); - new_ebp=readmemw(base,0x1C); - new_esi=readmemw(base,0x1E); - new_edi=readmemw(base,0x20); - - new_es=readmemw(base,0x22); - new_cs=readmemw(base,0x24); - new_ss=readmemw(base,0x26); - new_ds=readmemw(base,0x28); - new_ldt=readmemw(base,0x2A); - - if (cpu_state.abrt) return; - if (optype==JMP || optype==OPTYPE_INT) + if (limit < 43) { - if (tr.seg&4) tempw=readmemw(ldt.base,(tr.seg&~7)+4); - else tempw=readmemw(gdt.base,(tr.seg&~7)+4); - if (cpu_state.abrt) return; - tempw&=~0x200; - if (tr.seg&4) writememw(ldt.base,(tr.seg&~7)+4,tempw); - else writememw(gdt.base,(tr.seg&~7)+4,tempw); + pclog("16-bit TSS %04X limit less than 43.\n", seg); + x86ts(NULL, seg); + return; } - + + if (optype==JMP || optype==CALL || optype==OPTYPE_INT) + { + if (tr.seg&4) tempw=readmemw(ldt.base,(seg&~7)+4); + else tempw=readmemw(gdt.base,(seg&~7)+4); + if (cpu_state.abrt) return; + tempw|=0x200; + if (tr.seg&4) writememw(ldt.base,(seg&~7)+4,tempw); + else writememw(gdt.base,(seg&~7)+4,tempw); + } + if (cpu_state.abrt) return; + if (optype==IRET) flags&=~NT_FLAG; cpu_386_flags_rebuild(); @@ -2361,24 +2369,46 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) writememw(tr.base,0x24,CS); writememw(tr.base,0x26,SS); writememw(tr.base,0x28,DS); - writememw(tr.base,0x2A,ldt.seg); - if (optype==OPTYPE_INT) + if (optype==JMP || optype==IRET) + { + if (tr.seg&4) tempw=readmemw(ldt.base,(tr.seg&~7)+4); + else tempw=readmemw(gdt.base,(tr.seg&~7)+4); + if (cpu_state.abrt) return; + tempw&=~0x200; + if (tr.seg&4) writememw(ldt.base,(tr.seg&~7)+4,tempw); + else writememw(gdt.base,(tr.seg&~7)+4,tempw); + } + if (cpu_state.abrt) return; + + if (optype==OPTYPE_INT || optype==CALL) { writememw(base,0,tr.seg); new_flags|=NT_FLAG; } if (cpu_state.abrt) return; - if (optype==JMP || optype==OPTYPE_INT) - { - if (tr.seg&4) tempw=readmemw(ldt.base,(seg&~7)+4); - else tempw=readmemw(gdt.base,(seg&~7)+4); - if (cpu_state.abrt) return; - tempw|=0x200; - if (tr.seg&4) writememw(ldt.base,(seg&~7)+4,tempw); - else writememw(gdt.base,(seg&~7)+4,tempw); - } + new_pc=readmemw(base,0x0E); + new_flags=readmemw(base,0x10); + + new_eax=readmemw(base,0x12); + new_ecx=readmemw(base,0x14); + new_edx=readmemw(base,0x16); + new_ebx=readmemw(base,0x18); + + new_esp=readmemw(base,0x1A); + new_ebp=readmemw(base,0x1C); + new_esi=readmemw(base,0x1E); + new_edi=readmemw(base,0x20); + + new_es=readmemw(base,0x22); + new_cs=readmemw(base,0x24); + new_ss=readmemw(base,0x26); + new_ds=readmemw(base,0x28); + new_ldt=readmemw(base,0x2A); + + msw |= 8; + cpu_state.pc=new_pc; flags=new_flags; cpu_386_flags_extract(); @@ -2387,11 +2417,20 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) templ=(ldt.seg&~7)+gdt.base; ldt.limit=readmemw(0,templ); ldt.base=(readmemw(0,templ+2))|(readmemb(0,templ+4)<<16); + if (is386) + { + if (readmemb(0,templ+6)&0x80) + { + ldt.limit<<=12; + ldt.limit|=0xFFF; + } + ldt.base|=(readmemb(0,templ+7)<<24); + } if (!(new_cs&~3)) { pclog("TS loading null CS\n"); - x86gpf(NULL,0); + x86ts(NULL,0); return; } addr=new_cs&~7; @@ -2400,7 +2439,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) if (addr>=ldt.limit) { pclog("Bigger than LDT limit %04X %04X %04X TS\n",new_cs,ldt.limit,addr); - x86gpf(NULL,0); + x86ts(NULL,new_cs&~3); return; } addr+=ldt.base; @@ -2410,7 +2449,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) if (addr>=gdt.limit) { pclog("Bigger than GDT limit %04X %04X TS\n",new_cs,gdt.limit); - x86gpf(NULL,0); + x86ts(NULL,new_cs&~3); return; } addr+=gdt.base; @@ -2431,7 +2470,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) if ((new_cs&3) != DPL2) { pclog("TS load CS non-conforming RPL != DPL"); - x86gpf(NULL,new_cs&~3); + x86ts(NULL,new_cs&~3); return; } break; @@ -2439,13 +2478,13 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) if ((new_cs&3) < DPL2) { pclog("TS load CS non-conforming RPL < DPL"); - x86gpf(NULL,new_cs&~3); + x86ts(NULL,new_cs&~3); return; } break; default: pclog("TS load CS not code segment\n"); - x86gpf(NULL,new_cs&~3); + x86ts(NULL,new_cs&~3); return; } @@ -2454,14 +2493,14 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); set_use32(0); - AX=new_eax; - CX=new_ecx; - DX=new_edx; - BX=new_ebx; - SP=new_esp; - BP=new_ebp; - SI=new_esi; - DI=new_edi; + EAX=new_eax | 0xFFFF0000; + ECX=new_ecx | 0xFFFF0000; + EDX=new_edx | 0xFFFF0000; + EBX=new_ebx | 0xFFFF0000; + ESP=new_esp | 0xFFFF0000; + EBP=new_ebp | 0xFFFF0000; + ESI=new_esi | 0xFFFF0000; + EDI=new_edi | 0xFFFF0000; if (output) pclog("Load ES %04X\n",new_es); loadseg(new_es,&_es); @@ -2469,6 +2508,11 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) loadseg(new_ss,&_ss); if (output) pclog("Load DS %04X\n",new_ds); loadseg(new_ds,&_ds); + if (is386) + { + loadseg(0,&_fs); + loadseg(0,&_gs); + } if (output) pclog("Resuming at %04X:%08X\n",CS,cpu_state.pc); } diff --git a/src/mem.c b/src/mem.c index 5a5543dc6..8ac06a2b7 100644 --- a/src/mem.c +++ b/src/mem.c @@ -63,7 +63,7 @@ int shadowbios,shadowbios_write; int mem_a20_state; -static unsigned char isram[0x10000]; +unsigned char isram[0x10000]; static uint8_t ff_array[0x1000]; diff --git a/src/mem.h b/src/mem.h index 916e89995..651095b6b 100644 --- a/src/mem.h +++ b/src/mem.h @@ -38,6 +38,7 @@ extern int readlnum,writelnum; extern int memspeed[11]; extern int nopageerrors; extern uint32_t biosmask; +extern unsigned char isram[0x10000]; #define MEM_MAP_TO_SHADOW_RAM_MASK 1 #define MEM_MAP_TO_RAM_ADDR_MASK 2 diff --git a/src/model.c b/src/model.c index c30df365c..311bb1af5 100644 --- a/src/model.c +++ b/src/model.c @@ -140,76 +140,88 @@ int romset; MODEL models[] = { - {"IBM PC", ROM_IBMPC, "ibmpc", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 32, 0, xt_init, NULL }, - {"IBM XT", ROM_IBMXT, "ibmxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL }, - {"Compaq Portable", ROM_PORTABLE, "portable", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 128, 640, 128, 0, xt_init, NULL }, - {"IBM PCjr", ROM_IBMPCJR, "ibmpcjr", {{"", cpus_pcjr}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, 0, 128, 640, 128, 0, pcjr_init, &pcjr_device }, - {"Generic XT clone", ROM_GENXT, "genxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL }, - {"AMI XT clone", ROM_AMIXT, "amixt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL }, - {"DTK XT clone", ROM_DTKXT, "dtk", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL }, - {"VTech Laser Turbo XT", ROM_LTXT, "ltxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 1152, 64, 0, xt_laserxt_init, NULL }, - {"VTech Laser XT3", ROM_LXT3, "lxt3", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 1152, 64, 0, xt_laserxt_init, NULL }, - {"Phoenix XT clone", ROM_PXXT, "pxxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL }, - {"Juko XT clone", ROM_JUKOPC, "jukopc", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL }, - {"Tandy 1000", ROM_TANDY, "tandy", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, 0, 128, 640, 128, 0, tandy1k_init, &tandy1000_device }, - {"Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, 0, 256, 640, 128, 0, tandy1k_init, &tandy1000hx_device }, - {"Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, 0, 512, 768, 128, 0, tandy1ksl2_init, NULL }, - {"Amstrad PC1512", ROM_PC1512, "pc1512", {{"", cpus_pc1512}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 512, 640, 128, 63, ams_init, NULL }, - {"Sinclair PC200", ROM_PC200, "pc200", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 512, 640, 128, 63, ams_init, NULL }, - {"Schneider EuroPC", ROM_EUROPC, "europc", {{"", cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 512, 640, 128, 0, europc_init, NULL }, - {"Olivetti M24", ROM_OLIM24, "olivetti_m24", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_OLIM24, 128, 640, 128, 0, olim24_init, NULL }, - {"Amstrad PC1640", ROM_PC1640, "pc1640", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL }, - {"Amstrad PC2086", ROM_PC2086, "pc2086", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL }, - {"Amstrad PC3086", ROM_PC3086, "pc3086", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL }, - {"IBM AT", ROM_IBMAT, "ibmat", {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 256,15872, 128, 63, ibm_at_init, NULL }, - {"Compaq Portable II", ROM_PORTABLEII, "portableii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL }, - {"Compaq Portable III", ROM_PORTABLEIII, "portableiii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL }, - {"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 640,16384, 128, 127, cmdpc30_init, NULL }, - {"AMI 286 clone", ROM_AMI286, "ami286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_neat_init, NULL }, - {"Award 286 clone", ROM_AWARD286, "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_scat_init, NULL }, - {"Hyundai Super-286TR", ROM_SUPER286TR, "super286tr", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_scat_init, NULL }, - {"Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 512,16384, 128, 127, at_scat_init, NULL }, - {"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", {{"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 512,16384, 512, 127, ps1_m2011_init, NULL }, - {"IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, 127, ps2_m30_286_init, NULL }, - {"IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 16, 1, 63, ps2_model_50_init, NULL }, - {"IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, ps1_m2121_init, NULL }, - {"IBM PS/1 m.2121 + ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, ps1_m2121_init, NULL }, - {"IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 8, 1, 63, ps2_model_55sx_init, NULL }, - {"DTK 386SX clone", ROM_DTK386, "dtk386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_neat_init, NULL }, - {"Amstrad MegaPC", ROM_MEGAPC, "megapc", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, at_wd76c10_init, NULL }, - {"AMI 386SX clone", ROM_AMI386SX, "ami386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_headland_init, NULL }, - {"Compaq Deskpro 386", ROM_DESKPRO_386, "dekspro386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, deskpro386_init, NULL }, - {"Compaq Portable III 386", ROM_PORTABLEIII386, "portableiii386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL }, - {"IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 12, 1, 63, ps2_model_80_init, NULL }, - {"Amstrad MegaPC 386DX", ROM_MEGAPCDX, "megapcdx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, at_wd76c10_init, NULL }, - {"MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_opti495_init, NULL }, - {"AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_opti495_init, NULL }, - {"IBM PS/1 model 2133", ROM_IBMPS1_2133, "ibmps1_2133", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 64, 1, 127, ps1_m2133_init, NULL }, - {"AMI 486 clone", ROM_AMI486, "ami486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_ali1429_init, NULL }, - {"AMI WinBIOS 486", ROM_WIN486, "win486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_ali1429_init, NULL }, - {"DTK PKM-0038S E-2", ROM_DTK486, "dtk486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_dtk486_init, NULL }, - {"Rise Computer R418", ROM_R418, "r418", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 64, 1, 127, at_r418_init, NULL }, - {"Intel Premiere/PCI", ROM_REVENGE, "revenge", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_batman_init, NULL }, + {"[8088] AMI XT clone", ROM_AMIXT, "amixt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL }, + {"[8088] Compaq Portable", ROM_PORTABLE, "portable", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 128, 640, 128, 0, xt_init, NULL }, + {"[8088] DTK XT clone", ROM_DTKXT, "dtk", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL }, + {"[8088] IBM PC", ROM_IBMPC, "ibmpc", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 32, 0, xt_init, NULL }, + {"[8088] IBM PCjr", ROM_IBMPCJR, "ibmpcjr", {{"", cpus_pcjr}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, 0, 128, 640, 128, 0, pcjr_init, &pcjr_device }, + {"[8088] IBM XT", ROM_IBMXT, "ibmxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL }, + {"[8088] Generic XT clone", ROM_GENXT, "genxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL }, + {"[8088] Juko XT clone", ROM_JUKOPC, "jukopc", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL }, + {"[8088] Phoenix XT clone", ROM_PXXT, "pxxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL }, + {"[8088] Schneider EuroPC", ROM_EUROPC, "europc", {{"", cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 512, 640, 128, 0, europc_init, NULL }, + {"[8088] Tandy 1000", ROM_TANDY, "tandy", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, 0, 128, 640, 128, 0, tandy1k_init, &tandy1000_device }, + {"[8088] Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, 0, 256, 640, 128, 0, tandy1k_init, &tandy1000hx_device }, + {"[8088] VTech Laser Turbo XT", ROM_LTXT, "ltxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 1152, 64, 0, xt_laserxt_init, NULL }, + {"[8088] VTech Laser XT3", ROM_LXT3, "lxt3", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 1152, 64, 0, xt_laserxt_init, NULL }, + + {"[8086] Amstrad PC1512", ROM_PC1512, "pc1512", {{"", cpus_pc1512}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 512, 640, 128, 63, ams_init, NULL }, + {"[8086] Amstrad PC1640", ROM_PC1640, "pc1640", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL }, + {"[8086] Amstrad PC2086", ROM_PC2086, "pc2086", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL }, + {"[8086] Amstrad PC3086", ROM_PC3086, "pc3086", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL }, + {"[8086] Olivetti M24", ROM_OLIM24, "olivetti_m24", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_OLIM24, 128, 640, 128, 0, olim24_init, NULL }, + {"[8086] Sinclair PC200", ROM_PC200, "pc200", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 512, 640, 128, 63, ams_init, NULL }, + {"[8086] Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, 0, 512, 768, 128, 0, tandy1ksl2_init, NULL }, + + {"[286] AMI 286 clone", ROM_AMI286, "ami286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_neat_init, NULL }, + {"[286] Award 286 clone", ROM_AWARD286, "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_scat_init, NULL }, + {"[286] Compaq Portable II", ROM_PORTABLEII, "portableii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL }, + {"[286] Compaq Portable III", ROM_PORTABLEIII, "portableiii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL }, + {"[286] Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 640,16384, 128, 127, cmdpc30_init, NULL }, + {"[286] Hyundai Super-286TR", ROM_SUPER286TR, "super286tr", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_scat_init, NULL }, + {"[286] IBM AT", ROM_IBMAT, "ibmat", {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 256,15872, 128, 63, ibm_at_init, NULL }, + {"[286] IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", {{"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 512,16384, 512, 127, ps1_m2011_init, NULL }, + {"[286] IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, 127, ps2_m30_286_init, NULL }, + {"[286] IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 16, 1, 63, ps2_model_50_init, NULL }, + {"[286] Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 512,16384, 128, 127, at_scat_init, NULL }, + + {"[386SX] AMI 386SX clone", ROM_AMI386SX, "ami386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_headland_init, NULL }, + {"[386SX] Amstrad MegaPC", ROM_MEGAPC, "megapc", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, at_wd76c10_init, NULL }, + {"[386SX] DTK 386SX clone", ROM_DTK386, "dtk386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_neat_init, NULL }, + {"[386SX] IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, ps1_m2121_init, NULL }, + {"[386SX] IBM PS/1 m.2121+ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, ps1_m2121_init, NULL }, + {"[386SX] IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 8, 1, 63, ps2_model_55sx_init, NULL }, + + {"[386DX] AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_opti495_init, NULL }, + {"[386DX] Amstrad MegaPC 386DX",ROM_MEGAPCDX, "megapcdx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, at_wd76c10_init, NULL }, + {"[386DX] Compaq Deskpro 386", ROM_DESKPRO_386, "dekspro386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, deskpro386_init, NULL }, + {"[386DX] Compaq Portable III 386",ROM_PORTABLEIII386, "portableiii386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL }, + {"[386DX] IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 12, 1, 63, ps2_model_80_init, NULL }, + {"[386DX] MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_opti495_init, NULL }, + + {"[486] AMI 486 clone", ROM_AMI486, "ami486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_ali1429_init, NULL }, + {"[486] AMI WinBIOS 486", ROM_WIN486, "win486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_ali1429_init, NULL }, + {"[486] DTK PKM-0038S E-2", ROM_DTK486, "dtk486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_dtk486_init, NULL }, + {"[486] IBM PS/1 model 2133", ROM_IBMPS1_2133, "ibmps1_2133", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 64, 1, 127, ps1_m2133_init, NULL }, + {"[486] Rise Computer R418", ROM_R418, "r418", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 64, 1, 127, at_r418_init, NULL }, + + {"[Socket 4 LX] Intel Premiere/PCI",ROM_REVENGE, "revenge", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_batman_init, NULL }, #if 0 - {"Micro Star 586MC1", ROM_586MC1, "586mc1", {{"Intel", cpus_Pentium5V50}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_586mc1_init, NULL }, + {"[Socket 4 LX] Micro Star 586MC1",ROM_586MC1, "586mc1", {{"Intel", cpus_Pentium5V50}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_586mc1_init, NULL }, #endif - {"Intel Premiere/PCI II", ROM_PLATO, "plato", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_plato_init, NULL }, - {"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_endeavor_init, NULL }, - {"Intel Advanced/ZP", ROM_ZAPPA, "zappa", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_endeavor_init, NULL }, - {"PC Partner MB500N", ROM_MB500N, "mb500n", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_mb500n_init, NULL }, - {"President Award 430FX PCI", ROM_PRESIDENT, "president", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_president_init, NULL }, - {"ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p54tp4xe_init, NULL }, - {"Intel Advanced/ATX", ROM_THOR, "thor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_endeavor_init, NULL }, - {"MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_endeavor_init, NULL }, - {"AOpen AP53", ROM_AP53, "ap53", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_ap53_init, NULL }, - {"ASUS P/I-P55T2S", ROM_P55T2S, "p55t2s", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2s_init, NULL }, - {"Acer M3a", ROM_ACERM3A, "acerm3a", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_acerm3a_init, NULL }, - {"Acer V35n", ROM_ACERV35N, "acerv35n", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_acerv35n_init, NULL }, - {"ASUS P/I-P55T2P4", ROM_P55T2P4, "p55r2p4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2p4_init, NULL }, - {"Epox P55-VA", ROM_P55VA, "p55va", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55va_init, NULL }, - {"ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55tvp4_init, NULL }, - {"Tyan Titan-Pro AT", ROM_440FX, "440fx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_i440fx_init, NULL }, - {"Tyan Titan-Pro ATX", ROM_S1668, "tpatx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_s1668_init, NULL }, + + {"[Socket 5 NX] Intel Premiere/PCI II", ROM_PLATO, "plato", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_plato_init, NULL }, + + {"[Socket 5 FX] ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p54tp4xe_init, NULL }, + {"[Socket 5 FX] Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_endeavor_init, NULL }, + {"[Socket 5 FX] Intel Advanced/ZP", ROM_ZAPPA, "zappa", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_endeavor_init, NULL }, + {"[Socket 5 FX] PC Partner MB500N", ROM_MB500N, "mb500n", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_mb500n_init, NULL }, + {"[Socket 5 FX] President Award 430FX PCI",ROM_PRESIDENT,"president", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_president_init, NULL }, + + {"[Socket 7 FX] Intel Advanced/ATX", ROM_THOR, "thor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_endeavor_init, NULL }, + {"[Socket 7 FX] MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_endeavor_init, NULL }, + + {"[Socket 7 HX] Acer M3a", ROM_ACERM3A, "acerm3a", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_acerm3a_init, NULL }, + {"[Socket 7 HX] Acer V35n", ROM_ACERV35N, "acerv35n", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_acerv35n_init, NULL }, + {"[Socket 7 HX] AOpen AP53", ROM_AP53, "ap53", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_ap53_init, NULL }, + {"[Socket 7 HX] ASUS P/I-P55T2P4", ROM_P55T2P4, "p55r2p4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2p4_init, NULL }, + {"[Socket 7 HX] ASUS P/I-P55T2S", ROM_P55T2S, "p55t2s", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2s_init, NULL }, + + {"[Socket 7 VX] ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55tvp4_init, NULL }, + {"[Socket 7 VX] Epox P55-VA", ROM_P55VA, "p55va", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55va_init, NULL }, + + {"[Socket 8 FX] Tyan Titan-Pro AT", ROM_440FX, "440fx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_i440fx_init, NULL }, + {"[Socket 8 FX] Tyan Titan-Pro ATX", ROM_S1668, "tpatx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_s1668_init, NULL }, {"", -1, "", {{"", 0}, {"", 0}, {"", 0}}, 0,0,0,0, 0 } }; diff --git a/src/model.h b/src/model.h index 02b8ddcb8..c25d19850 100644 --- a/src/model.h +++ b/src/model.h @@ -33,7 +33,7 @@ typedef struct { - char name[32]; + char name[64]; int id; char internal_name[24]; struct { diff --git a/src/scat.c b/src/scat.c index fdcca8a11..f1b9e8b69 100644 --- a/src/scat.c +++ b/src/scat.c @@ -1,64 +1,35 @@ -/* Copyright holders: Greatpsycho - see COPYING for more details -*/ /*This is the chipset used in the Award 286 clone model*/ #include "ibm.h" -#include "cpu/cpu.h" +#include "CPU/cpu.h" #include "io.h" #include "mem.h" -#include "device.h" -#include "model.h" - - -#define SCAT_DMA_WAIT_STATE_CONTROL 0x01 -#define SCAT_VERSION 0x40 -#define SCAT_CLOCK_CONTROL 0x41 -#define SCAT_PERIPHERAL_CONTROL 0x44 -#define SCAT_MISCELLANEOUS_STATUS 0x45 -#define SCAT_POWER_MANAGEMENT 0x46 -#define SCAT_ROM_ENABLE 0x48 -#define SCAT_RAM_WRITE_PROTECT 0x49 -#define SCAT_SHADOW_RAM_ENABLE_1 0x4A -#define SCAT_SHADOW_RAM_ENABLE_2 0x4B -#define SCAT_SHADOW_RAM_ENABLE_3 0x4C -#define SCAT_DRAM_CONFIGURATION 0x4D -#define SCAT_EXTENDED_BOUNDARY 0x4E -#define SCAT_EMS_CONTROL 0x4F - - -typedef struct { - uint8_t regs_2x8; - uint8_t regs_2x9; -} scat_t; - +#include "scat.h" +#include "CPU/x86.h" +#include "CPU/cpu.h" static uint8_t scat_regs[256]; static int scat_index; static uint8_t scat_port_92 = 0; static uint8_t scat_ems_reg_2xA = 0; +static mem_mapping_t scat_mapping[32]; static mem_mapping_t scat_high_mapping[16]; static scat_t scat_stat[32]; static uint32_t scat_xms_bound; static mem_mapping_t scat_shadowram_mapping; static mem_mapping_t scat_512k_clip_mapping; +static mem_mapping_t scat_4000_9FFF_mapping[24]; +static mem_mapping_t scat_A000_BFFF_mapping; +uint8_t scat_read(uint16_t port, void *priv); +void scat_write(uint16_t port, uint8_t val, void *priv); -static void scat_shadow_state_update(void) +void scat_shadow_state_update() { int i, val; for (i = 0; i < 24; i++) { - if((scat_regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1) - { - val = MEM_READ_INTERNAL; - ram_mapped_addr[i + 40] |= 1; - } - else - { - val = MEM_READ_EXTERNAL; - ram_mapped_addr[i + 40] &= ~1; - } + val = ((scat_regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1) ? MEM_READ_INTERNAL : MEM_READ_EXTERNAL; if (i < 8) { val |= ((scat_regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTERNAL; @@ -74,14 +45,13 @@ static void scat_shadow_state_update(void) val |= ((scat_regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTERNAL; } } - mem_set_mem_state((i + 40) << 14, 0x4000, val); + mem_set_mem_state((i + 40) << 14, 0x4000, val); } flushmmucache(); } - -static void scat_set_xms_bound(uint8_t val) +void scat_set_xms_bound(uint8_t val) { uint32_t max_xms_size = (mem_size >= 16384) ? 0xFC0000 : mem_size << 10; @@ -155,8 +125,7 @@ static void scat_set_xms_bound(uint8_t val) } } - -static uint32_t get_scat_addr(uint32_t addr, scat_t *p) +uint32_t get_scat_addr(uint32_t addr, scat_t *p) { if (p && (scat_regs[SCAT_EMS_CONTROL] & 0x80) && (p->regs_2x9 & 0x80)) { @@ -170,8 +139,33 @@ static uint32_t get_scat_addr(uint32_t addr, scat_t *p) return addr; } +void scat_set_global_EMS_state(int state) +{ + int i; + uint32_t base_addr, virt_addr; -static void scat_write(uint16_t port, uint8_t val, void *priv) + for(i=0; i<32; i++) + { + base_addr = (i + 16) << 14; + if(i >= 24) + base_addr += 0x30000; + if(state && (scat_stat[i].regs_2x9 & 0x80)) + { + virt_addr = get_scat_addr(base_addr, &scat_stat[i]); + if(i < 24) mem_mapping_disable(&scat_4000_9FFF_mapping[i]); + mem_mapping_set_exec(&scat_mapping[i], ram + virt_addr); + mem_mapping_enable(&scat_mapping[i]); + } + else + { + mem_mapping_set_exec(&scat_mapping[i], ram + base_addr); + mem_mapping_disable(&scat_mapping[i]); + if(i < 24) mem_mapping_enable(&scat_4000_9FFF_mapping[i]); + } + } +} + +void scat_write(uint16_t port, uint8_t val, void *priv) { uint8_t scat_reg_valid = 0, scat_shadow_update = 0, index; uint32_t base_addr, virt_addr; @@ -187,11 +181,32 @@ static void scat_write(uint16_t port, uint8_t val, void *priv) { case SCAT_CLOCK_CONTROL: case SCAT_PERIPHERAL_CONTROL: + scat_reg_valid = 1; + break; case SCAT_EMS_CONTROL: + if(val & 0x40) + { + if(val & 1) + { + io_sethandler(0x0218, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); + io_removehandler(0x0208, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); + } + else + { + io_sethandler(0x0208, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); + io_removehandler(0x0218, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); + } + } + else + { + io_removehandler(0x0208, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); + io_removehandler(0x0218, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); + } + scat_set_global_EMS_state(val & 0x80); scat_reg_valid = 1; break; case SCAT_POWER_MANAGEMENT: - val &= 0x40; /* TODO - Only use AUX parity disable bit for this version. Other bits should be implemented later. */ + val &= 0x40; scat_reg_valid = 1; break; case SCAT_DRAM_CONFIGURATION: @@ -212,6 +227,10 @@ static void scat_write(uint16_t port, uint8_t val, void *priv) } } flushmmucache(); + + cpu_waitstates = (val & 0x70) == 0 ? 1 : 2; + cpu_update_waitstates(); + scat_reg_valid = 1; break; case SCAT_EXTENDED_BOUNDARY: @@ -235,7 +254,6 @@ static void scat_write(uint16_t port, uint8_t val, void *priv) scat_regs[scat_index] = val; if (scat_shadow_update) scat_shadow_state_update(); - pclog("Write SCAT Register %02X to %02X at %04X:%04X\n", scat_index, val, CS, cpu_state.pc); break; case 0x92: @@ -247,7 +265,7 @@ static void scat_write(uint16_t port, uint8_t val, void *priv) if ((~scat_port_92 & val) & 1) { softresetx86(); - cpu_set_edx(); + cpu_set_edx(); } scat_port_92 = val; break; @@ -255,17 +273,11 @@ static void scat_write(uint16_t port, uint8_t val, void *priv) case 0x208: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) { - pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); index = scat_ems_reg_2xA & 0x1F; scat_stat[index].regs_2x8 = val; - base_addr = (index + 16) << 14; - if(index >= 24) - base_addr += 0x30000; - if(scat_stat[index].regs_2x9 & 0x80) + if((scat_regs[SCAT_EMS_CONTROL] & 0x80) && (scat_stat[index].regs_2x9 & 0x80)) { - ram_mapped_addr[base_addr >> 14] &= 0xFFC000FF; - ram_mapped_addr[base_addr >> 14] |= val << 14; flushmmucache(); } } @@ -273,25 +285,29 @@ static void scat_write(uint16_t port, uint8_t val, void *priv) case 0x209: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) { - pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); index = scat_ems_reg_2xA & 0x1F; scat_stat[index].regs_2x9 = val; base_addr = (index + 16) << 14; if(index >= 24) base_addr += 0x30000; - ram_mapped_addr[base_addr >> 14] &= 1; - if (val & 0x80) + if (scat_regs[SCAT_EMS_CONTROL] & 0x80) { - virt_addr = (((scat_stat[index].regs_2x9 & 3) << 8) | scat_stat[index].regs_2x8) << 14; - pclog("Map page %d(address %05X) to address %06X\n", scat_ems_reg_2xA & 0x1f, base_addr, virt_addr); - ram_mapped_addr[base_addr >> 14] |= virt_addr | 2; + if (val & 0x80) + { + virt_addr = get_scat_addr(base_addr, &scat_stat[index]); + if(index < 24) mem_mapping_disable(&scat_4000_9FFF_mapping[index]); + mem_mapping_set_exec(&scat_mapping[index], ram + virt_addr); + mem_mapping_enable(&scat_mapping[index]); + } + else + { + mem_mapping_set_exec(&scat_mapping[index], ram + base_addr); + mem_mapping_disable(&scat_mapping[index]); + if(index < 24) mem_mapping_enable(&scat_4000_9FFF_mapping[index]); + } + flushmmucache(); } - else - { - pclog("Unmap page %d(address %06X)\n", scat_ems_reg_2xA & 0x1f, base_addr); - } - flushmmucache(); if (scat_ems_reg_2xA & 0x80) { @@ -302,7 +318,6 @@ static void scat_write(uint16_t port, uint8_t val, void *priv) case 0x20A: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) { - pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); scat_ems_reg_2xA = val; } break; @@ -310,17 +325,11 @@ static void scat_write(uint16_t port, uint8_t val, void *priv) case 0x218: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) { - pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); index = scat_ems_reg_2xA & 0x1F; scat_stat[index].regs_2x8 = val; - base_addr = (index + 16) << 14; - if(index >= 24) - base_addr += 0x30000; - if(scat_stat[index].regs_2x9 & 0x80) + if((scat_regs[SCAT_EMS_CONTROL] & 0x80) && (scat_stat[index].regs_2x9 & 0x80)) { - ram_mapped_addr[base_addr >> 14] &= 0xFFC000FF; - ram_mapped_addr[base_addr >> 14] |= val << 14; flushmmucache(); } } @@ -328,24 +337,31 @@ static void scat_write(uint16_t port, uint8_t val, void *priv) case 0x219: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) { - pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); index = scat_ems_reg_2xA & 0x1F; scat_stat[index].regs_2x9 = val; base_addr = (index + 16) << 14; if (index >= 24) base_addr += 0x30000; - if (val & 0x80) + if (scat_regs[SCAT_EMS_CONTROL] & 0x80) { - virt_addr = (((scat_stat[index].regs_2x9 & 3) << 8) | scat_stat[index].regs_2x8) << 14; - pclog("Map page %d(address %05X) to address %06X\n", scat_ems_reg_2xA & 0x1f, base_addr, virt_addr); - ram_mapped_addr[base_addr >> 14] |= virt_addr | 2; + if (val & 0x80) + { + virt_addr = get_scat_addr(base_addr, &scat_stat[index]); + if(index < 24) mem_mapping_disable(&scat_4000_9FFF_mapping[index]); + mem_mapping_set_exec(&scat_mapping[index], ram + virt_addr); + mem_mapping_enable(&scat_mapping[index]); + pclog("Map page %d(address %05X) to address %06X\n", scat_ems_reg_2xA & 0x1f, base_addr, virt_addr); + } + else + { + mem_mapping_set_exec(&scat_mapping[index], ram + base_addr); + mem_mapping_disable(&scat_mapping[index]); + if(index < 24) mem_mapping_enable(&scat_4000_9FFF_mapping[index]); + pclog("Unmap page %d(address %05X)\n", scat_ems_reg_2xA & 0x1f, base_addr); + } + flushmmucache(); } - else - { - pclog("Unmap page %d(address %05X)\n", scat_ems_reg_2xA & 0x1f, base_addr); - } - flushmmucache(); if (scat_ems_reg_2xA & 0x80) { @@ -356,15 +372,13 @@ static void scat_write(uint16_t port, uint8_t val, void *priv) case 0x21A: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) { - pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); scat_ems_reg_2xA = val; } break; } } - -static uint8_t scat_read(uint16_t port, void *priv) +uint8_t scat_read(uint16_t port, void *priv) { uint8_t val = 0xff, index; switch (port) @@ -375,11 +389,13 @@ static uint8_t scat_read(uint16_t port, void *priv) case SCAT_MISCELLANEOUS_STATUS: val = (scat_regs[scat_index] & 0xbf) | ((mem_a20_key & 2) << 5); break; + case SCAT_DRAM_CONFIGURATION: + val = (scat_regs[scat_index] & 0x8f) | (cpu_waitstates == 1 ? 0 : 0x10); + break; default: val = scat_regs[scat_index]; break; } - pclog("Read SCAT Register %02X at %04X:%04X\n", scat_index, CS, cpu_state.pc); break; case 0x92: @@ -389,7 +405,6 @@ static uint8_t scat_read(uint16_t port, void *priv) case 0x208: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) { - pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); index = scat_ems_reg_2xA & 0x1F; val = scat_stat[index].regs_2x8; } @@ -397,7 +412,6 @@ static uint8_t scat_read(uint16_t port, void *priv) case 0x209: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) { - pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); index = scat_ems_reg_2xA & 0x1F; val = scat_stat[index].regs_2x9; } @@ -405,7 +419,6 @@ static uint8_t scat_read(uint16_t port, void *priv) case 0x20A: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) { - pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); val = scat_ems_reg_2xA; } break; @@ -413,7 +426,6 @@ static uint8_t scat_read(uint16_t port, void *priv) case 0x218: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) { - pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); index = scat_ems_reg_2xA & 0x1F; val = scat_stat[index].regs_2x8; } @@ -421,7 +433,6 @@ static uint8_t scat_read(uint16_t port, void *priv) case 0x219: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) { - pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); index = scat_ems_reg_2xA & 0x1F; val = scat_stat[index].regs_2x9; } @@ -429,7 +440,6 @@ static uint8_t scat_read(uint16_t port, void *priv) case 0x21A: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) { - pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); val = scat_ems_reg_2xA; } break; @@ -437,8 +447,7 @@ static uint8_t scat_read(uint16_t port, void *priv) return val; } - -static uint8_t mem_read_scatems(uint32_t addr, void *priv) +uint8_t mem_read_scatems(uint32_t addr, void *priv) { uint8_t val = 0xff; scat_t *stat = (scat_t *)priv; @@ -450,34 +459,7 @@ static uint8_t mem_read_scatems(uint32_t addr, void *priv) return val; } - -static uint16_t mem_read_scatemsw(uint32_t addr, void *priv) -{ - uint16_t val = 0xffff; - scat_t *stat = (scat_t *)priv; - - addr = get_scat_addr(addr, stat); - if (addr < (mem_size << 10)) - val = mem_read_ramw(addr, priv); - - return val; -} - - -static uint32_t mem_read_scatemsl(uint32_t addr, void *priv) -{ - uint32_t val = 0xffffffff; - scat_t *stat = (scat_t *)priv; - - addr = get_scat_addr(addr, stat); - if (addr < (mem_size << 10)) - val = mem_read_raml(addr, priv); - - return val; -} - - -static void mem_write_scatems(uint32_t addr, uint8_t val, void *priv) +void mem_write_scatems(uint32_t addr, uint8_t val, void *priv) { scat_t *stat = (scat_t *)priv; @@ -486,46 +468,18 @@ static void mem_write_scatems(uint32_t addr, uint8_t val, void *priv) mem_write_ram(addr, val, priv); } - -static void mem_write_scatemsw(uint32_t addr, uint16_t val, void *priv) -{ - scat_t *stat = (scat_t *)priv; - - addr = get_scat_addr(addr, stat); - if (addr < (mem_size << 10)) - mem_write_ramw(addr, val, priv); -} - - -static void mem_write_scatemsl(uint32_t addr, uint32_t val, void *priv) -{ - scat_t *stat = (scat_t *)priv; - - addr = get_scat_addr(addr, stat); - if (addr < (mem_size << 10)) - mem_write_raml(addr, val, priv); -} - - -void scat_init(void) +void scat_init() { int i; io_sethandler(0x0022, 0x0002, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); io_sethandler(0x0092, 0x0001, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); - io_sethandler(0x0208, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); - io_sethandler(0x0218, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); for (i = 0; i < 256; i++) { scat_regs[i] = 0xff; } - for (i = 0; i < 64; i++) - { - ram_mapped_addr[i] = 0; - } - scat_regs[SCAT_DMA_WAIT_STATE_CONTROL] = 0; scat_regs[SCAT_VERSION] = 10; scat_regs[SCAT_CLOCK_CONTROL] = 2; @@ -537,17 +491,34 @@ void scat_init(void) scat_regs[SCAT_SHADOW_RAM_ENABLE_1] = 0; scat_regs[SCAT_SHADOW_RAM_ENABLE_2] = 0; scat_regs[SCAT_SHADOW_RAM_ENABLE_3] = 0; - scat_regs[SCAT_DRAM_CONFIGURATION] = 2; + scat_regs[SCAT_DRAM_CONFIGURATION] = cpu_waitstates == 1 ? 2 : 0x12; scat_regs[SCAT_EXTENDED_BOUNDARY] = 0; scat_regs[SCAT_EMS_CONTROL] = 0; + mem_mapping_set_addr(&ram_low_mapping, 0, 0x40000); + + for (i = 0; i < 24; i++) + { + if(mem_size > 256 + (i << 4)) + { + mem_mapping_add(&scat_4000_9FFF_mapping[i], 0x40000 + (i << 14), 0x4000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0x40000 + (i << 14), MEM_MAPPING_INTERNAL, NULL); + mem_mapping_enable(&scat_4000_9FFF_mapping[i]); + } + } + + mem_mapping_add(&scat_A000_BFFF_mapping, 0xA0000, 0x20000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0xA0000, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_enable(&scat_A000_BFFF_mapping); + for (i = 0; i < 32; i++) { scat_stat[i].regs_2x8 = 0xff; scat_stat[i].regs_2x9 = 0x03; + mem_mapping_add(&scat_mapping[i], (i + (i >= 24 ? 28 : 16)) << 14, 0x04000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, ram + ((i + (i >= 24 ? 28 : 16)) << 14), 0, &scat_stat[i]); + mem_mapping_disable(&scat_mapping[i]); } - /* TODO - Only normal CPU accessing address FF0000 to FFFFFF mapped to ROM. Normal CPU accessing address FC0000 to FEFFFF map to ROM should be implemented later. */ + for(i=4;i<10;i++) isram[i] = 0; + for (i = 12; i < 16; i++) { mem_mapping_add(&scat_high_mapping[i], (i << 14) + 0xFC0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (i << 14), 0, NULL); @@ -555,14 +526,11 @@ void scat_init(void) if (mem_size == 1024) { - mem_mapping_add(&scat_shadowram_mapping, 0x100000, 0x60000, mem_read_scatems, mem_read_scatemsw, mem_read_scatemsl, mem_write_scatems, mem_write_scatemsw, mem_write_scatemsl, ram + 0xA0000, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_add(&scat_shadowram_mapping, 0x100000, 0x60000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, ram + 0xA0000, MEM_MAPPING_INTERNAL, NULL); } - /* Need to RAM 512kb clipping emulation if only 256KB or 64KB modules installed in memory bank. - TODO - 512KB clipping should be applied all RAM refer. */ - mem_mapping_add(&scat_512k_clip_mapping, 0x80000, 0x20000, mem_read_scatems, mem_read_scatemsw, mem_read_scatemsl, mem_write_scatems, mem_write_scatemsw, mem_write_scatemsl, ram, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_add(&scat_512k_clip_mapping, 0x80000, 0x20000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, ram, MEM_MAPPING_INTERNAL, NULL); mem_mapping_disable(&scat_512k_clip_mapping); - /* --- */ scat_set_xms_bound(0); scat_shadow_state_update(); diff --git a/src/scat.h b/src/scat.h new file mode 100644 index 000000000..1fee0cee3 --- /dev/null +++ b/src/scat.h @@ -0,0 +1,22 @@ +#define SCAT_DMA_WAIT_STATE_CONTROL 0x01 +#define SCAT_VERSION 0x40 +#define SCAT_CLOCK_CONTROL 0x41 +#define SCAT_PERIPHERAL_CONTROL 0x44 +#define SCAT_MISCELLANEOUS_STATUS 0x45 +#define SCAT_POWER_MANAGEMENT 0x46 +#define SCAT_ROM_ENABLE 0x48 +#define SCAT_RAM_WRITE_PROTECT 0x49 +#define SCAT_SHADOW_RAM_ENABLE_1 0x4A +#define SCAT_SHADOW_RAM_ENABLE_2 0x4B +#define SCAT_SHADOW_RAM_ENABLE_3 0x4C +#define SCAT_DRAM_CONFIGURATION 0x4D +#define SCAT_EXTENDED_BOUNDARY 0x4E +#define SCAT_EMS_CONTROL 0x4F + +typedef struct scat_t +{ + uint8_t regs_2x8; + uint8_t regs_2x9; +} scat_t; + +void scat_init();