This commit is contained in:
RichardG867
2020-04-26 13:26:54 -03:00
75 changed files with 4187 additions and 7680 deletions

View File

@@ -32,6 +32,7 @@
#include <86box/keyboard.h>
#include <86box/nvr.h>
#include <86box/pit.h>
#include <86box/apm.h>
#include <86box/acpi.h>
@@ -77,8 +78,28 @@ acpi_update_irq(void *priv)
}
static void
acpi_raise_smi(void *priv)
{
acpi_t *dev = (acpi_t *) priv;
if (dev->vendor == VEN_VIA) {
if ((dev->regs.glbctl & 0x01) && (!dev->regs.smi_lock || !dev->regs.smi_active)) {
smi_line = 1;
dev->regs.smi_active = 1;
}
} else {
if (dev->regs.glbctl & 0x01) {
smi_line = 1;
/* Clear bit 16 of GLBCTL. */
dev->regs.glbctl &= ~0x00010000;
}
}
}
static uint32_t
acpi_reg_read_common(int size, uint16_t addr, void *p)
acpi_reg_read_intel(int size, uint16_t addr, void *p)
{
acpi_t *dev = (acpi_t *) p;
uint32_t ret = 0x00000000;
@@ -117,16 +138,6 @@ acpi_reg_read_common(int size, uint16_t addr, void *p)
/* PCNTRL - Processor Control Register (IO) */
ret = (dev->regs.pcntrl >> shift32) & 0xff;
break;
case 0x14:
/* PLVL2 - Processor Level 2 Register (IO) */
if (size == 1)
ret = dev->regs.plvl2;
break;
case 0x15:
/* PLVL3 - Processor Level 3 Register (IO) */
if (size == 1)
ret = dev->regs.plvl3;
break;
case 0x18: case 0x19:
/* GLBSTS - Global Status Register (IO) */
ret = (dev->regs.glbsts >> shift16) & 0xff;
@@ -173,8 +184,118 @@ acpi_reg_read_common(int size, uint16_t addr, void *p)
}
static uint32_t
acpi_reg_read_via(int size, uint16_t addr, void *p)
{
acpi_t *dev = (acpi_t *) p;
uint32_t ret = 0x00000000;
int shift16, shift32;
addr &= 0xff;
shift16 = (addr & 1) << 3;
shift32 = (addr & 3) << 3;
switch (addr) {
case 0x00: case 0x01:
/* PMSTS - Power Management Status Register (IO) */
ret = (dev->regs.pmsts >> shift16) & 0xff;
break;
case 0x02: case 0x03:
/* PMEN - Power Management Resume Enable Register (IO) */
ret = (dev->regs.pmen >> shift16) & 0xff;
break;
case 0x04: case 0x05:
/* PMCNTRL - Power Management Control Register (IO) */
ret = (dev->regs.pmcntrl >> shift16) & 0xff;
break;
case 0x08: case 0x09: case 0x0a: case 0x0b:
/* PMTMR - Power Management Timer Register (IO) */
ret = (dev->regs.timer_val >> shift32) & 0xff;
break;
case 0x10: case 0x11: case 0x12: case 0x13:
/* PCNTRL - Processor Control Register (IO) */
ret = (dev->regs.pcntrl >> shift32) & 0xff;
break;
case 0x20: case 0x21:
/* GPSTS - General Purpose Status Register (IO) */
ret = (dev->regs.gpsts >> shift16) & 0xff;
break;
case 0x22: case 0x23:
/* General Purpose SCI Enable */
ret = (dev->regs.gpscien >> shift16) & 0xff;
break;
case 0x24: case 0x25:
/* General Purpose SMI Enable */
ret = (dev->regs.gpsmien >> shift16) & 0xff;
break;
case 0x26: case 0x27:
/* Power Supply Control */
ret = (dev->regs.pscntrl >> shift16) & 0xff;
break;
case 0x28: case 0x29:
/* GLBSTS - Global Status Register (IO) */
ret = (dev->regs.glbsts >> shift16) & 0xff;
break;
case 0x2a: case 0x2b:
/* GLBEN - Global Enable Register (IO) */
ret = (dev->regs.glben >> shift16) & 0xff;
break;
case 0x2c: case 0x2d:
/* GLBCTL - Global Control Register (IO) */
ret = (dev->regs.glbctl >> shift16) & 0xff;
ret &= ~0x0110;
ret |= (dev->regs.smi_lock ? 0x10 : 0x00);
ret |= (dev->regs.smi_active ? 0x01 : 0x00);
break;
case 0x2f:
/* SMI Command */
if (size == 1)
ret = dev->regs.smicmd & 0xff;
break;
case 0x30: case 0x31: case 0x32: case 0x33:
/* Primary Activity Detect Status */
ret = (dev->regs.padsts >> shift32) & 0xff;
break;
case 0x34: case 0x35: case 0x36: case 0x37:
/* Primary Activity Detect Enable */
ret = (dev->regs.paden >> shift32) & 0xff;
break;
case 0x38: case 0x39: case 0x3a: case 0x3b:
/* GP Timer Reload Enable */
ret = (dev->regs.gptren >> shift32) & 0xff;
break;
case 0x40:
/* GPIO Direction Control */
if (size == 1)
ret = dev->regs.gpio_dir & 0xff;
break;
case 0x42:
/* GPIO port Output Value */
if (size == 1)
ret = dev->regs.gpio_val & 0xff;
break;
case 0x44:
/* GPIO port Output Value */
if (size == 1)
ret = dev->regs.extsmi_val & 0xff;
break;
case 0x46: case 0x47:
/* GPO Port Output Value */
ret = (dev->regs.gpo_val >> shift16) & 0xff;
break;
case 0x48: case 0x49:
/* GPO Port Input Value */
ret = (dev->regs.gpi_val >> shift16) & 0xff;
break;
}
acpi_log("(%i) ACPI Read (%i) %02X: %02X\n", in_smm, size, addr, ret);
return ret;
}
static void
acpi_reg_write_common(int size, uint16_t addr, uint8_t val, void *p)
acpi_reg_write_intel(int size, uint16_t addr, uint8_t val, void *p)
{
acpi_t *dev = (acpi_t *) p;
int shift16, shift32;
@@ -199,6 +320,12 @@ acpi_reg_write_common(int size, uint16_t addr, uint8_t val, void *p)
case 0x04: case 0x05:
/* PMCNTRL - Power Management Control Register (IO) */
dev->regs.pmcntrl = ((dev->regs.pmcntrl & ~(0xff << shift16)) | (val << shift16)) & 0x3c07;
/* Setting GBL_RLS also sets BIOS_STS and generates SMI. */
if ((addr == 0x04) && (dev->regs.pmcntrl & 0x0004)) {
dev->regs.glbsts |= 0x01;
if (dev->regs.glben & 0x02)
acpi_raise_smi(dev);
}
if (dev->regs.pmcntrl & 0x2000) {
sus_typ = (dev->regs.pmcntrl >> 10) & 7;
switch (sus_typ) {
@@ -240,16 +367,6 @@ acpi_reg_write_common(int size, uint16_t addr, uint8_t val, void *p)
/* PCNTRL - Processor Control Register (IO) */
dev->regs.pcntrl = ((dev->regs.pcntrl & ~(0xff << shift32)) | (val << shift32)) & 0x00023e1e;
break;
case 0x14:
/* PLVL2 - Processor Level 2 Register (IO) */
if (size == 1)
dev->regs.plvl2 = val;
break;
case 0x15:
/* PLVL3 - Processor Level 3 Register (IO) */
if (size == 1)
dev->regs.plvl3 = val;
break;
case 0x18: case 0x19:
/* GLBSTS - Global Status Register (IO) */
dev->regs.glbsts &= ~((val << shift16) & 0x0df7);
@@ -264,8 +381,13 @@ acpi_reg_write_common(int size, uint16_t addr, uint8_t val, void *p)
break;
case 0x28: case 0x29: case 0x2a: case 0x2b:
/* GLBCTL - Global Control Register (IO) */
// dev->regs.glbctl = ((dev->regs.glbctl & ~(0xff << shift32)) | (val << shift32)) & 0x0701ff07;
dev->regs.glbctl = ((dev->regs.glbctl & ~(0xff << shift32)) | (val << shift32)) & 0x0700ff07;
dev->regs.glbctl = ((dev->regs.glbctl & ~(0xff << shift32)) | (val << shift32)) & 0x0701ff07;
/* Setting BIOS_RLS also sets GBL_STS and generates SMI. */
if (dev->regs.glbctl & 0x00000002) {
dev->regs.pmsts |= 0x20;
if (dev->regs.pmen & 0x20)
acpi_update_irq(dev);
}
break;
case 0x2c: case 0x2d: case 0x2e: case 0x2f:
/* DEVCTL - Device Control Register (IO) */
@@ -280,6 +402,180 @@ acpi_reg_write_common(int size, uint16_t addr, uint8_t val, void *p)
}
static void
acpi_reg_write_via(int size, uint16_t addr, uint8_t val, void *p)
{
acpi_t *dev = (acpi_t *) p;
int shift16, shift32;
int sus_typ;
addr &= 0xff;
acpi_log("(%i) ACPI Write (%i) %02X: %02X\n", in_smm, size, addr, val);
shift16 = (addr & 1) << 3;
shift32 = (addr & 3) << 3;
switch (addr) {
case 0x00: case 0x01:
/* PMSTS - Power Management Status Register (IO) */
dev->regs.pmsts &= ~((val << shift16) & 0x8d31);
acpi_update_irq(dev);
if ((addr == 0x00) && !(dev->regs.pmsts & 0x20))
dev->regs.glbctl &= ~0x0002;
break;
case 0x02: case 0x03:
/* PMEN - Power Management Resume Enable Register (IO) */
dev->regs.pmen = ((dev->regs.pmen & ~(0xff << shift16)) | (val << shift16)) & 0x0521;
acpi_update_irq(dev);
break;
case 0x04: case 0x05:
/* PMCNTRL - Power Management Control Register (IO) */
dev->regs.pmcntrl = ((dev->regs.pmcntrl & ~(0xff << shift16)) | (val << shift16)) & 0x3c07;
/* Setting GBL_RLS also sets BIOS_STS and generates SMI. */
if ((addr == 0x04) && (dev->regs.pmcntrl & 0x0004)) {
dev->regs.glbsts |= 0x20;
if (dev->regs.glben & 0x20)
acpi_raise_smi(dev);
}
if (dev->regs.pmcntrl & 0x2000) {
sus_typ = (dev->regs.pmcntrl >> 10) & 7;
switch (sus_typ) {
case 0:
/* Soft power off. */
exit(-1);
break;
case 1:
/* Suspend to RAM. */
nvr_reg_write(0x000f, 0xff, dev->nvr);
/* Do a hard reset. */
device_reset_all_pci();
cpu_alt_reset = 0;
pci_reset();
keyboard_at_reset();
mem_a20_alt = 0;
mem_a20_recalc();
flushmmucache();
resetx86();
break;
}
}
break;
case 0x10: case 0x11: case 0x12: case 0x13:
/* PCNTRL - Processor Control Register (IO) */
dev->regs.pcntrl = ((dev->regs.pcntrl & ~(0xff << shift32)) | (val << shift32)) & 0x0000001e;
break;
case 0x20: case 0x21:
/* GPSTS - General Purpose Status Register (IO) */
dev->regs.gpsts &= ~((val << shift16) & 0x03ff);
break;
case 0x22: case 0x23:
/* General Purpose SCI Enable */
dev->regs.gpscien = ((dev->regs.gpscien & ~(0xff << shift16)) | (val << shift16)) & 0x03ff;
break;
case 0x24: case 0x25:
/* General Purpose SMI Enable */
dev->regs.gpsmien = ((dev->regs.gpsmien & ~(0xff << shift16)) | (val << shift16)) & 0x03ff;
break;
case 0x26: case 0x27:
/* Power Supply Control */
dev->regs.pscntrl = ((dev->regs.pscntrl & ~(0xff << shift16)) | (val << shift16)) & 0x0701;
break;
case 0x28: case 0x29:
/* GLBSTS - Global Status Register (IO) */
dev->regs.glbsts &= ~((val << shift16) & 0x007f);
break;
case 0x2a: case 0x2b:
/* GLBEN - Global Enable Register (IO) */
dev->regs.glben = ((dev->regs.glben & ~(0xff << shift16)) | (val << shift16)) & 0x007f;
break;
case 0x2c:
/* GLBCTL - Global Control Register (IO) */
dev->regs.glbctl = (dev->regs.glbctl & ~0xff) | (val & 0xff);
dev->regs.smi_lock = !!(dev->regs.glbctl & 0x0010);
/* Setting BIOS_RLS also sets GBL_STS and generates SMI. */
if (dev->regs.glbctl & 0x0002) {
dev->regs.pmsts |= 0x20;
if (dev->regs.pmen & 0x20)
acpi_update_irq(dev);
}
break;
case 0x2d:
/* GLBCTL - Global Control Register (IO) */
dev->regs.glbctl &= ~((val << 8) & 0x0100);
if (val & 0x01)
dev->regs.smi_active = 0;
break;
case 0x2f:
/* SMI Command */
if (size == 1) {
dev->regs.smicmd = val & 0xff;
dev->regs.glbsts |= 0x40;
if (dev->regs.glben & 0x40)
acpi_raise_smi(dev);
}
break;
case 0x30: case 0x31: case 0x32: case 0x33:
/* Primary Activity Detect Status */
dev->regs.padsts &= ~((val << shift32) & 0x000000fd);
break;
case 0x34: case 0x35: case 0x36: case 0x37:
/* Primary Activity Detect Enable */
dev->regs.paden = ((dev->regs.paden & ~(0xff << shift32)) | (val << shift32)) & 0x000000fd;
break;
case 0x38: case 0x39: case 0x3a: case 0x3b:
/* GP Timer Reload Enable */
dev->regs.gptren = ((dev->regs.gptren & ~(0xff << shift32)) | (val << shift32)) & 0x000000d9;
break;
case 0x40:
/* GPIO Direction Control */
if (size == 1)
dev->regs.gpio_dir = val & 0xff;
break;
case 0x42:
/* GPIO port Output Value */
if (size == 1)
dev->regs.gpio_val = val & 0xff;
break;
case 0x46: case 0x47:
/* GPO Port Output Value */
dev->regs.gpo_val = ((dev->regs.gpo_val & ~(0xff << shift16)) | (val << shift16)) & 0xffff;
break;
}
}
static uint32_t
acpi_reg_read_common(int size, uint16_t addr, void *p)
{
acpi_t *dev = (acpi_t *) p;
uint8_t ret = 0xff;
if (dev->vendor == VEN_VIA)
ret = acpi_reg_read_via(size, addr, p);
else
ret = acpi_reg_read_intel(size, addr, p);
return ret;
}
static void
acpi_reg_write_common(int size, uint16_t addr, uint8_t val, void *p)
{
acpi_t *dev = (acpi_t *) p;
if (dev->vendor == VEN_VIA)
acpi_reg_write_via(size, addr, val, p);
else
acpi_reg_write_intel(size, addr, val, p);
}
static uint32_t
acpi_reg_readl(uint16_t addr, void *p)
{
@@ -440,6 +736,46 @@ acpi_set_nvr(acpi_t *dev, nvr_t *nvr)
}
static void
acpi_apm_out(uint16_t port, uint8_t val, void *p)
{
acpi_t *dev = (acpi_t *) p;
acpi_log("[%04X:%08X] APM write: %04X = %02X (BX = %04X, CX = %04X)\n", CS, cpu_state.pc, port, val, BX, CX);
port &= 0x0001;
if (port == 0x0000) {
dev->apm->cmd = val;
if (dev->apm->do_smi) {
if (dev->vendor == VEN_INTEL)
dev->regs.glbsts |= 0x20;
acpi_raise_smi(dev);
}
} else
dev->apm->stat = val;
}
static uint8_t
acpi_apm_in(uint16_t port, void *p)
{
acpi_t *dev = (acpi_t *) p;
uint8_t ret = 0xff;
port &= 0x0001;
if (port == 0x0000)
ret = dev->apm->cmd;
else
ret = dev->apm->stat;
acpi_log("[%04X:%08X] APM read: %04X = %02X\n", CS, cpu_state.pc, port, ret);
return ret;
}
static void
acpi_reset(void *priv)
{
@@ -482,6 +818,13 @@ acpi_init(const device_t *info)
if (dev == NULL) return(NULL);
memset(dev, 0x00, sizeof(acpi_t));
dev->vendor = info->local;
if (dev->vendor == VEN_INTEL) {
dev->apm = device_add(&apm_pci_acpi_device);
io_sethandler(0x00b2, 0x0002, acpi_apm_in, NULL, NULL, acpi_apm_out, NULL, NULL, dev);
}
timer_add(&dev->timer, acpi_timer_count, dev, 0);
timer_set_delay_u64(&dev->timer, ACPICONST);
@@ -489,11 +832,26 @@ acpi_init(const device_t *info)
}
const device_t acpi_device =
const device_t acpi_intel_device =
{
"ACPI",
"ACPI v1.0",
DEVICE_PCI,
0,
VEN_INTEL,
acpi_init,
acpi_close,
acpi_reset,
NULL,
acpi_speed_changed,
NULL,
NULL
};
const device_t acpi_via_device =
{
"ACPI v1.2",
DEVICE_PCI,
VEN_VIA,
acpi_init,
acpi_close,
acpi_reset,

View File

@@ -49,43 +49,55 @@ apm_log(const char *fmt, ...)
void
apm_set_do_smi(apm_t *apm, uint8_t do_smi)
apm_set_do_smi(apm_t *dev, uint8_t do_smi)
{
apm->do_smi = do_smi;
dev->do_smi = do_smi;
}
static void
apm_out(uint16_t port, uint8_t val, void *p)
{
apm_t *apm = (apm_t *) p;
apm_t *dev = (apm_t *) p;
apm_log("[%04X:%08X] APM write: %04X = %02X (BX = %04X, CX = %04X)\n", CS, cpu_state.pc, port, val, BX, CX);
port &= 0x0001;
if (port == 0x0000) {
apm->cmd = val;
if (apm->do_smi)
dev->cmd = val;
if (dev->do_smi)
smi_line = 1;
} else
apm->stat = val;
dev->stat = val;
}
static uint8_t
apm_in(uint16_t port, void *p)
{
apm_t *apm = (apm_t *) p;
apm_log("[%04X:%08X] APM read: %04X = FF\n", CS, cpu_state.pc, port);
apm_t *dev = (apm_t *) p;
uint8_t ret = 0xff;
port &= 0x0001;
if (port == 0x0000)
return apm->cmd;
ret = dev->cmd;
else
return apm->stat;
ret = dev->stat;
apm_log("[%04X:%08X] APM read: %04X = %02X\n", CS, cpu_state.pc, port, ret);
return ret;
}
static void
apm_reset(void *p)
{
apm_t *dev = (apm_t *)p;
dev->cmd = dev->stat = 0x00;
}
@@ -101,12 +113,13 @@ apm_close(void *p)
static void
*apm_init(const device_t *info)
{
apm_t *apm = (apm_t *) malloc(sizeof(apm_t));
memset(apm, 0, sizeof(apm_t));
apm_t *dev = (apm_t *) malloc(sizeof(apm_t));
memset(dev, 0, sizeof(apm_t));
io_sethandler(0x00b2, 0x0002, apm_in, NULL, NULL, apm_out, NULL, NULL, apm);
if (info->local == 0)
io_sethandler(0x00b2, 0x0002, apm_in, NULL, NULL, apm_out, NULL, NULL, dev);
return apm;
return dev;
}
@@ -123,3 +136,33 @@ const device_t apm_device =
NULL,
NULL
};
const device_t apm_pci_device =
{
"Advanced Power Management (PCI)",
DEVICE_PCI,
0,
apm_init,
apm_close,
apm_reset,
NULL,
NULL,
NULL,
NULL
};
const device_t apm_pci_acpi_device =
{
"Advanced Power Management (PCI)",
DEVICE_PCI,
1,
apm_init,
apm_close,
apm_reset,
NULL,
NULL,
NULL,
NULL
};

View File

@@ -957,7 +957,12 @@ load_hard_disks(void)
wcsncpy(hdd[c].fn, &wp[wcslen(usr_path)], sizeof_w(hdd[c].fn));
} else
#endif
wcsncpy(hdd[c].fn, wp, sizeof_w(hdd[c].fn));
if (plat_path_abs(wp)) {
wcsncpy(hdd[c].fn, wp, sizeof_w(hdd[c].fn));
} else {
wcsncpy(hdd[c].fn, usr_path, sizeof_w(hdd[c].fn));
wcsncat(hdd[c].fn, wp, sizeof_w(hdd[c].fn)-wcslen(usr_path));
}
/* If disk is empty or invalid, mark it for deletion. */
if (! hdd_is_valid(c)) {
@@ -1832,7 +1837,10 @@ save_hard_disks(void)
sprintf(temp, "hdd_%02i_fn", c+1);
if (hdd_is_valid(c) && (wcslen(hdd[c].fn) != 0))
config_set_wstring(cat, temp, hdd[c].fn);
if (!wcsnicmp(hdd[c].fn, usr_path, wcslen(usr_path)))
config_set_wstring(cat, temp, &hdd[c].fn[wcslen(usr_path)]);
else
config_set_wstring(cat, temp, hdd[c].fn);
else
config_delete_var(cat, temp);
}

File diff suppressed because it is too large Load Diff

View File

@@ -548,8 +548,8 @@ static int opcode_modrm[256] =
};
int opcode_0f_modrm[256] =
{
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*00*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*10*/
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, /*00*/
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/
1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*20*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*30*/

View File

@@ -1660,8 +1660,8 @@ static int opcode_modrm[256] =
};
int opcode_0f_modrm[256] =
{
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*00*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*10*/
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, /*00*/
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/
1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*20*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*30*/
@@ -1680,7 +1680,7 @@ int opcode_0f_modrm[256] =
0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*e0*/
0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0 /*f0*/
};
void codegen_debug()
{
}

View File

@@ -1177,7 +1177,7 @@ const OpFn OP_TABLE(pentiumpro_0f)[1024] =
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opNOP, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16,
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
@@ -1199,7 +1199,7 @@ const OpFn OP_TABLE(pentiumpro_0f)[1024] =
/*32-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opNOP, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16,
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
@@ -1221,7 +1221,7 @@ const OpFn OP_TABLE(pentiumpro_0f)[1024] =
/*16-bit data, 32-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opNOP, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32,
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
@@ -1243,7 +1243,7 @@ const OpFn OP_TABLE(pentiumpro_0f)[1024] =
/*32-bit data, 32-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opNOP, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32,
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
@@ -1268,7 +1268,7 @@ const OpFn OP_TABLE(pentium2_0f)[1024] =
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opNOP, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16,
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
@@ -1290,7 +1290,7 @@ const OpFn OP_TABLE(pentium2_0f)[1024] =
/*32-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opNOP, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16,
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
@@ -1312,7 +1312,7 @@ const OpFn OP_TABLE(pentium2_0f)[1024] =
/*16-bit data, 32-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opNOP, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32,
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
@@ -1334,7 +1334,7 @@ const OpFn OP_TABLE(pentium2_0f)[1024] =
/*32-bit data, 32-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opNOP, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32,
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
@@ -1359,7 +1359,7 @@ const OpFn OP_TABLE(pentium2d_0f)[1024] =
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opNOP, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16,
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
@@ -1381,7 +1381,7 @@ const OpFn OP_TABLE(pentium2d_0f)[1024] =
/*32-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opNOP, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16, opHINT_NOP_a16,
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
@@ -1403,7 +1403,7 @@ const OpFn OP_TABLE(pentium2d_0f)[1024] =
/*16-bit data, 32-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opNOP, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32,
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
@@ -1425,7 +1425,7 @@ const OpFn OP_TABLE(pentium2d_0f)[1024] =
/*32-bit data, 32-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opNOP, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32, opHINT_NOP_a32,
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,

View File

@@ -2779,14 +2779,20 @@ void cpu_RDMSR()
if (machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_PENTIUMPRO) goto i686_invalid_rdmsr;
EAX &= 0xFFFF0000;
EAX |= cs_msr;
EDX = 0x00000000;
break;
case 0x175:
if (machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_PENTIUMPRO) goto i686_invalid_rdmsr;
EAX = esp_msr;
EDX = 0x00000000;
break;
case 0x176:
if (machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_PENTIUMPRO) goto i686_invalid_rdmsr;
EAX = eip_msr;
EDX = 0x00000000;
break;
case 0x179:
EAX = EDX = 0x00000000;
break;
case 0x186:
EAX = ecx186_msr & 0xffffffff;
@@ -3212,6 +3218,8 @@ void cpu_WRMSR()
if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr;
eip_msr = EAX;
break;
case 0x179:
break;
case 0x186:
ecx186_msr = EAX | ((uint64_t)EDX << 32);
break;

View File

@@ -132,83 +132,96 @@ static int opCMPXCHG8B_a32(uint32_t fetchdat)
return 0;
}
/* dest = eab, src = r8 */
static int opXADD_b_a16(uint32_t fetchdat)
{
uint8_t temp, temp2;
uint8_t temp;
uint8_t src, dest;
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteab(); if (cpu_state.abrt) return 1;
temp2 = getr8(cpu_reg);
setr8(cpu_reg, temp);
seteab(temp + temp2); if (cpu_state.abrt) return 1;
setadd8(temp, temp2);
src = getr8(cpu_reg);
dest = geteab(); if (cpu_state.abrt) return 1;
temp = src + dest;
seteab(temp); if (cpu_state.abrt) return 1;
setadd8(src, dest);
setr8(cpu_reg, dest);
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
return 0;
}
static int opXADD_b_a32(uint32_t fetchdat)
{
uint8_t temp, temp2;
uint8_t temp;
uint8_t src, dest;
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteab(); if (cpu_state.abrt) return 1;
temp2 = getr8(cpu_reg);
setr8(cpu_reg, temp);
seteab(temp + temp2); if (cpu_state.abrt) return 1;
setadd8(temp, temp2);
src = getr8(cpu_reg);
dest = geteab(); if (cpu_state.abrt) return 1;
temp = src + dest;
seteab(temp); if (cpu_state.abrt) return 1;
setadd8(src, dest);
setr8(cpu_reg, dest);
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
return 0;
}
static int opXADD_w_a16(uint32_t fetchdat)
{
uint16_t temp, temp2;
uint16_t temp;
uint16_t src, dest;
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
temp2 = cpu_state.regs[cpu_reg].w;
cpu_state.regs[cpu_reg].w = temp;
seteaw(temp + temp2); if (cpu_state.abrt) return 1;
setadd16(temp, temp2);
src = cpu_state.regs[cpu_reg].w;
dest = geteaw(); if (cpu_state.abrt) return 1;
temp = src + dest;
seteaw(temp); if (cpu_state.abrt) return 1;
setadd16(src, dest);
cpu_state.regs[cpu_reg].w = dest;
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
return 0;
}
static int opXADD_w_a32(uint32_t fetchdat)
{
uint16_t temp, temp2;
uint16_t temp;
uint16_t src, dest;
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
temp2 = cpu_state.regs[cpu_reg].w;
cpu_state.regs[cpu_reg].w = temp;
seteaw(temp + temp2); if (cpu_state.abrt) return 1;
setadd16(temp, temp2);
src = cpu_state.regs[cpu_reg].w;
dest = geteaw(); if (cpu_state.abrt) return 1;
temp = src + dest;
seteaw(temp); if (cpu_state.abrt) return 1;
setadd16(src, dest);
cpu_state.regs[cpu_reg].w = dest;
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
return 0;
}
static int opXADD_l_a16(uint32_t fetchdat)
{
uint32_t temp, temp2;
uint32_t temp;
uint32_t src, dest;
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal(); if (cpu_state.abrt) return 1;
temp2 = cpu_state.regs[cpu_reg].l;
cpu_state.regs[cpu_reg].l = temp;
seteal(temp + temp2); if (cpu_state.abrt) return 1;
setadd32(temp, temp2);
src = cpu_state.regs[cpu_reg].l;
dest = geteal(); if (cpu_state.abrt) return 1;
temp = src + dest;
seteal(temp); if (cpu_state.abrt) return 1;
setadd32(src, dest);
cpu_state.regs[cpu_reg].l = dest;
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
return 0;
}
static int opXADD_l_a32(uint32_t fetchdat)
{
uint32_t temp, temp2;
uint32_t temp;
uint32_t src, dest;
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal(); if (cpu_state.abrt) return 1;
temp2 = cpu_state.regs[cpu_reg].l;
cpu_state.regs[cpu_reg].l = temp;
seteal(temp + temp2); if (cpu_state.abrt) return 1;
setadd32(temp, temp2);
src = cpu_state.regs[cpu_reg].l;
dest = geteal(); if (cpu_state.abrt) return 1;
temp = src + dest;
seteal(temp); if (cpu_state.abrt) return 1;
setadd32(src, dest);
cpu_state.regs[cpu_reg].l = dest;
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4);
return 0;
}

View File

@@ -45,377 +45,216 @@ opSYSEXIT(uint32_t fetchdat)
}
static int
fx_save_stor_common(uint32_t fetchdat, int bits)
{
uint8_t fxinst = 0;
uint16_t twd = x87_gettag();
uint32_t old_eaaddr = 0;
uint8_t ftwb = 0;
uint16_t rec_ftw = 0;
uint16_t fpus = 0;
uint64_t *p;
if (CPUID < 0x650)
return ILLEGAL(fetchdat);
FP_ENTER();
if (bits == 32) {
fetch_ea_32(fetchdat);
} else {
fetch_ea_16(fetchdat);
}
if (cpu_state.eaaddr & 0xf) {
x386_dynarec_log("Effective address %08X not on 16-byte boundary\n", cpu_state.eaaddr);
x86gpf(NULL, 0);
return cpu_state.abrt;
}
fxinst = (rmdat >> 3) & 7;
if ((fxinst > 1) || (cpu_mod == 3)) {
x86illegal();
return cpu_state.abrt;
}
FP_ENTER();
old_eaaddr = cpu_state.eaaddr;
if (fxinst == 1) {
/* FXRSTOR */
cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr);
fpus = readmemw(easeg, cpu_state.eaaddr + 2);
cpu_state.npxc = (cpu_state.npxc & ~FPU_CW_Reserved_Bits) | 0x0040;
codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3);
cpu_state.TOP = (fpus >> 11) & 7;
cpu_state.npxs &= fpus & ~0x3800;
x87_pc_off = readmeml(easeg, cpu_state.eaaddr+8);
x87_pc_seg = readmemw(easeg, cpu_state.eaaddr+12);
ftwb = readmemb(easeg, cpu_state.eaaddr + 4);
if (ftwb & 0x01) rec_ftw |= 0x0003;
if (ftwb & 0x02) rec_ftw |= 0x000C;
if (ftwb & 0x04) rec_ftw |= 0x0030;
if (ftwb & 0x08) rec_ftw |= 0x00C0;
if (ftwb & 0x10) rec_ftw |= 0x0300;
if (ftwb & 0x20) rec_ftw |= 0x0C00;
if (ftwb & 0x40) rec_ftw |= 0x3000;
if (ftwb & 0x80) rec_ftw |= 0xC000;
x87_op_off = readmeml(easeg, cpu_state.eaaddr+16);
x87_op_off |= (readmemw(easeg, cpu_state.eaaddr + 6) >> 12) << 16;
x87_op_seg = readmemw(easeg, cpu_state.eaaddr+20);
cpu_state.eaaddr = old_eaaddr + 32;
x87_ldmmx(&(cpu_state.MM[0]), &(cpu_state.MM_w4[0])); x87_ld_frstor(0);
cpu_state.eaaddr = old_eaaddr + 48;
x87_ldmmx(&(cpu_state.MM[1]), &(cpu_state.MM_w4[1])); x87_ld_frstor(1);
cpu_state.eaaddr = old_eaaddr + 64;
x87_ldmmx(&(cpu_state.MM[2]), &(cpu_state.MM_w4[2])); x87_ld_frstor(2);
cpu_state.eaaddr = old_eaaddr + 80;
x87_ldmmx(&(cpu_state.MM[3]), &(cpu_state.MM_w4[3])); x87_ld_frstor(3);
cpu_state.eaaddr = old_eaaddr + 96;
x87_ldmmx(&(cpu_state.MM[4]), &(cpu_state.MM_w4[4])); x87_ld_frstor(4);
cpu_state.eaaddr = old_eaaddr + 112;
x87_ldmmx(&(cpu_state.MM[5]), &(cpu_state.MM_w4[5])); x87_ld_frstor(5);
cpu_state.eaaddr = old_eaaddr + 128;
x87_ldmmx(&(cpu_state.MM[6]), &(cpu_state.MM_w4[6])); x87_ld_frstor(6);
cpu_state.eaaddr = old_eaaddr + 144;
x87_ldmmx(&(cpu_state.MM[7]), &(cpu_state.MM_w4[7])); x87_ld_frstor(7);
cpu_state.ismmx = 0;
/*Horrible hack, but as 86Box doesn't keep the FPU stack in 80-bit precision at all times
something like this is needed*/
p = (uint64_t *) cpu_state.tag;
#ifdef USE_NEW_DYNAREC
if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff &&
cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff &&
!cpu_state.TOP && (*p == 0x0101010101010101ull))
#else
if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff &&
cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff &&
!cpu_state.TOP && !(*p))
#endif
cpu_state.ismmx = 1;
x87_settag(rec_ftw);
CLOCK_CYCLES((cr0 & 1) ? 34 : 44);
if (cpu_state.abrt)
x386_dynarec_log("FXRSTOR: abrt != 0\n");
} else {
/* FXSAVE */
if ((twd & 0x0003) == 0x0003) ftwb |= 0x01;
if ((twd & 0x000C) == 0x000C) ftwb |= 0x02;
if ((twd & 0x0030) == 0x0030) ftwb |= 0x04;
if ((twd & 0x00C0) == 0x00C0) ftwb |= 0x08;
if ((twd & 0x0300) == 0x0300) ftwb |= 0x10;
if ((twd & 0x0C00) == 0x0C00) ftwb |= 0x20;
if ((twd & 0x3000) == 0x3000) ftwb |= 0x40;
if ((twd & 0xC000) == 0xC000) ftwb |= 0x80;
writememw(easeg,cpu_state.eaaddr,cpu_state.npxc);
writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs);
writememb(easeg,cpu_state.eaaddr+4,ftwb);
writememw(easeg,cpu_state.eaaddr+6,(x87_op_off>>16)<<12);
writememl(easeg,cpu_state.eaaddr+8,x87_pc_off);
writememw(easeg,cpu_state.eaaddr+12,x87_pc_seg);
writememl(easeg,cpu_state.eaaddr+16,x87_op_off);
writememw(easeg,cpu_state.eaaddr+20,x87_op_seg);
cpu_state.eaaddr = old_eaaddr + 32;
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[0]) : x87_st_fsave(0);
cpu_state.eaaddr = old_eaaddr + 48;
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[1]) : x87_st_fsave(1);
cpu_state.eaaddr = old_eaaddr + 64;
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[2]) : x87_st_fsave(2);
cpu_state.eaaddr = old_eaaddr + 80;
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[3]) : x87_st_fsave(3);
cpu_state.eaaddr = old_eaaddr + 96;
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[4]) : x87_st_fsave(4);
cpu_state.eaaddr = old_eaaddr + 112;
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[5]) : x87_st_fsave(5);
cpu_state.eaaddr = old_eaaddr + 128;
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[6]) : x87_st_fsave(6);
cpu_state.eaaddr = old_eaaddr + 144;
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[7]) : x87_st_fsave(7);
cpu_state.eaaddr = old_eaaddr;
cpu_state.npxc = 0x37F;
codegen_set_rounding_mode(X87_ROUNDING_NEAREST);
cpu_state.npxs = 0;
p = (uint64_t *)cpu_state.tag;
#ifdef USE_NEW_DYNAREC
*p = 0;
#else
*p = 0x0303030303030303ll;
#endif
cpu_state.TOP = 0;
cpu_state.ismmx = 0;
CLOCK_CYCLES((cr0 & 1) ? 56 : 67);
if (cpu_state.abrt)
x386_dynarec_log("FXSAVE: abrt != 0\n");
}
return cpu_state.abrt;
}
static int
opFXSAVESTOR_a16(uint32_t fetchdat)
{
uint8_t fxinst = 0;
uint16_t twd = x87_gettag();
uint16_t old_eaaddr = 0;
uint8_t ftwb = 0;
uint16_t rec_ftw = 0;
uint16_t fpus = 0;
uint64_t *p;
if (CPUID < 0x650) return ILLEGAL(fetchdat);
FP_ENTER();
fetch_ea_16(fetchdat);
if (cpu_state.eaaddr & 0xf)
{
x386_dynarec_log("Effective address %04X not on 16-byte boundary\n", cpu_state.eaaddr);
x86gpf(NULL, 0);
return cpu_state.abrt;
}
fxinst = (rmdat >> 3) & 7;
if ((fxinst > 1) || (cpu_mod == 3))
{
x86illegal();
return cpu_state.abrt;
}
FP_ENTER();
old_eaaddr = cpu_state.eaaddr;
if (fxinst == 1)
{
/* FXRSTOR */
cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr);
#ifdef USE_NEW_DYNAREC
codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3);
#endif
fpus = readmemw(easeg, cpu_state.eaaddr + 2);
cpu_state.npxc = (cpu_state.npxc & ~FPU_CW_Reserved_Bits) | 0x0040;
#ifdef USE_NEW_DYNAREC
codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3);
#endif
cpu_state.TOP = (fpus >> 11) & 7;
cpu_state.npxs &= fpus & ~0x3800;
/* foo = readmemw(easeg, cpu_state.eaaddr + 6) & 0x7FF; */
x87_pc_off = readmeml(easeg, cpu_state.eaaddr+8);
x87_pc_seg = readmemw(easeg, cpu_state.eaaddr+12);
/* if (cr0 & 1)
{
x87_pc_seg &= 0xFFFC;
x87_pc_seg |= ((cpu_state.seg_cs.access >> 5) & 3);
} */
ftwb = readmemb(easeg, cpu_state.eaaddr + 4);
if (ftwb & 0x01) rec_ftw |= 0x0003;
if (ftwb & 0x02) rec_ftw |= 0x000C;
if (ftwb & 0x04) rec_ftw |= 0x0030;
if (ftwb & 0x08) rec_ftw |= 0x00C0;
if (ftwb & 0x10) rec_ftw |= 0x0300;
if (ftwb & 0x20) rec_ftw |= 0x0C00;
if (ftwb & 0x40) rec_ftw |= 0x3000;
if (ftwb & 0x80) rec_ftw |= 0xC000;
x87_op_off = readmeml(easeg, cpu_state.eaaddr+16);
x87_op_off |= (readmemw(easeg, cpu_state.eaaddr + 6) >> 12) << 16;
x87_op_seg = readmemw(easeg, cpu_state.eaaddr+20);
/* if (cr0 & 1)
{
x87_op_seg &= 0xFFFC;
x87_op_seg |= ((_ds.access >> 5) & 3);
} */
cpu_state.eaaddr = old_eaaddr + 32;
x87_ldmmx(&(cpu_state.MM[0]), &(cpu_state.MM_w4[0])); x87_ld_frstor(0);
cpu_state.eaaddr = old_eaaddr + 48;
x87_ldmmx(&(cpu_state.MM[1]), &(cpu_state.MM_w4[1])); x87_ld_frstor(1);
cpu_state.eaaddr = old_eaaddr + 64;
x87_ldmmx(&(cpu_state.MM[2]), &(cpu_state.MM_w4[2])); x87_ld_frstor(2);
cpu_state.eaaddr = old_eaaddr + 80;
x87_ldmmx(&(cpu_state.MM[3]), &(cpu_state.MM_w4[3])); x87_ld_frstor(3);
cpu_state.eaaddr = old_eaaddr + 96;
x87_ldmmx(&(cpu_state.MM[4]), &(cpu_state.MM_w4[4])); x87_ld_frstor(4);
cpu_state.eaaddr = old_eaaddr + 112;
x87_ldmmx(&(cpu_state.MM[5]), &(cpu_state.MM_w4[5])); x87_ld_frstor(5);
cpu_state.eaaddr = old_eaaddr + 128;
x87_ldmmx(&(cpu_state.MM[6]), &(cpu_state.MM_w4[6])); x87_ld_frstor(6);
cpu_state.eaaddr = old_eaaddr + 144;
x87_ldmmx(&(cpu_state.MM[7]), &(cpu_state.MM_w4[7])); x87_ld_frstor(7);
cpu_state.ismmx = 0;
/*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times
something like this is needed*/
p = (uint64_t *)cpu_state.tag;
if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff &&
cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff &&
!cpu_state.TOP && !(*p))
cpu_state.ismmx = 1;
x87_settag(rec_ftw);
CLOCK_CYCLES((cr0 & 1) ? 34 : 44);
if(cpu_state.abrt) x386_dynarec_log("FXRSTOR: abrt != 0\n");
}
else
{
/* FXSAVE */
if ((twd & 0x0003) == 0x0003) ftwb |= 0x01;
if ((twd & 0x000C) == 0x000C) ftwb |= 0x02;
if ((twd & 0x0030) == 0x0030) ftwb |= 0x04;
if ((twd & 0x00C0) == 0x00C0) ftwb |= 0x08;
if ((twd & 0x0300) == 0x0300) ftwb |= 0x10;
if ((twd & 0x0C00) == 0x0C00) ftwb |= 0x20;
if ((twd & 0x3000) == 0x3000) ftwb |= 0x40;
if ((twd & 0xC000) == 0xC000) ftwb |= 0x80;
writememw(easeg,cpu_state.eaaddr,cpu_state.npxc);
writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs);
writememb(easeg,cpu_state.eaaddr+4,ftwb);
writememw(easeg,cpu_state.eaaddr+6,(x87_op_off>>16)<<12);
writememl(easeg,cpu_state.eaaddr+8,x87_pc_off);
writememw(easeg,cpu_state.eaaddr+12,x87_pc_seg);
writememl(easeg,cpu_state.eaaddr+16,x87_op_off);
writememw(easeg,cpu_state.eaaddr+20,x87_op_seg);
cpu_state.eaaddr = old_eaaddr + 32;
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[0]) : x87_st_fsave(0);
cpu_state.eaaddr = old_eaaddr + 48;
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[1]) : x87_st_fsave(1);
cpu_state.eaaddr = old_eaaddr + 64;
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[2]) : x87_st_fsave(2);
cpu_state.eaaddr = old_eaaddr + 80;
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[3]) : x87_st_fsave(3);
cpu_state.eaaddr = old_eaaddr + 96;
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[4]) : x87_st_fsave(4);
cpu_state.eaaddr = old_eaaddr + 112;
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[5]) : x87_st_fsave(5);
cpu_state.eaaddr = old_eaaddr + 128;
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[6]) : x87_st_fsave(6);
cpu_state.eaaddr = old_eaaddr + 144;
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[7]) : x87_st_fsave(7);
cpu_state.eaaddr = old_eaaddr;
cpu_state.npxc = 0x37F;
#ifdef USE_NEW_DYNAREC
codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3);
#endif
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00);
cpu_state.npxs = 0;
p = (uint64_t *)cpu_state.tag;
*p = 0x0303030303030303ll;
cpu_state.TOP = 0;
cpu_state.ismmx = 0;
CLOCK_CYCLES((cr0 & 1) ? 56 : 67);
if(cpu_state.abrt) x386_dynarec_log("FXSAVE: abrt != 0\n");
}
return cpu_state.abrt;
return fx_save_stor_common(fetchdat, 16);
}
static int opFXSAVESTOR_a32(uint32_t fetchdat)
static int
opFXSAVESTOR_a32(uint32_t fetchdat)
{
uint8_t fxinst = 0;
uint16_t twd = x87_gettag();
uint32_t old_eaaddr = 0;
uint8_t ftwb = 0;
uint16_t rec_ftw = 0;
uint16_t fpus = 0;
uint64_t *p;
if (CPUID < 0x650) return ILLEGAL(fetchdat);
FP_ENTER();
fetch_ea_32(fetchdat);
if (cpu_state.eaaddr & 0xf)
{
x386_dynarec_log("Effective address %08X not on 16-byte boundary\n", cpu_state.eaaddr);
x86gpf(NULL, 0);
return cpu_state.abrt;
}
fxinst = (rmdat >> 3) & 7;
if ((fxinst > 1) || (cpu_mod == 3))
{
x86illegal();
return cpu_state.abrt;
}
FP_ENTER();
old_eaaddr = cpu_state.eaaddr;
if (fxinst == 1)
{
/* FXRSTOR */
cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr);
#ifdef USE_NEW_DYNAREC
codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3);
#endif
fpus = readmemw(easeg, cpu_state.eaaddr + 2);
cpu_state.npxc = (cpu_state.npxc & ~FPU_CW_Reserved_Bits) | 0x0040;
#ifdef USE_NEW_DYNAREC
codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3);
#endif
cpu_state.TOP = (fpus >> 11) & 7;
cpu_state.npxs &= fpus & ~0x3800;
/* foo = readmemw(easeg, cpu_state.eaaddr + 6) & 0x7FF; */
x87_pc_off = readmeml(easeg, cpu_state.eaaddr+8);
x87_pc_seg = readmemw(easeg, cpu_state.eaaddr+12);
/* if (cr0 & 1)
{
x87_pc_seg &= 0xFFFC;
x87_pc_seg |= ((cpu_state.seg_cs.access >> 5) & 3);
} */
ftwb = readmemb(easeg, cpu_state.eaaddr + 4);
if (ftwb & 0x01) rec_ftw |= 0x0003;
if (ftwb & 0x02) rec_ftw |= 0x000C;
if (ftwb & 0x04) rec_ftw |= 0x0030;
if (ftwb & 0x08) rec_ftw |= 0x00C0;
if (ftwb & 0x10) rec_ftw |= 0x0300;
if (ftwb & 0x20) rec_ftw |= 0x0C00;
if (ftwb & 0x40) rec_ftw |= 0x3000;
if (ftwb & 0x80) rec_ftw |= 0xC000;
x87_op_off = readmeml(easeg, cpu_state.eaaddr+16);
x87_op_off |= (readmemw(easeg, cpu_state.eaaddr + 6) >> 12) << 16;
x87_op_seg = readmemw(easeg, cpu_state.eaaddr+20);
/* if (cr0 & 1)
{
x87_op_seg &= 0xFFFC;
x87_op_seg |= ((_ds.access >> 5) & 3);
} */
cpu_state.eaaddr = old_eaaddr + 32;
x87_ldmmx(&(cpu_state.MM[0]), &(cpu_state.MM_w4[0])); x87_ld_frstor(0);
cpu_state.eaaddr = old_eaaddr + 48;
x87_ldmmx(&(cpu_state.MM[1]), &(cpu_state.MM_w4[1])); x87_ld_frstor(1);
cpu_state.eaaddr = old_eaaddr + 64;
x87_ldmmx(&(cpu_state.MM[2]), &(cpu_state.MM_w4[2])); x87_ld_frstor(2);
cpu_state.eaaddr = old_eaaddr + 80;
x87_ldmmx(&(cpu_state.MM[3]), &(cpu_state.MM_w4[3])); x87_ld_frstor(3);
cpu_state.eaaddr = old_eaaddr + 96;
x87_ldmmx(&(cpu_state.MM[4]), &(cpu_state.MM_w4[4])); x87_ld_frstor(4);
cpu_state.eaaddr = old_eaaddr + 112;
x87_ldmmx(&(cpu_state.MM[5]), &(cpu_state.MM_w4[5])); x87_ld_frstor(5);
cpu_state.eaaddr = old_eaaddr + 128;
x87_ldmmx(&(cpu_state.MM[6]), &(cpu_state.MM_w4[6])); x87_ld_frstor(6);
cpu_state.eaaddr = old_eaaddr + 144;
x87_ldmmx(&(cpu_state.MM[7]), &(cpu_state.MM_w4[7])); x87_ld_frstor(7);
cpu_state.ismmx = 0;
/*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times
something like this is needed*/
p = (uint64_t *)cpu_state.tag;
if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff &&
cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff &&
!cpu_state.TOP && !(*p))
cpu_state.ismmx = 1;
x87_settag(rec_ftw);
CLOCK_CYCLES((cr0 & 1) ? 34 : 44);
if(cpu_state.abrt) x386_dynarec_log("FXRSTOR: abrt != 0\n");
}
else
{
/* FXSAVE */
if ((twd & 0x0003) == 0x0003) ftwb |= 0x01;
if ((twd & 0x000C) == 0x000C) ftwb |= 0x02;
if ((twd & 0x0030) == 0x0030) ftwb |= 0x04;
if ((twd & 0x00C0) == 0x00C0) ftwb |= 0x08;
if ((twd & 0x0300) == 0x0300) ftwb |= 0x10;
if ((twd & 0x0C00) == 0x0C00) ftwb |= 0x20;
if ((twd & 0x3000) == 0x3000) ftwb |= 0x40;
if ((twd & 0xC000) == 0xC000) ftwb |= 0x80;
writememw(easeg,cpu_state.eaaddr,cpu_state.npxc);
writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs);
writememb(easeg,cpu_state.eaaddr+4,ftwb);
writememw(easeg,cpu_state.eaaddr+6,(x87_op_off>>16)<<12);
writememl(easeg,cpu_state.eaaddr+8,x87_pc_off);
writememw(easeg,cpu_state.eaaddr+12,x87_pc_seg);
writememl(easeg,cpu_state.eaaddr+16,x87_op_off);
writememw(easeg,cpu_state.eaaddr+20,x87_op_seg);
cpu_state.eaaddr = old_eaaddr + 32;
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[0]) : x87_st_fsave(0);
cpu_state.eaaddr = old_eaaddr + 48;
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[1]) : x87_st_fsave(1);
cpu_state.eaaddr = old_eaaddr + 64;
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[2]) : x87_st_fsave(2);
cpu_state.eaaddr = old_eaaddr + 80;
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[3]) : x87_st_fsave(3);
cpu_state.eaaddr = old_eaaddr + 96;
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[4]) : x87_st_fsave(4);
cpu_state.eaaddr = old_eaaddr + 112;
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[5]) : x87_st_fsave(5);
cpu_state.eaaddr = old_eaaddr + 128;
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[6]) : x87_st_fsave(6);
cpu_state.eaaddr = old_eaaddr + 144;
cpu_state.ismmx ? x87_stmmx(cpu_state.MM[7]) : x87_st_fsave(7);
cpu_state.eaaddr = old_eaaddr;
cpu_state.npxc = 0x37F;
#ifdef USE_NEW_DYNAREC
codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3);
#endif
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00);
cpu_state.npxs = 0;
p = (uint64_t *)cpu_state.tag;
*p = 0x0303030303030303ll;
cpu_state.TOP = 0;
cpu_state.ismmx = 0;
CLOCK_CYCLES((cr0 & 1) ? 56 : 67);
if(cpu_state.abrt) x386_dynarec_log("FXSAVE: abrt != 0\n");
}
return cpu_state.abrt;
return fx_save_stor_common(fetchdat, 32);
}
static int
opHINT_NOP_a16(uint32_t fetchdat)
{
fetch_ea_16(fetchdat);
CLOCK_CYCLES((is486) ? 1 : 3);
PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0);
return 0;
}
static int
opHINT_NOP_a32(uint32_t fetchdat)
{
fetch_ea_32(fetchdat);
CLOCK_CYCLES((is486) ? 1 : 3);
PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0);
return 0;
}

View File

@@ -42,6 +42,7 @@ fpu_log(const char *fmt, ...)
#define X87_TAG_INVALID 2
#define X87_TAG_EMPTY 3
#ifdef USE_NEW_DYNAREC
uint16_t x87_gettag()
{
uint16_t ret = 0;
@@ -78,6 +79,35 @@ void x87_settag(uint16_t new_tag)
cpu_state.tag[c] = TAG_VALID;
}
}
#else
uint16_t x87_gettag()
{
uint16_t ret = 0;
int c;
for (c = 0; c < 8; c++)
{
if (cpu_state.tag[c] & TAG_UINT64)
ret |= 2 << (c*2);
else
ret |= (cpu_state.tag[c] << (c*2));
}
return ret;
}
void x87_settag(uint16_t new_tag)
{
cpu_state.tag[0] = new_tag & 3;
cpu_state.tag[1] = (new_tag >> 2) & 3;
cpu_state.tag[2] = (new_tag >> 4) & 3;
cpu_state.tag[3] = (new_tag >> 6) & 3;
cpu_state.tag[4] = (new_tag >> 8) & 3;
cpu_state.tag[5] = (new_tag >> 10) & 3;
cpu_state.tag[6] = (new_tag >> 12) & 3;
cpu_state.tag[7] = (new_tag >> 14) & 3;
}
#endif
#ifdef ENABLE_808X_LOG

View File

@@ -30,10 +30,14 @@ void x87_settag(uint16_t new_tag);
#define TAG_EMPTY 0
#define TAG_VALID (1 << 0)
/*Hack for FPU copy. If set then MM[].q contains the 64-bit integer loaded by FILD*/
#ifdef USE_NEW_DYNAREC
#define TAG_UINT64 (1 << 7)
#else
#define TAG_UINT64 (1 << 2)
#endif
/*Old dynarec stuff.*/
#define TAG_NOT_UINT64 0x7f
#define TAG_NOT_UINT64 0xfb
#define X87_ROUNDING_NEAREST 0
#define X87_ROUNDING_DOWN 1

View File

@@ -98,7 +98,11 @@ static __inline void x87_push(double i)
cpu_state.TOP=(cpu_state.TOP-1)&7;
#endif
cpu_state.ST[cpu_state.TOP&7] = i;
#ifdef USE_NEW_DYNAREC
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
#else
cpu_state.tag[cpu_state.TOP&7] = (i == 0.0) ? TAG_VALID : 0;
#endif
}
static __inline void x87_push_u64(uint64_t i)
@@ -117,7 +121,11 @@ static __inline void x87_push_u64(uint64_t i)
cpu_state.TOP=(cpu_state.TOP-1)&7;
#endif
cpu_state.ST[cpu_state.TOP&7] = td.d;
#ifdef USE_NEW_DYNAREC
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
#else
cpu_state.tag[cpu_state.TOP&7] = (td.d == 0.0) ? TAG_VALID : 0;
#endif
}
static __inline double x87_pop()
@@ -127,6 +135,7 @@ static __inline double x87_pop()
#ifdef USE_NEW_DYNAREC
cpu_state.TOP++;
#else
cpu_state.tag[cpu_state.TOP&7] |= TAG_UINT64;
cpu_state.TOP=(cpu_state.TOP+1)&7;
#endif
return t;
@@ -263,13 +272,22 @@ static __inline void x87_ld_frstor(int reg)
cpu_state.MM[reg].q = readmemq(easeg, cpu_state.eaaddr);
cpu_state.MM_w4[reg] = readmemw(easeg, cpu_state.eaaddr + 8);
#ifdef USE_NEW_DYNAREC
if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] & TAG_UINT64))
#else
if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] == 2))
#endif
{
#ifndef USE_NEW_DYNAREC
cpu_state.tag[reg] = TAG_UINT64;
#endif
cpu_state.ST[reg] = (double)cpu_state.MM[reg].q;
}
else
{
#ifdef USE_NEW_DYNAREC
cpu_state.tag[reg] &= ~TAG_UINT64;
#endif
cpu_state.ST[reg] = x87_ld80();
}
}
@@ -426,6 +444,18 @@ typedef union
} while (0)
#endif
#ifdef USE_NEW_DYNAREC
# define FP_TAG_VALID cpu_state.tag[cpu_state.TOP&7] = TAG_VALID
# define FP_TAG_VALID_F cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID
# define FP_TAG_DEFAULT cpu_state.tag[cpu_state.TOP&7] = TAG_VALID | TAG_UINT64
# define FP_TAG_VALID_N cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID
#else
# define FP_TAG_VALID cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64
# define FP_TAG_VALID_F cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64
# define FP_TAG_DEFAULT cpu_state.tag[cpu_state.TOP] |= TAG_UINT64;
# define FP_TAG_VALID_N cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64
#endif
#include "x87_ops_arith.h"
#include "x87_ops_misc.h"
#include "x87_ops_loadstore.h"

View File

@@ -11,7 +11,7 @@ static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \
ST(0) += use_var; \
if ((cpu_state.npxc >> 10) & 3) \
fesetround(FE_TONEAREST); \
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \
FP_TAG_VALID; \
CLOCK_CYCLES(8); \
return 0; \
} \
@@ -48,7 +48,7 @@ static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
x87_div(ST(0), ST(0), use_var); \
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \
FP_TAG_VALID; \
CLOCK_CYCLES(73); \
return 0; \
} \
@@ -60,7 +60,7 @@ static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
x87_div(ST(0), use_var, ST(0)); \
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \
FP_TAG_VALID; \
CLOCK_CYCLES(73); \
return 0; \
} \
@@ -72,7 +72,7 @@ static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
ST(0) *= use_var; \
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \
FP_TAG_VALID; \
CLOCK_CYCLES(11); \
return 0; \
} \
@@ -84,7 +84,7 @@ static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
ST(0) -= use_var; \
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \
FP_TAG_VALID; \
CLOCK_CYCLES(8); \
return 0; \
} \
@@ -96,7 +96,7 @@ static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
ST(0) = use_var - ST(0); \
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \
FP_TAG_VALID; \
CLOCK_CYCLES(8); \
return 0; \
}
@@ -126,7 +126,7 @@ static int opFADD(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
ST(0) = ST(0) + ST(fetchdat & 7);
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
FP_TAG_VALID;
CLOCK_CYCLES(8);
return 0;
}
@@ -135,7 +135,7 @@ static int opFADDr(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
FP_TAG_VALID_F;
CLOCK_CYCLES(8);
return 0;
}
@@ -144,7 +144,7 @@ static int opFADDP(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
FP_TAG_VALID_F;
x87_pop();
CLOCK_CYCLES(8);
return 0;
@@ -233,7 +233,7 @@ static int opFDIV(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
x87_div(ST(0), ST(0), ST(fetchdat & 7));
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
FP_TAG_VALID;
CLOCK_CYCLES(73);
return 0;
}
@@ -242,7 +242,7 @@ static int opFDIVr(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0));
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
FP_TAG_VALID_F;
CLOCK_CYCLES(73);
return 0;
}
@@ -251,7 +251,7 @@ static int opFDIVP(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0));
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
FP_TAG_VALID_F;
x87_pop();
CLOCK_CYCLES(73);
return 0;
@@ -262,7 +262,7 @@ static int opFDIVR(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
x87_div(ST(0), ST(fetchdat&7), ST(0));
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
FP_TAG_VALID;
CLOCK_CYCLES(73);
return 0;
}
@@ -271,7 +271,7 @@ static int opFDIVRr(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7));
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
FP_TAG_VALID_F;
CLOCK_CYCLES(73);
return 0;
}
@@ -280,7 +280,7 @@ static int opFDIVRP(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7));
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
FP_TAG_VALID_F;
x87_pop();
CLOCK_CYCLES(73);
return 0;
@@ -291,7 +291,7 @@ static int opFMUL(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
ST(0) = ST(0) * ST(fetchdat & 7);
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
FP_TAG_VALID;
CLOCK_CYCLES(16);
return 0;
}
@@ -300,7 +300,7 @@ static int opFMULr(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
FP_TAG_VALID_F;
CLOCK_CYCLES(16);
return 0;
}
@@ -309,7 +309,7 @@ static int opFMULP(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
FP_TAG_VALID_F;
x87_pop();
CLOCK_CYCLES(16);
return 0;
@@ -320,7 +320,7 @@ static int opFSUB(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
ST(0) = ST(0) - ST(fetchdat & 7);
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
FP_TAG_VALID;
CLOCK_CYCLES(8);
return 0;
}
@@ -329,7 +329,7 @@ static int opFSUBr(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
FP_TAG_VALID_F;
CLOCK_CYCLES(8);
return 0;
}
@@ -338,7 +338,7 @@ static int opFSUBP(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
FP_TAG_VALID_F;
x87_pop();
CLOCK_CYCLES(8);
return 0;
@@ -349,7 +349,7 @@ static int opFSUBR(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
ST(0) = ST(fetchdat & 7) - ST(0);
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
FP_TAG_VALID;
CLOCK_CYCLES(8);
return 0;
}
@@ -358,7 +358,7 @@ static int opFSUBRr(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
FP_TAG_VALID_F;
CLOCK_CYCLES(8);
return 0;
}
@@ -367,7 +367,7 @@ static int opFSUBRP(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
FP_TAG_VALID_F;
x87_pop();
CLOCK_CYCLES(8);
return 0;

View File

@@ -15,7 +15,6 @@
* Copyright 2008-2019 Sarah Walker.
* Copyright 2016-2019 Miran Grca.
*/
static int opFILDiw_a16(uint32_t fetchdat)
{
int16_t temp;
@@ -102,7 +101,7 @@ static int opFILDiq_a16(uint32_t fetchdat)
temp64 = geteaq(); if (cpu_state.abrt) return 1;
x87_push((double)temp64);
cpu_state.MM[cpu_state.TOP&7].q = temp64;
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID | TAG_UINT64;
FP_TAG_DEFAULT;
CLOCK_CYCLES(10);
return 0;
@@ -117,7 +116,7 @@ static int opFILDiq_a32(uint32_t fetchdat)
temp64 = geteaq(); if (cpu_state.abrt) return 1;
x87_push((double)temp64);
cpu_state.MM[cpu_state.TOP&7].q = temp64;
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID | TAG_UINT64;
FP_TAG_DEFAULT;
CLOCK_CYCLES(10);
return 0;

View File

@@ -51,7 +51,11 @@ static int opFINIT(uint32_t fetchdat)
codegen_set_rounding_mode(X87_ROUNDING_NEAREST);
cpu_state.npxs = 0;
p = (uint64_t *)cpu_state.tag;
#ifdef USE_NEW_DYNAREC
*p = 0;
#else
*p = 0x0303030303030303ll;
#endif
cpu_state.TOP = 0;
cpu_state.ismmx = 0;
CLOCK_CYCLES(17);
@@ -64,7 +68,11 @@ static int opFFREE(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
#ifdef USE_NEW_DYNAREC
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_EMPTY;
#else
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3;
#endif
CLOCK_CYCLES(3);
return 0;
}
@@ -141,10 +149,16 @@ static int FSTOR()
/*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times
something like this is needed*/
p = (uint64_t *) cpu_state.tag;
#ifdef USE_NEW_DYNAREC
if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff &&
cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff &&
!cpu_state.TOP && (*p == 0x0101010101010101ull))
cpu_state.ismmx = 1;
#else
if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff &&
cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff &&
!cpu_state.TOP && !(*p))
#endif
cpu_state.ismmx = 1;
CLOCK_CYCLES((cr0 & 1) ? 34 : 44);
return cpu_state.abrt;
@@ -308,7 +322,11 @@ static int FSAVE()
codegen_set_rounding_mode(X87_ROUNDING_NEAREST);
cpu_state.npxs = 0;
p = (uint64_t *)cpu_state.tag;
#ifdef USE_NEW_DYNAREC
*p = 0;
#else
*p = 0x0303030303030303ll;
#endif
cpu_state.TOP = 0;
cpu_state.ismmx = 0;
@@ -398,7 +416,7 @@ static int opFCHS(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
ST(0) = -ST(0);
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
FP_TAG_VALID;
CLOCK_CYCLES(6);
return 0;
}
@@ -408,7 +426,7 @@ static int opFABS(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
ST(0) = fabs(ST(0));
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
FP_TAG_VALID;
CLOCK_CYCLES(3);
return 0;
}
@@ -429,7 +447,11 @@ static int opFXAM(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
cpu_state.npxs &= ~(C0|C1|C2|C3);
#ifdef USE_NEW_DYNAREC
if (cpu_state.tag[cpu_state.TOP&7] == TAG_EMPTY) cpu_state.npxs |= (C0|C3);
#else
if (cpu_state.tag[cpu_state.TOP&7] == 3) cpu_state.npxs |= (C0|C3);
#endif
else if (ST(0) == 0.0) cpu_state.npxs |= C3;
else cpu_state.npxs |= C2;
if (ST(0) < 0.0) cpu_state.npxs |= C1;
@@ -496,7 +518,7 @@ static int opFLDZ(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
x87_push(0.0);
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
FP_TAG_VALID;
CLOCK_CYCLES(4);
return 0;
}
@@ -506,7 +528,7 @@ static int opF2XM1(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
ST(0) = pow(2.0, ST(0)) - 1.0;
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
FP_TAG_VALID;
CLOCK_CYCLES(200);
return 0;
}
@@ -516,7 +538,7 @@ static int opFYL2X(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
ST(1) = ST(1) * (log(ST(0)) / log(2.0));
cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID;
FP_TAG_VALID_N;
x87_pop();
CLOCK_CYCLES(250);
return 0;
@@ -527,7 +549,7 @@ static int opFYL2XP1(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
ST(1) = ST(1) * (log1p(ST(0)) / log(2.0));
cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID;
FP_TAG_VALID_N;
x87_pop();
CLOCK_CYCLES(250);
return 0;
@@ -538,7 +560,7 @@ static int opFPTAN(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
ST(0) = tan(ST(0));
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
FP_TAG_VALID;
x87_push(1.0);
cpu_state.npxs &= ~C2;
CLOCK_CYCLES(235);
@@ -550,7 +572,7 @@ static int opFPATAN(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
ST(1) = atan2(ST(1), ST(0));
cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID;
FP_TAG_VALID_N;
x87_pop();
CLOCK_CYCLES(250);
return 0;
@@ -589,7 +611,7 @@ static int opFPREM(uint32_t fetchdat)
cpu_state.pc++;
temp64 = (int64_t)(ST(0) / ST(1));
ST(0) = ST(0) - (ST(1) * (double)temp64);
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
FP_TAG_VALID;
cpu_state.npxs &= ~(C0|C1|C2|C3);
if (temp64 & 4) cpu_state.npxs|=C0;
if (temp64 & 2) cpu_state.npxs|=C3;
@@ -605,7 +627,7 @@ static int opFPREM1(uint32_t fetchdat)
cpu_state.pc++;
temp64 = (int64_t)(ST(0) / ST(1));
ST(0) = ST(0) - (ST(1) * (double)temp64);
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
FP_TAG_VALID;
cpu_state.npxs &= ~(C0|C1|C2|C3);
if (temp64 & 4) cpu_state.npxs|=C0;
if (temp64 & 2) cpu_state.npxs|=C3;
@@ -620,7 +642,7 @@ static int opFSQRT(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
ST(0) = sqrt(ST(0));
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
FP_TAG_VALID;
CLOCK_CYCLES(83);
return 0;
}
@@ -633,7 +655,7 @@ static int opFSINCOS(uint32_t fetchdat)
cpu_state.pc++;
td = ST(0);
ST(0) = sin(td);
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
FP_TAG_VALID;
x87_push(cos(td));
cpu_state.npxs &= ~C2;
CLOCK_CYCLES(330);
@@ -646,7 +668,7 @@ static int opFRNDINT(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
ST(0) = (double)x87_fround(ST(0));
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
FP_TAG_VALID;
CLOCK_CYCLES(21);
return 0;
}
@@ -658,7 +680,7 @@ static int opFSCALE(uint32_t fetchdat)
cpu_state.pc++;
temp64 = (int64_t)ST(1);
ST(0) = ST(0) * pow(2.0, (double)temp64);
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
FP_TAG_VALID;
CLOCK_CYCLES(30);
return 0;
}
@@ -669,7 +691,7 @@ static int opFSIN(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
ST(0) = sin(ST(0));
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
FP_TAG_VALID;
cpu_state.npxs &= ~C2;
CLOCK_CYCLES(300);
return 0;
@@ -680,7 +702,7 @@ static int opFCOS(uint32_t fetchdat)
FP_ENTER();
cpu_state.pc++;
ST(0) = cos(ST(0));
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
FP_TAG_VALID;
cpu_state.npxs &= ~C2;
CLOCK_CYCLES(300);
return 0;

View File

@@ -370,7 +370,7 @@ static uint8_t opcode_modrm[256] =
static uint8_t opcode_0f_modrm[256] =
{
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, /*00*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*10*/
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/
1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*20*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*30*/

File diff suppressed because it is too large Load Diff

200
src/ddma.c Normal file
View File

@@ -0,0 +1,200 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Distributed DMA emulation.
*
*
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2020 Miran Grca.
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include "cpu.h"
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/io.h>
#include <86box/pci.h>
#include <86box/pic.h>
#include <86box/timer.h>
#include <86box/keyboard.h>
#include <86box/nvr.h>
#include <86box/pit.h>
#include <86box/dma.h>
#include <86box/ddma.h>
#ifdef ENABLE_DDMA_LOG
int ddma_do_log = ENABLE_DDMA_LOG;
static void
ddma_log(const char *fmt, ...)
{
va_list ap;
if (ddma_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define ddma_log(fmt, ...)
#endif
static uint8_t
ddma_reg_read(uint16_t addr, void *p)
{
ddma_channel_t *dev = (ddma_channel_t *) p;
uint8_t ret = 0xff;
int ch = dev->channel;
int dmab = (ch >= 4) ? 0xc0 : 0x00;
switch (addr & 0x0f) {
case 0x00:
ret = dma[ch].ac & 0xff;
break;
case 0x01:
ret = (dma[ch].ac >> 8) & 0xff;
break;
case 0x02:
ret = dma[ch].page;
break;
case 0x04:
ret = dma[ch].cc & 0xff;
break;
case 0x05:
ret = (dma[ch].cc >> 8) & 0xff;
break;
case 0x09:
ret = inb(dmab + 0x08);
break;
}
return ret;
}
static void
ddma_reg_write(uint16_t addr, uint8_t val, void *p)
{
ddma_channel_t *dev = (ddma_channel_t *) p;
int ch = dev->channel;
int page_regs[4] = { 7, 3, 1, 2 };
int i, dmab = (ch >= 4) ? 0xc0 : 0x00;
switch (addr & 0x0f) {
case 0x00:
dma[ch].ab = (dma[ch].ab & 0xffff00) | val;
dma[ch].ac = dma[ch].ab;
break;
case 0x01:
dma[ch].ab = (dma[ch].ab & 0xff00ff) | (val << 8);
dma[ch].ac = dma[ch].ab;
break;
case 0x02:
if (ch >= 4)
outb(0x88 + page_regs[ch & 3], val);
else
outb(0x80 + page_regs[ch & 3], val);
break;
case 0x04:
dma[ch].cb = (dma[ch].cb & 0xffff00) | val;
dma[ch].cc = dma[ch].cb;
break;
case 0x05:
dma[ch].cb = (dma[ch].cb & 0xff00ff) | (val << 8);
dma[ch].cc = dma[ch].cb;
break;
case 0x08:
outb(dmab + 0x08, val);
break;
case 0x09:
outb(dmab + 0x09, val);
break;
case 0x0a:
outb(dmab + 0x0a, val);
break;
case 0x0b:
outb(dmab + 0x0b, val);
break;
case 0x0d:
outb(dmab + 0x0d, val);
break;
case 0x0e:
for (i = 0; i < 4; i++)
outb(dmab + 0x0a, i);
break;
case 0x0f:
outb(dmab + 0x0a, (val << 2) | (ch & 3));
break;
}
}
void
ddma_update_io_mapping(ddma_t *dev, int ch, uint8_t base_l, uint8_t base_h, int enable)
{
if (dev->channels[ch].enable && (dev->channels[ch].io_base != 0x0000))
io_removehandler(dev->channels[ch].io_base, 0x10, ddma_reg_read, NULL, NULL, ddma_reg_write, NULL, NULL, &dev->channels[ch]);
dev->channels[ch].io_base = base_l | (base_h << 8);
dev->channels[ch].enable = enable;
if (dev->channels[ch].enable && (dev->channels[ch].io_base != 0x0000))
io_sethandler(dev->channels[ch].io_base, 0x10, ddma_reg_read, NULL, NULL, ddma_reg_write, NULL, NULL, &dev->channels[ch]);
}
static void
ddma_close(void *priv)
{
ddma_t *dev = (ddma_t *) priv;
free(dev);
}
static void *
ddma_init(const device_t *info)
{
ddma_t *dev;
int i;
dev = (ddma_t *)malloc(sizeof(ddma_t));
if (dev == NULL) return(NULL);
memset(dev, 0x00, sizeof(ddma_t));
for (i = 0; i < 8; i++)
dev->channels[i].channel = i;
return dev;
}
const device_t ddma_device =
{
"Distributed DMA",
DEVICE_PCI,
0,
ddma_init,
ddma_close,
NULL,
NULL,
NULL,
NULL,
NULL
};

View File

@@ -410,7 +410,7 @@ ide_get_max(ide_t *ide, int type)
return -1;
case TYPE_UDMA: /* UDMA */
if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL))
return 2;
return 4 /*2*/;
return -1;
default:
@@ -1815,12 +1815,13 @@ ide_readb(uint16_t addr, void *priv)
case 0x2: /* Sector count */
if (ide->type == IDE_ATAPI)
temp = ide->sc->phase;
else
else if (ide->type != IDE_NONE)
temp = ide->secount;
break;
case 0x3: /* Sector */
temp = (uint8_t) ide->sector;
if (ide->type != IDE_NONE)
temp = (uint8_t) ide->sector;
break;
case 0x4: /* Cylinder low */

View File

@@ -1983,7 +1983,7 @@ mo_get_max(int ide_has_dma, int type)
ret = ide_has_dma ? 1 : -1;
break;
case TYPE_UDMA:
ret = ide_has_dma ? 2 : -1;
ret = ide_has_dma ? 4 /*2*/ : -1;
break;
}

View File

@@ -2243,7 +2243,7 @@ zip_get_max(int ide_has_dma, int type)
ret = ide_has_dma ? 1 : -1;
break;
case TYPE_UDMA:
ret = ide_has_dma ? 2 : -1;
ret = ide_has_dma ? 4 /*2*/ : -1;
break;
}

View File

@@ -6,13 +6,6 @@
*
* This file is part of the 86Box distribution.
*
* Implementation of the ISA Bus (de)Bugger expansion card
* sold as a DIY kit in the late 1980's in The Netherlands.
* This card was a assemble-yourself 8bit ISA addon card for
* PC and AT systems that had several tools to aid in low-
* level debugging (mostly for faulty BIOSes, bootloaders
* and system kernels...)
*
* Definitions for the ACPI emulation.
*
*
@@ -46,21 +39,31 @@ extern "C" {
#define ACPI_ENABLE 0xf1
#define ACPI_DISABLE 0xf0
#define VEN_INTEL 0x8086
#define VEN_VIA 0x1106
typedef struct
{
uint8_t plvl2, plvl3,
smicmd, gpio_dir,
gpio_val, extsmi_val,
timer32,
gpireg[3], gporeg[4];
uint16_t pmsts, pmen,
pmcntrl, gpsts,
gpen, io_base;
int slot,
irq_mode, irq_pin;
gpen, io_base,
gpscien, gpsmien,
pscntrl, gpo_val,
gpi_val;
int slot, irq_mode,
irq_pin, smi_lock,
smi_active;
uint32_t pcntrl, glbsts,
devsts, glben,
glbctl, devctl,
timer_val;
padsts, paden,
gptren, timer_val;
uint64_t tmr_overflow_time;
} acpi_regs_t;
@@ -69,13 +72,16 @@ typedef struct
{
acpi_regs_t regs;
uint8_t gporeg_default[4];
int vendor;
pc_timer_t timer;
nvr_t *nvr;
apm_t *apm;
} acpi_t;
/* Global variables. */
extern const device_t acpi_device;
extern const device_t acpi_intel_device;
extern const device_t acpi_via_device;
/* Functions. */

View File

@@ -6,13 +6,6 @@
*
* This file is part of the 86Box distribution.
*
* Implementation of the ISA Bus (de)Bugger expansion card
* sold as a DIY kit in the late 1980's in The Netherlands.
* This card was a assemble-yourself 8bit ISA addon card for
* PC and AT systems that had several tools to aid in low-
* level debugging (mostly for faulty BIOSes, bootloaders
* and system kernels...)
*
* Definitions for the Advanced Power Management emulation.
*
*
@@ -39,9 +32,12 @@ typedef struct
/* Global variables. */
extern const device_t apm_device;
extern const device_t apm_pci_device;
extern const device_t apm_pci_acpi_device;
/* Functions. */
extern void apm_set_do_smi(apm_t *apm, uint8_t do_smi);
extern void apm_set_do_smi(apm_t *dev, uint8_t do_smi);
#ifdef __cplusplus
}

49
src/include/86box/ddma.h Normal file
View File

@@ -0,0 +1,49 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Definitions for the Distributed DMA emulation.
*
*
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2020 Miran Grca.
*/
#ifndef DDMA_H
# define DDMA_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
uint16_t io_base;
int channel, enable;
} ddma_channel_t;
typedef struct
{
ddma_channel_t channels[8];
} ddma_t;
/* Global variables. */
extern const device_t ddma_device;
/* Functions. */
extern void ddma_update_io_mapping(ddma_t *dev, int ch, uint8_t base_l, uint8_t base_h, int enable);
#ifdef __cplusplus
}
#endif
#endif /*DDMA_H*/

View File

@@ -99,6 +99,7 @@
#define IDS_2123 2123 // "Unable to initialize Ghostscript..."
#define IDS_2124 2124 // "MO %i (%03i): %ls"
#define IDS_2125 2125 // "MO images (*.IM?)\0*.IM..."
#define IDS_2126 2126 // "Welcome to 86Box!"
#define IDS_4096 4096 // "Hard disk (%s)"
#define IDS_4097 4097 // "%01i:%01i"
@@ -177,7 +178,7 @@
#define IDS_LANG_ENUS IDS_7168
#define STR_NUM_2048 78
#define STR_NUM_2048 79
#define STR_NUM_3072 11
#define STR_NUM_4096 18
#define STR_NUM_4352 7

View File

@@ -227,7 +227,9 @@ extern int machine_at_opti495_mr_init(const machine_t *);
extern int machine_at_ami471_init(const machine_t *);
extern int machine_at_dtk486_init(const machine_t *);
extern int machine_at_px471_init(const machine_t *);
#if defined(DEV_BRANCH) && defined(USE_WIN471)
extern int machine_at_win471_init(const machine_t *);
#endif
extern int machine_at_r418_init(const machine_t *);
extern int machine_at_ls486e_init(const machine_t *);
@@ -263,7 +265,6 @@ extern int machine_at_endeavor_init(const machine_t *);
extern int machine_at_zappa_init(const machine_t *);
extern int machine_at_mb500n_init(const machine_t *);
extern int machine_at_president_init(const machine_t *);
extern int machine_at_apollo_init(const machine_t *);
#if defined(DEV_BRANCH) && defined(USE_VECTRA54)
extern int machine_at_vectra54_init(const machine_t *);
#endif
@@ -285,15 +286,15 @@ extern int machine_at_acerv35n_init(const machine_t *);
extern int machine_at_ap53_init(const machine_t *);
extern int machine_at_p55t2p4_init(const machine_t *);
extern int machine_at_p55t2s_init(const machine_t *);
extern int machine_at_m7shi_init(const machine_t *);
extern int machine_at_tc430hx_init(const machine_t *);
extern int machine_at_equium5200_init(const machine_t *); /* Toshiba branded CU430HX.
Works as intended (No need to set an MPU too). */
extern int machine_at_equium5200_init(const machine_t *);
extern int machine_at_p55tvp4_init(const machine_t *);
extern int machine_at_i430vx_init(const machine_t *);
extern int machine_at_p55va_init(const machine_t *);
extern int machine_at_j656vxd_init(const machine_t *);
extern int machine_at_mb520n_init(const machine_t *);
extern int machine_at_i430vx_init(const machine_t *);
extern int machine_at_brio80xx_init(const machine_t *);
extern int machine_at_pb680_init(const machine_t *);
extern int machine_at_p55xb2_init(const machine_t *);
extern int machine_at_tx97_init(const machine_t *);
@@ -334,10 +335,6 @@ extern int machine_at_atc7020bxii_init(const machine_t *);
extern int machine_at_63a_init(const machine_t *);
extern int machine_at_apas3_init(const machine_t *);
#if defined(DEV_BRANCH) && defined(USE_596B)
extern int machine_at_bx98_init(const machine_t *);
#endif
/* m_at_t3100e.c */
extern int machine_at_t3100e_init(const machine_t *);

View File

@@ -66,6 +66,7 @@ enum {
typedef void (*NETRXCB)(void *, uint8_t *, int);
typedef int (*NETWAITCB)(void *);
typedef int (*NETSETLINKSTATE)(void *);
typedef struct {
@@ -76,6 +77,7 @@ typedef struct {
int (*poll)(void *);
NETRXCB rx;
NETWAITCB wait;
NETSETLINKSTATE set_link_state;
} netcard_t;
typedef struct {
@@ -101,7 +103,7 @@ extern void network_busy(uint8_t set);
extern void network_end(void);
extern void network_init(void);
extern void network_attach(void *, uint8_t *, NETRXCB, NETWAITCB);
extern void network_attach(void *, uint8_t *, NETRXCB, NETWAITCB, NETSETLINKSTATE);
extern void network_close(void);
extern void network_reset(void);
extern int network_available(void);

View File

@@ -4,7 +4,8 @@
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* Emulation of the Intel PIIX and PIIX3 Xcelerators.
* Emulation of the Intel PIIX, PIIX3, PIIX4, PIIX4E, and SMSC
* SLC90E66 (Victory66) Xcelerators.
*
* Emulation core dispatcher.
*

View File

@@ -300,6 +300,8 @@
#define IDM_VID_GRAY_GREEN 40083
#define IDM_VID_GRAY_WHITE 40084
#define IDM_MEDIA 40085
#ifdef USE_DISCORD
#define IDM_DISCORD 40090
#endif

View File

@@ -1,41 +1,48 @@
/* Copyright holders: Melissa Goad
see COPYING for more details
*/
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Definitions for the Distributed DMA emulation.
*
*
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2020 Miran Grca.
*/
#ifndef USB_H
# define USB_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
uint8_t pid; //low 4 bits are the real pid, top 4 bits are just ~pid
uint8_t dev_addr;
uint8_t dev_endpoint;
int crc5;
uint16_t crc16;
uint8_t data[1024];
int len;
void* device;
} usb_packet_t;
uint8_t ohci_mmio[4096];
uint16_t uhci_io_base;
int uhci_enable, ohci_enable;
uint32_t ohci_mem_base;
mem_mapping_t ohci_mmio_mapping;
} usb_t;
typedef enum
{
USB_DEV_TYPE_NONE = 0,
USB_DEV_TYPE_MOUSE,
USB_DEV_TYPE_TABLET,
USB_DEV_TYPE_KEYPAD,
USB_DEV_TYPE_DISK,
USB_DEV_TYPE_CDROM,
USB_DEV_TYPE_HUB,
USB_DEV_TYPE_PRINTER
} usb_device_type_t;
typedef enum
{
USB_PID_TOKEN_STALL = 0x1e,
USB_PID_TOKEN_SETUP = 0x2d,
USB_PID_TOKEN_PRE = 0x3c,
USB_PID_TOKEN_DATA1 = 0x4b,
USB_PID_TOKEN_NAK = 0x5a,
USB_PID_TOKEN_IN = 0x69,
USB_PID_TOKEN_SOF = 0xa5,
USB_PID_TOKEN_DATA0 = 0xc3,
USB_PID_TOKEN_ACK = 0xd2,
USB_PID_TOKEN_OUT = 0xe1
} usb_pid_type_t;
/* Global variables. */
extern const device_t usb_device;
/* Functions. */
extern void uhci_update_io_mapping(usb_t *dev, uint8_t base_l, uint8_t base_h, int enable);
extern void ohci_update_mem_mapping(usb_t *dev, uint8_t base1, uint8_t base2, uint8_t base3, int enable);
#ifdef __cplusplus
}
#endif
#endif /*USB_H*/

View File

@@ -269,9 +269,11 @@ extern const device_t ht216_32_pb410a_device;
extern const device_t im1024_device;
extern const device_t pgc_device;
#if defined(DEV_BRANCH) && defined(USE_MGA)
/* Matrox Mystique */
extern const device_t mystique_device;
extern const device_t mystique_220_device;
#endif
/* Oak OTI-0x7 */
extern const device_t oti037c_device;

View File

@@ -168,6 +168,7 @@ extern void win_settings_open_ex(HWND hwnd, int category);
/* Functions in win_stbar.c: */
extern HWND hwndSBAR;
extern void StatusBarCreate(HWND hwndParent, uintptr_t idStatus, HINSTANCE hInst);
extern int MediaMenuHandler(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
/* Functions in win_dialog.c: */

View File

@@ -4,7 +4,8 @@
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* Emulation of the Intel PIIX and PIIX3 Xcelerators.
* Emulation of the Intel PIIX, PIIX3, PIIX4, PIIX4E, and SMSC
* SLC90E66 (Victory66) Xcelerators.
*
* PRD format :
* word 0 - base address
@@ -40,6 +41,7 @@
#include <86box/timer.h>
#include <86box/nvr.h>
#include <86box/acpi.h>
#include <86box/ddma.h>
#include <86box/pci.h>
#include <86box/pic.h>
#include <86box/pit.h>
@@ -47,19 +49,13 @@
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#include <86box/hdc_ide_sff8038i.h>
#include <86box/usb.h>
#include <86box/zip.h>
#include <86box/machine.h>
#include <86box/smbus_piix4.h>
#include <86box/piix.h>
typedef struct
{
uint16_t io_base;
int base_channel;
} ddma_t;
typedef struct
{
uint8_t cur_readout_reg, rev,
@@ -68,15 +64,14 @@ typedef struct
regs[4][256],
readout_regs[256], board_config[2];
uint16_t func0_id, nvr_io_base,
usb_io_base, acpi_io_base;
acpi_io_base;
double fast_off_period;
uint8_t *usb_smsc_mmio;
mem_mapping_t usb_smsc_mmio_mapping;
sff8038i_t *bm[2];
ddma_t ddma[2];
smbus_piix4_t * smbus;
apm_t * apm;
nvr_t * nvr;
ddma_t * ddma;
usb_t * usb;
acpi_t * acpi;
port_92_t * port_92;
pc_timer_t fast_off_timer;
@@ -246,200 +241,6 @@ kbc_alias_update_io_mapping(piix_t *dev)
}
static uint8_t
ddma_reg_read(uint16_t addr, void *p)
{
ddma_t *dev = (ddma_t *) p;
uint8_t ret = 0xff;
int rel_ch = (addr & 0x30) >> 4;
int ch = dev->base_channel + rel_ch;
int dmab = (ch >= 4) ? 0xc0 : 0x00;
switch (addr & 0x0f) {
case 0x00:
ret = dma[ch].ac & 0xff;
break;
case 0x01:
ret = (dma[ch].ac >> 8) & 0xff;
break;
case 0x02:
ret = dma[ch].page;
break;
case 0x04:
ret = dma[ch].cc & 0xff;
break;
case 0x05:
ret = (dma[ch].cc >> 8) & 0xff;
break;
case 0x09:
ret = inb(dmab + 0x08);
break;
}
return ret;
}
static void
ddma_reg_write(uint16_t addr, uint8_t val, void *p)
{
ddma_t *dev = (ddma_t *) p;
int rel_ch = (addr & 0x30) >> 4;
int ch = dev->base_channel + rel_ch;
int page_regs[4] = { 7, 3, 1, 2 };
int i, dmab = (ch >= 4) ? 0xc0 : 0x00;
switch (addr & 0x0f) {
case 0x00:
dma[ch].ab = (dma[ch].ab & 0xffff00) | val;
dma[ch].ac = dma[ch].ab;
break;
case 0x01:
dma[ch].ab = (dma[ch].ab & 0xff00ff) | (val << 8);
dma[ch].ac = dma[ch].ab;
break;
case 0x02:
if (ch >= 4)
outb(0x88 + page_regs[rel_ch], val);
else
outb(0x80 + page_regs[rel_ch], val);
break;
case 0x04:
dma[ch].cb = (dma[ch].cb & 0xffff00) | val;
dma[ch].cc = dma[ch].cb;
break;
case 0x05:
dma[ch].cb = (dma[ch].cb & 0xff00ff) | (val << 8);
dma[ch].cc = dma[ch].cb;
break;
case 0x08:
outb(dmab + 0x08, val);
break;
case 0x09:
outb(dmab + 0x09, val);
break;
case 0x0a:
outb(dmab + 0x0a, val);
break;
case 0x0b:
outb(dmab + 0x0b, val);
break;
case 0x0d:
outb(dmab + 0x0d, val);
break;
case 0x0e:
for (i = 0; i < 4; i++)
outb(dmab + 0x0a, i);
break;
case 0x0f:
outb(dmab + 0x0a, (val << 2) | rel_ch);
break;
}
}
static void
ddma_update_io_mapping(piix_t *dev, int n)
{
int base_reg = 0x92 + (n << 1);
if (dev->ddma[n].io_base != 0x0000)
io_removehandler(dev->ddma[n].io_base, 0x40, ddma_reg_read, NULL, NULL, ddma_reg_write, NULL, NULL, &dev->ddma[n]);
dev->ddma[n].io_base = (dev->regs[0][base_reg] & ~0x3f) | (dev->regs[0][base_reg + 1] << 8);
if (dev->ddma[n].io_base != 0x0000)
io_sethandler(dev->ddma[n].io_base, 0x40, ddma_reg_read, NULL, NULL, ddma_reg_write, NULL, NULL, &dev->ddma[n]);
}
static uint8_t
usb_reg_read(uint16_t addr, void *p)
{
uint8_t ret = 0xff;
switch (addr & 0x1f) {
case 0x10: case 0x11: case 0x12: case 0x13:
/* Port status */
ret = 0x00;
break;
}
return ret;
}
static void
usb_reg_write(uint16_t addr, uint8_t val, void *p)
{
}
static void
usb_update_io_mapping(piix_t *dev)
{
if (dev->usb_io_base != 0x0000)
io_removehandler(dev->usb_io_base, 0x20, usb_reg_read, NULL, NULL, usb_reg_write, NULL, NULL, dev);
dev->usb_io_base = (dev->regs[2][0x20] & ~0x1f) | (dev->regs[2][0x21] << 8);
if ((dev->regs[2][PCI_REG_COMMAND] & PCI_COMMAND_IO) && (dev->usb_io_base != 0x0000))
io_sethandler(dev->usb_io_base, 0x20, usb_reg_read, NULL, NULL, usb_reg_write, NULL, NULL, dev);
}
static void
usb_smsc_update_mem_mapping(piix_t *dev)
{
uint32_t usb_bar;
mem_mapping_disable(&dev->usb_smsc_mmio_mapping);
usb_bar = ((dev->regs[2][0x11] << 8) | (dev->regs[2][0x12] << 16) | (dev->regs[2][0x13] << 24)) & 0xfffff000;
if ((dev->regs[2][0x04] & 0x02) && (usb_bar != 0x00000000))
mem_mapping_set_addr(&dev->usb_smsc_mmio_mapping, usb_bar, 0x1000);
}
static uint8_t
usb_smsc_mmio_read(uint32_t addr, void *p)
{
piix_t *dev = (piix_t *) p;
uint8_t ret = 0x00;
addr &= 0x00000fff;
ret = dev->usb_smsc_mmio[addr];
return ret;
}
static void
usb_smsc_mmio_write(uint32_t addr, uint8_t val, void *p)
{
piix_t *dev = (piix_t *) p;
addr &= 0x00000fff;
switch (addr) {
case 0x08: /* HCCOMMANDSTATUS */
/* bit HostControllerReset must be cleared for the controller to be seen as initialized */
val &= ~0x01;
/* bit OwnershipChangeRequest triggers an ownership change (SMM <-> OS) */
if (val & 0x0f) {
dev->usb_smsc_mmio[0x0f] = 0x40;
dev->usb_smsc_mmio[0x05] &= ~(dev->usb_smsc_mmio[0x05] & 0x01);
}
break;
}
dev->usb_smsc_mmio[addr] = val;
}
static void
smbus_update_io_mapping(piix_t *dev)
{
@@ -480,6 +281,7 @@ piix_write(int func, int addr, uint8_t val, void *priv)
{
piix_t *dev = (piix_t *) priv;
uint8_t *fregs;
int i;
/* Return on unsupported function. */
if (dev->max_func > 0) {
@@ -643,16 +445,18 @@ piix_write(int func, int addr, uint8_t val, void *priv)
case 0x92: case 0x93: case 0x94: case 0x95:
if (dev->type > 3) {
if (addr & 0x01)
fregs[addr] = val & 0xc0;
else
fregs[addr] = val & 0xff;
ddma_update_io_mapping(dev, (addr >> 2) & 1);
else
fregs[addr] = val & 0xc0;
for (i = 0; i < 4; i++)
ddma_update_io_mapping(dev->ddma, (addr & 4) + i, fregs[addr & 0xfe] + (i << 4), fregs[addr | 0x01], 1);
}
break;
case 0xa0:
if (dev->type < 4) {
fregs[addr] = val & 0x1f;
apm_set_do_smi(dev->apm, (val & 0x01) | (fregs[0xa2] & 0x80));
apm_set_do_smi(dev->apm, !!(val & 0x01) && !!(fregs[0xa2] & 0x80));
switch ((val & 0x18) >> 3) {
case 0x00:
dev->fast_off_period = PCICLK * 32768.0 * 60000.0;
@@ -677,7 +481,7 @@ piix_write(int func, int addr, uint8_t val, void *priv)
case 0xa2:
if (dev->type < 4) {
fregs[addr] = val & 0xff;
apm_set_do_smi(dev->apm, (fregs[0xa0] & 0x01) | (val & 0x80));
apm_set_do_smi(dev->apm, !!(fregs[0xa0] & 0x01) && !!(val & 0x80));
}
break;
case 0xaa: case 0xac: case 0xae:
@@ -886,10 +690,10 @@ piix_write(int func, int addr, uint8_t val, void *priv)
case 0x04:
if (dev->type > 4) {
fregs[0x04] = (val & 7);
usb_smsc_update_mem_mapping(dev);
ohci_update_mem_mapping(dev->usb, fregs[0x11], fregs[0x12], fregs[0x13], fregs[PCI_REG_COMMAND] & PCI_COMMAND_MEM);
} else {
fregs[0x04] = (val & 5);
usb_update_io_mapping(dev);
uhci_update_io_mapping(dev->usb, fregs[0x20] & ~0x1f, fregs[0x21], fregs[PCI_REG_COMMAND] & PCI_COMMAND_IO);
}
break;
case 0x07:
@@ -917,25 +721,25 @@ piix_write(int func, int addr, uint8_t val, void *priv)
case 0x11:
if (dev->type > 4) {
fregs[addr] = val & 0xf0;
usb_smsc_update_mem_mapping(dev);
ohci_update_mem_mapping(dev->usb, fregs[0x11], fregs[0x12], fregs[0x13], fregs[PCI_REG_COMMAND] & PCI_COMMAND_MEM);
}
break;
case 0x12: case 0x13:
if (dev->type > 4) {
fregs[addr] = val;
usb_smsc_update_mem_mapping(dev);
ohci_update_mem_mapping(dev->usb, fregs[0x11], fregs[0x12], fregs[0x13], fregs[PCI_REG_COMMAND] & PCI_COMMAND_MEM);
}
break;
case 0x20:
if (dev->type < 5) {
fregs[0x20] = (val & 0xe0) | 1;
usb_update_io_mapping(dev);
uhci_update_io_mapping(dev->usb, fregs[0x20] & ~0x1f, fregs[0x21], fregs[PCI_REG_COMMAND] & PCI_COMMAND_IO);
}
break;
case 0x21:
if (dev->type < 5) {
fregs[0x21] = val;
usb_update_io_mapping(dev);
uhci_update_io_mapping(dev->usb, fregs[0x20] & ~0x1f, fregs[0x21], fregs[PCI_REG_COMMAND] & PCI_COMMAND_IO);
}
break;
case 0x3c:
@@ -976,7 +780,7 @@ piix_write(int func, int addr, uint8_t val, void *priv)
case 0x04:
fregs[0x04] = (val & 0x01);
smbus_update_io_mapping(dev);
apm_set_do_smi(dev->apm, !!(fregs[0x5b] & 0x02) && !!(val & 0x01));
apm_set_do_smi(dev->acpi->apm, !!(fregs[0x5b] & 0x02) && !!(val & 0x01));
break;
case 0x07:
if (val & 0x08)
@@ -1041,7 +845,7 @@ piix_write(int func, int addr, uint8_t val, void *priv)
break;
case 0x5b:
fregs[addr] = val & 0x03;
apm_set_do_smi(dev->apm, !!(val & 0x02) && !!(fregs[0x04] & 0x01));
apm_set_do_smi(dev->acpi->apm, !!(val & 0x02) && !!(fregs[0x04] & 0x01));
break;
case 0x63:
fregs[addr] = val & 0xf7;
@@ -1263,14 +1067,6 @@ piix_reset_hard(piix_t *dev)
fregs[0xff] = (dev->type > 3) ? 0x10 : 0x00;
}
dev->max_func = 1; /* It starts with USB disabled, then enables it. */
/* SMSC OHCI memory-mapped registers */
if (dev->usb_smsc_mmio) {
memset(dev->usb_smsc_mmio, 0, 4096);
dev->usb_smsc_mmio[0x00] = 0x10;
dev->usb_smsc_mmio[0x01] = 0x01;
dev->usb_smsc_mmio[0x48] = 0x02;
}
}
/* Function 3: Power Management */
@@ -1314,9 +1110,7 @@ piix_apm_out(uint16_t port, uint8_t val, void *p)
piix_t *dev = (piix_t *) p;
if (dev->apm->do_smi) {
if (dev->type > 3)
dev->acpi->regs.glbsts |= 0x20;
else
if (dev->type < 4)
dev->regs[0][0xaa] |= 0x80;
}
}
@@ -1387,27 +1181,21 @@ static void
dev->bm[0] = device_add_inst(&sff8038i_device, 1);
dev->bm[1] = device_add_inst(&sff8038i_device, 2);
if (dev->type >= 3)
dev->usb = device_add(&usb_device);
if (dev->type > 3) {
dev->nvr = device_add(&piix4_nvr_device);
dev->smbus = device_add(&piix4_smbus_device);
dev->acpi = device_add(&acpi_device);
dev->acpi = device_add(&acpi_intel_device);
acpi_set_slot(dev->acpi, dev->pci_slot);
acpi_set_nvr(dev->acpi, dev->nvr);
dev->ddma = device_add(&ddma_device);
} else
timer_add(&dev->fast_off_timer, piix_fast_off_count, dev, 0);
if (dev->type > 4) {
dev->usb_smsc_mmio = (uint8_t *) malloc(4096);
memset(dev->usb_smsc_mmio, 0x00, 4096);
mem_mapping_add(&dev->usb_smsc_mmio_mapping, 0, 0,
usb_smsc_mmio_read, NULL, NULL,
usb_smsc_mmio_write, NULL, NULL,
NULL, MEM_MAPPING_EXTERNAL, dev);
mem_mapping_disable(&dev->usb_smsc_mmio_mapping);
}
piix_reset_hard(dev);
piix_log("Maximum function: %i\n", dev->max_func);
cpu_fast_off_flags = 0x00000000;
@@ -1417,9 +1205,13 @@ static void
} else
cpu_fast_off_val = cpu_fast_off_count = 0;
dev->apm = device_add(&apm_device);
/* APM intercept handler to update PIIX/PIIX3 and PIIX4/4E/SMSC ACPI SMI status on APM SMI. */
io_sethandler(0x00b2, 0x0001, NULL, NULL, NULL, piix_apm_out, NULL, NULL, dev);
/* On PIIX4, PIIX4E, and SMSC, APM is added by the ACPI device. */
if (dev->type < 4) {
dev->apm = device_add(&apm_pci_device);
/* APM intercept handler to update PIIX/PIIX3 and PIIX4/4E/SMSC ACPI SMI status on APM SMI. */
io_sethandler(0x00b2, 0x0001, NULL, NULL, NULL, piix_apm_out, NULL, NULL, dev);
}
dev->port_92 = device_add(&port_92_pci_device);
dma_alias_set();

View File

@@ -267,6 +267,7 @@ machine_at_px471_init(const machine_t *model)
}
#if defined(DEV_BRANCH) && defined(USE_WIN471)
int
machine_at_win471_init(const machine_t *model)
{
@@ -283,6 +284,7 @@ machine_at_win471_init(const machine_t *model)
return ret;
}
#endif
static void

View File

@@ -33,12 +33,14 @@
#include <86box/intel_sio.h>
#include <86box/piix.h>
#include <86box/sio.h>
#include <86box/intel_sio.h>
#include <86box/sst_flash.h>
#include <86box/hwm.h>
#include <86box/spd.h>
#include <86box/video.h>
#include "cpu.h"
#include <86box/machine.h>
int
machine_at_p6kfx_init(const machine_t *model)
{
@@ -69,6 +71,7 @@ machine_at_p6kfx_init(const machine_t *model)
return ret;
}
#if defined(DEV_BRANCH) && defined(NO_SIO)
int
machine_at_6bxc_init(const machine_t *model)
{
@@ -93,12 +96,13 @@ machine_at_6bxc_init(const machine_t *model)
device_add(&i440bx_device);
device_add(&piix4e_device);
device_add(&keyboard_ps2_pci_device);
device_add(&um8669f_device); /*Placeholder for ITE 8671*/
device_add(&um8669f_device); /*ITE 8671*/
device_add(&sst_flash_39sf020_device);
spd_register(SPD_TYPE_SDRAM, 0xF, 256);
return ret;
}
#endif
int
machine_at_p2bls_init(const machine_t *model)

View File

@@ -199,32 +199,3 @@ machine_at_apas3_init(const machine_t *model)
return ret;
}
#if defined(DEV_BRANCH) && defined(USE_596B)
int
machine_at_bx98_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/bx98/vc98103e.bin",
0x000c0000, 262144, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init_ex(model, 2);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
pci_register_slot(0x01, PCI_CARD_NORMAL, 1, 2, 3, 4);
device_add(&via_apro_device);
device_add(&via_vt82c596b_device);
device_add(&um8669f_device);
device_add(&keyboard_ps2_ami_pci_device);
device_add(&sst_flash_39sf020_device);
spd_register(SPD_TYPE_SDRAM, 0x7, 256);
return ret;
}
#endif

View File

@@ -384,37 +384,6 @@ machine_at_president_init(const machine_t *model)
}
int
machine_at_apollo_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/apollo/S728P.ROM",
0x000e0000, 131072, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init_ex(model, 2);
device_add(&ls486e_nvr_device);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
device_add(&i430fx_device);
device_add(&piix_device);
device_add(&keyboard_ps2_pci_device);
device_add(&fdc37c932fr_device);
device_add(&intel_flash_bxt_device);
return ret;
}
#if defined(DEV_BRANCH) && defined(USE_VECTRA54)
int
machine_at_vectra54_init(const machine_t *model)

View File

@@ -302,6 +302,34 @@ machine_at_p55t2s_init(const machine_t *model)
return ret;
}
int
machine_at_m7shi_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/m7shi/m7shi2n.rom",
0x000c0000, 262144, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x12, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
device_add(&i430hx_device);
device_add(&piix3_device);
device_add(&keyboard_ps2_ami_pci_device);
device_add(&fdc37c935_device);
device_add(&intel_flash_bxt_device);
return ret;
}
int
machine_at_tc430hx_init(const machine_t *model)
@@ -372,13 +400,12 @@ machine_at_equium5200_init(const machine_t *model) // Information about that mac
return ret;
}
int
machine_at_p55tvp4_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/p55tvp4/tv5i0204.awd",
ret = bios_load_linear(L"roms/machines/p55tvp4/0204_128.BIN",
0x000e0000, 131072, 0);
if (bios_only || !ret)
@@ -388,21 +415,20 @@ machine_at_p55tvp4_init(const machine_t *model)
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
device_add(&i430vx_device);
device_add(&piix3_device);
device_add(&keyboard_ps2_pci_device);
device_add(&keyboard_ps2_ami_pci_device); //It uses the AMIKEY KBC
device_add(&w83877f_device);
device_add(&intel_flash_bxt_device);
return ret;
}
int
machine_at_i430vx_init(const machine_t *model)
{
@@ -432,7 +458,6 @@ machine_at_i430vx_init(const machine_t *model)
return ret;
}
int
machine_at_p55va_init(const machine_t *model)
{
@@ -462,14 +487,13 @@ machine_at_p55va_init(const machine_t *model)
return ret;
}
int
machine_at_j656vxd_init(const machine_t *model)
machine_at_brio80xx_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/j656vxd/J656VXD.BIN",
0x000e0000, 131072, 0);
ret = bios_load_linear(L"roms/machines/brio80xx/Hf0705.rom",
0x000c0000, 262144, 0);
if (bios_only || !ret)
return ret;
@@ -477,49 +501,55 @@ machine_at_j656vxd_init(const machine_t *model)
machine_at_common_init(model);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
device_add(&i430vx_device);
device_add(&piix3_device);
device_add(&keyboard_ps2_pci_device);
device_add(&fdc37c669_device);
device_add(&intel_flash_bxt_device);
return ret;
}
int
machine_at_mb520n_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/mb520n/520n503s.rom",
0x000e0000, 131072, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
device_add(&i430vx_device);
device_add(&piix3_device);
device_add(&keyboard_ps2_ami_pci_device);
device_add(&fdc37c669_device);
device_add(&intel_flash_bxt_device);
device_add(&fdc37c935_device);
device_add(&sst_flash_29ee020_device);
return ret;
}
int
machine_at_pb680_init(const machine_t *model)
{
int ret;
ret = bios_load_linear_combined2(L"roms/machines/pb680/1012DN0R.BIO",
L"roms/machines/pb680/1012DN0R.BI1",
L"roms/machines/pb680/1012DN0R.BI2",
L"roms/machines/pb680/1012DN0R.BI3",
L"roms/machines/pb680/1012DN0R.RCV",
0x3a000, 128);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x08, PCI_CARD_ONBOARD, 4, 0, 0, 0);
pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
device_add(&i430vx_device);
device_add(&piix3_device);
device_add(&keyboard_ps2_ami_pci_device);
device_add(&pc87306_device);
device_add(&intel_flash_bxt_ami_device);
return ret;
}
#if defined(DEV_BRANCH) && defined(NO_SIO)
int
machine_at_p55xb2_init(const machine_t *model)
{
@@ -548,7 +578,7 @@ machine_at_p55xb2_init(const machine_t *model)
return ret;
}
#endif
int
machine_at_tx97_init(const machine_t *model)
@@ -673,7 +703,7 @@ machine_at_ym430tx_init(const machine_t *model)
return ret;
}
#if defined(DEV_BRANCH) && defined(NO_SIO)
int
machine_at_586t2_init(const machine_t *model)
{
@@ -767,7 +797,7 @@ machine_at_807ds_init(const machine_t *model)
return ret;
}
#endif
int
machine_at_p5mms98_init(const machine_t *model)
@@ -833,6 +863,7 @@ machine_at_p5mms98_init(const machine_t *model)
return ret;
}
#if defined(DEV_BRANCH) && defined(NO_SIO)
int
machine_at_tx100_init(const machine_t *model)
{
@@ -890,4 +921,5 @@ machine_at_advanceii_init(const machine_t *model)
spd_register(SPD_TYPE_SDRAM, 0xF, 64);
return ret;
}
}
#endif

View File

@@ -156,4 +156,36 @@ machine_at_m6mi_init(const machine_t *model)
device_add(&intel_flash_bxt_device);
return ret;
}
}
#if defined(DEV_BRANCH) && defined(NO_SIO)
int
machine_at_vs440fx_init(const machine_t *model)
{
int ret;
ret = bios_load_linear_combined2(L"roms/machines/vs440fx/1011CS1_.BIO",
L"roms/machines/vs440fx/1011CS1_.BI1",
L"roms/machines/vs440fx/1011CS1_.BI2",
L"roms/machines/vs440fx/1011CS1_.BI3",
L"roms/machines/vs440fx/1011CS1_.RCV",
0x3a000, 128);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
device_add(&i440fx_device);
device_add(&piix3_device);
device_add(&keyboard_ps2_ami_pci_device);
//device_add(&pc87307_device);
device_add(&pc87306_device);
device_add(&intel_flash_bxt_ami_device);
return ret;
}
#endif

View File

@@ -1024,7 +1024,7 @@ t1000_configsys_load(void)
f = plat_fopen(nvr_path(L"t1000_config.nvr"), L"rb");
if (f != NULL) {
size = sizeof(t1000.t1000_nvram);
if (fread(t1000.t1000_nvram, size, 1, f) != size)
if (fread(t1000.t1000_nvram, 1, size, f) != size)
fatal("t1000_configsys_load(): Error reading data\n");
fclose(f);
}

View File

@@ -61,7 +61,7 @@
const machine_t machines[] = {
//8088 Machines
/* 8088 Machines */
{ "[8088] AMI XT clone", "amixt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_amixt_init, NULL },
{ "[8088] Compaq Portable", "portable", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO, 128, 640, 128, 0, machine_xt_compaq_init, NULL },
{ "[8088] DTK XT clone", "dtk", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_dtk_init, NULL },
@@ -84,7 +84,7 @@ const machine_t machines[] = {
{ "[8088] Xi8088", "xi8088", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 64, 1024, 128, 127, machine_xt_xi8088_init, xi8088_get_device },
{ "[8088] Zenith Data SupersPort", "zdsupers", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 128, 640, 128, 0, machine_xt_zenith_init, NULL },
//8086 Machines
/* 8086 Machines */
{ "[8086] Amstrad PC1512", "pc1512", {{"Intel", cpus_pc1512}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 512, 640, 128, 63, machine_pc1512_init, pc1512_get_device },
{ "[8086] Amstrad PC1640", "pc1640", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_pc1640_init, pc1640_get_device },
{ "[8086] Amstrad PC2086", "pc2086", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VIDEO | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 640, 640, 0, 63, machine_pc2086_init, pc2086_get_device },
@@ -98,10 +98,10 @@ const machine_t machines[] = {
{ "[8086] VTech Laser XT3", "lxt3", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 256, 640, 256, 0, machine_xt_lxt3_init, NULL },
#endif
//286 XT machines
/* 286 XT machines */
{ "[286 XT] Hedaka HED-919", "hed919", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA, 64, 640, 64, 0, machine_xt_hed919_init, NULL },
//286 AT machines
/* 286 AT machines */
{ "[286 ISA] AMI 286 clone", "ami286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512, 8192, 128, 127, machine_at_neat_ami_init, NULL },
{ "[286 ISA] Award 286 clone", "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_award286_init, NULL },
{ "[286 ISA] Phoenix 286 clone", "px286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_px286_init, NULL },
@@ -131,10 +131,10 @@ const machine_t machines[] = {
{ "[286 ISA] Samsung Deskmaster 286", "deskmaster286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_deskmaster286_init, NULL },
//286 machines that utilize the MCA bus
/* 286 machines that utilize the MCA bus */
{ "[286 MCA] IBM PS/2 model 50", "ibmps2_m50", {{"Intel", cpus_ps2_m30_286}, {"IBM",cpus_IBM486SLC},{"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 1, 10, 1, 63, machine_ps2_model_50_init, NULL },
//386SX machines
/* 386SX machines */
{ "[386SX ISA] AMA-932J", "ama932j", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO, 512, 8192, 128, 127, machine_at_ama932j_init, at_ama932j_get_device },
#if defined(DEV_BRANCH) && defined(USE_AMI386SX)
{ "[386SX ISA] AMI Unknown 386SX", "ami386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_headland_init, NULL },
@@ -148,29 +148,29 @@ const machine_t machines[] = {
{ "[386SX ISA] Goldstar 386", "goldstar386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 8192, 128, 127, machine_at_goldstar386_init, NULL },
//386SX machines which utilize the MCA bus
/* 386SX machines which utilize the MCA bus */
{ "[386SX MCA] IBM PS/2 model 55SX", "ibmps2_m55sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"IBM",cpus_IBM486SLC},{"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 1, 8, 1, 63, machine_ps2_model_55sx_init, NULL },
//386DX machines
/* 386DX machines */
{ "[386DX ISA] Compaq Portable III (386)", "portableiii386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO, 1, 14, 1, 127, machine_at_portableiii386_init, at_cpqiii_get_device },
{ "[386DX ISA] ECS 386/32", "ecs386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 512, 127, machine_at_ecs386_init, NULL },
{ "[386DX ISA] Micronics 386 clone", "micronics386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512, 8192, 128, 127, machine_at_micronics386_init, NULL },
//386DX machines which utilize the VLB bus
/* 386DX machines which utilize the VLB bus */
{ "[386DX VLB] Award 386DX clone", "award386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_init, NULL },
{ "[386DX VLB] Dataexpert SX495 (386DX)", "ami386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_ami_init, NULL },
#if defined(DEV_BRANCH) && defined(USE_MR495)
{ "[386DX VLB] MR 386DX clone", "mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_mr_init, NULL },
#endif
//386DX machines which utilize the MCA bus
/* 386DX machines which utilize the MCA bus */
{ "[386DX MCA] IBM PS/2 model 70 (type 3)", "ibmps2_m70_type3", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"IBM",cpus_IBM486BL},{"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 2, 16, 2, 63, machine_ps2_model_70_type3_init, NULL },
{ "[386DX MCA] IBM PS/2 model 80", "ibmps2_m80", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"IBM",cpus_IBM486BL},{"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 1, 12, 1, 63, machine_ps2_model_80_init, NULL },
//486 machines with just the ISA slot
/* 486 machines with just the ISA slot */
{ "[486 ISA] Packard Bell PB410A", "pb410a", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 4, 36, 1, 127, machine_at_pb410a_init, NULL },
//486 machines
/* 486 machines */
{ "[486 VLB] Award 486 clone", "award486", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_init, NULL },
{ "[486 VLB] Dataexpert SX495 (486)", "ami486", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_ami_init, NULL },
{ "[486 VLB] Olystar LIL1429", "ali1429", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_ali1429_init, NULL },
@@ -179,7 +179,9 @@ const machine_t machines[] = {
#endif
{ "[486 VLB] AMI SiS 471", "ami471", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_ami471_init, NULL },
{ "[486 VLB] AMI WinBIOS 486", "win486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_winbios1429_init, NULL },
#if defined(DEV_BRANCH) && defined(USE_WIN471)
{ "[486 VLB] AMI WinBIOS SiS 471", "win471", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_win471_init, NULL },
#endif
{ "[486 VLB] DTK PKM-0038S E-2", "dtk486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_dtk486_init, NULL },
#if defined(DEV_BRANCH) && defined(USE_MR495)
@@ -191,14 +193,15 @@ const machine_t machines[] = {
{ "[486 MCA] IBM PS/2 model 70 (type 4)", "ibmps2_m70_type4", {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO, 2, 16, 2, 63, machine_ps2_model_70_type4_init, NULL },
#endif
//486 machines which utilize the PCI bus
/* 486 machines which utilize the PCI bus */
{ "[486 PCI] ASUS PCI/I-486SP3G", "486sp3g", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_486sp3g_init, NULL },
{ "[486 PCI] Intel Classic/PCI", "alfredo", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_alfredo_init, NULL },
{ "[486 PCI] Lucky Star LS-486E", "ls486e", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_ls486e_init, NULL },
{ "[486 PCI] Rise Computer R418", "r418", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 127, machine_at_r418_init, NULL },
{ "[486 PCI] Zida Tomato 4DP", "4dps", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 127, machine_at_4dps_init, NULL },
//Socket 4 machines
/* Socket 4 machines */
/* 430LX */
{ "[Socket 4 LX] IBM Ambra DP60 PCI", "ambradp60", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_ambradp60_init, NULL },
#if defined(DEV_BRANCH) && defined(USE_VPP60)
{ "[Socket 4 LX] IBM PS/ValuePoint P60", "valuepointp60", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_valuepointp60_init, NULL },
@@ -206,12 +209,13 @@ const machine_t machines[] = {
{ "[Socket 4 LX] Intel Premiere/PCI", "revenge", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_batman_init, NULL },
{ "[Socket 4 LX] Micro Star 586MC1", "586mc1", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_586mc1_init, NULL },
//Socket 5 machines
/* Socket 5 machines */
/* 430NX */
{ "[Socket 5 NX] Intel Premiere/PCI II", "plato", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_plato_init, NULL },
{ "[Socket 5 NX] IBM Ambra DP90 PCI", "ambradp90", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_ambradp90_init, NULL },
{ "[Socket 5 NX] Gigabyte GA-586IP", "430nx", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_430nx_init, NULL },
{ "[Socket 5 FX] AMI Apollo", "apollo", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_apollo_init, NULL },
/* 430FX */
#if defined(DEV_BRANCH) && defined(USE_VECTRA54)
{ "[Socket 5 FX] HP Vectra VL 5 Series 4", "vectra54", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 511, machine_at_vectra54_init, NULL },
#endif
@@ -220,7 +224,8 @@ const machine_t machines[] = {
{ "[Socket 5 FX] PC Partner MB500N", "mb500n", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_mb500n_init, NULL },
{ "[Socket 5 FX] President Award 430FX PCI","president", MACHINE_CPUS_PENTIUM_S5, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 8, 128, 8, 127, machine_at_president_init, NULL },
//Socket 7 machines
/* Socket 7 machines */
/* 430FX */
{ "[Socket 7-3V FX] ASUS P/I-P54TP4XE", "p54tp4xe", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p54tp4xe_init, NULL },
{ "[Socket 7-3V FX] Intel Advanced/ATX", "thor", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_thor_init, NULL },
{ "[Socket 7-3V FX] Intel Advanced/EV", "endeavor", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_endeavor_init, at_endeavor_get_device },
@@ -229,61 +234,86 @@ const machine_t machines[] = {
#endif
{ "[Socket 7-3V FX] Packard Bell PB640", "pb640", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 8, 128, 8, 127, machine_at_pb640_init, at_pb640_get_device },
/* 430HX */
{ "[Socket 7-3V HX] Acer M3a", "acerm3a", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerm3a_init, NULL },
{ "[Socket 7-3V HX] AOpen AP53", "ap53", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_ap53_init, NULL },
{ "[Socket 7-3V HX] SuperMicro Super P55T2S","p55t2s", MACHINE_CPUS_PENTIUM_S73V, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 127, machine_at_p55t2s_init, NULL },
{ "[Socket 7 HX] Acer V35n", "acerv35n", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_acerv35n_init, NULL },
{ "[Socket 7 HX] ASUS P/I-P55T2P4", "p55t2p4", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 127, machine_at_p55t2p4_init, NULL },
{ "[Socket 7 HX] TC430HX", "tc430hx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 255, machine_at_tc430hx_init, NULL },
{ "[Socket 7 HX] Micronics M7S-Hi", "m7shi", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 511, machine_at_m7shi_init, NULL },
{ "[Socket 7 HX] Intel TC430HX", "tc430hx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 255, machine_at_tc430hx_init, NULL },
{ "[Socket 7 HX] Toshiba Equium 5200D", "equium5200", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 192, 8, 127, machine_at_equium5200_init, NULL },
/* 430VX */
{ "[Socket 7 VX] ASUS P/I-P55TVP4", "p55tvp4", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55tvp4_init, NULL },
{ "[Socket 7 VX] Epox P55-VA", "p55va", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55va_init, NULL },
{ "[Socket 7 VX] Jetway J656VXD", "j656vxd", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_j656vxd_init, NULL },
{ "[Socket 7 VX] PC Partner MB520N", "mb520n", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_mb520n_init, NULL },
{ "[Socket 7 VX] Shuttle HOT-557", "430vx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_i430vx_init, NULL },
// txp4 for compatibility reasons
{ "[Socket 7 VX] Epox P55-VA", "p55va", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_p55va_init, NULL },
{ "[Socket 7 VX] HP Brio 80xx", "brio80xx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_brio80xx_init, NULL },
{ "[Socket 7 VX] Packard Bell PB680", "pb680", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_pb680_init, NULL },
/* 430TX */
{ "[Socket 7 TX] ASUS TX97", "tx97", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_tx97_init, NULL },
#if defined(DEV_BRANCH) && defined(NO_SIO)
{ "[Socket 7 TX] Gigabyte GA-586T2", "586t2", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_586t2_init, NULL },
#endif
{ "[Socket 7 TX] Intel YM430TX", "ym430tx", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_ym430tx_init, NULL },
#if defined(DEV_BRANCH) && defined(NO_SIO)
{ "[Socket 7 TX] Iwill P55XB2", "p55xb2", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_p55xb2_init, NULL },
{ "[Socket 7 TX] PC Partner TXA807DS", "807ds", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_807ds_init, NULL },
#endif
{ "[Socket 7 TX] SuperMicro P5MMS98", "p5mms98", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 255, machine_at_p5mms98_init, NULL },
#if defined(DEV_BRANCH) && defined(NO_SIO)
/* Apollo VPX */
{ "[Socket 7 VPX] Zida Tomato TX100", "tx100", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_tx100_init, NULL },
/* Apollo VP3 */
{ "[Socket 7 VP3] QDI Advance II", "advanceii", MACHINE_CPUS_PENTIUM_S7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 128, 8, 127, machine_at_advanceii_init, NULL },
//Super Socket 7 machines
#endif
/* Super Socket 7 machines */
/* Apollo MVP3 */
{ "[Super 7 MVP3] AOpen AX59 Pro", "ax59pro", MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_ax59pro_init, NULL },
{ "[Super 7 MVP3] FIC VA-503+", "ficva503p", MACHINE_CPUS_PENTIUM_SS7, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 255, machine_at_mvp3_init, NULL },
//Socket 8 machines
/* Socket 8 machines */
/* 440FX */
{ "[Socket 8 FX] Gigabyte GA-686NX", "686nx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_686nx_init, NULL },
{ "[Socket 8 FX] PC Partner MB600N", "mb600n", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_mb600n_init, NULL },
{ "[Socket 8 FX] Biostar MB-8500ttc", "8500ttc", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 127, machine_at_8500ttc_init, NULL },
{ "[Socket 8 FX] Micronics M6MI", "m6mi", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 384, 8, 127, machine_at_m6mi_init, NULL },
//Slot 1 machines
#if defined(DEV_BRANCH) && defined(NO_SIO)
{ "[Socket 8 FX] Intel Venus", "vs440fx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 256, 8, 127, machine_at_vs440fx_init, NULL },
#endif
/* Slot 1 machines */
/* 440FX */
{ "[Slot 1 FX] ECS P6KFX-A", "p6kfx", {{"Intel", cpus_PentiumII_28v},{"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 384, 8, 127, machine_at_p6kfx_init, NULL },
/* 440LX */
/* 440BX */
#if defined(DEV_BRANCH) && defined(NO_SIO)
{ "[Slot 1 BX] Gigabyte GA-6BXC", "6bxc", {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_6bxc_init, NULL },
#endif
{ "[Slot 1 BX] ASUS P2B-LS", "p2bls", {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_p2bls_init, NULL },
{ "[Slot 1 BX] ASUS P3B-F", "p3bf", {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_p3bf_init, NULL },
{ "[Slot 1 BX] ABit BF6", "bf6", {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 768, 8, 255, machine_at_bf6_init, NULL },
/* 440ZX */
{ "[Slot 1 ZX] Packard Bell Bora Pro", "borapro", {{"Intel", cpus_PentiumII}, {"Intel/PGA370", cpus_Celeron},{"VIA", cpus_Cyrix3},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 255, machine_at_borapro_init, NULL },
//PGA370 machines
/* PGA370 machines */
/* 440BX */
{ "[Socket 370 BX] ASUS CUBX", "cubx", {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_cubx_init, NULL },
{ "[Socket 370 BX] A-Trend ATC7020BXII", "atc7020bxii", {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_atc7020bxii_init, NULL },
{ "[Socket 370 ZX] Soltek SL-63A1", "63a", {{"Intel", cpus_Celeron}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 255, machine_at_63a_init, NULL },
{ "[Socket 370 APRO] PC Partner APAS3", "apas3", {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_apas3_init, NULL },
#if defined(DEV_BRANCH) && defined(USE_596B)
{ "[Socket 370 APRO] Zida Tomato BX98", "bx98", {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_bx98_init, NULL },
#endif
/* 440ZX */
{ "[Socket 370 ZX] Soltek SL-63A1", "63a", {{"Intel", cpus_Celeron}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 512, 8, 255, machine_at_63a_init, NULL },
/* VIA Apollo Pro */
{ "[Socket 370 APRO] PC Partner APAS3", "apas3", {{"Intel", cpus_Celeron}, {"VIA", cpus_Cyrix3}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 8, 1024, 8, 255, machine_at_apas3_init, NULL },
{ NULL, NULL, {{"", 0}, {"", 0}, {"", 0}, {"", 0}, {"", 0}}, 0, 0, 0, 0, 0, NULL, NULL }
};

View File

@@ -355,14 +355,14 @@ mmutranslatereal_normal(uint32_t addr, int rw)
static uint64_t
mmutranslatereal_pae(uint32_t addr, int rw)
{
uint64_t temp,temp2,temp3;
uint64_t temp,temp2,temp3,temp4;
uint64_t addr2,addr3,addr4;
if (cpu_state.abrt)
return 0xffffffffffffffffULL;
addr2 = (cr3 & ~0x1f) + ((addr >> 27) & 0x18);
temp = temp2 = rammap64(addr2);
temp = temp2 = rammap64(addr2) & 0x000000ffffffffffULL;
if (!(temp & 1)) {
cr2 = addr;
temp &= 1;
@@ -373,8 +373,8 @@ mmutranslatereal_pae(uint32_t addr, int rw)
return 0xffffffffffffffffULL;
}
addr3 = (temp & ~0xfff) + ((addr >> 18) & 0xff8);
temp = rammap64(addr3);
addr3 = (temp & ~0xfffULL) + ((addr >> 18) & 0xff8);
temp = temp4 = rammap64(addr3) & 0x000000ffffffffffULL;
temp3 = temp & temp2;
if (!(temp & 1)) {
cr2 = addr;
@@ -387,8 +387,8 @@ mmutranslatereal_pae(uint32_t addr, int rw)
}
if (temp & 0x80) {
/*4MB page*/
if (((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && (((CPL == 3) && !cpl_override) || (cr0 & WP_FLAG)))) {
/*2MB page*/
if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && (((CPL == 3) && !cpl_override) || (cr0 & WP_FLAG)))) {
cr2 = addr;
temp &= 1;
if (CPL == 3)
@@ -403,12 +403,12 @@ mmutranslatereal_pae(uint32_t addr, int rw)
mmu_perm = temp & 4;
rammap64(addr3) |= 0x20;
return ((temp & ~0x1fffff) + (addr & 0x1fffff)) & 0x0000000fffffffffULL;
return ((temp & ~0x1fffffULL) + (addr & 0x1fffffULL)) & 0x000000ffffffffffULL;
}
addr4 = (temp & ~0xfff) + ((addr >> 9) & 0xff8);
temp = rammap64(addr4);
temp3 = temp & temp3;
addr4 = (temp & ~0xfffULL) + ((addr >> 9) & 0xff8);
temp = rammap64(addr4) & 0x000000ffffffffffULL;
temp3 = temp & temp4;
if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && (((CPL == 3) && !cpl_override) || (cr0 & WP_FLAG)))) {
cr2 = addr;
temp &= 1;
@@ -423,7 +423,7 @@ mmutranslatereal_pae(uint32_t addr, int rw)
rammap64(addr3) |= 0x20;
rammap64(addr4) |= (rw? 0x60 : 0x20);
return ((temp & ~0xfff) + ((uint64_t) (addr & 0xfff))) & 0x0000000fffffffffULL;
return ((temp & ~0xfffULL) + ((uint64_t) (addr & 0xfff))) & 0x000000ffffffffffULL;
}
@@ -481,20 +481,20 @@ mmutranslate_noabrt_normal(uint32_t addr, int rw)
static uint64_t
mmutranslate_noabrt_pae(uint32_t addr, int rw)
{
uint32_t temp,temp2,temp3;
uint32_t addr2,addr3,addr4;
uint64_t temp,temp2,temp3,temp4;
uint64_t addr2,addr3,addr4;
if (cpu_state.abrt)
return 0xffffffffffffffffULL;
addr2 = (cr3 & ~0x1f) + ((addr >> 27) & 0x18);
temp = temp2 = rammap64(addr2);
temp = temp2 = rammap64(addr2) & 0x000000ffffffffffULL;
if (! (temp & 1))
return 0xffffffffffffffffULL;
addr3 = (temp & ~0xfff) + ((addr >> 18) & 0xff8);
temp = rammap64(addr3);
addr3 = (temp & ~0xfffULL) + ((addr >> 18) & 0xff8);
temp = temp4 = rammap64(addr3) & 0x000000ffffffffffULL;
temp3 = temp & temp2;
if (! (temp & 1))
@@ -502,20 +502,20 @@ mmutranslate_noabrt_pae(uint32_t addr, int rw)
if (temp & 0x80) {
/*2MB page*/
if (((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && ((CPL == 3) || (cr0 & WP_FLAG))))
if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && ((CPL == 3) || (cr0 & WP_FLAG))))
return 0xffffffffffffffffULL;
return ((temp & ~0x1fffff) + (addr & 0x1fffff)) & 0x0000000fffffffffULL;
return ((temp & ~0x1fffffULL) + (addr & 0x1fffff)) & 0x000000ffffffffffULL;
}
addr4 = (temp & ~0xfff) + ((addr >> 9) & 0xff8);
temp = rammap64(addr4);
temp3 = temp & temp3;
addr4 = (temp & ~0xfffULL) + ((addr >> 9) & 0xff8);
temp = rammap64(addr4) & 0x000000ffffffffffULL;;
temp3 = temp & temp4;
if (!(temp&1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && ((CPL == 3) || (cr0 & WP_FLAG))))
return 0xffffffffffffffffULL;
return ((temp & ~0xfff) + ((uint64_t) (addr & 0xfff))) & 0x0000000fffffffffULL;
return ((temp & ~0xfffULL) + ((uint64_t) (addr & 0xfff))) & 0x000000ffffffffffULL;
}
@@ -2192,6 +2192,13 @@ mem_set_mem_state_smm(uint32_t base, uint32_t size, int state)
void
mem_add_bios(void)
{
int temp_cpu_type, temp_cpu_16bitbus = 1;
if (AT) {
temp_cpu_type = machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type;
temp_cpu_16bitbus = (temp_cpu_type == CPU_286 || temp_cpu_type == CPU_386SX || temp_cpu_type == CPU_486SLC || temp_cpu_type == CPU_IBM386SLC || temp_cpu_type == CPU_IBM486SLC );
}
if (biosmask > 0x1ffff) {
/* 256k+ BIOS'es only have low mappings at E0000-FFFFF. */
mem_mapping_add(&bios_mapping, 0xe0000, 0x20000,
@@ -2212,12 +2219,12 @@ mem_add_bios(void)
}
if (AT) {
mem_mapping_add(&bios_high_mapping, biosaddr | (cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1,
mem_mapping_add(&bios_high_mapping, biosaddr | (temp_cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1,
mem_read_bios,mem_read_biosw,mem_read_biosl,
mem_write_null,mem_write_nullw,mem_write_nulll,
rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0);
mem_set_mem_state(biosaddr | (cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1,
mem_set_mem_state(biosaddr | (temp_cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1,
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
}
}

View File

@@ -832,7 +832,7 @@ static const device_config_t ms_config[] = {
const device_t mouse_logibus_device = {
"Logitech Bus Mouse",
"Logitech/Microsoft Bus Mouse",
DEVICE_ISA,
MOUSE_TYPE_LOGIBUS,
bm_init, bm_close, NULL,

Binary file not shown.

View File

@@ -617,7 +617,7 @@ threec503_nic_init(const device_t *info)
dev->regs.gacfr = 0x09; /* Start with RAM mapping enabled. */
/* Attach ourselves to the network module. */
network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx, NULL);
network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx, NULL, NULL);
return(dev);
}

View File

@@ -204,11 +204,8 @@ dp8390_write_cr(dp8390_t *dev, uint32_t val)
/* Check for start-tx */
if ((val & 0x04) && dev->TCR.loop_cntl) {
if (dev->TCR.loop_cntl) {
if ((dev->flags & DP8390_FLAG_CHECK_CR) || (dev->flags & DP8390_FLAG_EVEN_MAC))
dp8390_rx(dev, &dev->mem[(dev->tx_page_start * 256) - dev->mem_start],
dev->tx_bytes);
else
dp8390_rx(dev, dev->mem, dev->tx_bytes);
dp8390_rx(dev, &dev->mem[(dev->tx_page_start * 256) - dev->mem_start],
dev->tx_bytes);
}
} else if (val & 0x04) {
if (dev->CR.stop || (!dev->CR.start && (dev->flags & DP8390_FLAG_CHECK_CR))) {
@@ -226,11 +223,8 @@ dp8390_write_cr(dp8390_t *dev, uint32_t val)
/* Send the packet to the system driver */
dev->CR.tx_packet = 1;
if ((dev->flags & DP8390_FLAG_CHECK_CR) || (dev->flags & DP8390_FLAG_EVEN_MAC))
network_tx(&dev->mem[(dev->tx_page_start * 256) - dev->mem_start], dev->tx_bytes);
else
network_tx(dev->mem, dev->tx_bytes);
network_tx(&dev->mem[(dev->tx_page_start * 256) - dev->mem_start], dev->tx_bytes);
/* some more debug */
#ifdef ENABLE_DP8390_LOG
@@ -394,10 +388,7 @@ dp8390_rx(void *priv, uint8_t *buf, int io_len)
pkthdr[0], pkthdr[1], pkthdr[2], pkthdr[3]);
/* Copy into buffer, update curpage, and signal interrupt if config'd */
if ((dev->flags & DP8390_FLAG_CHECK_CR) || (dev->flags & DP8390_FLAG_EVEN_MAC))
startptr = &dev->mem[(dev->curr_page * 256) - dev->mem_start];
else
startptr = dev->mem + ((dev->curr_page * 256) - dev->mem_start);
startptr = &dev->mem[(dev->curr_page * 256) - dev->mem_start];
memcpy(startptr, pkthdr, sizeof(pkthdr));
if ((nextpage > dev->curr_page) ||
((dev->curr_page + pages) == dev->page_stop)) {
@@ -405,10 +396,7 @@ dp8390_rx(void *priv, uint8_t *buf, int io_len)
} else {
endbytes = (dev->page_stop - dev->curr_page) * 256;
memcpy(startptr+sizeof(pkthdr), buf, endbytes-sizeof(pkthdr));
if ((dev->flags & DP8390_FLAG_CHECK_CR) || (dev->flags & DP8390_FLAG_EVEN_MAC))
startptr = &dev->mem[(dev->page_start * 256) - dev->mem_start];
else
startptr = dev->mem + ((dev->page_start * 256) - dev->mem_start);
startptr = &dev->mem[(dev->page_start * 256) - dev->mem_start];
memcpy(startptr, buf+endbytes-sizeof(pkthdr), io_len-endbytes+8);
}
dev->curr_page = nextpage;

View File

@@ -1469,7 +1469,7 @@ nic_init(const device_t *info)
nic_reset(dev);
/* Attach ourselves to the network module. */
network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx, NULL);
network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx, NULL, NULL);
nelog(1, "%s: %s attached IO=0x%X IRQ=%d\n", dev->name,
dev->is_pci?"PCI":"ISA", dev->base_address, dev->base_irq);

View File

@@ -184,7 +184,7 @@ poll_thread(void *arg)
if (pcap == NULL) break;
/* Wait for the next packet to arrive. */
if (network_get_wait() || (poll_card->wait && poll_card->wait(poll_card->priv)))
if (network_get_wait() || (poll_card->set_link_state && poll_card->set_link_state(poll_card->priv)) || (poll_card->wait && poll_card->wait(poll_card->priv)))
data = NULL;
else
data = (uint8_t *)f_pcap_next((void *)pcap, &h);

View File

@@ -64,10 +64,12 @@ typedef struct RTNETETHERHDR
#define MII_MAX_REG 32
#define CSR_MAX_REG 128
/** Maximum number of times we report a link down to the guest (failure to send frame) */
#define PCNET_MAX_LINKDOWN_REPORTED 3
/** Maximum frame size we handle */
#define MAX_FRAME 1536
/** @name Bus configuration registers
* @{ */
#define BCR_MSRDA 0
@@ -230,9 +232,16 @@ typedef struct {
/** Error counter for bad receive descriptors. */
uint32_t uCntBadRMD;
uint16_t u16CSR0LastSeenByGuest;
uint64_t last_poll;
/** If set the link is currently up. */
int fLinkUp;
/** If set the link is temporarily down because of a saved state load. */
int fLinkTempDown;
/** Number of times we've reported the link down. */
uint32_t cLinkDownReported;
/** MS to wait before we enable the link. */
uint32_t cMsLinkUpDelay;
uint8_t maclocal[6]; /* configured MAC (local) address */
pc_timer_t poll_timer, timer_soft_int;
pc_timer_t timer_soft_int, timer_restore;
} nic_t;
/** @todo All structs: big endian? */
@@ -403,6 +412,17 @@ pcnet_do_irq(nic_t *dev, int issue)
}
}
/**
* Checks if the link is up.
* @returns true if the link is up.
* @returns false if the link is down.
*/
static __inline int
pcnetIsLinkUp(nic_t *dev)
{
return !dev->fLinkTempDown && dev->fLinkUp;
}
/**
* Load transmit message descriptor
* Make sure we read the own flag first.
@@ -1214,6 +1234,12 @@ pcnetReceiveNoSync(void *priv, uint8_t *buf, int size)
buf = buf1;
size = 60;
}
/*
* Drop packets if the cable is not connected
*/
if (!pcnetIsLinkUp(dev))
return;
pcnetlog(1, "%s: pcnetReceiveNoSync: RX %x:%x:%x:%x:%x:%x > %x:%x:%x:%x:%x:%x len %d\n", dev->name,
buf[6], buf[7], buf[8], buf[9], buf[10], buf[11],
@@ -1408,6 +1434,28 @@ pcnetReceiveNoSync(void *priv, uint8_t *buf, int size)
pcnetUpdateIrq(dev);
}
/**
* Fails a TMD with a link down error.
*/
static void
pcnetXmitFailTMDLinkDown(nic_t *dev, TMD *pTmd)
{
/* make carrier error - hope this is correct. */
dev->cLinkDownReported++;
pTmd->tmd2.lcar = pTmd->tmd1.err = 1;
dev->aCSR[0] |= 0x8000 | 0x2000; /* ERR | CERR */
}
/**
* Fails a TMD with a generic error.
*/
static void
pcnetXmitFailTMDGeneric(nic_t *dev, TMD *pTmd)
{
/* make carrier error - hope this is correct. */
pTmd->tmd2.lcar = pTmd->tmd1.err = 1;
dev->aCSR[0] |= 0x8000 | 0x2000; /* ERR | CERR */
}
/**
* Actually try transmit frames.
@@ -1435,6 +1483,12 @@ pcnetAsyncTransmit(nic_t *dev)
if (!pcnetTdtePoll(dev, &tmd))
break;
/* Don't continue sending packets when the link is down. */
if ((!pcnetIsLinkUp(dev)
&& dev->cLinkDownReported > PCNET_MAX_LINKDOWN_REPORTED)
)
break;
pcnetlog(3, "%s: TMDLOAD %#010x\n", dev->name, PHYSADDR(dev, CSR_CXDA(dev)));
int fLoopback = CSR_LOOP(dev);
@@ -1446,52 +1500,59 @@ pcnetAsyncTransmit(nic_t *dev)
const int cb = 4096 - tmd.tmd1.bcnt;
pcnetlog("%s: pcnetAsyncTransmit: stp&enp: cb=%d xmtrc=%#x\n", dev->name, cb, CSR_XMTRC(dev));
/* From the manual: ``A zero length buffer is acceptable as
* long as it is not the last buffer in a chain (STP = 0 and
* ENP = 1).'' That means that the first buffer might have a
* zero length if it is not the last one in the chain. */
if (cb <= MAX_FRAME) {
dev->xmit_pos = cb;
DMAPageRead(PHYSADDR(dev, tmd.tmd0.tbadr), dev->abLoopBuf, cb);
if ((pcnetIsLinkUp(dev) || fLoopback)) {
/* From the manual: ``A zero length buffer is acceptable as
* long as it is not the last buffer in a chain (STP = 0 and
* ENP = 1).'' That means that the first buffer might have a
* zero length if it is not the last one in the chain. */
if (cb <= MAX_FRAME) {
dev->xmit_pos = cb;
DMAPageRead(PHYSADDR(dev, tmd.tmd0.tbadr), dev->abLoopBuf, cb);
if (fLoopback) {
if (HOST_IS_OWNER(CSR_CRST(dev)))
pcnetRdtePoll(dev);
if (fLoopback) {
if (HOST_IS_OWNER(CSR_CRST(dev)))
pcnetRdtePoll(dev);
pcnetReceiveNoSync(dev, dev->abLoopBuf, dev->xmit_pos);
pcnetReceiveNoSync(dev, dev->abLoopBuf, dev->xmit_pos);
} else {
pcnetlog(3, "%s: pcnetAsyncTransmit: transmit loopbuf stp and enp, xmit pos = %d\n", dev->name, dev->xmit_pos);
network_tx(dev->abLoopBuf, dev->xmit_pos);
}
} else if (cb == 4096) {
/* The Windows NT4 pcnet driver sometimes marks the first
* unused descriptor as owned by us. Ignore that (by
* passing it back). Do not update the ring counter in this
* case (otherwise that driver becomes even more confused,
* which causes transmit to stall for about 10 seconds).
* This is just a workaround, not a final solution.
*/
/* r=frank: IMHO this is the correct implementation. The
* manual says: ``If the OWN bit is set and the buffer
* length is 0, the OWN bit will be cleared. In the C-LANCE
* the buffer length of 0 is interpreted as a 4096-byte
* buffer.''
*/
/* r=michaln: Perhaps not quite right. The C-LANCE (Am79C90)
* datasheet explains that the old LANCE (Am7990) ignored
* the top four bits next to BCNT and a count of 0 was
* interpreted as 4096. In the C-LANCE, that is still the
* case if the top bits are all ones. If all 16 bits are
* zero, the C-LANCE interprets it as zero-length transmit
* buffer. It's not entirely clear if the later models
* (PCnet-ISA, PCnet-PCI) behave like the C-LANCE or not.
* It is possible that the actual behavior of the C-LANCE
* and later hardware is that the buffer lengths are *16-bit*
* two's complement numbers between 0 and 4096. AMD's drivers
* in fact generally treat the length as a 16-bit quantity. */
pcnetlog(1, "%s: pcnetAsyncTransmit: illegal 4kb frame -> ignoring\n", dev->name);
pcnetTmdStorePassHost(dev, &tmd, PHYSADDR(dev, CSR_CXDA(dev)));
break;
} else {
pcnetlog(3, "%s: pcnetAsyncTransmit: transmit loopbuf stp and enp, xmit pos = %d\n", dev->name, dev->xmit_pos);
network_tx(dev->abLoopBuf, dev->xmit_pos);
pcnetXmitFailTMDGeneric(dev, &tmd);
}
} else if (cb == 4096) {
/* The Windows NT4 pcnet driver sometimes marks the first
* unused descriptor as owned by us. Ignore that (by
* passing it back). Do not update the ring counter in this
* case (otherwise that driver becomes even more confused,
* which causes transmit to stall for about 10 seconds).
* This is just a workaround, not a final solution.
*/
/* r=frank: IMHO this is the correct implementation. The
* manual says: ``If the OWN bit is set and the buffer
* length is 0, the OWN bit will be cleared. In the C-LANCE
* the buffer length of 0 is interpreted as a 4096-byte
* buffer.''
*/
/* r=michaln: Perhaps not quite right. The C-LANCE (Am79C90)
* datasheet explains that the old LANCE (Am7990) ignored
* the top four bits next to BCNT and a count of 0 was
* interpreted as 4096. In the C-LANCE, that is still the
* case if the top bits are all ones. If all 16 bits are
* zero, the C-LANCE interprets it as zero-length transmit
* buffer. It's not entirely clear if the later models
* (PCnet-ISA, PCnet-PCI) behave like the C-LANCE or not.
* It is possible that the actual behavior of the C-LANCE
* and later hardware is that the buffer lengths are *16-bit*
* two's complement numbers between 0 and 4096. AMD's drivers
* in fact generally treat the length as a 16-bit quantity. */
pcnetlog(1, "%s: pcnetAsyncTransmit: illegal 4kb frame -> ignoring\n", dev->name);
pcnetTmdStorePassHost(dev, &tmd, PHYSADDR(dev, CSR_CXDA(dev)));
break;
} else {
pcnetXmitFailTMDLinkDown(dev, &tmd);
}
/* Write back the TMD and pass it to the host (clear own bit). */
@@ -2021,8 +2082,9 @@ pcnet_mii_readw(nic_t *dev, uint16_t miiaddr)
| 0x0008 /* Able to do auto-negotiation. */
| 0x0004 /* Link up. */
| 0x0001; /* Extended Capability, i.e. registers 4+ valid. */
if (isolate) {
if (!dev->fLinkUp || dev->fLinkTempDown || isolate) {
val &= ~(0x0020 | 0x0004);
dev->cLinkDownReported++;
}
if (!autoneg) {
/* Auto-negotiation disabled. */
@@ -2056,7 +2118,7 @@ pcnet_mii_readw(nic_t *dev, uint16_t miiaddr)
case 5:
/* Link partner ability register. */
if (!isolate) {
if (dev->fLinkUp && !dev->fLinkTempDown && !isolate) {
val = 0x8000 /* Next page bit. */
| 0x4000 /* Link partner acked us. */
| 0x0400 /* Can do flow control. */
@@ -2064,23 +2126,25 @@ pcnet_mii_readw(nic_t *dev, uint16_t miiaddr)
| 0x0001; /* Use CSMA selector. */
} else {
val = 0;
dev->cLinkDownReported++;
}
break;
case 6:
/* Auto negotiation expansion register. */
if (!isolate) {
if (dev->fLinkUp && !dev->fLinkTempDown && !isolate) {
val = 0x0008 /* Link partner supports npage. */
| 0x0004 /* Enable npage words. */
| 0x0001; /* Can do N-way auto-negotiation. */
} else {
val = 0;
dev->cLinkDownReported++;
}
break;
case 18:
/* Diagnostic Register (FreeBSD pcn/ac101 driver reads this). */
if (!isolate) {
if (dev->fLinkUp && !dev->fLinkTempDown && !isolate) {
val = 0x1000 /* Receive PLL locked. */
| 0x0200; /* Signal detected. */
@@ -2095,6 +2159,7 @@ pcnet_mii_readw(nic_t *dev, uint16_t miiaddr)
}
} else {
val = 0;
dev->cLinkDownReported++;
}
break;
@@ -2117,6 +2182,11 @@ pcnet_bcr_readw(nic_t *dev, uint16_t rap)
case BCR_LED2:
case BCR_LED3:
val = dev->aBCR[rap] & ~0x8000;
if (dev->fLinkTempDown || !dev->fLinkUp) {
if (rap == 4)
dev->cLinkDownReported++;
val &= ~0x40;
}
val |= (val & 0x017f & dev->u32Lnkst) ? 0x8000 : 0;
break;
@@ -2623,6 +2693,27 @@ pcnet_pci_read(int func, int addr, void *p)
return(0);
}
/**
* Takes down the link temporarily if it's current status is up.
*
* This is used during restore and when replumbing the network link.
*
* The temporary link outage is supposed to indicate to the OS that all network
* connections have been lost and that it for instance is appropriate to
* renegotiate any DHCP lease.
*
* @param pThis The PCnet shared instance data.
*/
static void
pcnetTempLinkDown(nic_t *dev)
{
if (dev->fLinkUp) {
dev->fLinkTempDown = 1;
dev->cLinkDownReported = 0;
dev->aCSR[0] |= 0x8000 | 0x2000; /* ERR | CERR (this is probably wrong) */
timer_set_delay_u64(&dev->timer_restore, (dev->cMsLinkUpDelay * 1000) * TIMER_USEC);
}
}
/**
* Check if the device/driver can receive data now.
@@ -2664,6 +2755,34 @@ pcnetWaitReceiveAvail(void *priv)
return dev->fMaybeOutOfSpace;
}
static int
pcnetSetLinkState(void *priv)
{
nic_t *dev = (nic_t *) priv;
int fLinkUp;
if (dev->fLinkTempDown) {
pcnetTempLinkDown(dev);
return 1;
}
fLinkUp = (dev->fLinkUp && !dev->fLinkTempDown);
if (dev->fLinkUp != fLinkUp) {
dev->fLinkUp = fLinkUp;
if (fLinkUp) {
dev->fLinkTempDown = 1;
dev->cLinkDownReported = 0;
dev->aCSR[0] |= 0x8000 | 0x2000; /* ERR | CERR (this is probably wrong) */
timer_set_delay_u64(&dev->timer_restore, (dev->cMsLinkUpDelay * 1000) * TIMER_USEC);
} else {
dev->cLinkDownReported = 0;
dev->aCSR[0] |= 0x8000 | 0x2000; /* ERR | CERR (this is probably wrong) */
}
}
return 0;
}
static void
pcnetTimerSoftInt(void *priv)
{
@@ -2675,16 +2794,18 @@ pcnetTimerSoftInt(void *priv)
}
static void
pcnetTimerCallback(void *priv)
pcnetTimerRestore(void *priv)
{
nic_t *dev = (nic_t *) priv;
#ifdef ENABLE_PCNET_LOG
pcnetlog(3, "Timer Callback to RX\n");
#endif
pcnetPollRxTx(dev);
timer_disable(&dev->poll_timer);
if (dev->cLinkDownReported <= PCNET_MAX_LINKDOWN_REPORTED) {
timer_advance_u64(&dev->timer_restore, 1500000 * TIMER_USEC);
} else {
dev->fLinkTempDown = 0;
if (dev->fLinkUp) {
dev->aCSR[0] &= ~(0x8000 | 0x2000); /* ERR | CERR - probably not 100% correct either... */
}
}
}
static void *
@@ -2717,10 +2838,19 @@ pcnet_init(const device_t *info)
pcnet_mem_init(dev, 0x0fffff00);
pcnet_mem_disable(dev);
}
dev->maclocal[0] = 0x00; /* 00:0C:87 (AMD OID) */
dev->maclocal[1] = 0x0C;
dev->maclocal[2] = 0x87;
dev->fLinkUp = 1;
dev->cMsLinkUpDelay = 5000;
if (dev->board == DEV_AM79C960_EB) {
dev->maclocal[0] = 0x02; /* 02:07:01 (Racal OID) */
dev->maclocal[1] = 0x07;
dev->maclocal[2] = 0x01;
} else {
dev->maclocal[0] = 0x00; /* 00:0C:87 (AMD OID) */
dev->maclocal[1] = 0x0C;
dev->maclocal[2] = 0x87;
}
/* See if we have a local MAC address configured. */
mac = device_get_config_mac("mac", -1);
@@ -2816,12 +2946,12 @@ pcnet_init(const device_t *info)
pcnetHardReset(dev);
/* Attach ourselves to the network module. */
network_attach(dev, dev->aPROM, pcnetReceiveNoSync, pcnetWaitReceiveAvail);
network_attach(dev, dev->aPROM, pcnetReceiveNoSync, pcnetWaitReceiveAvail, pcnetSetLinkState);
if (dev->board == DEV_AM79C973)
timer_add(&dev->timer_soft_int, pcnetTimerSoftInt, dev, 0);
timer_add(&dev->poll_timer, pcnetTimerCallback, dev, 0);
timer_add(&dev->timer_restore, pcnetTimerRestore, dev, 0);
return(dev);
}
@@ -2838,8 +2968,6 @@ pcnet_close(void *priv)
network_close();
if (dev) {
timer_disable(&dev->poll_timer);
free(dev);
dev = NULL;

View File

@@ -147,7 +147,7 @@ poll_thread(void *arg)
/* Wait for the next packet to arrive. */
data_valid = 0;
if ((!network_get_wait() && !(poll_card->wait && poll_card->wait(poll_card->priv))) && (QueuePeek(slirpq) != 0)) {
if ((!network_get_wait() && !(poll_card->set_link_state && poll_card->set_link_state(poll_card->priv)) && !(poll_card->wait && poll_card->wait(poll_card->priv))) && (QueuePeek(slirpq) != 0)) {
/* Grab a packet from the queue. */
// ui_sb_update_icon(SB_NETWORK, 1);

View File

@@ -175,68 +175,22 @@ wd_soft_reset(void *priv)
}
static uint32_t
wd_ram_read(uint32_t addr, unsigned len, void *priv)
{
wd_t *dev = (wd_t *)priv;
uint32_t ret;
uint16_t ram_mask = dev->ram_size - 1;
ret = dev->dp8390->mem[addr & ram_mask];
if (len == 2)
ret |= dev->dp8390->mem[(addr + 1) & ram_mask] << 8;
return ret;
}
static uint8_t
wd_ram_readb(uint32_t addr, void *priv)
wd_ram_read(uint32_t addr, void *priv)
{
wd_t *dev = (wd_t *)priv;
return wd_ram_read(addr, 1, dev);
wdlog("WD80x3: RAM Read: addr=%06x, val=%02x\n", addr & (dev->ram_size - 1), dev->dp8390->mem[addr & (dev->ram_size - 1)]);
return dev->dp8390->mem[addr & (dev->ram_size - 1)];
}
static uint16_t
wd_ram_readw(uint32_t addr, void *priv)
{
wd_t *dev = (wd_t *)priv;
return wd_ram_read(addr, 2, dev);
}
static void
wd_ram_write(uint32_t addr, uint32_t val, unsigned len, void *priv)
wd_ram_write(uint32_t addr, uint8_t val, void *priv)
{
wd_t *dev = (wd_t *)priv;
uint16_t ram_mask = dev->ram_size - 1;
dev->dp8390->mem[addr & ram_mask] = val & 0xff;
if (len == 2)
dev->dp8390->mem[(addr + 1) & ram_mask] = val >> 8;
}
static void
wd_ram_writeb(uint32_t addr, uint8_t val, void *priv)
{
wd_t *dev = (wd_t *)priv;
wd_ram_write(addr, val, 1, dev);
}
static void
wd_ram_writew(uint32_t addr, uint16_t val, void *priv)
{
wd_t *dev = (wd_t *)priv;
wd_ram_write(addr, val, 2, dev);
dev->dp8390->mem[addr & (dev->ram_size - 1)] = val;
wdlog("WD80x3: RAM Write: addr=%06x, val=%02x\n", addr & (dev->ram_size - 1), val);
}
@@ -605,7 +559,7 @@ wd_mca_write(int port, uint8_t val, void *priv)
* So, remove current address, if any.
*/
if (dev->base_address)
wd_io_remove(dev, dev->base_address);
wd_io_remove(dev, dev->base_address);
dev->base_address = (dev->pos_regs[2] & 0xfe) << 4;
dev->ram_addr = (dev->pos_regs[3] & 0xfc) << 12;
@@ -685,7 +639,7 @@ wd_init(const device_t *info)
dev->dp8390 = device_add(&dp8390_device);
dev->dp8390->priv = dev;
dev->dp8390->interrupt = wd_interrupt;
dp8390_set_defaults(dev->dp8390, DP8390_FLAG_CLEAR_IRQ);
dp8390_set_defaults(dev->dp8390, DP8390_FLAG_CHECK_CR | DP8390_FLAG_CLEAR_IRQ);
switch(dev->board) {
/* Ethernet, ISA, no interface chip, RAM 8k */
@@ -748,30 +702,23 @@ wd_init(const device_t *info)
memcpy(dev->dp8390->physaddr, dev->maclocal, sizeof(dev->maclocal));
wdlog("%s: I/O=%04x, IRQ=%d, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n",
dev->name, dev->base_address, dev->irq,
dev->dp8390->physaddr[0], dev->dp8390->physaddr[1], dev->dp8390->physaddr[2],
dev->dp8390->physaddr[3], dev->dp8390->physaddr[4], dev->dp8390->physaddr[5]);
dev->name, dev->base_address, dev->irq,
dev->dp8390->physaddr[0], dev->dp8390->physaddr[1], dev->dp8390->physaddr[2],
dev->dp8390->physaddr[3], dev->dp8390->physaddr[4], dev->dp8390->physaddr[5]);
/* Reset the board. */
wd_reset(dev);
/* Map this system into the memory map. */
if (dev->bit16 & 1) {
mem_mapping_add(&dev->ram_mapping, dev->ram_addr, dev->ram_size,
wd_ram_readb, wd_ram_readw, NULL,
wd_ram_writeb, wd_ram_writew, NULL,
NULL, MEM_MAPPING_EXTERNAL, dev);
} else {
mem_mapping_add(&dev->ram_mapping, dev->ram_addr, dev->ram_size,
wd_ram_readb, NULL, NULL,
wd_ram_writeb, NULL, NULL,
NULL, MEM_MAPPING_EXTERNAL, dev);
}
mem_mapping_add(&dev->ram_mapping, dev->ram_addr, dev->ram_size,
wd_ram_read, NULL, NULL,
wd_ram_write, NULL, NULL,
NULL, MEM_MAPPING_EXTERNAL, dev);
mem_mapping_disable(&dev->ram_mapping);
/* Attach ourselves to the network module. */
network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx, NULL);
network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx, NULL, NULL);
if (!(dev->board_chip & WE_ID_BUS_MCA)) {
wdlog("%s: attached IO=0x%X IRQ=%d, RAM addr=0x%06x\n", dev->name,

View File

@@ -223,7 +223,7 @@ network_init(void)
* modules.
*/
void
network_attach(void *dev, uint8_t *mac, NETRXCB rx, NETWAITCB wait)
network_attach(void *dev, uint8_t *mac, NETRXCB rx, NETWAITCB wait, NETSETLINKSTATE set_link_state)
{
if (network_card == 0) return;
@@ -231,6 +231,7 @@ network_attach(void *dev, uint8_t *mac, NETRXCB rx, NETWAITCB wait)
net_cards[network_card].priv = dev;
net_cards[network_card].rx = rx;
net_cards[network_card].wait = wait;
net_cards[network_card].set_link_state = set_link_state;
network_mac = mac;
network_set_wait(0);

View File

@@ -710,7 +710,6 @@ void
trc_write(uint16_t port, uint8_t val, void *priv)
{
pci_log("TRC Write: %02X\n", val);
pci_log("TRC Write: %02X\n", val);
if (!(trc_reg & 4) && (val & 4))
trc_reset(val);

View File

@@ -2595,7 +2595,7 @@ scsi_cdrom_get_max(int ide_has_dma, int type)
ret = ide_has_dma ? 2 : -1;
break;
case TYPE_UDMA:
ret = ide_has_dma ? 2 : -1;
ret = ide_has_dma ? 4 /*2*/ : -1;
break;
default:
ret = -1;

View File

@@ -393,6 +393,8 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv)
fdc37c93x_serial_handler(dev, 0);
if (valxor & 0x20)
fdc37c93x_serial_handler(dev, 1);
if ((valxor & 0x40) && (dev->chip_id != 0x02))
fdc37c932fr_access_bus_handler(dev);
break;
}
@@ -406,6 +408,8 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv)
case 0x30:
case 0x60:
case 0x61:
if ((dev->cur_reg == 0x30) && (val & 0x01))
dev->regs[0x22] |= 0x01;
if (valxor)
fdc37c93x_fdc_handler(dev);
break;
@@ -454,6 +458,8 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv)
case 0x60:
case 0x61:
case 0x70:
if ((dev->cur_reg == 0x30) && (val & 0x01))
dev->regs[0x22] |= 0x08;
if (valxor)
fdc37c93x_lpt_handler(dev);
break;
@@ -466,6 +472,8 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv)
case 0x60:
case 0x61:
case 0x70:
if ((dev->cur_reg == 0x30) && (val & 0x01))
dev->regs[0x22] |= 0x10;
if (valxor)
fdc37c93x_serial_handler(dev, 0);
break;
@@ -478,6 +486,8 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv)
case 0x60:
case 0x61:
case 0x70:
if ((dev->cur_reg == 0x30) && (val & 0x01))
dev->regs[0x22] |= 0x20;
if (valxor)
fdc37c93x_serial_handler(dev, 1);
break;
@@ -556,6 +566,8 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv)
case 0x60:
case 0x61:
case 0x70:
if ((dev->cur_reg == 0x30) && (val & 0x01))
dev->regs[0x22] |= 0x40;
if (valxor)
fdc37c932fr_access_bus_handler(dev);
break;
@@ -757,6 +769,8 @@ fdc37c93x_init(const device_t *info)
if (dev->chip_id == 0x03)
dev->access_bus = device_add(&access_bus_device);
io_sethandler(0x370, 0x0002,
fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, dev);
io_sethandler(0x3f0, 0x0002,
fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, dev);

View File

@@ -1179,7 +1179,6 @@ azt_init(const device_t *info)
mpu401_init(azt2316a->mpu, azt2316a->cur_mpu401_addr, azt2316a->cur_mpu401_irq, M_UART, device_get_config_int("receive_input401"));
} else
azt2316a->mpu = NULL;
sb_dsp_set_mpu(&azt2316a->sb->dsp, azt2316a->mpu);
if (device_get_config_int("receive_input"))
midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &azt2316a->sb->dsp);

View File

@@ -184,7 +184,7 @@ sb_update_irq(sb_dsp_t *dsp)
irq_pending = (dsp->sb_irq8 && !dsp->sb_irqm8) ||
(dsp->sb_irq16 && !dsp->sb_irqm16) ||
(dsp->sb_irq401 && !dsp->sb_irq401);
(dsp->sb_irq401 && !dsp->sb_irqm401);
if (irq_pending)
picint(1 << dsp->sb_irqnum);

196
src/usb.c
View File

@@ -1,53 +1,185 @@
/* Copyright holders: Melissa Goad
see COPYING for more details
*/
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Universal Serial Bus emulation (currently dummy UHCI and
* OHCI).
*
*
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2020 Miran Grca.
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/io.h>
#include <86box/mem.h>
#include <86box/usb.h>
void *usb_priv[32];
static int usb_min_card, usb_max_card;
#ifdef ENABLE_USB_LOG
int usb_do_log = ENABLE_USB_LOG;
void (*usb_packet_handle[32])(usb_packet_t* packet, void *priv);
void usb_init(int min_card, int max_card)
static void
usb_log(const char *fmt, ...)
{
int c;
for (c = 0; c < 32; c++)
usb_packet_handle[c] = usb_priv[c] = NULL;
usb_min_card = min_card;
usb_max_card = max_card;
va_list ap;
if (usb_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define usb_log(fmt, ...)
#endif
static uint8_t
uhci_reg_read(uint16_t addr, void *p)
{
uint8_t ret = 0xff;
switch (addr & 0x1f) {
case 0x10: case 0x11: case 0x12: case 0x13:
/* Port status */
ret = 0x00;
break;
}
return ret;
}
void usb_add_specific(int card, void (*packet_handle)(usb_packet_t *packet, void *priv), void *priv)
static void
uhci_reg_write(uint16_t addr, uint8_t val, void *p)
{
usb_packet_handle[card] = packet_handle;
usb_priv[card] = priv;
}
void usb_add(void (*packet_handle)(usb_packet_t *packet, void *priv), void *priv)
void
uhci_update_io_mapping(usb_t *dev, uint8_t base_l, uint8_t base_h, int enable)
{
int c;
for (c = usb_min_card; c <= usb_max_card; c++)
{
if (!usb_packet_handle[c])
{
usb_packet_handle[c] = packet_handle;
usb_priv[c] = priv;
// pclog("USB device added to card: %i\n", c);
return;
}
}
if (dev->uhci_enable && (dev->uhci_io_base != 0x0000))
io_removehandler(dev->uhci_io_base, 0x20, uhci_reg_read, NULL, NULL, uhci_reg_write, NULL, NULL, dev);
dev->uhci_io_base = base_l | (base_h << 8);
dev->uhci_enable = enable;
if (dev->uhci_enable && (dev->uhci_io_base != 0x0000))
io_sethandler(dev->uhci_io_base, 0x20, uhci_reg_read, NULL, NULL, uhci_reg_write, NULL, NULL, dev);
}
static uint8_t
ohci_mmio_read(uint32_t addr, void *p)
{
usb_t *dev = (usb_t *) p;
uint8_t ret = 0x00;
addr &= 0x00000fff;
ret = dev->ohci_mmio[addr];
return ret;
}
static void
ohci_mmio_write(uint32_t addr, uint8_t val, void *p)
{
usb_t *dev = (usb_t *) p;
addr &= 0x00000fff;
switch (addr) {
case 0x08: /* HCCOMMANDSTATUS */
/* bit HostControllerReset must be cleared for the controller to be seen as initialized */
val &= ~0x01;
/* bit OwnershipChangeRequest triggers an ownership change (SMM <-> OS) */
if (val & 0x0f) {
dev->ohci_mmio[0x0f] = 0x40;
dev->ohci_mmio[0x05] &= ~(dev->ohci_mmio[0x05] & 0x01);
}
break;
}
dev->ohci_mmio[addr] = val;
}
void
ohci_update_mem_mapping(usb_t *dev, uint8_t base1, uint8_t base2, uint8_t base3, int enable)
{
if (dev->ohci_enable && (dev->ohci_mem_base != 0x00000000))
mem_mapping_disable(&dev->ohci_mmio_mapping);
dev->ohci_mem_base = ((base1 << 8) | (base2 << 16) | (base3 << 24)) & 0xfffff000;
dev->ohci_enable = enable;
if (dev->ohci_enable && (dev->ohci_mem_base != 0x00000000))
mem_mapping_set_addr(&dev->ohci_mmio_mapping, dev->ohci_mem_base, 0x1000);
}
static void
usb_close(void *priv)
{
usb_t *dev = (usb_t *) priv;
free(dev);
}
static void *
usb_init(const device_t *info)
{
usb_t *dev;
dev = (usb_t *)malloc(sizeof(usb_t));
if (dev == NULL) return(NULL);
memset(dev, 0x00, sizeof(usb_t));
memset(dev->ohci_mmio, 0x00, 4096);
dev->ohci_mmio[0x00] = 0x10;
dev->ohci_mmio[0x01] = 0x01;
dev->ohci_mmio[0x48] = 0x02;
mem_mapping_add(&dev->ohci_mmio_mapping, 0, 0,
ohci_mmio_read, NULL, NULL,
ohci_mmio_write, NULL, NULL,
NULL, MEM_MAPPING_EXTERNAL, dev);
mem_mapping_disable(&dev->ohci_mmio_mapping);
return dev;
}
const device_t usb_device =
{
"Universal Serial Bus",
DEVICE_PCI,
0,
usb_init,
usb_close,
NULL,
NULL,
NULL,
NULL,
NULL
};

View File

@@ -210,6 +210,7 @@ typedef struct virge_t
uint32_t pattern_8[8*8];
uint32_t pattern_16[8*8];
uint32_t pattern_24[8*8];
uint32_t pattern_32[8*8];
uint32_t prdx;
@@ -1072,16 +1073,29 @@ static void fifo_thread(void *param)
{
int x = (fifo->addr_type & FIFO_ADDR) & 4;
int y = ((fifo->addr_type & FIFO_ADDR) >> 3) & 7;
int color, xx;
int byte, addr;
virge->s3d.pattern_8[y*8 + x] = val & 0xff;
virge->s3d.pattern_8[y*8 + x + 1] = val >> 8;
virge->s3d.pattern_8[y*8 + x + 2] = val >> 16;
virge->s3d.pattern_8[y*8 + x + 3] = val >> 24;
x = ((fifo->addr_type & FIFO_ADDR) >> 1) & 6;
y = ((fifo->addr_type & FIFO_ADDR) >> 4) & 7;
virge->s3d.pattern_16[y*8 + x] = val & 0xffff;
virge->s3d.pattern_16[y*8 + x + 1] = val >> 16;
addr = ((fifo->addr_type & FIFO_ADDR) & 0x00ff);
for (xx = 0; xx < 4; xx++) {
x = ((addr + xx) / 3) % 8;
y = ((addr + xx) / 24) % 8;
color = ((addr + xx) % 3) << 3;
byte = (xx << 3);
virge->s3d.pattern_24[y*8 + x] &= ~(0xff << color);
virge->s3d.pattern_24[y*8 + x] |= ((val >> byte) & 0xff) << color;
}
x = ((fifo->addr_type & FIFO_ADDR) >> 2) & 7;
y = ((fifo->addr_type & FIFO_ADDR) >> 5) & 7;
virge->s3d.pattern_32[y*8 + x] = val & 0xffffff;
@@ -1597,6 +1611,8 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p)
{
int x = addr & 4;
int y = (addr >> 3) & 7;
int color, xx;
int byte;
virge->s3d.pattern_8[y*8 + x] = val & 0xff;
virge->s3d.pattern_8[y*8 + x + 1] = val >> 8;
virge->s3d.pattern_8[y*8 + x + 2] = val >> 16;
@@ -1607,6 +1623,16 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p)
virge->s3d.pattern_16[y*8 + x] = val & 0xffff;
virge->s3d.pattern_16[y*8 + x + 1] = val >> 16;
addr &= 0x00ff;
for (xx = 0; xx < 4; xx++) {
x = ((addr + xx) / 3) % 8;
y = ((addr + xx) / 24) % 8;
color = ((addr + xx) % 3) << 3;
byte = (xx << 3);
virge->s3d.pattern_24[y*8 + x] &= ~(0xff << color);
virge->s3d.pattern_24[y*8 + x] |= ((val >> byte) & 0xff) << color;
}
x = (addr >> 2) & 7;
y = (addr >> 5) & 7;
virge->s3d.pattern_32[y*8 + x] = val & 0xffffff;
@@ -1989,7 +2015,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat)
bpp = 2;
x_mul = 3;
cpu_dat_shift = 24;
pattern_data = virge->s3d.pattern_32;
pattern_data = virge->s3d.pattern_24;
src_fg_clr = virge->s3d.src_fg_clr;
src_bg_clr = virge->s3d.src_bg_clr;
break;

View File

@@ -122,8 +122,10 @@ video_cards[] = {
{ "[PCI] Diamond Stealth 3D 3000 (S3 ViRGE/VX)", "stealth3d_3000_pci", &s3_virge_988_pci_device },
{ "[PCI] Diamond Stealth 64 DRAM (S3 Trio64)", "stealth64d_pci", &s3_diamond_stealth64_pci_device },
{ "[PCI] Diamond Stealth 64 VRAM (S3 Vision964)", "stealth64v_pci", &s3_diamond_stealth64_964_pci_device },
#if defined(DEV_BRANCH) && defined(USE_MGA)
{ "[PCI] Matrox Mystique", "mystique", &mystique_device },
{ "[PCI] Matrox Mystique 220", "mystique_220", &mystique_220_device },
#endif
{ "[PCI] Number Nine 9FX (S3 Trio64)", "n9_9fx_pci", &s3_9fx_pci_device },
{ "[PCI] Paradise Bahamas 64 (S3 Vision864)", "bahamas64_pci", &s3_bahamas64_pci_device },
{ "[PCI] Phoenix S3 Vision864", "px_vision864_pci", &s3_phoenix_vision864_pci_device },

View File

@@ -112,6 +112,7 @@ BEGIN
MENUITEM "CGA/PCjr/Tandy/E&GA/(S)VGA overscan", IDM_VID_OVERSCAN
MENUITEM "Change contrast for &monochrome display", IDM_VID_CGACON
END
MENUITEM "&Media", IDM_MEDIA
POPUP "&Tools"
BEGIN
MENUITEM "&Settings...", IDM_CONFIG
@@ -915,6 +916,7 @@ BEGIN
IDS_2123 "Unable to initialize Ghostscript, gsdll32.dll is required for automatic convertion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript files (.ps)."
IDS_2124 "MO %i (%03i): %ls"
IDS_2125 "MO images (*.IM?)\0*.IM?\0All files (*.*)\0*.*\0"
IDS_2126 "Welcome to 86Box!"
END
STRINGTABLE DISCARDABLE

View File

@@ -47,6 +47,9 @@ ifeq ($(DEV_BUILD), y)
ifndef LASERXT
LASERXT := y
endif
ifndef MGA
MGA := y
endif
ifndef MR495
MR495 := y
endif
@@ -83,9 +86,15 @@ ifeq ($(DEV_BUILD), y)
ifndef VNC
VNC := y
endif
ifndef WIN471
WIN471 := y
endif
ifndef XL24
XL24 := y
endif
ifndef NO_SIO
NO_SIO := y
endif
else
ifndef DEBUG
DEBUG := n
@@ -102,6 +111,9 @@ else
ifndef LASERXT
LASERXT := n
endif
ifndef MGA
MGA := n
endif
ifndef MR495
MR495 := n
endif
@@ -135,9 +147,15 @@ else
ifndef VNC
VNC := n
endif
ifndef WIN471
WIN471 := n
endif
ifndef XL24
XL24 := n
endif
ifndef NO_SIO
NO_SIO := n
endif
endif
# Defaults for several build options (possibly defined in a chained file.)
@@ -414,6 +432,11 @@ OPTS += -DUSE_LASERXT
DEVBROBJ += m_xt_laserxt.o
endif
ifeq ($(MGA), y)
OPTS += -DUSE_MGA
DEVBROBJ += vid_mga.o
endif
ifeq ($(MR495), y)
OPTS += -DUSE_MR495
endif
@@ -459,10 +482,18 @@ ifeq ($(VGAWONDER), y)
OPTS += -DUSE_VGAWONDER
endif
ifeq ($(WIN471), y)
OPTS += -DUSE_WIN471
endif
ifeq ($(XL24), y)
OPTS += -DUSE_XL24
endif
ifeq ($(NO_SIO), y)
OPTS += -DNO_SIO
endif
endif
@@ -491,9 +522,9 @@ CXXFLAGS := $(CFLAGS)
#########################################################################
# Create the (final) list of objects to build. #
#########################################################################
MAINOBJ := pc.o config.o random.o timer.o io.o acpi.o apm.o dma.o nmi.o \
pic.o pit.o port_92.o ppi.o pci.o mca.o mcr.o mem.o \
rom.o device.o nvr.o nvr_at.o nvr_ps2.o sst_flash.o via_vt82c586b.o \
MAINOBJ := pc.o config.o random.o timer.o io.o acpi.o apm.o dma.o ddma.o \
nmi.o pic.o pit.o port_92.o ppi.o pci.o mca.o mcr.o mem.o rom.o \
usb.o device.o nvr.o nvr_at.o nvr_ps2.o sst_flash.o via_vt82c586b.o \
via_vt82c596b.o $(VNCOBJ)
INTELOBJ := intel_flash.o \
@@ -639,7 +670,6 @@ VIDOBJ := video.o \
vid_et4000.o vid_sc1502x_ramdac.o \
vid_et4000w32.o vid_stg_ramdac.o \
vid_ht216.o \
vid_mga.o \
vid_oak_oti.o \
vid_paradise.o \
vid_ti_cf62011.o \

View File

@@ -47,6 +47,9 @@ ifeq ($(DEV_BUILD), y)
ifndef LASERXT
LASERXT := y
endif
ifndef MGA
MGA := y
endif
ifndef MR495
MR495 := y
endif
@@ -83,9 +86,15 @@ ifeq ($(DEV_BUILD), y)
ifndef VNC
VNC := y
endif
ifndef WIN471
WIN471 := y
endif
ifndef XL24
XL24 := y
endif
ifndef NO_SIO
NO_SIO := y
endif
else
ifndef DEBUG
DEBUG := n
@@ -102,6 +111,9 @@ else
ifndef LASERXT
LASERXT := n
endif
ifndef MGA
MGA := n
endif
ifndef MR495
MR495 := n
endif
@@ -138,9 +150,15 @@ else
ifndef VNC
VNC := n
endif
ifndef WIN471
WIN471 := n
endif
ifndef XL24
XL24 := n
endif
ifndef NO_SIO
NO_SIO := n
endif
endif
# Defaults for several build options (possibly defined in a chained file.)
@@ -423,6 +441,11 @@ OPTS += -DUSE_LASERXT
DEVBROBJ += m_xt_laserxt.o
endif
ifeq ($(MGA), y)
OPTS += -DUSE_MGA
DEVBROBJ += vid_mga.o
endif
ifeq ($(MR495), y)
OPTS += -DUSE_MR495
endif
@@ -468,10 +491,18 @@ ifeq ($(VGAWONDER), y)
OPTS += -DUSE_VGAWONDER
endif
ifeq ($(WIN471), y)
OPTS += -DUSE_WIN471
endif
ifeq ($(XL24), y)
OPTS += -DUSE_XL24
endif
ifeq ($(NO_SIO), y)
OPTS += -DNO_SIO
endif
endif
@@ -495,9 +526,9 @@ CXXFLAGS := $(CFLAGS)
#########################################################################
# Create the (final) list of objects to build. #
#########################################################################
MAINOBJ := pc.o config.o random.o timer.o io.o acpi.o apm.o dma.o nmi.o \
pic.o pit.o port_92.o ppi.o pci.o mca.o mcr.o mem.o \
rom.o device.o nvr.o nvr_at.o nvr_ps2.o sst_flash.o via_vt82c586b.o \
MAINOBJ := pc.o config.o random.o timer.o io.o acpi.o apm.o dma.o ddma.o \
nmi.o pic.o pit.o port_92.o ppi.o pci.o mca.o mcr.o mem.o rom.o \
usb.o device.o nvr.o nvr_at.o nvr_ps2.o sst_flash.o via_vt82c586b.o \
via_vt82c596b.o $(VNCOBJ)
INTELOBJ := intel_flash.o \
@@ -643,7 +674,6 @@ VIDOBJ := video.o \
vid_et4000.o vid_sc1502x_ramdac.o \
vid_et4000w32.o vid_stg_ramdac.o \
vid_ht216.o \
vid_mga.o \
vid_oak_oti.o \
vid_paradise.o \
vid_ti_cf62011.o \

View File

@@ -233,7 +233,8 @@ CreateConsole(int init)
int i;
if (! init) {
FreeConsole();
if (force_debug)
FreeConsole();
return;
}
@@ -271,6 +272,13 @@ CreateConsole(int init)
}
static void
CloseConsole(void)
{
CreateConsole(0);
}
/* Process the commandline, and create standard argc/argv array. */
static int
ProcessCommandLine(wchar_t ***argw)
@@ -362,7 +370,8 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nCmdShow)
set_language(0x0409);
/* Create console window. */
CreateConsole(1);
if (force_debug)
CreateConsole(1);
/* Process the command line for options. */
argc = ProcessCommandLine(&argw);
@@ -370,7 +379,8 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nCmdShow)
/* Pre-initialize the system, this loads the config file. */
if (! pc_init(argc, argw)) {
/* Detach from console. */
CreateConsole(0);
if (force_debug)
CreateConsole(0);
if (source_hwnd)
PostMessage((HWND) (uintptr_t) source_hwnd, WM_HAS_SHUTDOWN, (WPARAM) 0, (LPARAM) hwndMain);
@@ -380,9 +390,8 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nCmdShow)
return(1);
}
/* Cleanup: we may no longer need the console. */
if (! force_debug)
CreateConsole(0);
if (force_debug)
atexit(CloseConsole);
/* Handle our GUI. */
i = ui_init(nCmdShow);

View File

@@ -53,6 +53,7 @@ AboutDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
case IDCANCEL:
EndDialog(hdlg, 0);
plat_pause(0);
return TRUE;

View File

@@ -59,7 +59,7 @@ static void rebuild_axis_button_selections(HWND hdlg)
sprintf(s, "%s (Y axis)", plat_joystick_state[joystick-1].pov[d].name);
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s);
}
for (d = 0; d < plat_joystick_state[joystick - 1].nr_sliders; d++)
for (d = 0; d < plat_joystick_state[joystick - 1].nr_sliders; d++)
{
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)plat_joystick_state[joystick - 1].slider[d].name);
}
@@ -126,8 +126,7 @@ static int get_axis(HWND hdlg, int id)
HWND h = GetDlgItem(hdlg, id);
int axis_sel = SendMessage(h, CB_GETCURSEL, 0, 0);
int nr_axes = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr-1].nr_axes;
int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_povs;
int nr_sliders = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_sliders;
int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_povs;
if (axis_sel < nr_axes)
return axis_sel;
@@ -175,7 +174,6 @@ joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
int joystick;
int nr_axes;
int nr_povs;
int nr_sliders;
int mapping;
switch (message)
@@ -199,7 +197,6 @@ joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
{
nr_axes = plat_joystick_state[joystick-1].nr_axes;
nr_povs = plat_joystick_state[joystick-1].nr_povs;
nr_sliders = plat_joystick_state[joystick - 1].nr_sliders;
for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++)
{
@@ -211,8 +208,8 @@ joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
else if (mapping & POV_Y)
SendMessage(h, CB_SETCURSEL, nr_axes + (mapping & 3)*2 + 1, 0);
else if (mapping & SLIDER)
SendMessage(h, CB_SETCURSEL, nr_axes + nr_povs * 2 + (mapping & 3), 0);
else
SendMessage(h, CB_SETCURSEL, nr_axes + nr_povs * 2 + (mapping & 3), 0);
else
SendMessage(h, CB_SETCURSEL, mapping, 0);
id += 2;
}

View File

@@ -2352,7 +2352,10 @@ win_settings_hard_disks_update_item(HWND hwndList, int i, int column)
lvI.pszText = szText;
lvI.iImage = 0;
} else if (column == 1) {
lvI.pszText = temp_hdd[i].fn;
if (!wcsnicmp(temp_hdd[i].fn, usr_path, wcslen(usr_path)))
lvI.pszText = temp_hdd[i].fn + wcslen(usr_path);
else
lvI.pszText = temp_hdd[i].fn;
lvI.iImage = 0;
} else if (column == 2) {
wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].tracks);
@@ -2421,7 +2424,10 @@ win_settings_hard_disks_recalc_list(HWND hwndList)
return FALSE;
lvI.iSubItem = 1;
lvI.pszText = temp_hdd[i].fn;
if (!wcsnicmp(temp_hdd[i].fn, usr_path, wcslen(usr_path)))
lvI.pszText = temp_hdd[i].fn + wcslen(usr_path);
else
lvI.pszText = temp_hdd[i].fn;
lvI.iItem = j;
lvI.iImage = 0;

View File

@@ -72,6 +72,9 @@ static int sb_parts = 0;
static int sb_ready = 0;
static uint8_t sb_map[256];
static HMENU hmenuMedia;
static HMENU *media_menu_handles;
/* Also used by win_settings.c */
intptr_t
@@ -483,10 +486,33 @@ ui_sb_update_tip(int meaning)
}
SendMessage(hwndSBAR, SB_SETTIPTEXT, part, (LPARAM)sbTips[part]);
ModifyMenu(hmenuMedia, part, MF_BYPOSITION, (UINT_PTR)media_menu_handles[part], sbTips[part]);
}
}
static void
MediaMenuDestroyMenus(void)
{
int i;
if (sb_parts == 0) return;
if (! media_menu_handles) return;
for (i=0; i<sb_parts; i++) {
if (media_menu_handles[i]) {
RemoveMenu(hmenuMedia, (UINT_PTR)media_menu_handles[i], MF_BYCOMMAND);
DestroyMenu(media_menu_handles[i]);
media_menu_handles[i] = NULL;
}
}
free(media_menu_handles);
media_menu_handles = NULL;
}
static void
StatusBarDestroyMenus(void)
{
@@ -529,6 +555,18 @@ StatusBarDestroyTips(void)
}
static HMENU
MediaMenuCreatePopupMenu(int part)
{
HMENU h;
h = CreatePopupMenu();
AppendMenu(hmenuMedia, MF_POPUP | MF_STRING, (UINT_PTR)h, 0);
return(h);
}
static HMENU
StatusBarCreatePopupMenu(int part)
{
@@ -594,6 +632,7 @@ ui_sb_update_panes(void)
}
StatusBarDestroyMenus();
StatusBarDestroyTips();
MediaMenuDestroyMenus();
}
memset(sb_map, 0xff, sizeof(sb_map));
@@ -656,6 +695,8 @@ ui_sb_update_panes(void)
memset(sb_menu_handles, 0, sb_parts * sizeof(HMENU));
sbTips = (WCHAR **)malloc(sb_parts * sizeof(WCHAR *));
memset(sbTips, 0, sb_parts * sizeof(WCHAR *));
media_menu_handles = (HMENU *)malloc(sb_parts * sizeof(HMENU));
memset(media_menu_handles, 0, sb_parts * sizeof(HMENU));
sb_parts = 0;
for (i=0; i<FDD_NUM; i++) {
@@ -777,9 +818,15 @@ ui_sb_update_panes(void)
sb_part_icons[i] = (wcslen(floppyfns[sb_part_meanings[i] & 0xf]) == 0) ? 128 : 0;
sb_part_icons[i] |= fdd_type_to_icon(fdd_get_type(sb_part_meanings[i] & 0xf));
sb_menu_handles[i] = StatusBarCreatePopupMenu(i);
media_menu_handles[i] = MediaMenuCreatePopupMenu(i);
StatusBarCreateFloppySubmenu(sb_menu_handles[i], sb_part_meanings[i] & 0xf);
StatusBarCreateFloppySubmenu(media_menu_handles[i], sb_part_meanings[i] & 0xf);
EnableMenuItem(sb_menu_handles[i], IDM_FLOPPY_EJECT | (sb_part_meanings[i] & 0xf), MF_BYCOMMAND | ((sb_part_icons[i] & 128) ? MF_GRAYED : MF_ENABLED));
EnableMenuItem(media_menu_handles[i], IDM_FLOPPY_EJECT | (sb_part_meanings[i] & 0xf), MF_BYCOMMAND | ((sb_part_icons[i] & 128) ? MF_GRAYED : MF_ENABLED));
StatusBarCreateFloppyTip(i);
break;
case SB_CDROM: /* CD-ROM */
@@ -790,27 +837,45 @@ ui_sb_update_panes(void)
sb_part_icons[i] = 128;
sb_part_icons[i] |= 32;
sb_menu_handles[i] = StatusBarCreatePopupMenu(i);
media_menu_handles[i] = MediaMenuCreatePopupMenu(i);
StatusBarCreateCdromSubmenu(sb_menu_handles[i], sb_part_meanings[i] & 0xf);
StatusBarCreateCdromSubmenu(media_menu_handles[i], sb_part_meanings[i] & 0xf);
EnableMenuItem(sb_menu_handles[i], IDM_CDROM_RELOAD | (sb_part_meanings[i] & 0xf), MF_BYCOMMAND | MF_GRAYED);
EnableMenuItem(media_menu_handles[i], IDM_CDROM_RELOAD | (sb_part_meanings[i] & 0xf), MF_BYCOMMAND | MF_GRAYED);
StatusBarCreateCdromTip(i);
break;
case SB_ZIP: /* Iomega ZIP */
sb_part_icons[i] = (wcslen(zip_drives[sb_part_meanings[i] & 0xf].image_path) == 0) ? 128 : 0;
sb_part_icons[i] |= 48;
sb_menu_handles[i] = StatusBarCreatePopupMenu(i);
media_menu_handles[i] = MediaMenuCreatePopupMenu(i);
StatusBarCreateZIPSubmenu(sb_menu_handles[i], sb_part_meanings[i] & 0xf);
StatusBarCreateZIPSubmenu(media_menu_handles[i], sb_part_meanings[i] & 0xf);
EnableMenuItem(sb_menu_handles[i], IDM_ZIP_EJECT | (sb_part_meanings[i] & 0xf), MF_BYCOMMAND | ((sb_part_icons[i] & 128) ? MF_GRAYED : MF_ENABLED));
EnableMenuItem(media_menu_handles[i], IDM_ZIP_EJECT | (sb_part_meanings[i] & 0xf), MF_BYCOMMAND | ((sb_part_icons[i] & 128) ? MF_GRAYED : MF_ENABLED));
StatusBarCreateZIPTip(i);
break;
case SB_MO: /* Magneto-Optical disk */
sb_part_icons[i] = (wcslen(mo_drives[sb_part_meanings[i] & 0xf].image_path) == 0) ? 128 : 0;
sb_part_icons[i] |= 56;
sb_menu_handles[i] = StatusBarCreatePopupMenu(i);
media_menu_handles[i] = MediaMenuCreatePopupMenu(i);
StatusBarCreateMOSubmenu(sb_menu_handles[i], sb_part_meanings[i] & 0xf);
StatusBarCreateMOSubmenu(media_menu_handles[i], sb_part_meanings[i] & 0xf);
EnableMenuItem(sb_menu_handles[i], IDM_MO_EJECT | (sb_part_meanings[i] & 0xf), MF_BYCOMMAND | ((sb_part_icons[i] & 128) ? MF_GRAYED : MF_ENABLED));
EnableMenuItem(media_menu_handles[i], IDM_MO_EJECT | (sb_part_meanings[i] & 0xf), MF_BYCOMMAND | ((sb_part_icons[i] & 128) ? MF_GRAYED : MF_ENABLED));
StatusBarCreateMOTip(i);
break;
case SB_HDD: /* Hard disk */
@@ -838,6 +903,7 @@ ui_sb_update_panes(void)
SendMessage(hwndSBAR, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM)L"");
SendMessage(hwndSBAR, SB_SETICON, i, (LPARAM)hIcon[sb_part_icons[i]]);
SendMessage(hwndSBAR, SB_SETTIPTEXT, i, (LPARAM)sbTips[i]);
ModifyMenu(hmenuMedia, i, MF_BYPOSITION, (UINT_PTR)media_menu_handles[i], sbTips[i]);
} else
SendMessage(hwndSBAR, SB_SETICON, i, (LPARAM)NULL);
}
@@ -868,8 +934,8 @@ ui_sb_mount_floppy_img(uint8_t id, int part, uint8_t wp, wchar_t *file_name)
fdd_load(id, file_name);
if (sb_ready) {
ui_sb_update_icon_state(SB_FLOPPY | id, wcslen(floppyfns[id]) ? 0 : 1);
EnableMenuItem(sb_menu_handles[part], IDM_FLOPPY_EJECT | id, MF_BYCOMMAND | (wcslen(floppyfns[id]) ? MF_ENABLED : MF_GRAYED));
EnableMenuItem(sb_menu_handles[part], IDM_FLOPPY_EXPORT_TO_86F | id, MF_BYCOMMAND | (wcslen(floppyfns[id]) ? MF_ENABLED : MF_GRAYED));
ui_sb_enable_menu_item(SB_FLOPPY | id, IDM_FLOPPY_EJECT | id, MF_BYCOMMAND | (wcslen(floppyfns[id]) ? MF_ENABLED : MF_GRAYED));
ui_sb_enable_menu_item(SB_FLOPPY | id, IDM_FLOPPY_EXPORT_TO_86F | id, MF_BYCOMMAND | (wcslen(floppyfns[id]) ? MF_ENABLED : MF_GRAYED));
ui_sb_update_tip(SB_FLOPPY | id);
}
config_save();
@@ -887,8 +953,8 @@ ui_sb_mount_zip_img(uint8_t id, int part, uint8_t wp, wchar_t *file_name)
zip_insert(dev);
if (sb_ready) {
ui_sb_update_icon_state(SB_ZIP | id, wcslen(zip_drives[id].image_path) ? 0 : 1);
EnableMenuItem(sb_menu_handles[part], IDM_ZIP_EJECT | id, MF_BYCOMMAND | (wcslen(zip_drives[id].image_path) ? MF_ENABLED : MF_GRAYED));
EnableMenuItem(sb_menu_handles[part], IDM_ZIP_RELOAD | id, MF_BYCOMMAND | (wcslen(zip_drives[id].image_path) ? MF_GRAYED : MF_ENABLED));
ui_sb_enable_menu_item(SB_ZIP | id, IDM_ZIP_EJECT | id, MF_BYCOMMAND | (wcslen(zip_drives[id].image_path) ? MF_ENABLED : MF_GRAYED));
ui_sb_enable_menu_item(SB_ZIP | id, IDM_ZIP_RELOAD | id, MF_BYCOMMAND | (wcslen(zip_drives[id].image_path) ? MF_GRAYED : MF_ENABLED));
ui_sb_update_tip(SB_ZIP | id);
}
config_save();
@@ -905,13 +971,203 @@ ui_sb_mount_mo_img(uint8_t id, int part, uint8_t wp, wchar_t *file_name)
mo_insert(dev);
if (sb_ready) {
ui_sb_update_icon_state(SB_MO | id, wcslen(mo_drives[id].image_path) ? 0 : 1);
EnableMenuItem(sb_menu_handles[part], IDM_MO_EJECT | id, MF_BYCOMMAND | (wcslen(zip_drives[id].image_path) ? MF_ENABLED : MF_GRAYED));
EnableMenuItem(sb_menu_handles[part], IDM_MO_RELOAD | id, MF_BYCOMMAND | (wcslen(zip_drives[id].image_path) ? MF_GRAYED : MF_ENABLED));
ui_sb_enable_menu_item(SB_MO | id, IDM_MO_EJECT | id, MF_BYCOMMAND | (wcslen(zip_drives[id].image_path) ? MF_ENABLED : MF_GRAYED));
ui_sb_enable_menu_item(SB_MO | id, IDM_MO_RELOAD | id, MF_BYCOMMAND | (wcslen(zip_drives[id].image_path) ? MF_GRAYED : MF_ENABLED));
ui_sb_update_tip(SB_MO | id);
}
config_save();
}
int
MediaMenuHandler(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int id = 0, ret = 0;
uint8_t part = 0;
WCHAR temp_path[1024];
int item_id, item_params;
item_id = LOWORD(wParam) & 0xff00; /* low 8 bits */
item_params = LOWORD(wParam) & 0x00ff; /* high 8 bits */
switch (item_id) {
case IDM_FLOPPY_IMAGE_NEW:
id = item_params & 0x0003;
part = sb_map[SB_FLOPPY | id];
if ((part == 0xff) || (sb_menu_handles == NULL))
break;
NewFloppyDialogCreate(hwnd, id, part);
break;
case IDM_FLOPPY_IMAGE_EXISTING:
case IDM_FLOPPY_IMAGE_EXISTING_WP:
id = item_params & 0x0003;
part = sb_map[SB_FLOPPY | id];
if ((part == 0xff) || (sb_menu_handles == NULL))
break;
ret = file_dlg_w_st(hwnd, IDS_2118, floppyfns[id], 0);
if (! ret)
ui_sb_mount_floppy_img(id, part, (item_id == IDM_FLOPPY_IMAGE_EXISTING_WP) ? 1 : 0, wopenfilestring);
break;
case IDM_FLOPPY_EJECT:
id = item_params & 0x0003;
part = sb_map[SB_FLOPPY | id];
if ((part == 0xff) || (sb_menu_handles == NULL))
break;
fdd_close(id);
ui_sb_update_icon_state(SB_FLOPPY | id, 1);
ui_sb_enable_menu_item(SB_FLOPPY | id, IDM_FLOPPY_EJECT | id, MF_BYCOMMAND | MF_GRAYED);
ui_sb_enable_menu_item(SB_FLOPPY | id, IDM_FLOPPY_EJECT | id, MF_BYCOMMAND | MF_GRAYED);
ui_sb_update_tip(SB_FLOPPY | id);
config_save();
break;
case IDM_FLOPPY_EXPORT_TO_86F:
id = item_params & 0x0003;
part = sb_map[SB_FLOPPY | id];
if ((part == 0xff) || (sb_menu_handles == NULL))
break;
ret = file_dlg_w_st(hwnd, IDS_2076, floppyfns[id], 1);
if (! ret) {
plat_pause(1);
ret = d86f_export(id, wopenfilestring);
if (!ret)
ui_msgbox(MBX_ERROR, (wchar_t *)IDS_4108);
plat_pause(0);
}
break;
case IDM_CDROM_MUTE:
id = item_params & 0x0007;
part = sb_map[SB_CDROM | id];
if ((part == 0xff) || (sb_menu_handles == NULL))
break;
cdrom[id].sound_on ^= 1;
ui_sb_check_menu_item(SB_CDROM | id, IDM_CDROM_MUTE | id, cdrom[id].sound_on ? MF_UNCHECKED : MF_CHECKED);
config_save();
sound_cd_thread_reset();
break;
case IDM_CDROM_EMPTY:
id = item_params & 0x0007;
part = sb_map[SB_CDROM | id];
if ((part == 0xff) || (sb_menu_handles == NULL))
break;
cdrom_eject(id);
break;
case IDM_CDROM_RELOAD:
id = item_params & 0x0007;
part = sb_map[SB_CDROM | id];
if ((part == 0xff) || (sb_menu_handles == NULL))
break;
cdrom_reload(id);
break;
case IDM_CDROM_IMAGE:
id = item_params & 0x0007;
part = sb_map[SB_CDROM | id];
if ((part == 0xff) || (sb_menu_handles == NULL))
break;
if (!file_dlg_w_st(hwnd, IDS_2075, cdrom[id].image_path, 0)) {
cdrom[id].prev_host_drive = cdrom[id].host_drive;
wcscpy(temp_path, wopenfilestring);
wcscpy(cdrom[id].prev_image_path, cdrom[id].image_path);
if (cdrom[id].ops && cdrom[id].ops->exit)
cdrom[id].ops->exit(&(cdrom[id]));
cdrom[id].ops = NULL;
memset(cdrom[id].image_path, 0, sizeof(cdrom[id].image_path));
cdrom_image_open(&(cdrom[id]), temp_path);
/* Signal media change to the emulated machine. */
if (cdrom[id].insert)
cdrom[id].insert(cdrom[id].priv);
cdrom[id].host_drive = (wcslen(cdrom[id].image_path) == 0) ? 0 : 200;
if (cdrom[id].host_drive == 200) {
ui_sb_check_menu_item(SB_CDROM | id, IDM_CDROM_EMPTY | id, MF_UNCHECKED);
ui_sb_check_menu_item(SB_CDROM | id, IDM_CDROM_IMAGE | id, MF_CHECKED);
ui_sb_update_icon_state(SB_CDROM | id, 0);
} else {
ui_sb_check_menu_item(SB_CDROM | id, IDM_CDROM_IMAGE | id, MF_UNCHECKED);
ui_sb_check_menu_item(SB_CDROM | id, IDM_CDROM_EMPTY | id, MF_CHECKED);
ui_sb_update_icon_state(SB_CDROM | id, 1);
}
ui_sb_enable_menu_item(SB_CDROM | id, IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_GRAYED);
ui_sb_update_tip(SB_CDROM | id);
config_save();
}
break;
case IDM_ZIP_IMAGE_NEW:
id = item_params & 0x0003;
part = sb_map[SB_ZIP | id];
NewFloppyDialogCreate(hwnd, id | 0x80, part); /* NewZIPDialogCreate */
break;
case IDM_ZIP_IMAGE_EXISTING:
case IDM_ZIP_IMAGE_EXISTING_WP:
id = item_params & 0x0003;
part = sb_map[SB_ZIP | id];
if ((part == 0xff) || (sb_menu_handles == NULL))
break;
ret = file_dlg_w_st(hwnd, IDS_2058, zip_drives[id].image_path, 0);
if (! ret)
ui_sb_mount_zip_img(id, part, (item_id == IDM_ZIP_IMAGE_EXISTING_WP) ? 1 : 0, wopenfilestring);
break;
case IDM_ZIP_EJECT:
id = item_params & 0x0003;
zip_eject(id);
break;
case IDM_ZIP_RELOAD:
id = item_params & 0x0003;
zip_reload(id);
break;
case IDM_MO_IMAGE_NEW:
id = item_params & 0x0003;
part = sb_map[SB_MO | id];
NewFloppyDialogCreate(hwnd, id | 0x80, part); /* NewZIPDialogCreate */
break;
case IDM_MO_IMAGE_EXISTING:
case IDM_MO_IMAGE_EXISTING_WP:
id = item_params & 0x0003;
part = sb_map[SB_MO | id];
if ((part == 0xff) || (sb_menu_handles == NULL))
break;
ret = file_dlg_w_st(hwnd, IDS_2125, mo_drives[id].image_path, 0);
if (! ret)
ui_sb_mount_mo_img(id, part, (item_id == IDM_MO_IMAGE_EXISTING_WP) ? 1 : 0, wopenfilestring);
break;
case IDM_MO_EJECT:
id = item_params & 0x0003;
mo_eject(id);
break;
case IDM_MO_RELOAD:
id = item_params & 0x0003;
mo_reload(id);
break;
default:
return(0);
}
return(1);
}
/* Handle messages for the Status Bar window. */
#if defined(__amd64__) || defined(__aarch64__)
@@ -921,195 +1177,13 @@ static BOOL CALLBACK
#endif
StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
WCHAR temp_path[1024];
RECT rc;
POINT pt;
int ret = 0;
int item_id = 0;
int item_params = 0;
int id = 0;
uint8_t part = 0;
switch (message) {
case WM_COMMAND:
item_id = LOWORD(wParam) & 0xff00; /* low 8 bits */
item_params = LOWORD(wParam) & 0x00ff; /* high 8 bits */
switch (item_id) {
case IDM_FLOPPY_IMAGE_NEW:
id = item_params & 0x0003;
part = sb_map[SB_FLOPPY | id];
if ((part == 0xff) || (sb_menu_handles == NULL))
break;
NewFloppyDialogCreate(hwnd, id, part);
break;
case IDM_FLOPPY_IMAGE_EXISTING:
case IDM_FLOPPY_IMAGE_EXISTING_WP:
id = item_params & 0x0003;
part = sb_map[SB_FLOPPY | id];
if ((part == 0xff) || (sb_menu_handles == NULL))
break;
ret = file_dlg_w_st(hwnd, IDS_2118, floppyfns[id], 0);
if (! ret)
ui_sb_mount_floppy_img(id, part, (item_id == IDM_FLOPPY_IMAGE_EXISTING_WP) ? 1 : 0, wopenfilestring);
break;
case IDM_FLOPPY_EJECT:
id = item_params & 0x0003;
part = sb_map[SB_FLOPPY | id];
if ((part == 0xff) || (sb_menu_handles == NULL))
break;
fdd_close(id);
ui_sb_update_icon_state(SB_FLOPPY | id, 1);
EnableMenuItem(sb_menu_handles[part], IDM_FLOPPY_EJECT | id, MF_BYCOMMAND | MF_GRAYED);
EnableMenuItem(sb_menu_handles[part], IDM_FLOPPY_EXPORT_TO_86F | id, MF_BYCOMMAND | MF_GRAYED);
ui_sb_update_tip(SB_FLOPPY | id);
config_save();
break;
case IDM_FLOPPY_EXPORT_TO_86F:
id = item_params & 0x0003;
part = sb_map[SB_FLOPPY | id];
if ((part == 0xff) || (sb_menu_handles == NULL))
break;
ret = file_dlg_w_st(hwnd, IDS_2076, floppyfns[id], 1);
if (! ret) {
plat_pause(1);
ret = d86f_export(id, wopenfilestring);
if (!ret)
ui_msgbox(MBX_ERROR, (wchar_t *)IDS_4108);
plat_pause(0);
}
break;
case IDM_CDROM_MUTE:
id = item_params & 0x0007;
part = sb_map[SB_CDROM | id];
if ((part == 0xff) || (sb_menu_handles == NULL))
break;
cdrom[id].sound_on ^= 1;
CheckMenuItem(sb_menu_handles[part], IDM_CDROM_MUTE | id, cdrom[id].sound_on ? MF_UNCHECKED : MF_CHECKED);
config_save();
sound_cd_thread_reset();
break;
case IDM_CDROM_EMPTY:
id = item_params & 0x0007;
part = sb_map[SB_CDROM | id];
if ((part == 0xff) || (sb_menu_handles == NULL))
break;
cdrom_eject(id);
break;
case IDM_CDROM_RELOAD:
id = item_params & 0x0007;
part = sb_map[SB_CDROM | id];
if ((part == 0xff) || (sb_menu_handles == NULL))
break;
cdrom_reload(id);
break;
case IDM_CDROM_IMAGE:
id = item_params & 0x0007;
part = sb_map[SB_CDROM | id];
if ((part == 0xff) || (sb_menu_handles == NULL))
break;
if (!file_dlg_w_st(hwnd, IDS_2075, cdrom[id].image_path, 0)) {
cdrom[id].prev_host_drive = cdrom[id].host_drive;
wcscpy(temp_path, wopenfilestring);
wcscpy(cdrom[id].prev_image_path, cdrom[id].image_path);
if (cdrom[id].ops && cdrom[id].ops->exit)
cdrom[id].ops->exit(&(cdrom[id]));
cdrom[id].ops = NULL;
memset(cdrom[id].image_path, 0, sizeof(cdrom[id].image_path));
cdrom_image_open(&(cdrom[id]), temp_path);
/* Signal media change to the emulated machine. */
if (cdrom[id].insert)
cdrom[id].insert(cdrom[id].priv);
cdrom[id].host_drive = (wcslen(cdrom[id].image_path) == 0) ? 0 : 200;
if (cdrom[id].host_drive == 200) {
CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED);
CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_CHECKED);
ui_sb_update_icon_state(SB_CDROM | id, 0);
} else {
CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_UNCHECKED);
CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_CHECKED);
ui_sb_update_icon_state(SB_CDROM | id, 1);
}
EnableMenuItem(sb_menu_handles[part], IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_GRAYED);
ui_sb_update_tip(SB_CDROM | id);
config_save();
}
break;
case IDM_ZIP_IMAGE_NEW:
id = item_params & 0x0003;
part = sb_map[SB_ZIP | id];
NewFloppyDialogCreate(hwnd, id | 0x80, part); /* NewZIPDialogCreate */
break;
case IDM_ZIP_IMAGE_EXISTING:
case IDM_ZIP_IMAGE_EXISTING_WP:
id = item_params & 0x0003;
part = sb_map[SB_ZIP | id];
if ((part == 0xff) || (sb_menu_handles == NULL))
break;
ret = file_dlg_w_st(hwnd, IDS_2058, zip_drives[id].image_path, 0);
if (! ret)
ui_sb_mount_zip_img(id, part, (item_id == IDM_ZIP_IMAGE_EXISTING_WP) ? 1 : 0, wopenfilestring);
break;
case IDM_ZIP_EJECT:
id = item_params & 0x0003;
zip_eject(id);
break;
case IDM_ZIP_RELOAD:
id = item_params & 0x0003;
zip_reload(id);
break;
case IDM_MO_IMAGE_NEW:
id = item_params & 0x0003;
part = sb_map[SB_MO | id];
NewFloppyDialogCreate(hwnd, id | 0x80, part); /* NewZIPDialogCreate */
break;
case IDM_MO_IMAGE_EXISTING:
case IDM_MO_IMAGE_EXISTING_WP:
id = item_params & 0x0003;
part = sb_map[SB_MO | id];
if ((part == 0xff) || (sb_menu_handles == NULL))
break;
ret = file_dlg_w_st(hwnd, IDS_2125, mo_drives[id].image_path, 0);
if (! ret)
ui_sb_mount_mo_img(id, part, (item_id == IDM_MO_IMAGE_EXISTING_WP) ? 1 : 0, wopenfilestring);
break;
case IDM_MO_EJECT:
id = item_params & 0x0003;
mo_eject(id);
break;
case IDM_MO_RELOAD:
id = item_params & 0x0003;
mo_reload(id);
break;
default:
break;
}
MediaMenuHandler(hwnd, message, wParam, lParam);
return(0);
case WM_LBUTTONDOWN:
@@ -1141,6 +1215,27 @@ StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
}
void
MediaMenuCreate(HWND hwndParent, uintptr_t idStatus, HINSTANCE hInst)
{
HMENU hmenu;
LPWSTR lpMenuName;
hmenu = GetMenu(hwndParent);
hmenuMedia = CreatePopupMenu();
int len = GetMenuString(hmenu, IDM_MEDIA, NULL, 0, MF_BYCOMMAND);
lpMenuName = malloc((len + 1) * sizeof(WCHAR));
GetMenuString(hmenu, IDM_MEDIA, lpMenuName, len + 1, MF_BYCOMMAND);
InsertMenu(hmenu, IDM_MEDIA, MF_BYCOMMAND | MF_STRING | MF_POPUP, (UINT_PTR)hmenuMedia, lpMenuName);
RemoveMenu(hmenu, IDM_MEDIA, MF_BYCOMMAND);
DrawMenuBar(hwndParent);
free(lpMenuName);
}
/* API: Create and set up the Status Bar window. */
void
StatusBarCreate(HWND hwndParent, uintptr_t idStatus, HINSTANCE hInst)
@@ -1219,6 +1314,8 @@ StatusBarCreate(HWND hwndParent, uintptr_t idStatus, HINSTANCE hInst)
memset(sb_menu_handles, 0, sb_parts * sizeof(HMENU));
sbTips = (WCHAR **)malloc(sb_parts * sizeof(WCHAR *));
memset(sbTips, 0, sb_parts * sizeof(WCHAR *));
media_menu_handles = (HMENU *)malloc(sb_parts * sizeof(HMENU));
memset(media_menu_handles, 0, sb_parts * sizeof(HMENU));
sb_parts = 0;
iStatusWidths[sb_parts] = -1;
sb_part_meanings[sb_parts] = SB_TEXT;
@@ -1226,7 +1323,10 @@ StatusBarCreate(HWND hwndParent, uintptr_t idStatus, HINSTANCE hInst)
sb_parts++;
SendMessage(hwndSBAR, SB_SETPARTS, (WPARAM)sb_parts, (LPARAM)iStatusWidths);
SendMessage(hwndSBAR, SB_SETTEXT, 0 | SBT_NOBORDERS,
(LPARAM)L"Welcome to 86Box !");
(LPARAM)plat_get_string(IDS_2126));
MediaMenuCreate(hwndParent, idStatus, hInst);
sb_ready = 1;
}
@@ -1245,6 +1345,7 @@ ui_sb_check_menu_item(int tag, int id, int chk)
return;
CheckMenuItem(sb_menu_handles[part], id, chk);
CheckMenuItem(media_menu_handles[part], id, chk);
}
@@ -1262,6 +1363,7 @@ ui_sb_enable_menu_item(int tag, int id, int flg)
return;
EnableMenuItem(sb_menu_handles[part], id, flg);
EnableMenuItem(media_menu_handles[part], id, flg);
}

View File

@@ -594,6 +594,9 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
svga_dump_vram();
break;
#endif
default:
MediaMenuHandler(hwnd, message, wParam, lParam);
break;
}
return(0);

View File

@@ -1,58 +0,0 @@
#define C0 (1<<8)
#define C1 (1<<9)
#define C2 (1<<10)
#define C3 (1<<14)
uint32_t x87_pc_off,x87_op_off;
uint16_t x87_pc_seg,x87_op_seg;
static inline void x87_set_mmx()
{
#ifdef USE_NEW_DYNAREC
cpu_state.TOP = 0;
*(uint64_t *)cpu_state.tag = 0x0101010101010101ull;
cpu_state.ismmx = 1;
#else
uint64_t *p;
cpu_state.TOP = 0;
p = (uint64_t *)cpu_state.tag;
*p = 0;
cpu_state.ismmx = 1;
#endif
}
static inline void x87_emms()
{
#ifdef USE_NEW_DYNAREC
*(uint64_t *)cpu_state.tag = 0;
cpu_state.ismmx = 0;
#else
uint64_t *p;
p = (uint64_t *)cpu_state.tag;
*p = 0;
cpu_state.ismmx = 0;
#endif
}
uint16_t x87_gettag();
void x87_settag(uint16_t new_tag);
#ifdef USE_NEW_DYNAREC
#define TAG_EMPTY 0
#define TAG_VALID (1 << 0)
/*Hack for FPU copy. If set then MM[].q contains the 64-bit integer loaded by FILD*/
#define TAG_UINT64 (1 << 7)
#define X87_ROUNDING_NEAREST 0
#define X87_ROUNDING_DOWN 1
#define X87_ROUNDING_UP 2
#define X87_ROUNDING_CHOP 3
void codegen_set_rounding_mode(int mode);
#else
#define TAG_EMPTY 0
#define TAG_VALID (1 << 0)
/*Hack for FPU copy. If set then MM[].q contains the 64-bit integer loaded by FILD*/
#define TAG_UINT64 (1 << 2)
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,427 +0,0 @@
#define opFPU(name, optype, a_size, load_var, get, use_var) \
static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \
{ \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
if ((cpu_state.npxc >> 10) & 3) \
fesetround(rounding_modes[(cpu_state.npxc >> 10) & 3]); \
ST(0) += use_var; \
if ((cpu_state.npxc >> 10) & 3) \
fesetround(FE_TONEAREST); \
FP_TAG(); \
CLOCK_CYCLES(8); \
return 0; \
} \
static int opFCOM ## name ## _a ## a_size(uint32_t fetchdat) \
{ \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
cpu_state.npxs &= ~(C0|C2|C3); \
cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \
CLOCK_CYCLES(4); \
return 0; \
} \
static int opFCOMP ## name ## _a ## a_size(uint32_t fetchdat) \
{ \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
cpu_state.npxs &= ~(C0|C2|C3); \
cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \
x87_pop(); \
CLOCK_CYCLES(4); \
return 0; \
} \
static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \
{ \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
x87_div(ST(0), ST(0), use_var); \
FP_TAG(); \
CLOCK_CYCLES(73); \
return 0; \
} \
static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \
{ \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
x87_div(ST(0), use_var, ST(0)); \
FP_TAG(); \
CLOCK_CYCLES(73); \
return 0; \
} \
static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \
{ \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
ST(0) *= use_var; \
FP_TAG(); \
CLOCK_CYCLES(11); \
return 0; \
} \
static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \
{ \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
ST(0) -= use_var; \
FP_TAG(); \
CLOCK_CYCLES(8); \
return 0; \
} \
static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \
{ \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
SEG_CHECK_READ(cpu_state.ea_seg); \
load_var = get(); if (cpu_state.abrt) return 1; \
ST(0) = use_var - ST(0); \
FP_TAG(); \
CLOCK_CYCLES(8); \
return 0; \
}
opFPU(s, x87_ts, 16, t.i, geteal, t.s)
#ifndef FPU_8087
opFPU(s, x87_ts, 32, t.i, geteal, t.s)
#endif
opFPU(d, x87_td, 16, t.i, geteaq, t.d)
#ifndef FPU_8087
opFPU(d, x87_td, 32, t.i, geteaq, t.d)
#endif
opFPU(iw, uint16_t, 16, t, geteaw, (double)(int16_t)t)
#ifndef FPU_8087
opFPU(iw, uint16_t, 32, t, geteaw, (double)(int16_t)t)
#endif
opFPU(il, uint32_t, 16, t, geteal, (double)(int32_t)t)
#ifndef FPU_8087
opFPU(il, uint32_t, 32, t, geteal, (double)(int32_t)t)
#endif
static int opFADD(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
ST(0) = ST(0) + ST(fetchdat & 7);
FP_TAG();
CLOCK_CYCLES(8);
return 0;
}
static int opFADDr(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0);
FP_FTAG();
CLOCK_CYCLES(8);
return 0;
}
static int opFADDP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0);
FP_FTAG();
x87_pop();
CLOCK_CYCLES(8);
return 0;
}
static int opFCOM(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
cpu_state.npxs &= ~(C0|C2|C3);
if (ST(0) == ST(fetchdat & 7)) cpu_state.npxs |= C3;
else if (ST(0) < ST(fetchdat & 7)) cpu_state.npxs |= C0;
CLOCK_CYCLES(4);
return 0;
}
static int opFCOMP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
cpu_state.npxs &= ~(C0|C2|C3);
cpu_state.npxs |= x87_compare(ST(0), ST(fetchdat & 7));
x87_pop();
CLOCK_CYCLES(4);
return 0;
}
static int opFCOMPP(uint32_t fetchdat)
{
uint64_t *p, *q;
FP_ENTER();
cpu_state.pc++;
cpu_state.npxs &= ~(C0|C2|C3);
p = (uint64_t *)&ST(0);
q = (uint64_t *)&ST(1);
if ((*p == ((uint64_t)1 << 63) && *q == 0) && is386)
cpu_state.npxs |= C0; /*Nasty hack to fix 80387 detection*/
else
cpu_state.npxs |= x87_compare(ST(0), ST(1));
x87_pop();
x87_pop();
CLOCK_CYCLES(4);
return 0;
}
#ifndef FPU_8087
static int opFUCOMPP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
cpu_state.npxs &= ~(C0|C2|C3);
cpu_state.npxs |= x87_ucompare(ST(0), ST(1));
x87_pop();
x87_pop();
CLOCK_CYCLES(5);
return 0;
}
#ifdef FP_686
static int opFCOMI(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
flags_rebuild();
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG;
else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG;
CLOCK_CYCLES(4);
return 0;
}
static int opFCOMIP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
flags_rebuild();
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG;
else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG;
x87_pop();
CLOCK_CYCLES(4);
return 0;
}
#endif
#endif
static int opFDIV(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
x87_div(ST(0), ST(0), ST(fetchdat & 7));
FP_TAG();
CLOCK_CYCLES(73);
return 0;
}
static int opFDIVr(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0));
FP_FTAG();
CLOCK_CYCLES(73);
return 0;
}
static int opFDIVP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0));
FP_FTAG();
x87_pop();
CLOCK_CYCLES(73);
return 0;
}
static int opFDIVR(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
x87_div(ST(0), ST(fetchdat&7), ST(0));
FP_TAG();
CLOCK_CYCLES(73);
return 0;
}
static int opFDIVRr(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7));
FP_FTAG();
CLOCK_CYCLES(73);
return 0;
}
static int opFDIVRP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7));
FP_FTAG();
x87_pop();
CLOCK_CYCLES(73);
return 0;
}
static int opFMUL(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
ST(0) = ST(0) * ST(fetchdat & 7);
FP_TAG();
CLOCK_CYCLES(16);
return 0;
}
static int opFMULr(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7);
FP_FTAG();
CLOCK_CYCLES(16);
return 0;
}
static int opFMULP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7);
FP_FTAG();
x87_pop();
CLOCK_CYCLES(16);
return 0;
}
static int opFSUB(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
ST(0) = ST(0) - ST(fetchdat & 7);
FP_TAG();
CLOCK_CYCLES(8);
return 0;
}
static int opFSUBr(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0);
FP_FTAG();
CLOCK_CYCLES(8);
return 0;
}
static int opFSUBP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0);
FP_FTAG();
x87_pop();
CLOCK_CYCLES(8);
return 0;
}
static int opFSUBR(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
ST(0) = ST(fetchdat & 7) - ST(0);
FP_TAG();
CLOCK_CYCLES(8);
return 0;
}
static int opFSUBRr(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7);
FP_FTAG();
CLOCK_CYCLES(8);
return 0;
}
static int opFSUBRP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7);
FP_FTAG();
x87_pop();
CLOCK_CYCLES(8);
return 0;
}
#ifndef FPU_8087
static int opFUCOM(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
cpu_state.npxs &= ~(C0|C2|C3);
cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7));
CLOCK_CYCLES(4);
return 0;
}
static int opFUCOMP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
cpu_state.npxs &= ~(C0|C2|C3);
cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7));
x87_pop();
CLOCK_CYCLES(4);
return 0;
}
#ifdef FP_686
static int opFUCOMI(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
flags_rebuild();
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG;
else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG;
CLOCK_CYCLES(4);
return 0;
}
static int opFUCOMIP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
flags_rebuild();
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG;
else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG;
x87_pop();
CLOCK_CYCLES(4);
return 0;
}
#endif
#endif

View File

@@ -1,492 +0,0 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* x87 FPU instructions core.
*
*
*
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Copyright 2008-2019 Sarah Walker.
* Copyright 2016-2019 Miran Grca.
*/
static int opFILDiw_a16(uint32_t fetchdat)
{
int16_t temp;
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
x87_push((double)temp);
CLOCK_CYCLES(13);
return 0;
}
#ifndef FPU_8087
static int opFILDiw_a32(uint32_t fetchdat)
{
int16_t temp;
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
x87_push((double)temp);
CLOCK_CYCLES(13);
return 0;
}
#endif
static int opFISTiw_a16(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp64 = x87_fround(ST(0));
seteaw((int16_t)temp64);
CLOCK_CYCLES(29);
return cpu_state.abrt;
}
#ifndef FPU_8087
static int opFISTiw_a32(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp64 = x87_fround(ST(0));
seteaw((int16_t)temp64);
CLOCK_CYCLES(29);
return cpu_state.abrt;
}
#endif
static int opFISTPiw_a16(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp64 = x87_fround(ST(0));
seteaw((int16_t)temp64); if (cpu_state.abrt) return 1;
x87_pop();
CLOCK_CYCLES(29);
return 0;
}
#ifndef FPU_8087
static int opFISTPiw_a32(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp64 = x87_fround(ST(0));
seteaw((int16_t)temp64); if (cpu_state.abrt) return 1;
x87_pop();
CLOCK_CYCLES(29);
return 0;
}
#endif
static int opFILDiq_a16(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
temp64 = geteaq(); if (cpu_state.abrt) return 1;
x87_push((double)temp64);
FP_LSQ();
FP_LSTAG();
CLOCK_CYCLES(10);
return 0;
}
#ifndef FPU_8087
static int opFILDiq_a32(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
temp64 = geteaq(); if (cpu_state.abrt) return 1;
x87_push((double)temp64);
FP_LSQ();
FP_LSTAG();
CLOCK_CYCLES(10);
return 0;
}
#endif
static int FBSTP_a16(uint32_t fetchdat)
{
double tempd;
int c;
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
tempd = ST(0);
if (tempd < 0.0)
tempd = -tempd;
for (c = 0; c < 9; c++)
{
uint8_t tempc = (uint8_t)floor(fmod(tempd, 10.0));
tempd -= floor(fmod(tempd, 10.0));
tempd /= 10.0;
tempc |= ((uint8_t)floor(fmod(tempd, 10.0))) << 4;
tempd -= floor(fmod(tempd, 10.0));
tempd /= 10.0;
writememb(easeg, cpu_state.eaaddr + c, tempc);
}
tempc = (uint8_t)floor(fmod(tempd, 10.0));
if (ST(0) < 0.0) tempc |= 0x80;
writememb(easeg, cpu_state.eaaddr + 9, tempc); if (cpu_state.abrt) return 1;
x87_pop();
return 0;
}
#ifndef FPU_8087
static int FBSTP_a32(uint32_t fetchdat)
{
double tempd;
int c;
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
tempd = ST(0);
if (tempd < 0.0)
tempd = -tempd;
for (c = 0; c < 9; c++)
{
uint8_t tempc = (uint8_t)floor(fmod(tempd, 10.0));
tempd -= floor(fmod(tempd, 10.0));
tempd /= 10.0;
tempc |= ((uint8_t)floor(fmod(tempd, 10.0))) << 4;
tempd -= floor(fmod(tempd, 10.0));
tempd /= 10.0;
writememb(easeg, cpu_state.eaaddr + c, tempc);
}
tempc = (uint8_t)floor(fmod(tempd, 10.0));
if (ST(0) < 0.0) tempc |= 0x80;
writememb(easeg, cpu_state.eaaddr + 9, tempc); if (cpu_state.abrt) return 1;
x87_pop();
return 0;
}
#endif
static int FISTPiq_a16(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
if (cpu_state.tag[cpu_state.TOP] & TAG_UINT64)
FP_LSRETQ()
else
temp64 = x87_fround(ST(0));
seteaq(temp64); if (cpu_state.abrt) return 1;
x87_pop();
CLOCK_CYCLES(29);
return 0;
}
#ifndef FPU_8087
static int FISTPiq_a32(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
if (cpu_state.tag[cpu_state.TOP] & TAG_UINT64)
FP_LSRETQ()
else
temp64 = x87_fround(ST(0));
seteaq(temp64); if (cpu_state.abrt) return 1;
x87_pop();
CLOCK_CYCLES(29);
return 0;
}
#endif
static int opFILDil_a16(uint32_t fetchdat)
{
int32_t templ;
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
templ = geteal(); if (cpu_state.abrt) return 1;
x87_push((double)templ);
CLOCK_CYCLES(9);
return 0;
}
#ifndef FPU_8087
static int opFILDil_a32(uint32_t fetchdat)
{
int32_t templ;
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
templ = geteal(); if (cpu_state.abrt) return 1;
x87_push((double)templ);
CLOCK_CYCLES(9);
return 0;
}
#endif
static int opFISTil_a16(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp64 = x87_fround(ST(0));
seteal((int32_t)temp64);
CLOCK_CYCLES(28);
return cpu_state.abrt;
}
#ifndef FPU_8087
static int opFISTil_a32(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp64 = x87_fround(ST(0));
seteal((int32_t)temp64);
CLOCK_CYCLES(28);
return cpu_state.abrt;
}
#endif
static int opFISTPil_a16(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp64 = x87_fround(ST(0));
seteal((int32_t)temp64); if (cpu_state.abrt) return 1;
x87_pop();
CLOCK_CYCLES(28);
return 0;
}
#ifndef FPU_8087
static int opFISTPil_a32(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp64 = x87_fround(ST(0));
seteal((int32_t)temp64); if (cpu_state.abrt) return 1;
x87_pop();
CLOCK_CYCLES(28);
return 0;
}
#endif
static int opFLDe_a16(uint32_t fetchdat)
{
double t;
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
t=x87_ld80(); if (cpu_state.abrt) return 1;
x87_push(t);
CLOCK_CYCLES(6);
return 0;
}
#ifndef FPU_8087
static int opFLDe_a32(uint32_t fetchdat)
{
double t;
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
t=x87_ld80(); if (cpu_state.abrt) return 1;
x87_push(t);
CLOCK_CYCLES(6);
return 0;
}
#endif
static int opFSTPe_a16(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
x87_st80(ST(0)); if (cpu_state.abrt) return 1;
x87_pop();
CLOCK_CYCLES(6);
return 0;
}
#ifndef FPU_8087
static int opFSTPe_a32(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
x87_st80(ST(0)); if (cpu_state.abrt) return 1;
x87_pop();
CLOCK_CYCLES(6);
return 0;
}
#endif
static int opFLDd_a16(uint32_t fetchdat)
{
x87_td t;
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
t.i = geteaq(); if (cpu_state.abrt) return 1;
x87_push(t.d);
CLOCK_CYCLES(3);
return 0;
}
#ifndef FPU_8087
static int opFLDd_a32(uint32_t fetchdat)
{
x87_td t;
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
t.i = geteaq(); if (cpu_state.abrt) return 1;
x87_push(t.d);
CLOCK_CYCLES(3);
return 0;
}
#endif
static int opFSTd_a16(uint32_t fetchdat)
{
x87_td t;
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
t.d = ST(0);
seteaq(t.i);
CLOCK_CYCLES(8);
return cpu_state.abrt;
}
#ifndef FPU_8087
static int opFSTd_a32(uint32_t fetchdat)
{
x87_td t;
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
t.d = ST(0);
seteaq(t.i);
CLOCK_CYCLES(8);
return cpu_state.abrt;
}
#endif
static int opFSTPd_a16(uint32_t fetchdat)
{
x87_td t;
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
t.d = ST(0);
seteaq(t.i); if (cpu_state.abrt) return 1;
x87_pop();
CLOCK_CYCLES(8);
return 0;
}
#ifndef FPU_8087
static int opFSTPd_a32(uint32_t fetchdat)
{
x87_td t;
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
t.d = ST(0);
seteaq(t.i); if (cpu_state.abrt) return 1;
x87_pop();
CLOCK_CYCLES(8);
return 0;
}
#endif
static int opFLDs_a16(uint32_t fetchdat)
{
x87_ts ts;
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
ts.i = geteal(); if (cpu_state.abrt) return 1;
x87_push((double)ts.s);
CLOCK_CYCLES(3);
return 0;
}
#ifndef FPU_8087
static int opFLDs_a32(uint32_t fetchdat)
{
x87_ts ts;
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
ts.i = geteal(); if (cpu_state.abrt) return 1;
x87_push((double)ts.s);
CLOCK_CYCLES(3);
return 0;
}
#endif
static int opFSTs_a16(uint32_t fetchdat)
{
x87_ts ts;
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
ts.s = (float)ST(0);
seteal(ts.i);
CLOCK_CYCLES(7);
return cpu_state.abrt;
}
#ifndef FPU_8087
static int opFSTs_a32(uint32_t fetchdat)
{
x87_ts ts;
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
ts.s = (float)ST(0);
seteal(ts.i);
CLOCK_CYCLES(7);
return cpu_state.abrt;
}
#endif
static int opFSTPs_a16(uint32_t fetchdat)
{
x87_ts ts;
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
ts.s = (float)ST(0);
seteal(ts.i); if (cpu_state.abrt) return 1;
x87_pop();
CLOCK_CYCLES(7);
return 0;
}
#ifndef FPU_8087
static int opFSTPs_a32(uint32_t fetchdat)
{
x87_ts ts;
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
ts.s = (float)ST(0);
seteal(ts.i); if (cpu_state.abrt) return 1;
x87_pop();
CLOCK_CYCLES(7);
return 0;
}
#endif

View File

@@ -1,877 +0,0 @@
#ifdef FPU_8087
static int opFI(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
cpu_state.npxc &= ~0x80;
if (rmdat == 0xe1)
cpu_state.npxc |= 0x80;
wait(3, 0);
return 0;
}
#else
static int opFSTSW_AX(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
AX = cpu_state.npxs;
CLOCK_CYCLES(3);
return 0;
}
#endif
static int opFNOP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
CLOCK_CYCLES(4);
return 0;
}
static int opFCLEX(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
cpu_state.npxs &= 0xff00;
CLOCK_CYCLES(4);
return 0;
}
static int opFINIT(uint32_t fetchdat)
{
uint64_t *p;
FP_ENTER();
cpu_state.pc++;
#ifdef FPU_8087
cpu_state.npxc = 0x3FF;
#else
cpu_state.npxc = 0x37F;
#endif
FP_RNPXC();
cpu_state.npxs = 0;
p = (uint64_t *)cpu_state.tag;
*p = FP_DTAG;
cpu_state.TOP = 0;
cpu_state.ismmx = 0;
CLOCK_CYCLES(17);
CPU_BLOCK_END();
return 0;
}
static int opFFREE(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = FP_EMPTY;
CLOCK_CYCLES(3);
return 0;
}
static int opFFREEP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = FP_EMPTY; if (cpu_state.abrt) return 1;
x87_pop();
CLOCK_CYCLES(3);
return 0;
}
static int opFST(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
ST(fetchdat & 7) = ST(0);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7];
CLOCK_CYCLES(3);
return 0;
}
static int opFSTP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
ST(fetchdat & 7) = ST(0);
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7];
x87_pop();
CLOCK_CYCLES(3);
return 0;
}
static int FSTOR()
{
uint64_t *p;
FP_ENTER();
switch ((cr0 & 1) | (cpu_state.op32 & 0x100))
{
case 0x000: /*16-bit real mode*/
case 0x001: /*16-bit protected mode*/
cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr);
FP_NNPXC();
cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2);
x87_settag(readmemw(easeg, cpu_state.eaaddr+4));
cpu_state.TOP = (cpu_state.npxs >> 11) & 7;
cpu_state.eaaddr += 14;
break;
case 0x100: /*32-bit real mode*/
case 0x101: /*32-bit protected mode*/
cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr);
FP_NNPXC();
cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4);
x87_settag(readmemw(easeg, cpu_state.eaaddr+8));
cpu_state.TOP = (cpu_state.npxs >> 11) & 7;
cpu_state.eaaddr += 28;
break;
}
x87_ld_frstor(0); cpu_state.eaaddr += 10;
x87_ld_frstor(1); cpu_state.eaaddr += 10;
x87_ld_frstor(2); cpu_state.eaaddr += 10;
x87_ld_frstor(3); cpu_state.eaaddr += 10;
x87_ld_frstor(4); cpu_state.eaaddr += 10;
x87_ld_frstor(5); cpu_state.eaaddr += 10;
x87_ld_frstor(6); cpu_state.eaaddr += 10;
x87_ld_frstor(7);
cpu_state.ismmx = 0;
/*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times
something like this is needed*/
p = (uint64_t *)cpu_state.tag;
if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff &&
cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff &&
!cpu_state.TOP && (*p == FP_CTAG))
cpu_state.ismmx = 1;
CLOCK_CYCLES((cr0 & 1) ? 34 : 44);
return cpu_state.abrt;
}
static int opFSTOR_a16(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
FSTOR();
return cpu_state.abrt;
}
#ifndef FPU_8087
static int opFSTOR_a32(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
FSTOR();
return cpu_state.abrt;
}
#endif
static int FSAVE()
{
uint64_t *p;
FP_ENTER();
cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | (FP_TOP(cpu_state.TOP) << 11);
switch ((cr0 & 1) | (cpu_state.op32 & 0x100))
{
case 0x000: /*16-bit real mode*/
writememw(easeg,cpu_state.eaaddr,cpu_state.npxc);
writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs);
writememw(easeg,cpu_state.eaaddr+4,x87_gettag());
writememw(easeg,cpu_state.eaaddr+6,x87_pc_off);
writememw(easeg,cpu_state.eaaddr+10,x87_op_off);
cpu_state.eaaddr+=14;
if (cpu_state.ismmx)
{
x87_stmmx(cpu_state.MM[0]); cpu_state.eaaddr+=10;
x87_stmmx(cpu_state.MM[1]); cpu_state.eaaddr+=10;
x87_stmmx(cpu_state.MM[2]); cpu_state.eaaddr+=10;
x87_stmmx(cpu_state.MM[3]); cpu_state.eaaddr+=10;
x87_stmmx(cpu_state.MM[4]); cpu_state.eaaddr+=10;
x87_stmmx(cpu_state.MM[5]); cpu_state.eaaddr+=10;
x87_stmmx(cpu_state.MM[6]); cpu_state.eaaddr+=10;
x87_stmmx(cpu_state.MM[7]);
}
else
{
x87_st_fsave(0); cpu_state.eaaddr+=10;
x87_st_fsave(1); cpu_state.eaaddr+=10;
x87_st_fsave(2); cpu_state.eaaddr+=10;
x87_st_fsave(3); cpu_state.eaaddr+=10;
x87_st_fsave(4); cpu_state.eaaddr+=10;
x87_st_fsave(5); cpu_state.eaaddr+=10;
x87_st_fsave(6); cpu_state.eaaddr+=10;
x87_st_fsave(7);
}
break;
case 0x001: /*16-bit protected mode*/
writememw(easeg,cpu_state.eaaddr,cpu_state.npxc);
writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs);
writememw(easeg,cpu_state.eaaddr+4,x87_gettag());
writememw(easeg,cpu_state.eaaddr+6,x87_pc_off);
writememw(easeg,cpu_state.eaaddr+8,x87_pc_seg);
writememw(easeg,cpu_state.eaaddr+10,x87_op_off);
writememw(easeg,cpu_state.eaaddr+12,x87_op_seg);
cpu_state.eaaddr+=14;
if (cpu_state.ismmx)
{
x87_stmmx(cpu_state.MM[0]); cpu_state.eaaddr+=10;
x87_stmmx(cpu_state.MM[1]); cpu_state.eaaddr+=10;
x87_stmmx(cpu_state.MM[2]); cpu_state.eaaddr+=10;
x87_stmmx(cpu_state.MM[3]); cpu_state.eaaddr+=10;
x87_stmmx(cpu_state.MM[4]); cpu_state.eaaddr+=10;
x87_stmmx(cpu_state.MM[5]); cpu_state.eaaddr+=10;
x87_stmmx(cpu_state.MM[6]); cpu_state.eaaddr+=10;
x87_stmmx(cpu_state.MM[7]);
}
else
{
x87_st_fsave(0); cpu_state.eaaddr+=10;
x87_st_fsave(1); cpu_state.eaaddr+=10;
x87_st_fsave(2); cpu_state.eaaddr+=10;
x87_st_fsave(3); cpu_state.eaaddr+=10;
x87_st_fsave(4); cpu_state.eaaddr+=10;
x87_st_fsave(5); cpu_state.eaaddr+=10;
x87_st_fsave(6); cpu_state.eaaddr+=10;
x87_st_fsave(7);
}
break;
case 0x100: /*32-bit real mode*/
writememw(easeg,cpu_state.eaaddr,cpu_state.npxc);
writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs);
writememw(easeg,cpu_state.eaaddr+8,x87_gettag());
writememw(easeg,cpu_state.eaaddr+12,x87_pc_off);
writememw(easeg,cpu_state.eaaddr+20,x87_op_off);
writememl(easeg,cpu_state.eaaddr+24,(x87_op_off>>16)<<12);
cpu_state.eaaddr+=28;
if (cpu_state.ismmx)
{
x87_stmmx(cpu_state.MM[0]); cpu_state.eaaddr+=10;
x87_stmmx(cpu_state.MM[1]); cpu_state.eaaddr+=10;
x87_stmmx(cpu_state.MM[2]); cpu_state.eaaddr+=10;
x87_stmmx(cpu_state.MM[3]); cpu_state.eaaddr+=10;
x87_stmmx(cpu_state.MM[4]); cpu_state.eaaddr+=10;
x87_stmmx(cpu_state.MM[5]); cpu_state.eaaddr+=10;
x87_stmmx(cpu_state.MM[6]); cpu_state.eaaddr+=10;
x87_stmmx(cpu_state.MM[7]);
}
else
{
x87_st_fsave(0); cpu_state.eaaddr+=10;
x87_st_fsave(1); cpu_state.eaaddr+=10;
x87_st_fsave(2); cpu_state.eaaddr+=10;
x87_st_fsave(3); cpu_state.eaaddr+=10;
x87_st_fsave(4); cpu_state.eaaddr+=10;
x87_st_fsave(5); cpu_state.eaaddr+=10;
x87_st_fsave(6); cpu_state.eaaddr+=10;
x87_st_fsave(7);
}
break;
case 0x101: /*32-bit protected mode*/
writememw(easeg,cpu_state.eaaddr,cpu_state.npxc);
writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs);
writememw(easeg,cpu_state.eaaddr+8,x87_gettag());
writememl(easeg,cpu_state.eaaddr+12,x87_pc_off);
writememl(easeg,cpu_state.eaaddr+16,x87_pc_seg);
writememl(easeg,cpu_state.eaaddr+20,x87_op_off);
writememl(easeg,cpu_state.eaaddr+24,x87_op_seg);
cpu_state.eaaddr+=28;
if (cpu_state.ismmx)
{
x87_stmmx(cpu_state.MM[0]); cpu_state.eaaddr+=10;
x87_stmmx(cpu_state.MM[1]); cpu_state.eaaddr+=10;
x87_stmmx(cpu_state.MM[2]); cpu_state.eaaddr+=10;
x87_stmmx(cpu_state.MM[3]); cpu_state.eaaddr+=10;
x87_stmmx(cpu_state.MM[4]); cpu_state.eaaddr+=10;
x87_stmmx(cpu_state.MM[5]); cpu_state.eaaddr+=10;
x87_stmmx(cpu_state.MM[6]); cpu_state.eaaddr+=10;
x87_stmmx(cpu_state.MM[7]);
}
else
{
x87_st_fsave(0); cpu_state.eaaddr+=10;
x87_st_fsave(1); cpu_state.eaaddr+=10;
x87_st_fsave(2); cpu_state.eaaddr+=10;
x87_st_fsave(3); cpu_state.eaaddr+=10;
x87_st_fsave(4); cpu_state.eaaddr+=10;
x87_st_fsave(5); cpu_state.eaaddr+=10;
x87_st_fsave(6); cpu_state.eaaddr+=10;
x87_st_fsave(7);
}
break;
}
cpu_state.npxc = 0x37F;
FP_RNPXC();
cpu_state.npxs = 0;
p = (uint64_t *)cpu_state.tag;
*p = FP_DTAG;
cpu_state.TOP = 0;
cpu_state.ismmx = 0;
CLOCK_CYCLES((cr0 & 1) ? 56 : 67);
return cpu_state.abrt;
}
static int opFSAVE_a16(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
FSAVE();
return cpu_state.abrt;
}
#ifndef FPU_8087
static int opFSAVE_a32(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
FSAVE();
return cpu_state.abrt;
}
#endif
static int opFSTSW_a16(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw((cpu_state.npxs & 0xC7FF) | (FP_TOP(cpu_state.TOP) << 11));
CLOCK_CYCLES(3);
return cpu_state.abrt;
}
#ifndef FPU_8087
static int opFSTSW_a32(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw((cpu_state.npxs & 0xC7FF) | (FP_TOP(cpu_state.TOP) << 11));
CLOCK_CYCLES(3);
return cpu_state.abrt;
}
#endif
static int opFLD(uint32_t fetchdat)
{
int old_tag;
uint64_t old_i64;
FP_ENTER();
cpu_state.pc++;
old_tag = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7];
old_i64 = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q;
x87_push(ST(fetchdat&7));
cpu_state.tag[FP_TOP(cpu_state.TOP)] = old_tag;
cpu_state.MM[FP_TOP(cpu_state.TOP)].q = old_i64;
CLOCK_CYCLES(4);
return 0;
}
static int opFXCH(uint32_t fetchdat)
{
double td;
uint8_t old_tag;
uint64_t old_i64;
FP_ENTER();
cpu_state.pc++;
td = ST(0);
ST(0) = ST(fetchdat&7);
ST(fetchdat&7) = td;
old_tag = cpu_state.tag[FP_TOP(cpu_state.TOP)];
cpu_state.tag[FP_TOP(cpu_state.TOP)] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7];
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = old_tag;
old_i64 = cpu_state.MM[FP_TOP(cpu_state.TOP)].q;
cpu_state.MM[FP_TOP(cpu_state.TOP)].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q;
cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q = old_i64;
CLOCK_CYCLES(4);
return 0;
}
static int opFCHS(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
ST(0) = -ST(0);
FP_TAG();
CLOCK_CYCLES(6);
return 0;
}
static int opFABS(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
ST(0) = fabs(ST(0));
FP_TAG();
CLOCK_CYCLES(3);
return 0;
}
static int opFTST(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
cpu_state.npxs &= ~(C0|C2|C3);
if (ST(0) == 0.0) cpu_state.npxs |= C3;
else if (ST(0) < 0.0) cpu_state.npxs |= C0;
CLOCK_CYCLES(4);
return 0;
}
static int opFXAM(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
cpu_state.npxs &= ~(C0|C1|C2|C3);
if (cpu_state.tag[cpu_state.TOP&7] == FP_EMPTY) cpu_state.npxs |= (C0|C3);
else if (ST(0) == 0.0) cpu_state.npxs |= C3;
else cpu_state.npxs |= C2;
if (ST(0) < 0.0) cpu_state.npxs |= C1;
CLOCK_CYCLES(8);
return 0;
}
static int opFLD1(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
x87_push(1.0);
CLOCK_CYCLES(4);
return 0;
}
static int opFLDL2T(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
x87_push(3.3219280948873623);
CLOCK_CYCLES(8);
return 0;
}
static int opFLDL2E(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
x87_push(1.4426950408889634);
CLOCK_CYCLES(8);
return 0;
}
static int opFLDPI(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
x87_push(3.141592653589793);
CLOCK_CYCLES(8);
return 0;
}
static int opFLDEG2(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
x87_push(0.3010299956639812);
CLOCK_CYCLES(8);
return 0;
}
static int opFLDLN2(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
x87_push_u64(0x3fe62e42fefa39f0ull);
CLOCK_CYCLES(8);
return 0;
}
static int opFLDZ(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
x87_push(0.0);
FP_ZTAG();
CLOCK_CYCLES(4);
return 0;
}
static int opF2XM1(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
ST(0) = pow(2.0, ST(0)) - 1.0;
FP_TAG();
CLOCK_CYCLES(200);
return 0;
}
static int opFYL2X(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
ST(1) = ST(1) * (log(ST(0)) / log(2.0));
FP_NTAG();
x87_pop();
CLOCK_CYCLES(250);
return 0;
}
static int opFYL2XP1(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
ST(1) = ST(1) * (log(ST(0)+1.0) / log(2.0));
FP_NTAG();
x87_pop();
CLOCK_CYCLES(250);
return 0;
}
static int opFPTAN(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
ST(0) = tan(ST(0));
FP_TAG();
x87_push(1.0);
cpu_state.npxs &= ~C2;
CLOCK_CYCLES(235);
return 0;
}
static int opFPATAN(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
ST(1) = atan2(ST(1), ST(0));
FP_NTAG();
x87_pop();
CLOCK_CYCLES(250);
return 0;
}
static int opFDECSTP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
FP_DECTOP();
CLOCK_CYCLES(4);
return 0;
}
static int opFINCSTP(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
FP_INCTOP();
CLOCK_CYCLES(4);
return 0;
}
static int opFPREM(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
cpu_state.pc++;
temp64 = (int64_t)(ST(0) / ST(1));
ST(0) = ST(0) - (ST(1) * (double)temp64);
FP_TAG();
cpu_state.npxs &= ~(C0|C1|C2|C3);
if (temp64 & 4) cpu_state.npxs|=C0;
if (temp64 & 2) cpu_state.npxs|=C3;
if (temp64 & 1) cpu_state.npxs|=C1;
CLOCK_CYCLES(100);
return 0;
}
#ifndef FPU_8087
static int opFPREM1(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
cpu_state.pc++;
temp64 = (int64_t)(ST(0) / ST(1));
ST(0) = ST(0) - (ST(1) * (double)temp64);
FP_TAG();
cpu_state.npxs &= ~(C0|C1|C2|C3);
if (temp64 & 4) cpu_state.npxs|=C0;
if (temp64 & 2) cpu_state.npxs|=C3;
if (temp64 & 1) cpu_state.npxs|=C1;
CLOCK_CYCLES(100);
return 0;
}
#endif
static int opFSQRT(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
ST(0) = sqrt(ST(0));
FP_TAG();
CLOCK_CYCLES(83);
return 0;
}
#ifndef FPU_8087
static int opFSINCOS(uint32_t fetchdat)
{
double td;
FP_ENTER();
cpu_state.pc++;
td = ST(0);
ST(0) = sin(td);
FP_TAG();
x87_push(cos(td));
cpu_state.npxs &= ~C2;
CLOCK_CYCLES(330);
return 0;
}
#endif
static int opFRNDINT(uint32_t fetchdat)
{
double rounded;
FP_ENTER();
cpu_state.pc++;
rounded = (double) x87_fround(ST(0));
#ifndef PCEM_CODE
if (rounded > ST(0))
cpu_state.npxs |= C1;
else
cpu_state.npxs &= ~C1;
#endif
ST(0) = rounded;
FP_TAG();
CLOCK_CYCLES(21);
return 0;
}
static int opFSCALE(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
cpu_state.pc++;
temp64 = (int64_t)ST(1);
ST(0) = ST(0) * pow(2.0, (double)temp64);
FP_TAG();
CLOCK_CYCLES(30);
return 0;
}
#ifndef FPU_8087
static int opFSIN(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
ST(0) = sin(ST(0));
FP_TAG();
cpu_state.npxs &= ~C2;
CLOCK_CYCLES(300);
return 0;
}
static int opFCOS(uint32_t fetchdat)
{
FP_ENTER();
cpu_state.pc++;
ST(0) = cos(ST(0));
FP_TAG();
cpu_state.npxs &= ~C2;
CLOCK_CYCLES(300);
return 0;
}
#endif
static int FLDENV()
{
FP_ENTER();
switch ((cr0 & 1) | (cpu_state.op32 & 0x100))
{
case 0x000: /*16-bit real mode*/
case 0x001: /*16-bit protected mode*/
cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr);
FP_NNPXC();
cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2);
x87_settag(readmemw(easeg, cpu_state.eaaddr+4));
cpu_state.TOP = (cpu_state.npxs >> 11) & 7;
break;
case 0x100: /*32-bit real mode*/
case 0x101: /*32-bit protected mode*/
cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr);
FP_NNPXC();
cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4);
x87_settag(readmemw(easeg, cpu_state.eaaddr+8));
cpu_state.TOP = (cpu_state.npxs >> 11) & 7;
break;
}
CLOCK_CYCLES((cr0 & 1) ? 34 : 44);
return cpu_state.abrt;
}
static int opFLDENV_a16(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
FLDENV();
return cpu_state.abrt;
}
#ifndef FPU_8087
static int opFLDENV_a32(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
FLDENV();
return cpu_state.abrt;
}
#endif
static int opFLDCW_a16(uint32_t fetchdat)
{
uint16_t tempw;
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
tempw = geteaw();
if (cpu_state.abrt) return 1;
cpu_state.npxc = tempw;
FP_NNPXC();
CLOCK_CYCLES(4);
return 0;
}
#ifndef FPU_8087
static int opFLDCW_a32(uint32_t fetchdat)
{
uint16_t tempw;
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_READ(cpu_state.ea_seg);
tempw = geteaw();
if (cpu_state.abrt) return 1;
cpu_state.npxc = tempw;
FP_NNPXC();
CLOCK_CYCLES(4);
return 0;
}
#endif
static int FSTENV()
{
FP_ENTER();
switch ((cr0 & 1) | (cpu_state.op32 & 0x100))
{
case 0x000: /*16-bit real mode*/
writememw(easeg,cpu_state.eaaddr,cpu_state.npxc);
writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs);
writememw(easeg,cpu_state.eaaddr+4,x87_gettag());
writememw(easeg,cpu_state.eaaddr+6,x87_pc_off);
writememw(easeg,cpu_state.eaaddr+10,x87_op_off);
break;
case 0x001: /*16-bit protected mode*/
writememw(easeg,cpu_state.eaaddr,cpu_state.npxc);
writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs);
writememw(easeg,cpu_state.eaaddr+4,x87_gettag());
writememw(easeg,cpu_state.eaaddr+6,x87_pc_off);
writememw(easeg,cpu_state.eaaddr+8,x87_pc_seg);
writememw(easeg,cpu_state.eaaddr+10,x87_op_off);
writememw(easeg,cpu_state.eaaddr+12,x87_op_seg);
break;
case 0x100: /*32-bit real mode*/
writememw(easeg,cpu_state.eaaddr,cpu_state.npxc);
writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs);
writememw(easeg,cpu_state.eaaddr+8,x87_gettag());
writememw(easeg,cpu_state.eaaddr+12,x87_pc_off);
writememw(easeg,cpu_state.eaaddr+20,x87_op_off);
writememl(easeg,cpu_state.eaaddr+24,(x87_op_off>>16)<<12);
break;
case 0x101: /*32-bit protected mode*/
writememw(easeg,cpu_state.eaaddr,cpu_state.npxc);
writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs);
writememw(easeg,cpu_state.eaaddr+8,x87_gettag());
writememl(easeg,cpu_state.eaaddr+12,x87_pc_off);
writememl(easeg,cpu_state.eaaddr+16,x87_pc_seg);
writememl(easeg,cpu_state.eaaddr+20,x87_op_off);
writememl(easeg,cpu_state.eaaddr+24,x87_op_seg);
break;
}
CLOCK_CYCLES((cr0 & 1) ? 56 : 67);
return cpu_state.abrt;
}
static int opFSTENV_a16(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
FSTENV();
return cpu_state.abrt;
}
#ifndef FPU_8087
static int opFSTENV_a32(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
FSTENV();
return cpu_state.abrt;
}
#endif
static int opFSTCW_a16(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_16(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw(cpu_state.npxc);
CLOCK_CYCLES(3);
return cpu_state.abrt;
}
#ifndef FPU_8087
static int opFSTCW_a32(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_32(fetchdat);
SEG_CHECK_WRITE(cpu_state.ea_seg);
seteaw(cpu_state.npxc);
CLOCK_CYCLES(3);
return cpu_state.abrt;
}
#endif
#ifndef FPU_8087
#ifdef FP_686
#define opFCMOV(condition) \
static int opFCMOV ## condition(uint32_t fetchdat) \
{ \
FP_ENTER(); \
cpu_state.pc++; \
if (cond_ ## condition) \
{ \
cpu_state.tag[FP_TOP(cpu_state.TOP)] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; \
cpu_state.MM[FP_TOP(cpu_state.TOP)].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; \
ST(0) = ST(fetchdat & 7); \
} \
CLOCK_CYCLES(4); \
return 0; \
}
#define cond_U ( PF_SET())
#define cond_NU (!PF_SET())
opFCMOV(B)
opFCMOV(E)
opFCMOV(BE)
opFCMOV(U)
opFCMOV(NB)
opFCMOV(NE)
opFCMOV(NBE)
opFCMOV(NU)
#endif
#endif