Applied the remaining mainline PCem commits.

This commit is contained in:
OBattler
2017-07-15 14:01:19 +02:00
parent 713bce1205
commit 2dbce95fde
7 changed files with 381 additions and 334 deletions

View File

@@ -1191,6 +1191,14 @@ void loadcscall(uint16_t seg)
} }
break; 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: default:
x86gpf(NULL,seg&~3); x86gpf(NULL,seg&~3);
return; return;
@@ -1593,7 +1601,7 @@ void pmodeint(int num, int soft)
} }
else else
{ {
addr = 2 + tr.base + (DPL2 * 8); addr = 2 + tr.base + (DPL2 * 4);
newss=readmemw(0,addr+2); newss=readmemw(0,addr+2);
newsp=readmemw(0,addr); 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); base=segdat[1]|((segdat[2]&0xFF)<<16);
limit=segdat[0]; limit=segdat[0];
if (is32) if(is386)
{ {
base |= (segdat[3]>>8)<<24; base |= (segdat[3]>>8)<<24;
limit |= (segdat[3]&0xF)<<16; 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 (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 (is32)
{
if (limit < 103)
{
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; if (optype==IRET) flags&=~NT_FLAG;
cpu_386_flags_rebuild(); cpu_386_flags_rebuild();
@@ -2186,25 +2183,47 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
writememl(tr.base,0x54,DS); writememl(tr.base,0x54,DS);
writememl(tr.base,0x58,FS); writememl(tr.base,0x58,FS);
writememl(tr.base,0x5C,GS); 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); writememl(base,0,tr.seg);
new_flags|=NT_FLAG; new_flags|=NT_FLAG;
} }
if (cpu_state.abrt) return; 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; cr3=new_cr3;
flushmmucache(); flushmmucache();
@@ -2232,7 +2251,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
if (!(new_cs&~3)) if (!(new_cs&~3))
{ {
x86gpf(NULL,0); x86ts(NULL,0);
return; return;
} }
addr=new_cs&~7; addr=new_cs&~7;
@@ -2240,7 +2259,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
{ {
if (addr>=ldt.limit) if (addr>=ldt.limit)
{ {
x86gpf(NULL,0); x86ts(NULL,new_cs&~3);
return; return;
} }
addr+=ldt.base; addr+=ldt.base;
@@ -2249,7 +2268,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
{ {
if (addr>=gdt.limit) if (addr>=gdt.limit)
{ {
x86gpf(NULL,0); x86ts(NULL,new_cs&~3);
return; return;
} }
addr+=gdt.base; 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*/ case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/
if ((new_cs&3) != DPL2) if ((new_cs&3) != DPL2)
{ {
x86gpf(NULL,new_cs&~3); x86ts(NULL,new_cs&~3);
return; return;
} }
break; break;
case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/ case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/
if ((new_cs&3) < DPL2) if ((new_cs&3) < DPL2)
{ {
x86gpf(NULL,new_cs&~3); x86ts(NULL,new_cs&~3);
return; return;
} }
break; break;
default: default:
x86gpf(NULL,new_cs&~3); x86ts(NULL,new_cs&~3);
return; return;
} }
@@ -2313,35 +2332,24 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
} }
else else
{ {
new_pc=readmemw(base,0x0E); if (limit < 43)
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 (tr.seg&4) tempw=readmemw(ldt.base,(tr.seg&~7)+4); pclog("16-bit TSS %04X limit less than 43.\n", seg);
else tempw=readmemw(gdt.base,(tr.seg&~7)+4); x86ts(NULL, seg);
if (cpu_state.abrt) return; 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 (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; if (optype==IRET) flags&=~NT_FLAG;
cpu_386_flags_rebuild(); cpu_386_flags_rebuild();
@@ -2361,23 +2369,45 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
writememw(tr.base,0x24,CS); writememw(tr.base,0x24,CS);
writememw(tr.base,0x26,SS); writememw(tr.base,0x26,SS);
writememw(tr.base,0x28,DS); 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); writememw(base,0,tr.seg);
new_flags|=NT_FLAG; new_flags|=NT_FLAG;
} }
if (cpu_state.abrt) return; if (cpu_state.abrt) return;
if (optype==JMP || optype==OPTYPE_INT)
{ new_pc=readmemw(base,0x0E);
if (tr.seg&4) tempw=readmemw(ldt.base,(seg&~7)+4); new_flags=readmemw(base,0x10);
else tempw=readmemw(gdt.base,(seg&~7)+4);
if (cpu_state.abrt) return; new_eax=readmemw(base,0x12);
tempw|=0x200; new_ecx=readmemw(base,0x14);
if (tr.seg&4) writememw(ldt.base,(seg&~7)+4,tempw); new_edx=readmemw(base,0x16);
else writememw(gdt.base,(seg&~7)+4,tempw); 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; cpu_state.pc=new_pc;
flags=new_flags; flags=new_flags;
@@ -2387,11 +2417,20 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
templ=(ldt.seg&~7)+gdt.base; templ=(ldt.seg&~7)+gdt.base;
ldt.limit=readmemw(0,templ); ldt.limit=readmemw(0,templ);
ldt.base=(readmemw(0,templ+2))|(readmemb(0,templ+4)<<16); 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)) if (!(new_cs&~3))
{ {
pclog("TS loading null CS\n"); pclog("TS loading null CS\n");
x86gpf(NULL,0); x86ts(NULL,0);
return; return;
} }
addr=new_cs&~7; addr=new_cs&~7;
@@ -2400,7 +2439,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
if (addr>=ldt.limit) if (addr>=ldt.limit)
{ {
pclog("Bigger than LDT limit %04X %04X %04X TS\n",new_cs,ldt.limit,addr); pclog("Bigger than LDT limit %04X %04X %04X TS\n",new_cs,ldt.limit,addr);
x86gpf(NULL,0); x86ts(NULL,new_cs&~3);
return; return;
} }
addr+=ldt.base; addr+=ldt.base;
@@ -2410,7 +2449,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
if (addr>=gdt.limit) if (addr>=gdt.limit)
{ {
pclog("Bigger than GDT limit %04X %04X TS\n",new_cs,gdt.limit); pclog("Bigger than GDT limit %04X %04X TS\n",new_cs,gdt.limit);
x86gpf(NULL,0); x86ts(NULL,new_cs&~3);
return; return;
} }
addr+=gdt.base; addr+=gdt.base;
@@ -2431,7 +2470,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
if ((new_cs&3) != DPL2) if ((new_cs&3) != DPL2)
{ {
pclog("TS load CS non-conforming RPL != DPL"); pclog("TS load CS non-conforming RPL != DPL");
x86gpf(NULL,new_cs&~3); x86ts(NULL,new_cs&~3);
return; return;
} }
break; break;
@@ -2439,13 +2478,13 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
if ((new_cs&3) < DPL2) if ((new_cs&3) < DPL2)
{ {
pclog("TS load CS non-conforming RPL < DPL"); pclog("TS load CS non-conforming RPL < DPL");
x86gpf(NULL,new_cs&~3); x86ts(NULL,new_cs&~3);
return; return;
} }
break; break;
default: default:
pclog("TS load CS not code segment\n"); pclog("TS load CS not code segment\n");
x86gpf(NULL,new_cs&~3); x86ts(NULL,new_cs&~3);
return; return;
} }
@@ -2454,14 +2493,14 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
set_use32(0); set_use32(0);
AX=new_eax; EAX=new_eax | 0xFFFF0000;
CX=new_ecx; ECX=new_ecx | 0xFFFF0000;
DX=new_edx; EDX=new_edx | 0xFFFF0000;
BX=new_ebx; EBX=new_ebx | 0xFFFF0000;
SP=new_esp; ESP=new_esp | 0xFFFF0000;
BP=new_ebp; EBP=new_ebp | 0xFFFF0000;
SI=new_esi; ESI=new_esi | 0xFFFF0000;
DI=new_edi; EDI=new_edi | 0xFFFF0000;
if (output) pclog("Load ES %04X\n",new_es); if (output) pclog("Load ES %04X\n",new_es);
loadseg(new_es,&_es); loadseg(new_es,&_es);
@@ -2469,6 +2508,11 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
loadseg(new_ss,&_ss); loadseg(new_ss,&_ss);
if (output) pclog("Load DS %04X\n",new_ds); if (output) pclog("Load DS %04X\n",new_ds);
loadseg(new_ds,&_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); if (output) pclog("Resuming at %04X:%08X\n",CS,cpu_state.pc);
} }

View File

@@ -63,7 +63,7 @@ int shadowbios,shadowbios_write;
int mem_a20_state; int mem_a20_state;
static unsigned char isram[0x10000]; unsigned char isram[0x10000];
static uint8_t ff_array[0x1000]; static uint8_t ff_array[0x1000];

View File

@@ -38,6 +38,7 @@ extern int readlnum,writelnum;
extern int memspeed[11]; extern int memspeed[11];
extern int nopageerrors; extern int nopageerrors;
extern uint32_t biosmask; extern uint32_t biosmask;
extern unsigned char isram[0x10000];
#define MEM_MAP_TO_SHADOW_RAM_MASK 1 #define MEM_MAP_TO_SHADOW_RAM_MASK 1
#define MEM_MAP_TO_RAM_ADDR_MASK 2 #define MEM_MAP_TO_RAM_ADDR_MASK 2

View File

@@ -140,76 +140,88 @@ int romset;
MODEL models[] = MODEL models[] =
{ {
{"IBM PC", ROM_IBMPC, "ibmpc", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 32, 0, xt_init, NULL }, {"[8088] AMI XT clone", ROM_AMIXT, "amixt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL },
{"IBM XT", ROM_IBMXT, "ibmxt", {{"", 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 },
{"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 },
{"IBM PCjr", ROM_IBMPCJR, "ibmpcjr", {{"", cpus_pcjr}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, 0, 128, 640, 128, 0, pcjr_init, &pcjr_device }, {"[8088] IBM PC", ROM_IBMPC, "ibmpc", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 32, 0, xt_init, NULL },
{"Generic XT clone", ROM_GENXT, "genxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 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 },
{"AMI XT clone", ROM_AMIXT, "amixt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL }, {"[8088] IBM XT", ROM_IBMXT, "ibmxt", {{"", 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 }, {"[8088] Generic XT clone", ROM_GENXT, "genxt", {{"", 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 }, {"[8088] Juko XT clone", ROM_JUKOPC, "jukopc", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL },
{"VTech Laser XT3", ROM_LXT3, "lxt3", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 1152, 64, 0, xt_laserxt_init, NULL }, {"[8088] Phoenix XT clone", ROM_PXXT, "pxxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL },
{"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 },
{"Juko XT clone", ROM_JUKOPC, "jukopc", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL }, {"[8088] Tandy 1000", ROM_TANDY, "tandy", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, 0, 128, 640, 128, 0, tandy1k_init, &tandy1000_device },
{"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 },
{"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 },
{"Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, 0, 512, 768, 128, 0, tandy1ksl2_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 },
{"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 }, {"[8086] Amstrad PC1512", ROM_PC1512, "pc1512", {{"", cpus_pc1512}, {"", 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 }, {"[8086] Amstrad PC1640", ROM_PC1640, "pc1640", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL },
{"Olivetti M24", ROM_OLIM24, "olivetti_m24", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_OLIM24, 128, 640, 128, 0, olim24_init, NULL }, {"[8086] Amstrad PC2086", ROM_PC2086, "pc2086", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL },
{"Amstrad PC1640", ROM_PC1640, "pc1640", {{"", 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 },
{"Amstrad PC2086", ROM_PC2086, "pc2086", {{"", 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 },
{"Amstrad PC3086", ROM_PC3086, "pc3086", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL }, {"[8086] Sinclair PC200", ROM_PC200, "pc200", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 512, 640, 128, 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 }, {"[8086] Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, 0, 512, 768, 128, 0, tandy1ksl2_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 }, {"[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 },
{"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] 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 },
{"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] Compaq Portable II", ROM_PORTABLEII, "portableii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, at_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 }, {"[286] Compaq Portable III", ROM_PORTABLEIII, "portableiii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, at_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 }, {"[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 },
{"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 }, {"[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 },
{"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 AT", ROM_IBMAT, "ibmat", {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 256,15872, 128, 63, ibm_at_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 }, {"[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 },
{"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] 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/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 }, {"[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 },
{"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 }, {"[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 },
{"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 }, {"[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 },
{"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] 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 }, {"[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 },
{"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 }, {"[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 },
{"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 }, {"[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 },
{"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 }, {"[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 },
{"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 }, {"[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 },
{"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 },
{"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 }, {"[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 },
{"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 }, {"[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 },
{"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 }, {"[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 },
{"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 }, {"[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 },
{"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 }, {"[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 #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 #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 }, {"[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 },
{"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 }, {"[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 },
{"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 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 },
{"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/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 },
{"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 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 },
{"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 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 },
{"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 }, {"[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 },
{"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 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 },
{"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 }, {"[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 },
{"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 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 },
{"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 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 },
{"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 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 },
{"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 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 } {"", -1, "", {{"", 0}, {"", 0}, {"", 0}}, 0,0,0,0, 0 }
}; };

View File

@@ -33,7 +33,7 @@
typedef struct { typedef struct {
char name[32]; char name[64];
int id; int id;
char internal_name[24]; char internal_name[24];
struct { struct {

View File

@@ -1,64 +1,35 @@
/* Copyright holders: Greatpsycho
see COPYING for more details
*/
/*This is the chipset used in the Award 286 clone model*/ /*This is the chipset used in the Award 286 clone model*/
#include "ibm.h" #include "ibm.h"
#include "cpu/cpu.h" #include "CPU/cpu.h"
#include "io.h" #include "io.h"
#include "mem.h" #include "mem.h"
#include "device.h" #include "scat.h"
#include "model.h" #include "CPU/x86.h"
#include "CPU/cpu.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;
static uint8_t scat_regs[256]; static uint8_t scat_regs[256];
static int scat_index; static int scat_index;
static uint8_t scat_port_92 = 0; static uint8_t scat_port_92 = 0;
static uint8_t scat_ems_reg_2xA = 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 mem_mapping_t scat_high_mapping[16];
static scat_t scat_stat[32]; static scat_t scat_stat[32];
static uint32_t scat_xms_bound; static uint32_t scat_xms_bound;
static mem_mapping_t scat_shadowram_mapping; static mem_mapping_t scat_shadowram_mapping;
static mem_mapping_t scat_512k_clip_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; int i, val;
for (i = 0; i < 24; i++) for (i = 0; i < 24; i++)
{ {
if((scat_regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1) val = ((scat_regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1) ? MEM_READ_INTERNAL : MEM_READ_EXTERNAL;
{
val = MEM_READ_INTERNAL;
ram_mapped_addr[i + 40] |= 1;
}
else
{
val = MEM_READ_EXTERNAL;
ram_mapped_addr[i + 40] &= ~1;
}
if (i < 8) if (i < 8)
{ {
val |= ((scat_regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTERNAL; val |= ((scat_regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTERNAL;
@@ -80,8 +51,7 @@ static void scat_shadow_state_update(void)
flushmmucache(); flushmmucache();
} }
void scat_set_xms_bound(uint8_t val)
static void scat_set_xms_bound(uint8_t val)
{ {
uint32_t max_xms_size = (mem_size >= 16384) ? 0xFC0000 : mem_size << 10; 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)
} }
} }
uint32_t get_scat_addr(uint32_t addr, scat_t *p)
static uint32_t get_scat_addr(uint32_t addr, scat_t *p)
{ {
if (p && (scat_regs[SCAT_EMS_CONTROL] & 0x80) && (p->regs_2x9 & 0x80)) 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; 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; uint8_t scat_reg_valid = 0, scat_shadow_update = 0, index;
uint32_t base_addr, virt_addr; 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_CLOCK_CONTROL:
case SCAT_PERIPHERAL_CONTROL: case SCAT_PERIPHERAL_CONTROL:
scat_reg_valid = 1;
break;
case SCAT_EMS_CONTROL: 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; scat_reg_valid = 1;
break; break;
case SCAT_POWER_MANAGEMENT: 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; scat_reg_valid = 1;
break; break;
case SCAT_DRAM_CONFIGURATION: case SCAT_DRAM_CONFIGURATION:
@@ -212,6 +227,10 @@ static void scat_write(uint16_t port, uint8_t val, void *priv)
} }
} }
flushmmucache(); flushmmucache();
cpu_waitstates = (val & 0x70) == 0 ? 1 : 2;
cpu_update_waitstates();
scat_reg_valid = 1; scat_reg_valid = 1;
break; break;
case SCAT_EXTENDED_BOUNDARY: 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; scat_regs[scat_index] = val;
if (scat_shadow_update) if (scat_shadow_update)
scat_shadow_state_update(); scat_shadow_state_update();
pclog("Write SCAT Register %02X to %02X at %04X:%04X\n", scat_index, val, CS, cpu_state.pc);
break; break;
case 0x92: case 0x92:
@@ -255,17 +273,11 @@ static void scat_write(uint16_t port, uint8_t val, void *priv)
case 0x208: case 0x208:
if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) 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; index = scat_ems_reg_2xA & 0x1F;
scat_stat[index].regs_2x8 = val; 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(); flushmmucache();
} }
} }
@@ -273,25 +285,29 @@ static void scat_write(uint16_t port, uint8_t val, void *priv)
case 0x209: case 0x209:
if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) 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; index = scat_ems_reg_2xA & 0x1F;
scat_stat[index].regs_2x9 = val; scat_stat[index].regs_2x9 = val;
base_addr = (index + 16) << 14; base_addr = (index + 16) << 14;
if(index >= 24) if(index >= 24)
base_addr += 0x30000; base_addr += 0x30000;
ram_mapped_addr[base_addr >> 14] &= 1; if (scat_regs[SCAT_EMS_CONTROL] & 0x80)
{
if (val & 0x80) if (val & 0x80)
{ {
virt_addr = (((scat_stat[index].regs_2x9 & 3) << 8) | scat_stat[index].regs_2x8) << 14; virt_addr = get_scat_addr(base_addr, &scat_stat[index]);
pclog("Map page %d(address %05X) to address %06X\n", scat_ems_reg_2xA & 0x1f, base_addr, virt_addr); if(index < 24) mem_mapping_disable(&scat_4000_9FFF_mapping[index]);
ram_mapped_addr[base_addr >> 14] |= virt_addr | 2; mem_mapping_set_exec(&scat_mapping[index], ram + virt_addr);
mem_mapping_enable(&scat_mapping[index]);
} }
else else
{ {
pclog("Unmap page %d(address %06X)\n", scat_ems_reg_2xA & 0x1f, base_addr); 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(); flushmmucache();
}
if (scat_ems_reg_2xA & 0x80) if (scat_ems_reg_2xA & 0x80)
{ {
@@ -302,7 +318,6 @@ static void scat_write(uint16_t port, uint8_t val, void *priv)
case 0x20A: case 0x20A:
if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) 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; scat_ems_reg_2xA = val;
} }
break; break;
@@ -310,17 +325,11 @@ static void scat_write(uint16_t port, uint8_t val, void *priv)
case 0x218: case 0x218:
if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) 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; index = scat_ems_reg_2xA & 0x1F;
scat_stat[index].regs_2x8 = val; 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(); flushmmucache();
} }
} }
@@ -328,24 +337,31 @@ static void scat_write(uint16_t port, uint8_t val, void *priv)
case 0x219: case 0x219:
if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) 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; index = scat_ems_reg_2xA & 0x1F;
scat_stat[index].regs_2x9 = val; scat_stat[index].regs_2x9 = val;
base_addr = (index + 16) << 14; base_addr = (index + 16) << 14;
if (index >= 24) if (index >= 24)
base_addr += 0x30000; base_addr += 0x30000;
if (scat_regs[SCAT_EMS_CONTROL] & 0x80)
{
if (val & 0x80) if (val & 0x80)
{ {
virt_addr = (((scat_stat[index].regs_2x9 & 3) << 8) | scat_stat[index].regs_2x8) << 14; 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); 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;
} }
else 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); pclog("Unmap page %d(address %05X)\n", scat_ems_reg_2xA & 0x1f, base_addr);
} }
flushmmucache(); flushmmucache();
}
if (scat_ems_reg_2xA & 0x80) if (scat_ems_reg_2xA & 0x80)
{ {
@@ -356,15 +372,13 @@ static void scat_write(uint16_t port, uint8_t val, void *priv)
case 0x21A: case 0x21A:
if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) 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; scat_ems_reg_2xA = val;
} }
break; break;
} }
} }
uint8_t scat_read(uint16_t port, void *priv)
static uint8_t scat_read(uint16_t port, void *priv)
{ {
uint8_t val = 0xff, index; uint8_t val = 0xff, index;
switch (port) switch (port)
@@ -375,11 +389,13 @@ static uint8_t scat_read(uint16_t port, void *priv)
case SCAT_MISCELLANEOUS_STATUS: case SCAT_MISCELLANEOUS_STATUS:
val = (scat_regs[scat_index] & 0xbf) | ((mem_a20_key & 2) << 5); val = (scat_regs[scat_index] & 0xbf) | ((mem_a20_key & 2) << 5);
break; break;
case SCAT_DRAM_CONFIGURATION:
val = (scat_regs[scat_index] & 0x8f) | (cpu_waitstates == 1 ? 0 : 0x10);
break;
default: default:
val = scat_regs[scat_index]; val = scat_regs[scat_index];
break; break;
} }
pclog("Read SCAT Register %02X at %04X:%04X\n", scat_index, CS, cpu_state.pc);
break; break;
case 0x92: case 0x92:
@@ -389,7 +405,6 @@ static uint8_t scat_read(uint16_t port, void *priv)
case 0x208: case 0x208:
if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) 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; index = scat_ems_reg_2xA & 0x1F;
val = scat_stat[index].regs_2x8; val = scat_stat[index].regs_2x8;
} }
@@ -397,7 +412,6 @@ static uint8_t scat_read(uint16_t port, void *priv)
case 0x209: case 0x209:
if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) 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; index = scat_ems_reg_2xA & 0x1F;
val = scat_stat[index].regs_2x9; val = scat_stat[index].regs_2x9;
} }
@@ -405,7 +419,6 @@ static uint8_t scat_read(uint16_t port, void *priv)
case 0x20A: case 0x20A:
if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) 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; val = scat_ems_reg_2xA;
} }
break; break;
@@ -413,7 +426,6 @@ static uint8_t scat_read(uint16_t port, void *priv)
case 0x218: case 0x218:
if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) 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; index = scat_ems_reg_2xA & 0x1F;
val = scat_stat[index].regs_2x8; val = scat_stat[index].regs_2x8;
} }
@@ -421,7 +433,6 @@ static uint8_t scat_read(uint16_t port, void *priv)
case 0x219: case 0x219:
if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) 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; index = scat_ems_reg_2xA & 0x1F;
val = scat_stat[index].regs_2x9; val = scat_stat[index].regs_2x9;
} }
@@ -429,7 +440,6 @@ static uint8_t scat_read(uint16_t port, void *priv)
case 0x21A: case 0x21A:
if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) 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; val = scat_ems_reg_2xA;
} }
break; break;
@@ -437,8 +447,7 @@ static uint8_t scat_read(uint16_t port, void *priv)
return val; return val;
} }
uint8_t mem_read_scatems(uint32_t addr, void *priv)
static uint8_t mem_read_scatems(uint32_t addr, void *priv)
{ {
uint8_t val = 0xff; uint8_t val = 0xff;
scat_t *stat = (scat_t *)priv; scat_t *stat = (scat_t *)priv;
@@ -450,34 +459,7 @@ static uint8_t mem_read_scatems(uint32_t addr, void *priv)
return val; return val;
} }
void mem_write_scatems(uint32_t addr, uint8_t val, void *priv)
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)
{ {
scat_t *stat = (scat_t *)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); mem_write_ram(addr, val, priv);
} }
void scat_init()
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)
{ {
int i; int i;
io_sethandler(0x0022, 0x0002, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); 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(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++) for (i = 0; i < 256; i++)
{ {
scat_regs[i] = 0xff; 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_DMA_WAIT_STATE_CONTROL] = 0;
scat_regs[SCAT_VERSION] = 10; scat_regs[SCAT_VERSION] = 10;
scat_regs[SCAT_CLOCK_CONTROL] = 2; 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_1] = 0;
scat_regs[SCAT_SHADOW_RAM_ENABLE_2] = 0; scat_regs[SCAT_SHADOW_RAM_ENABLE_2] = 0;
scat_regs[SCAT_SHADOW_RAM_ENABLE_3] = 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_EXTENDED_BOUNDARY] = 0;
scat_regs[SCAT_EMS_CONTROL] = 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++) for (i = 0; i < 32; i++)
{ {
scat_stat[i].regs_2x8 = 0xff; scat_stat[i].regs_2x8 = 0xff;
scat_stat[i].regs_2x9 = 0x03; 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++) 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); 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) 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. mem_mapping_add(&scat_512k_clip_mapping, 0x80000, 0x20000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, ram, MEM_MAPPING_INTERNAL, NULL);
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_disable(&scat_512k_clip_mapping); mem_mapping_disable(&scat_512k_clip_mapping);
/* --- */
scat_set_xms_bound(0); scat_set_xms_bound(0);
scat_shadow_state_update(); scat_shadow_state_update();

22
src/scat.h Normal file
View File

@@ -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();