Changes to device_t struct to accomodate the upcoming PCI IRQ arbitration rewrite; Added device.c/h API to obtain name from the device_t struct; Significant changes to win/win_settings.c to clean up the code a bit and fix bugs; Ported all the CPU and AudioPCI commits from PCem; Added an API call to allow ACPI soft power off to gracefully stop the emulator; Removed the Siemens PCD-2L from the Dev branch because it now works; Removed the Socket 5 HP Vectra from the Dev branch because it now works; Fixed the Compaq Presario and the Micronics Spitfire; Give the IBM PC330 its own list of 486 CPU so it can have DX2's with CPUID 0x470; SMM fixes; Rewrote the SYSENTER, SYSEXIT, SYSCALL, and SYSRET instructions; Changed IDE reset period to match the specification, fixes #929; The keyboard input and output ports are now forced in front of the queue when read, fixes a number of bugs, including the AMI Apollo hanging on soft reset; Added the Intel AN430TX but Dev branched because it does not work; The network code no longer drops packets if the emulated network card has failed to receive them (eg. when the buffer is full); Changes to PCI card adding and renamed some PCI slot types, also added proper AGP bridge slot types; USB UHCI emulation is no longer a stub (still doesn't fully work, but at least Windows XP chk with Debug no longer ASSERT's on it); Fixed NVR on the the SMC FDC37C932QF and APM variants; A number of fixes to Intel 4x0 chipsets, including fixing every register of the 440LX and 440EX; Some ACPI changes.
275 lines
7.6 KiB
C
275 lines
7.6 KiB
C
/*Cyrix-only instructions*/
|
|
/*System Management Mode*/
|
|
static void opSVDC_common(uint32_t fetchdat)
|
|
{
|
|
switch (rmdat & 0x38)
|
|
{
|
|
case 0x00: /*ES*/
|
|
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_es);
|
|
writememw(0, easeg+cpu_state.eaaddr+8, ES);
|
|
break;
|
|
case 0x08: /*CS*/
|
|
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_cs);
|
|
writememw(0, easeg+cpu_state.eaaddr+8, CS);
|
|
break;
|
|
case 0x18: /*DS*/
|
|
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ds);
|
|
writememw(0, easeg+cpu_state.eaaddr+8, DS);
|
|
break;
|
|
case 0x10: /*SS*/
|
|
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ss);
|
|
writememw(0, easeg+cpu_state.eaaddr+8, SS);
|
|
break;
|
|
case 0x20: /*FS*/
|
|
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_fs);
|
|
writememw(0, easeg+cpu_state.eaaddr+8, FS);
|
|
break;
|
|
case 0x28: /*GS*/
|
|
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_gs);
|
|
writememw(0, easeg+cpu_state.eaaddr+8, GS);
|
|
break;
|
|
default:
|
|
pclog("opSVDC: unknown rmdat %02x\n", rmdat);
|
|
x86illegal();
|
|
}
|
|
}
|
|
static int opSVDC_a16(uint32_t fetchdat)
|
|
{
|
|
if (cpu_cur_status & CPU_STATUS_SMM)
|
|
{
|
|
fetch_ea_16(fetchdat);
|
|
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
|
opSVDC_common(fetchdat);
|
|
}
|
|
else
|
|
x86illegal();
|
|
|
|
return cpu_state.abrt;
|
|
}
|
|
static int opSVDC_a32(uint32_t fetchdat)
|
|
{
|
|
if (cpu_cur_status & CPU_STATUS_SMM)
|
|
{
|
|
fetch_ea_32(fetchdat);
|
|
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
|
opSVDC_common(fetchdat);
|
|
}
|
|
else
|
|
x86illegal();
|
|
|
|
return cpu_state.abrt;
|
|
}
|
|
|
|
static void opRSDC_common(uint32_t fetchdat)
|
|
{
|
|
switch (rmdat & 0x38)
|
|
{
|
|
case 0x00: /*ES*/
|
|
cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_es);
|
|
break;
|
|
case 0x18: /*DS*/
|
|
cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ds);
|
|
break;
|
|
case 0x10: /*SS*/
|
|
cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ss);
|
|
break;
|
|
case 0x20: /*FS*/
|
|
cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_fs);
|
|
break;
|
|
case 0x28: /*GS*/
|
|
cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_gs);
|
|
break;
|
|
default:
|
|
pclog("opRSDC: unknown rmdat %02x\n", rmdat);
|
|
x86illegal();
|
|
}
|
|
}
|
|
static int opRSDC_a16(uint32_t fetchdat)
|
|
{
|
|
if (cpu_cur_status & CPU_STATUS_SMM)
|
|
{
|
|
fetch_ea_16(fetchdat);
|
|
SEG_CHECK_READ(cpu_state.ea_seg);
|
|
opRSDC_common(fetchdat);
|
|
}
|
|
else
|
|
x86illegal();
|
|
|
|
return cpu_state.abrt;
|
|
}
|
|
static int opRSDC_a32(uint32_t fetchdat)
|
|
{
|
|
if (cpu_cur_status & CPU_STATUS_SMM)
|
|
{
|
|
fetch_ea_32(fetchdat);
|
|
SEG_CHECK_READ(cpu_state.ea_seg);
|
|
opRSDC_common(fetchdat);
|
|
}
|
|
else
|
|
x86illegal();
|
|
|
|
return cpu_state.abrt;
|
|
}
|
|
|
|
static int opSVLDT_a16(uint32_t fetchdat)
|
|
{
|
|
if (cpu_cur_status & CPU_STATUS_SMM)
|
|
{
|
|
fetch_ea_16(fetchdat);
|
|
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
|
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &ldt);
|
|
writememw(0, easeg+cpu_state.eaaddr+8, ldt.seg);
|
|
}
|
|
else
|
|
x86illegal();
|
|
|
|
return cpu_state.abrt;
|
|
}
|
|
static int opSVLDT_a32(uint32_t fetchdat)
|
|
{
|
|
if (cpu_cur_status & CPU_STATUS_SMM)
|
|
{
|
|
fetch_ea_32(fetchdat);
|
|
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
|
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &ldt);
|
|
writememw(0, easeg+cpu_state.eaaddr+8, ldt.seg);
|
|
}
|
|
else
|
|
x86illegal();
|
|
|
|
return cpu_state.abrt;
|
|
}
|
|
|
|
static int opRSLDT_a16(uint32_t fetchdat)
|
|
{
|
|
if (cpu_cur_status & CPU_STATUS_SMM)
|
|
{
|
|
fetch_ea_16(fetchdat);
|
|
SEG_CHECK_READ(cpu_state.ea_seg);
|
|
cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &ldt);
|
|
}
|
|
else
|
|
x86illegal();
|
|
|
|
return cpu_state.abrt;
|
|
}
|
|
static int opRSLDT_a32(uint32_t fetchdat)
|
|
{
|
|
if (cpu_cur_status & CPU_STATUS_SMM)
|
|
{
|
|
fetch_ea_32(fetchdat);
|
|
SEG_CHECK_READ(cpu_state.ea_seg);
|
|
cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &ldt);
|
|
}
|
|
else
|
|
x86illegal();
|
|
|
|
return cpu_state.abrt;
|
|
}
|
|
|
|
static int opSVTS_a16(uint32_t fetchdat)
|
|
{
|
|
if (cpu_cur_status & CPU_STATUS_SMM)
|
|
{
|
|
fetch_ea_16(fetchdat);
|
|
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
|
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr);
|
|
writememw(0, easeg+cpu_state.eaaddr+8, tr.seg);
|
|
}
|
|
else
|
|
x86illegal();
|
|
|
|
return cpu_state.abrt;
|
|
}
|
|
static int opSVTS_a32(uint32_t fetchdat)
|
|
{
|
|
if (cpu_cur_status & CPU_STATUS_SMM)
|
|
{
|
|
fetch_ea_32(fetchdat);
|
|
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
|
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr);
|
|
writememw(0, easeg+cpu_state.eaaddr+8, tr.seg);
|
|
}
|
|
else
|
|
x86illegal();
|
|
|
|
return cpu_state.abrt;
|
|
}
|
|
|
|
static int opRSTS_a16(uint32_t fetchdat)
|
|
{
|
|
if (cpu_cur_status & CPU_STATUS_SMM)
|
|
{
|
|
fetch_ea_16(fetchdat);
|
|
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
|
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr);
|
|
writememw(0, easeg+cpu_state.eaaddr+8, tr.seg);
|
|
}
|
|
else
|
|
x86illegal();
|
|
|
|
return cpu_state.abrt;
|
|
}
|
|
static int opRSTS_a32(uint32_t fetchdat)
|
|
{
|
|
if (cpu_cur_status & CPU_STATUS_SMM)
|
|
{
|
|
fetch_ea_32(fetchdat);
|
|
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
|
cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr);
|
|
writememw(0, easeg+cpu_state.eaaddr+8, tr.seg);
|
|
}
|
|
else
|
|
x86illegal();
|
|
|
|
return cpu_state.abrt;
|
|
}
|
|
|
|
static int opSMINT(uint32_t fetchdat)
|
|
{
|
|
if (cpu_cur_status & CPU_STATUS_SMM)
|
|
fatal("opSMINT\n");
|
|
else
|
|
x86illegal();
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int opRDSHR_a16(uint32_t fetchdat)
|
|
{
|
|
if (cpu_cur_status & CPU_STATUS_SMM)
|
|
fatal("opRDSHR_a16\n");
|
|
else
|
|
x86illegal();
|
|
|
|
return 1;
|
|
}
|
|
static int opRDSHR_a32(uint32_t fetchdat)
|
|
{
|
|
if (cpu_cur_status & CPU_STATUS_SMM)
|
|
fatal("opRDSHR_a32\n");
|
|
else
|
|
x86illegal();
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int opWRSHR_a16(uint32_t fetchdat)
|
|
{
|
|
if (cpu_cur_status & CPU_STATUS_SMM)
|
|
fatal("opWRSHR_a16\n");
|
|
else
|
|
x86illegal();
|
|
|
|
return 1;
|
|
}
|
|
static int opWRSHR_a32(uint32_t fetchdat)
|
|
{
|
|
if (cpu_cur_status & CPU_STATUS_SMM)
|
|
fatal("opWRSHR_a32\n");
|
|
else
|
|
x86illegal();
|
|
|
|
return 1;
|
|
}
|