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:
parent
1b73963997
commit
a4f3b2013e
14 changed files with 96 additions and 22 deletions
|
|
@ -290,6 +290,7 @@ opcodestart:
|
|||
{
|
||||
cpu_state.abrt = 0;
|
||||
softresetx86();
|
||||
cpu_set_edx();
|
||||
pclog("Triple fault - reset\n");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1693,6 +1693,7 @@ inrecomp=0;
|
|||
{
|
||||
cpu_state.abrt = 0;
|
||||
softresetx86();
|
||||
cpu_set_edx();
|
||||
pclog("Triple fault - reset\n");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
58
src/cpu.c
58
src/cpu.c
|
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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[];
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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*/
|
||||
|
|
|
|||
14
src/mem.c
14
src/mem.c
|
|
@ -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");
|
||||
|
|
|
|||
13
src/model.c
13
src/model.c
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -1603,6 +1603,7 @@ void pmodeint(int num, int soft)
|
|||
pclog("Triple fault!\n");
|
||||
// output=1;
|
||||
softresetx86();
|
||||
cpu_set_edx();
|
||||
}
|
||||
else if (num==0xD)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue