mirror of
https://github.com/86Box/86Box.git
synced 2026-02-23 01:48:21 -07:00
Merge branch 'master' of https://github.com/86Box/86Box
This commit is contained in:
412
src/acpi.c
412
src/acpi.c
@@ -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,
|
||||
|
||||
73
src/apm.c
73
src/apm.c
@@ -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
|
||||
};
|
||||
|
||||
12
src/config.c
12
src/config.c
@@ -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
@@ -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*/
|
||||
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
200
src/ddma.c
Normal 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
|
||||
};
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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
49
src/include/86box/ddma.h
Normal 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*/
|
||||
@@ -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
|
||||
|
||||
@@ -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 *);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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: */
|
||||
|
||||
282
src/intel_piix.c
282
src/intel_piix.c
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 }
|
||||
};
|
||||
|
||||
55
src/mem.c
55
src/mem.c
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
BIN
src/network.rar
BIN
src/network.rar
Binary file not shown.
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
196
src/usb.c
@@ -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
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user