Added AMI 386DX and MR 386DX models (both based on OPTi 495 chipset). AMI 386DX supports external cache, useful for with prefetch emulation.

Also commit a few fixes required :
- Set EDX correctly on soft reset
- LOCK NOP is now treated as an illegal instruction
- Tweaks to FDC sense interrupt handling following FDC reset
This commit is contained in:
SarahW 2016-11-27 21:53:13 +00:00
commit a4f3b2013e
14 changed files with 96 additions and 22 deletions

View file

@ -290,6 +290,7 @@ opcodestart:
{
cpu_state.abrt = 0;
softresetx86();
cpu_set_edx();
pclog("Triple fault - reset\n");
}
}

View file

@ -1693,6 +1693,7 @@ inrecomp=0;
{
cpu_state.abrt = 0;
softresetx86();
cpu_set_edx();
pclog("Triple fault - reset\n");
}
}

View file

@ -200,6 +200,16 @@ CPU cpus_i386[] =
{"", -1, 0, 0, 0}
};
CPU cpus_i386DX[] =
{
/*i386*/
{"i386DX/16", CPU_386DX, 0, 16000000, 1, 0, 0x0308, 0, 0, 0, 3,3,3,3},
{"i386DX/20", CPU_386DX, 1, 20000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3},
{"i386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3},
{"i386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3},
{"", -1, 0, 0, 0}
};
CPU cpus_acer[] =
{
/*i386*/
@ -221,22 +231,44 @@ CPU cpus_Am386[] =
{"", -1, 0, 0, 0}
};
CPU cpus_Am386DX[] =
{
/*Am386*/
{"Am386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3},
{"Am386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3},
{"Am386DX/40", CPU_386DX, 4, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3},
{"", -1, 0, 0, 0}
};
CPU cpus_486SDLC[] =
{
/*Cx486SLC/DLC*/
{"Cx486SLC/20", CPU_486SLC, 1, 20000000, 1, 0, 0, 0, 0x0000, 0, 4,4,3,3},
{"Cx486SLC/25", CPU_486SLC, 2, 25000000, 1, 0, 0, 0, 0x0000, 0, 4,4,3,3},
{"Cx486SLC/33", CPU_486SLC, 3, 33333333, 1, 0, 0, 0, 0x0000, 0, 6,6,3,3},
{"Cx486SRx2/32", CPU_486SLC, 3, 32000000, 2, 0, 0, 0, 0x0006, 0, 6,6,6,6},
{"Cx486SRx2/40", CPU_486SLC, 4, 40000000, 2, 0, 0, 0, 0x0006, 0, 8,8,6,6},
{"Cx486SRx2/50", CPU_486SLC, 5, 50000000, 2, 0, 0, 0, 0x0006, 0, 8,8,6,6},
{"Cx486DLC/25", CPU_486DLC, 2, 25000000, 1, 0, 0, 0, 0x0001, 0, 4,4,3,3},
{"Cx486DLC/33", CPU_486DLC, 3, 33333333, 1, 0, 0, 0, 0x0001, 0, 6,6,3,3},
{"Cx486DLC/40", CPU_486DLC, 4, 40000000, 1, 0, 0, 0, 0x0001, 0, 7,7,3,3},
{"Cx486DRx2/32", CPU_486DLC, 3, 32000000, 2, 0, 0, 0, 0x0007, 0, 6,6,6,6},
{"Cx486DRx2/40", CPU_486DLC, 4, 40000000, 2, 0, 0, 0, 0x0007, 0, 8,8,6,6},
{"Cx486DRx2/50", CPU_486DLC, 5, 50000000, 2, 0, 0, 0, 0x0007, 0, 8,8,6,6},
{"Cx486DRx2/66", CPU_486DLC, 6, 66666666, 2, 0, 0, 0, 0x0007, 0, 12,12,6,6},
{"Cx486SLC/20", CPU_486SLC, 1, 20000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3},
{"Cx486SLC/25", CPU_486SLC, 2, 25000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3},
{"Cx486SLC/33", CPU_486SLC, 3, 33333333, 1, 0, 0x400, 0, 0x0000, 0, 6,6,3,3},
{"Cx486SRx2/32", CPU_486SLC, 3, 32000000, 2, 0, 0x406, 0, 0x0006, 0, 6,6,6,6},
{"Cx486SRx2/40", CPU_486SLC, 4, 40000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6},
{"Cx486SRx2/50", CPU_486SLC, 5, 50000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6},
{"Cx486DLC/25", CPU_486DLC, 2, 25000000, 1, 0, 0x401, 0, 0x0001, 0, 4,4,3,3},
{"Cx486DLC/33", CPU_486DLC, 3, 33333333, 1, 0, 0x401, 0, 0x0001, 0, 6,6,3,3},
{"Cx486DLC/40", CPU_486DLC, 4, 40000000, 1, 0, 0x401, 0, 0x0001, 0, 7,7,3,3},
{"Cx486DRx2/32", CPU_486DLC, 3, 32000000, 2, 0, 0x407, 0, 0x0007, 0, 6,6,6,6},
{"Cx486DRx2/40", CPU_486DLC, 4, 40000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6},
{"Cx486DRx2/50", CPU_486DLC, 5, 50000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6},
{"Cx486DRx2/66", CPU_486DLC, 6, 66666666, 2, 0, 0x407, 0, 0x0007, 0, 12,12,6,6},
{"", -1, 0, 0, 0}
};
CPU cpus_486DLC[] =
{
/*Cx486DLC*/
{"Cx486DLC/25", CPU_486DLC, 2, 25000000, 1, 0, 0x401, 0, 0x0001, 0, 4,4,3,3},
{"Cx486DLC/33", CPU_486DLC, 3, 33333333, 1, 0, 0x401, 0, 0x0001, 0, 6,6,3,3},
{"Cx486DLC/40", CPU_486DLC, 4, 40000000, 1, 0, 0x401, 0, 0x0001, 0, 7,7,3,3},
{"Cx486DRx2/32", CPU_486DLC, 3, 32000000, 2, 0, 0x407, 0, 0x0007, 0, 6,6,6,6},
{"Cx486DRx2/40", CPU_486DLC, 4, 40000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6},
{"Cx486DRx2/50", CPU_486DLC, 5, 50000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6},
{"Cx486DRx2/66", CPU_486DLC, 6, 66666666, 2, 0, 0x407, 0, 0x0007, 0, 12,12,6,6},
{"", -1, 0, 0, 0}
};

View file

@ -72,8 +72,11 @@ extern CPU cpus_8088[];
extern CPU cpus_8086[];
extern CPU cpus_286[];
extern CPU cpus_i386[];
extern CPU cpus_i386DX[];
extern CPU cpus_Am386[];
extern CPU cpus_Am386DX[];
extern CPU cpus_486SDLC[];
extern CPU cpus_486DLC[];
extern CPU cpus_i486[];
extern CPU cpus_Am486[];
extern CPU cpus_Cx486[];

View file

@ -948,10 +948,10 @@ void fdc_callback()
else
fdc.res[9] = fdc.st0;
fdc.res[10] = fdc.track[fdc.drive];
if (fdc_reset_stat)
fdc_reset_stat--;
if (!fdc_reset_stat)
fdc.st0 = 0x80;
else
fdc_reset_stat--;
paramstogo = 2;
discint = 0;

View file

@ -344,7 +344,7 @@ int driveempty[2];
#define MDA ((gfxcard==GFX_MDA || gfxcard==GFX_HERCULES || gfxcard==GFX_INCOLOR) && (romset<ROM_TANDY || romset>=ROM_IBMAT))
#define VGA ((gfxcard>=GFX_TVGA || romset==ROM_ACER386) && gfxcard!=GFX_COLORPLUS && gfxcard!=GFX_INCOLOR && romset!=ROM_PC1640 && romset!=ROM_PC1512 && romset!=ROM_TANDY && romset!=ROM_PC200)
#define PCJR (romset == ROM_IBMPCJR)
#define AMIBIOS (romset==ROM_AMI386 || romset==ROM_AMI486 || romset == ROM_WIN486)
#define AMIBIOS (romset==ROM_AMI386SX || romset==ROM_AMI486 || romset == ROM_WIN486)
int GAMEBLASTER, GUS, SSI2001, voodoo_enabled;
extern int AMSTRAD, AT, is386, PCI, TANDY;
@ -382,7 +382,7 @@ enum
ROM_IBMAT386,
ROM_ACER386,
ROM_MEGAPC,
ROM_AMI386,
ROM_AMI386SX,
ROM_AMI486,
ROM_WIN486,
ROM_PCI486,
@ -393,7 +393,9 @@ enum
ROM_IBMPS1_2011,
ROM_DESKPRO_386,
ROM_IBMPS1_2121,
ROM_AMI386DX_OPTI495,
ROM_MR386DX_OPTI495,
ROM_MAX
};

View file

@ -417,6 +417,7 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv)
case 0xfe: /*Pulse output port - pin 0 selected - x86 reset*/
softresetx86(); /*Pulse reset!*/
cpu_set_edx();
break;
case 0xff: /*Pulse output port - but no pins selected - sent by MegaPC BIOS*/

View file

@ -336,7 +336,7 @@ int loadbios()
fread(rom,65536,1,f);
fclose(f);
return 1;*/
case ROM_AMI386: /*This uses the OPTi 82C495 chipset*/
case ROM_AMI386SX:
// f=romfopen("roms/at386/at386.bin","rb");
f=romfopen("roms/ami386/ami386.bin","rb");
if (!f) break;
@ -344,6 +344,18 @@ int loadbios()
fclose(f);
return 1;
case ROM_AMI386DX_OPTI495: /*This uses the OPTi 82C495 chipset*/
f=romfopen("roms/ami386dx/OPT495SX.AMI","rb");
if (!f) break;
fread(rom,65536,1,f);
fclose(f);
return 1;
case ROM_MR386DX_OPTI495: /*This uses the OPTi 82C495 chipset*/
f=romfopen("roms/mr386dx/OPT495SX.MR","rb");
if (!f) break;
fread(rom,65536,1,f);
fclose(f);
return 1;
case ROM_ACER386:
f=romfopen("roms/acer386/acer386.bin","rb");

View file

@ -32,6 +32,7 @@
#include "nmi.h"
#include "nvr.h"
#include "olivetti_m24.h"
#include "opti495.h"
#include "pci.h"
#include "pic.h"
#include "piix.h"
@ -67,6 +68,7 @@ void at_acer386sx_init();
void at_wd76c10_init();
void at_ali1429_init();
void at_headland_init();
void at_opti495_init();
void at_um8881f_init();
void at_sis496_init();
void at_i430vx_init();
@ -111,7 +113,9 @@ MODEL models[] =
{"DTK 386SX clone", ROM_DTK386, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, 1, 1, 16, 1, at_neat_init},
{"Phoenix 386 clone", ROM_PX386, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, 1, 1, 16, 1, at_init},
{"Amstrad MegaPC", ROM_MEGAPC, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 1, 1, 1, 16, 1, at_wd76c10_init},
{"AMI 386 clone", ROM_AMI386, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, 1, 1, 256, 1, at_headland_init},
{"AMI 386SX clone", ROM_AMI386SX, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, 1, 1, 256, 1, at_headland_init},
{"MR 386DX clone", ROM_MR386DX_OPTI495, { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 0, 1, 1, 256, 1, at_opti495_init},
{"AMI 386DX clone", ROM_AMI386DX_OPTI495, { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 0, 1, 1, 256, 1, at_opti495_init},
{"AMI 486 clone", ROM_AMI486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, 1, 1, 256, 1, at_ali1429_init},
{"AMI WinBIOS 486", ROM_WIN486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, 1, 1, 256, 1, at_ali1429_init},
/* {"AMI WinBIOS 486 PCI", ROM_PCI486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, 1, 1, 256, 1, at_um8881f_init},*/
@ -346,6 +350,13 @@ void at_headland_init()
mouse_serial_init();
}
void at_opti495_init()
{
at_init();
opti495_init();
mouse_serial_init();
}
void at_ali1429_init()
{
at_init();

View file

@ -214,7 +214,7 @@ void loadnvr()
case ROM_DESKPRO_386: f = romfopen("nvr/deskpro386.nvr", "rb"); break;
case ROM_ACER386: f = romfopen("nvr/acer386.nvr", "rb"); nvrmask = 127; break;
case ROM_MEGAPC: f = romfopen("nvr/megapc.nvr", "rb"); nvrmask = 127; break;
case ROM_AMI386: f = romfopen("nvr/ami386.nvr", "rb"); nvrmask = 127; break;
case ROM_AMI386SX: f = romfopen("nvr/ami386.nvr", "rb"); nvrmask = 127; break;
case ROM_AMI486: f = romfopen("nvr/ami486.nvr", "rb"); nvrmask = 127; break;
case ROM_WIN486: f = romfopen("nvr/win486.nvr", "rb"); nvrmask = 127; break;
case ROM_PCI486: f = romfopen("nvr/hot-433.nvr", "rb"); nvrmask = 127; break;
@ -224,6 +224,8 @@ void loadnvr()
case ROM_ENDEAVOR: f = romfopen("nvr/endeavor.nvr", "rb"); nvrmask = 127; break;
case ROM_PX386: f = romfopen("nvr/px386.nvr", "rb"); nvrmask = 127; break;
case ROM_DTK386: f = romfopen("nvr/dtk386.nvr", "rb"); nvrmask = 127; break;
case ROM_MR386DX_OPTI495: f = romfopen("nvr/mr386dx_opti495.nvr", "rb"); nvrmask = 127; break;
case ROM_AMI386DX_OPTI495: f = romfopen("nvr/ami386dx_opti495.nvr", "rb"); nvrmask = 127; break;
default: return;
}
if (!f)
@ -271,7 +273,7 @@ void savenvr()
case ROM_DESKPRO_386: f = romfopen("nvr/deskpro386.nvr", "wb"); break;
case ROM_ACER386: f = romfopen("nvr/acer386.nvr", "wb"); break;
case ROM_MEGAPC: f = romfopen("nvr/megapc.nvr", "wb"); break;
case ROM_AMI386: f = romfopen("nvr/ami386.nvr", "wb"); break;
case ROM_AMI386SX: f = romfopen("nvr/ami386.nvr", "wb"); break;
case ROM_AMI486: f = romfopen("nvr/ami486.nvr", "wb"); break;
case ROM_WIN486: f = romfopen("nvr/win486.nvr", "wb"); break;
case ROM_PCI486: f = romfopen("nvr/hot-433.nvr", "wb"); break;
@ -281,6 +283,8 @@ void savenvr()
case ROM_ENDEAVOR: f = romfopen("nvr/endeavor.nvr", "wb"); break;
case ROM_PX386: f = romfopen("nvr/px386.nvr", "wb"); break;
case ROM_DTK386: f = romfopen("nvr/dtk386.nvr", "wb"); break;
case ROM_MR386DX_OPTI495: f = romfopen("nvr/mr386dx_opti495.nvr", "wb"); break;
case ROM_AMI386DX_OPTI495: f = romfopen("nvr/ami386dx_opti495.nvr", "wb"); break;
default: return;
}
fwrite(nvrram,128,1,f);

View file

@ -213,7 +213,10 @@ void ps1_m2121_write(uint16_t port, uint8_t val, void *p)
{
case 0x0092:
if (val & 1)
{
softresetx86();
cpu_set_edx();
}
ps1_92 = val & ~1;
mem_a20_alt = val & 2;
mem_a20_recalc();

View file

@ -208,6 +208,7 @@ void scat_write(uint16_t port, uint8_t val, void *priv)
if ((~scat_port_92 & val) & 1)
{
softresetx86();
cpu_set_edx();
}
scat_port_92 = val;
break;

View file

@ -595,6 +595,8 @@ static int opLOCK(uint32_t fetchdat)
fetchdat = fastreadl(cs + cpu_state.pc);
if (cpu_state.abrt) return 0;
cpu_state.pc++;
ILLEGAL_ON((fetchdat & 0xff) == 0x90);
CLOCK_CYCLES(4);
PREFETCH_PREFIX();

View file

@ -1603,6 +1603,7 @@ void pmodeint(int num, int soft)
pclog("Triple fault!\n");
// output=1;
softresetx86();
cpu_set_edx();
}
else if (num==0xD)
{