mirror of
https://github.com/86Box/86Box.git
synced 2026-02-22 01:25:33 -07:00
Merge branch 'master' of https://github.com/86Box/86Box
This commit is contained in:
@@ -41,18 +41,19 @@
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t valid, pad;
|
||||
uint8_t valid, enabled;
|
||||
uint16_t mr;
|
||||
uint32_t virt_base;
|
||||
|
||||
struct headland_t * headland;
|
||||
} headland_mr_t;
|
||||
|
||||
|
||||
typedef struct headland_t {
|
||||
uint8_t type;
|
||||
uint8_t revision;
|
||||
|
||||
uint8_t cri;
|
||||
uint8_t cr[8];
|
||||
uint8_t cr[7];
|
||||
|
||||
uint8_t indx;
|
||||
uint8_t regs[256];
|
||||
@@ -68,6 +69,7 @@ typedef struct headland_t {
|
||||
mem_mapping_t ems_mapping[64];
|
||||
mem_mapping_t mid_mapping;
|
||||
mem_mapping_t high_mapping;
|
||||
mem_mapping_t shadow_mapping[2];
|
||||
mem_mapping_t upper_mapping[24];
|
||||
} headland_t;
|
||||
|
||||
@@ -95,38 +97,51 @@ static const int mem_conf_cr1[41] = {
|
||||
static uint32_t
|
||||
get_addr(headland_t *dev, uint32_t addr, headland_mr_t *mr)
|
||||
{
|
||||
uint32_t bank_base[4], bank_shift[4], shift, other_shift, bank;
|
||||
|
||||
if ((addr >= 0x0e0000) && (addr <= 0x0fffff))
|
||||
return addr;
|
||||
else if ((addr >= 0xfe0000) && (addr <= 0xffffff))
|
||||
return addr & 0x0fffff;
|
||||
|
||||
if (dev->revision == 8) {
|
||||
shift = (dev->cr[0] & 0x80) ? 21 : ((dev->cr[6] & 0x01) ? 23 : 19);
|
||||
other_shift = (dev->cr[0] & 0x80) ? ((dev->cr[6] & 0x01) ? 19 : 23) : 21;
|
||||
} else {
|
||||
shift = (dev->cr[0] & 0x80) ? 21 : 19;
|
||||
other_shift = (dev->cr[0] & 0x80) ? 21 : 19;
|
||||
}
|
||||
|
||||
/* Bank size = 1 << (bank shift + 2) . */
|
||||
bank_shift[0] = bank_shift[1] = shift;
|
||||
|
||||
bank_base[0] = 0x00000000;
|
||||
bank_base[1] = bank_base[0] + (1 << shift);
|
||||
bank_base[2] = bank_base[1] + (1 << shift);
|
||||
|
||||
if ((dev->revision > 0) && (dev->revision < 8) && (dev->cr[1] & 0x40)) {
|
||||
bank_shift[2] = bank_shift[3] = other_shift;
|
||||
bank_base[3] = bank_base[2] + (1 << other_shift);
|
||||
/* First address after the memory is bank_base[3] + (1 << other_shift) */
|
||||
} else {
|
||||
bank_shift[2] = bank_shift[3] = shift;
|
||||
bank_base[3] = bank_base[2] + (1 << shift);
|
||||
/* First address after the memory is bank_base[3] + (1 << shift) */
|
||||
}
|
||||
|
||||
if (mr && mr->valid && (dev->cr[0] & 2) && (mr->mr & 0x200)) {
|
||||
addr = (addr & 0x3fff) | ((mr->mr & 0x1F) << 14);
|
||||
if (dev->cr[1] & 0x40) {
|
||||
if ((dev->cr[4] & 0x80) && (dev->cr[6] & 1)) {
|
||||
if (dev->cr[0] & 0x80) {
|
||||
addr |= (mr->mr & 0x60) << 14;
|
||||
if (mr->mr & 0x100)
|
||||
addr += ((mr->mr & 0xC00) << 13) + (((mr->mr & 0x80) + 0x80) << 15);
|
||||
else
|
||||
addr += (mr->mr & 0x80) << 14;
|
||||
} else if (mr->mr & 0x100)
|
||||
addr += ((mr->mr & 0xC00) << 13) + (((mr->mr & 0x80) + 0x20) << 15);
|
||||
else
|
||||
addr += (mr->mr & 0x80) << 12;
|
||||
} else if (dev->cr[0] & 0x80)
|
||||
addr |= (mr->mr & 0x100) ? ((mr->mr & 0x80) + 0x400) << 12 : (mr->mr & 0xE0) << 14;
|
||||
else
|
||||
addr |= (mr->mr & 0x100) ? ((mr->mr & 0xE0) + 0x40) << 14 : (mr->mr & 0x80) << 12;
|
||||
} else {
|
||||
if ((dev->cr[4] & 0x80) && (dev->cr[6] & 1)) {
|
||||
if (dev->cr[0] & 0x80) {
|
||||
addr |= ((mr->mr & 0x60) << 14);
|
||||
if (mr->mr & 0x180)
|
||||
addr += ((mr->mr & 0xC00) << 13) + (((mr->mr & 0x180) - 0x60) << 16);
|
||||
} else
|
||||
addr |= ((mr->mr & 0x60) << 14) | ((mr->mr & 0x180) << 16) | ((mr->mr & 0xC00) << 13);
|
||||
} else if (dev->cr[0] & 0x80)
|
||||
addr |= (mr->mr & 0x1E0) << 14;
|
||||
else
|
||||
addr |= (mr->mr & 0x180) << 12;
|
||||
}
|
||||
} else if (((mr == NULL) || ((mr != NULL) && !mr->valid)) && ((dev->cr[0] & 4) == 0) && (mem_size >= 1024) && (addr >= 0x100000))
|
||||
|
||||
bank = (mr->mr >> 7) && 3;
|
||||
|
||||
if (bank_shift[bank] >= 21)
|
||||
addr |= (mr->mr & 0x060) << 14;
|
||||
|
||||
if ((dev->revision == 8) && (bank_shift[bank] == 23))
|
||||
addr |= (mr->mr & 0xc00) << 11;
|
||||
|
||||
addr |= bank_base[(mr->mr >> 7) & 3];
|
||||
} else if (((mr == NULL) || !mr->valid) && (mem_size >= 1024) && (addr >= 0x100000) && ((dev->cr[0] & 4) == 0))
|
||||
addr -= 0x60000;
|
||||
|
||||
return addr;
|
||||
@@ -136,7 +151,10 @@ get_addr(headland_t *dev, uint32_t addr, headland_mr_t *mr)
|
||||
static void
|
||||
hl_ems_disable(headland_t *dev, uint8_t mar, uint32_t base_addr, uint8_t indx)
|
||||
{
|
||||
mem_mapping_set_exec(&dev->ems_mapping[mar & 0x3f], ram + base_addr);
|
||||
if (base_addr < ((uint32_t)mem_size << 10))
|
||||
mem_mapping_set_exec(&dev->ems_mapping[mar & 0x3f], ram + base_addr);
|
||||
else
|
||||
mem_mapping_set_exec(&dev->ems_mapping[mar & 0x3f], NULL);
|
||||
mem_mapping_disable(&dev->ems_mapping[mar & 0x3f]);
|
||||
if (indx < 24) {
|
||||
mem_set_mem_state(base_addr, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
@@ -155,22 +173,21 @@ hl_ems_update(headland_t *dev, uint8_t mar)
|
||||
base_addr = (indx + 16) << 14;
|
||||
if (indx >= 24)
|
||||
base_addr += 0x20000;
|
||||
/* Do not disable unless the MAR at the correct context is locally disabled or
|
||||
EMS is globally disabled. */
|
||||
if (!(dev->cr[0] & 2) || !(dev->ems_mr[(mar & 0x1f) | ((dev->cr[0] & 1) << 5)].mr & 0x200))
|
||||
hl_ems_disable(dev, mar, base_addr, indx);
|
||||
if ((dev->cr[0] & 2) && ((dev->cr[0] & 1) == ((mar & 0x20) >> 5))) {
|
||||
if (dev->ems_mr[mar & 0x3f].mr & 0x200) {
|
||||
mem_set_mem_state(base_addr, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
virt_addr = get_addr(dev, base_addr, &dev->ems_mr[mar & 0x3f]);
|
||||
if (indx < 24)
|
||||
mem_mapping_disable(&dev->upper_mapping[indx]);
|
||||
if (virt_addr < ((uint32_t)mem_size << 10))
|
||||
mem_mapping_set_exec(&dev->ems_mapping[mar & 0x3f], ram + virt_addr);
|
||||
else
|
||||
mem_mapping_set_exec(&dev->ems_mapping[mar & 0x3f], NULL);
|
||||
mem_mapping_enable(&dev->ems_mapping[mar & 0x3f]);
|
||||
}
|
||||
hl_ems_disable(dev, mar, base_addr, indx);
|
||||
dev->ems_mr[mar & 0x3f].enabled = 0;
|
||||
dev->ems_mr[mar & 0x3f].virt_base = base_addr;
|
||||
if ((dev->cr[0] & 2) && ((dev->cr[0] & 1) == ((mar & 0x20) >> 5)) && (dev->ems_mr[mar & 0x3f].mr & 0x200)) {
|
||||
mem_set_mem_state(base_addr, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
virt_addr = get_addr(dev, base_addr, &dev->ems_mr[mar & 0x3f]);
|
||||
dev->ems_mr[mar & 0x3f].enabled = 1;
|
||||
dev->ems_mr[mar & 0x3f].virt_base = virt_addr;
|
||||
if (indx < 24)
|
||||
mem_mapping_disable(&dev->upper_mapping[indx]);
|
||||
if (virt_addr < ((uint32_t)mem_size << 10))
|
||||
mem_mapping_set_exec(&dev->ems_mapping[mar & 0x3f], ram + virt_addr);
|
||||
else
|
||||
mem_mapping_set_exec(&dev->ems_mapping[mar & 0x3f], NULL);
|
||||
mem_mapping_enable(&dev->ems_mapping[mar & 0x3f]);
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
@@ -182,8 +199,26 @@ set_global_EMS_state(headland_t *dev, int state)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 64; i++)
|
||||
hl_ems_update(dev, i);
|
||||
for (i = 0; i < 32; i++) {
|
||||
hl_ems_update(dev, i | (((dev->cr[0] & 0x01) << 5) ^ 0x20));
|
||||
hl_ems_update(dev, i | ((dev->cr[0] & 0x01) << 5));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
memmap_state_default(headland_t *dev, uint8_t ht_romcs)
|
||||
{
|
||||
mem_mapping_disable(&dev->mid_mapping);
|
||||
|
||||
if (ht_romcs)
|
||||
mem_set_mem_state(0x0e0000, 0x20000, MEM_READ_ROMCS | MEM_WRITE_ROMCS);
|
||||
else
|
||||
mem_set_mem_state(0x0e0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
mem_set_mem_state(0xfe0000, 0x20000, MEM_READ_ROMCS | MEM_WRITE_ROMCS);
|
||||
|
||||
mem_mapping_disable(&dev->shadow_mapping[0]);
|
||||
mem_mapping_disable(&dev->shadow_mapping[1]);
|
||||
}
|
||||
|
||||
|
||||
@@ -192,31 +227,96 @@ memmap_state_update(headland_t *dev)
|
||||
{
|
||||
uint32_t addr;
|
||||
int i;
|
||||
uint8_t ht_cr0 = dev->cr[0];
|
||||
uint8_t ht_romcs = !(dev->cr[4] & 0x01);
|
||||
if (dev->revision <= 1)
|
||||
ht_romcs = 1;
|
||||
if (!(dev->cr[0] & 0x04))
|
||||
ht_cr0 &= ~0x18;
|
||||
|
||||
for (i = 0; i < 24; i++) {
|
||||
addr = get_addr(dev, 0x40000 + (i << 14), NULL);
|
||||
mem_mapping_set_exec(&dev->upper_mapping[i], addr < ((uint32_t)mem_size << 10) ? ram + addr : NULL);
|
||||
}
|
||||
// mem_set_mem_state(0xA0000, 0x40000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
|
||||
memmap_state_default(dev, ht_romcs);
|
||||
|
||||
if (mem_size > 640) {
|
||||
if ((dev->cr[0] & 4) == 0) {
|
||||
mem_mapping_set_addr(&dev->mid_mapping, 0x100000, mem_size > 1024 ? 0x60000 : (mem_size - 640) << 10);
|
||||
if (ht_cr0 & 0x04) {
|
||||
mem_mapping_set_addr(&dev->mid_mapping, 0xA0000, 0x40000);
|
||||
mem_mapping_set_exec(&dev->mid_mapping, ram + 0xA0000);
|
||||
mem_mapping_disable(&dev->mid_mapping);
|
||||
if (mem_size > 1024) {
|
||||
mem_mapping_set_addr(&dev->high_mapping, 0x160000, (mem_size - 1024) << 10);
|
||||
mem_set_mem_state((mem_size << 10), 0x60000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
mem_mapping_set_addr(&dev->high_mapping, 0x100000, (mem_size - 1024) << 10);
|
||||
mem_mapping_set_exec(&dev->high_mapping, ram + 0x100000);
|
||||
}
|
||||
} else {
|
||||
mem_mapping_set_addr(&dev->mid_mapping, 0xA0000, mem_size > 1024 ? 0x60000 : (mem_size - 640) << 10);
|
||||
/* 1 MB - 1 MB + 384k: RAM pointing to A0000-FFFFF
|
||||
1 MB + 384k: Any ram pointing 1 MB onwards. */
|
||||
/* First, do the addresses above 1 MB. */
|
||||
mem_mapping_set_addr(&dev->mid_mapping, 0x100000, mem_size > 1024 ? 0x60000 : (mem_size - 640) << 10);
|
||||
mem_mapping_set_exec(&dev->mid_mapping, ram + 0xA0000);
|
||||
if (mem_size > 1024) {
|
||||
mem_mapping_set_addr(&dev->high_mapping, 0x100000, (mem_size - 1024) << 10);
|
||||
/* We have ram above 1 MB, we need to relocate that. */
|
||||
mem_set_mem_state((mem_size << 10), 0x60000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
mem_mapping_set_addr(&dev->high_mapping, 0x160000, (mem_size - 1024) << 10);
|
||||
mem_mapping_set_exec(&dev->high_mapping, ram + 0x100000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set_global_EMS_state(dev, dev->cr[0] & 3);
|
||||
switch (ht_cr0) {
|
||||
case 0x18:
|
||||
if ((mem_size << 10) > 0xe0000) {
|
||||
mem_set_mem_state(0x0e0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
mem_set_mem_state(0xfe0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
|
||||
mem_mapping_set_addr(&dev->shadow_mapping[0], 0x0e0000, 0x20000);
|
||||
mem_mapping_set_exec(&dev->shadow_mapping[0], ram + 0xe0000);
|
||||
mem_mapping_set_addr(&dev->shadow_mapping[1], 0xfe0000, 0x20000);
|
||||
mem_mapping_set_exec(&dev->shadow_mapping[1], ram + 0xe0000);
|
||||
} else {
|
||||
mem_mapping_disable(&dev->shadow_mapping[0]);
|
||||
mem_mapping_disable(&dev->shadow_mapping[1]);
|
||||
}
|
||||
break;
|
||||
case 0x10:
|
||||
if ((mem_size << 10) > 0xf0000) {
|
||||
mem_set_mem_state(0x0f0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
mem_set_mem_state(0xff0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
|
||||
mem_mapping_set_addr(&dev->shadow_mapping[0], 0x0f0000, 0x10000);
|
||||
mem_mapping_set_exec(&dev->shadow_mapping[0], ram + 0xf0000);
|
||||
mem_mapping_set_addr(&dev->shadow_mapping[1], 0xff0000, 0x10000);
|
||||
mem_mapping_set_exec(&dev->shadow_mapping[1], ram + 0xf0000);
|
||||
} else {
|
||||
mem_mapping_disable(&dev->shadow_mapping[0]);
|
||||
mem_mapping_disable(&dev->shadow_mapping[1]);
|
||||
}
|
||||
break;
|
||||
case 0x08:
|
||||
if ((mem_size << 10) > 0xe0000) {
|
||||
mem_set_mem_state(0x0e0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
mem_set_mem_state(0xfe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
|
||||
mem_mapping_set_addr(&dev->shadow_mapping[0], 0x0e0000, 0x10000);
|
||||
mem_mapping_set_exec(&dev->shadow_mapping[0], ram + 0xe0000);
|
||||
mem_mapping_set_addr(&dev->shadow_mapping[1], 0xfe0000, 0x10000);
|
||||
mem_mapping_set_exec(&dev->shadow_mapping[1], ram + 0xe0000);
|
||||
} else {
|
||||
mem_mapping_disable(&dev->shadow_mapping[0]);
|
||||
mem_mapping_disable(&dev->shadow_mapping[1]);
|
||||
}
|
||||
break;
|
||||
case 0x00:
|
||||
default:
|
||||
mem_mapping_disable(&dev->shadow_mapping[0]);
|
||||
mem_mapping_disable(&dev->shadow_mapping[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
set_global_EMS_state(dev, ht_cr0 & 3);
|
||||
}
|
||||
|
||||
|
||||
@@ -224,32 +324,8 @@ static void
|
||||
hl_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
headland_t *dev = (headland_t *)priv;
|
||||
uint8_t old_val;
|
||||
|
||||
switch(addr) {
|
||||
case 0x0022:
|
||||
dev->indx = val;
|
||||
break;
|
||||
|
||||
case 0x0023:
|
||||
old_val = dev->regs[dev->indx];
|
||||
|
||||
if ((dev->indx == 0xc1) && !is486)
|
||||
val = 0;
|
||||
dev->regs[dev->indx] = val;
|
||||
if (dev->indx == 0x82) {
|
||||
shadowbios = val & 0x10;
|
||||
shadowbios_write = !(val & 0x10);
|
||||
if (shadowbios)
|
||||
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
else
|
||||
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
} else if (dev->indx == 0x87) {
|
||||
if ((val & 1) && !(old_val & 1))
|
||||
softresetx86();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x01ec:
|
||||
dev->ems_mr[dev->ems_mar & 0x3f].mr = val | 0xff00;
|
||||
hl_ems_update(dev, dev->ems_mar & 0x3f);
|
||||
@@ -258,7 +334,8 @@ hl_write(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
|
||||
case 0x01ed:
|
||||
dev->cri = val;
|
||||
if (dev->revision > 0)
|
||||
dev->cri = val;
|
||||
break;
|
||||
|
||||
case 0x01ee:
|
||||
@@ -266,12 +343,9 @@ hl_write(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
|
||||
case 0x01ef:
|
||||
old_val = dev->cr[dev->cri];
|
||||
switch(dev->cri) {
|
||||
case 0:
|
||||
dev->cr[0] = (val & 0x1f) | mem_conf_cr0[(mem_size > 640 ? mem_size : mem_size - 128) >> 9];
|
||||
mem_set_mem_state(0xe0000, 0x10000, (val & 8 ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | MEM_WRITE_DISABLED);
|
||||
mem_set_mem_state(0xf0000, 0x10000, (val & 0x10 ? MEM_READ_INTERNAL: MEM_READ_EXTANY) | MEM_WRITE_DISABLED);
|
||||
memmap_state_update(dev);
|
||||
break;
|
||||
|
||||
@@ -289,17 +363,11 @@ hl_write(uint16_t addr, uint8_t val, void *priv)
|
||||
|
||||
case 4:
|
||||
dev->cr[4] = (dev->cr[4] & 0xf0) | (val & 0x0f);
|
||||
if (val & 1) {
|
||||
mem_mapping_set_addr(&bios_mapping, 0x000f0000, 0x10000);
|
||||
mem_mapping_set_exec(&bios_mapping, &(rom[0x10000]));
|
||||
} else {
|
||||
mem_mapping_set_addr(&bios_mapping, 0x000e0000, 0x20000);
|
||||
mem_mapping_set_exec(&bios_mapping, rom);
|
||||
}
|
||||
memmap_state_update(dev);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
if (dev->cr[4] & 0x80) {
|
||||
if (dev->revision == 8) {
|
||||
dev->cr[dev->cri] = (val & 0xfe) | (mem_size > 8192 ? 1 : 0);
|
||||
memmap_state_update(dev);
|
||||
}
|
||||
@@ -335,6 +403,14 @@ hl_writew(uint16_t addr, uint16_t val, void *priv)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hl_writel(uint16_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
hl_writew(addr, val, priv);
|
||||
hl_writew(addr + 2, val >> 16, priv);
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
hl_read(uint16_t addr, void *priv)
|
||||
{
|
||||
@@ -342,17 +418,6 @@ hl_read(uint16_t addr, void *priv)
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch(addr) {
|
||||
case 0x0022:
|
||||
ret = dev->indx;
|
||||
break;
|
||||
|
||||
case 0x0023:
|
||||
if ((dev->indx >= 0xc0 || dev->indx == 0x20) && cpu_iscyrix)
|
||||
ret = 0xff; /*Don't conflict with Cyrix config registers*/
|
||||
else
|
||||
ret = dev->regs[dev->indx];
|
||||
break;
|
||||
|
||||
case 0x01ec:
|
||||
ret = (uint8_t)dev->ems_mr[dev->ems_mar & 0x3f].mr;
|
||||
if (dev->ems_mar & 0x80)
|
||||
@@ -360,7 +425,8 @@ hl_read(uint16_t addr, void *priv)
|
||||
break;
|
||||
|
||||
case 0x01ed:
|
||||
ret = dev->cri;
|
||||
if (dev->revision > 0)
|
||||
ret = dev->cri;
|
||||
break;
|
||||
|
||||
case 0x01ee:
|
||||
@@ -378,7 +444,7 @@ hl_read(uint16_t addr, void *priv)
|
||||
break;
|
||||
|
||||
case 6:
|
||||
if (dev->cr[4] & 0x80)
|
||||
if (dev->revision == 8)
|
||||
ret = (dev->cr[6] & 0xfe) | (mem_size > 8192 ? 1 : 0);
|
||||
else
|
||||
ret = 0;
|
||||
@@ -419,6 +485,18 @@ hl_readw(uint16_t addr, void *priv)
|
||||
}
|
||||
|
||||
|
||||
static uint32_t
|
||||
hl_readl(uint16_t addr, void *priv)
|
||||
{
|
||||
uint32_t ret = 0xffffffff;
|
||||
|
||||
ret = hl_readw(addr, priv);
|
||||
ret |= (hl_readw(addr + 2, priv) << 16);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
mem_read_b(uint32_t addr, void *priv)
|
||||
{
|
||||
@@ -518,23 +596,19 @@ headland_init(const device_t *info)
|
||||
|
||||
dev = (headland_t *) malloc(sizeof(headland_t));
|
||||
memset(dev, 0x00, sizeof(headland_t));
|
||||
dev->type = info->local;
|
||||
|
||||
ht386 = (dev->type == 32) ? 1 : 0;
|
||||
dev->revision = info->local;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
dev->cr[i] = 0x00;
|
||||
dev->cr[0] = 0x04;
|
||||
if (dev->revision > 0)
|
||||
ht386 = 1;
|
||||
|
||||
if (ht386) {
|
||||
dev->cr[4] = 0x20;
|
||||
dev->cr[4] = dev->revision << 4;
|
||||
|
||||
if (ht386)
|
||||
device_add(&port_92_inv_device);
|
||||
} else
|
||||
dev->cr[4] = 0x00;
|
||||
|
||||
io_sethandler(0x01ec, 4,
|
||||
hl_read,hl_readw,NULL, hl_write,hl_writew,NULL, dev);
|
||||
hl_read,hl_readw,hl_readl, hl_write,hl_writew,hl_writel, dev);
|
||||
|
||||
dev->null_mr.valid = 0;
|
||||
dev->null_mr.mr = 0xff;
|
||||
@@ -557,11 +631,11 @@ headland_init(const device_t *info)
|
||||
ram, MEM_MAPPING_INTERNAL, &dev->null_mr);
|
||||
|
||||
if (mem_size > 640) {
|
||||
mem_mapping_add(&dev->mid_mapping, 0xa0000, 0x60000,
|
||||
mem_mapping_add(&dev->mid_mapping, 0xa0000, 0x40000,
|
||||
mem_read_b, mem_read_w, mem_read_l,
|
||||
mem_write_b, mem_write_w, mem_write_l,
|
||||
ram + 0xa0000, MEM_MAPPING_INTERNAL, &dev->null_mr);
|
||||
mem_mapping_enable(&dev->mid_mapping);
|
||||
mem_mapping_disable(&dev->mid_mapping);
|
||||
}
|
||||
|
||||
if (mem_size > 1024) {
|
||||
@@ -577,11 +651,27 @@ headland_init(const device_t *info)
|
||||
0x40000 + (i << 14), 0x4000,
|
||||
mem_read_b, mem_read_w, mem_read_l,
|
||||
mem_write_b, mem_write_w, mem_write_l,
|
||||
mem_size > 256 + (i << 4) ? ram + 0x40000 + (i << 14) : NULL,
|
||||
mem_size > (256 + (i << 4)) ? (ram + 0x40000 + (i << 14)) : NULL,
|
||||
MEM_MAPPING_INTERNAL, &dev->null_mr);
|
||||
mem_mapping_enable(&dev->upper_mapping[i]);
|
||||
}
|
||||
|
||||
mem_mapping_add(&dev->shadow_mapping[0],
|
||||
0xe0000, 0x20000,
|
||||
mem_read_b, mem_read_w, mem_read_l,
|
||||
mem_write_b, mem_write_w, mem_write_l,
|
||||
((mem_size << 10) > 0xe0000) ? (ram + 0xe0000) : NULL,
|
||||
MEM_MAPPING_INTERNAL, &dev->null_mr);
|
||||
mem_mapping_disable(&dev->shadow_mapping[0]);
|
||||
|
||||
mem_mapping_add(&dev->shadow_mapping[1],
|
||||
0xfe0000, 0x20000,
|
||||
mem_read_b, mem_read_w, mem_read_l,
|
||||
mem_write_b, mem_write_w, mem_write_l,
|
||||
((mem_size << 10) > 0xe0000) ? (ram + 0xe0000) : NULL,
|
||||
MEM_MAPPING_INTERNAL, &dev->null_mr);
|
||||
mem_mapping_disable(&dev->shadow_mapping[1]);
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
dev->ems_mr[i].mr = 0x00;
|
||||
mem_mapping_add(&dev->ems_mapping[i],
|
||||
@@ -599,8 +689,8 @@ headland_init(const device_t *info)
|
||||
}
|
||||
|
||||
|
||||
const device_t headland_device = {
|
||||
"Headland 286",
|
||||
const device_t headland_gc10x_device = {
|
||||
"Headland GC101/102/103",
|
||||
0,
|
||||
0,
|
||||
headland_init, headland_close, NULL,
|
||||
@@ -608,10 +698,28 @@ const device_t headland_device = {
|
||||
NULL
|
||||
};
|
||||
|
||||
const device_t headland_386_device = {
|
||||
"Headland 386",
|
||||
const device_t headland_ht18a_device = {
|
||||
"Headland HT18 Rev. A",
|
||||
0,
|
||||
32,
|
||||
1,
|
||||
headland_init, headland_close, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
const device_t headland_ht18b_device = {
|
||||
"Headland HT18 Rev. B",
|
||||
0,
|
||||
2,
|
||||
headland_init, headland_close, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
const device_t headland_ht18c_device = {
|
||||
"Headland HT18 Rev. C",
|
||||
0,
|
||||
8,
|
||||
headland_init, headland_close, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL
|
||||
|
||||
@@ -308,13 +308,6 @@ void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr);
|
||||
extern int cpu_block_end;
|
||||
extern uint32_t codegen_endpc;
|
||||
|
||||
extern int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks;
|
||||
extern int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched;
|
||||
extern int cpu_recomp_flushes, cpu_recomp_flushes_latched;
|
||||
extern int cpu_recomp_evicted, cpu_recomp_evicted_latched;
|
||||
extern int cpu_recomp_reuse, cpu_recomp_reuse_latched;
|
||||
extern int cpu_recomp_removed, cpu_recomp_removed_latched;
|
||||
|
||||
extern int codegen_block_cycles;
|
||||
|
||||
extern void (*codegen_timing_start)();
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
enum
|
||||
{
|
||||
ACCREG_ins = 0,
|
||||
ACCREG_cycles = 1,
|
||||
ACCREG_cycles = 0,
|
||||
|
||||
ACCREG_COUNT
|
||||
};
|
||||
|
||||
@@ -13,7 +13,6 @@ static struct
|
||||
uintptr_t dest_reg;
|
||||
} acc_regs[] =
|
||||
{
|
||||
[ACCREG_ins] = {0, (uintptr_t) &(ins)},
|
||||
[ACCREG_cycles] = {0, (uintptr_t) &(cycles)},
|
||||
};
|
||||
|
||||
@@ -22,37 +21,42 @@ void codegen_accumulate(int acc_reg, int delta)
|
||||
acc_regs[acc_reg].count += delta;
|
||||
|
||||
if ((acc_reg == ACCREG_cycles) && (delta != 0)) {
|
||||
addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t) (uintptr_t) &(acycs));
|
||||
addlong(-delta);
|
||||
if (delta == -1) {
|
||||
/* -delta = 1 */
|
||||
addbyte(0xff); /*inc dword ptr[&acycs]*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t) (uintptr_t) &(acycs));
|
||||
} else if (delta == 1) {
|
||||
/* -delta = -1 */
|
||||
addbyte(0xff); /*dec dword ptr[&acycs]*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t) (uintptr_t) &(acycs));
|
||||
} else {
|
||||
addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t) (uintptr_t) &(acycs));
|
||||
addlong(-delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void codegen_accumulate_flush(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c = 0; c < ACCREG_COUNT; c++)
|
||||
{
|
||||
if (acc_regs[c].count)
|
||||
{
|
||||
addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t) acc_regs[c].dest_reg);
|
||||
addlong(acc_regs[c].count);
|
||||
}
|
||||
if (acc_regs[0].count) {
|
||||
addbyte(0x81); /*ADD $acc_regs[0].count,acc_regs[0].dest*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t) acc_regs[0].dest_reg);
|
||||
addlong(acc_regs[0].count);
|
||||
}
|
||||
|
||||
acc_regs[c].count = 0;
|
||||
}
|
||||
acc_regs[0].count = 0;
|
||||
}
|
||||
|
||||
void codegen_accumulate_reset()
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c = 0; c < ACCREG_COUNT; c++)
|
||||
acc_regs[c].count = 0;
|
||||
acc_regs[0].count = 0;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ static struct
|
||||
uintptr_t dest_reg;
|
||||
} acc_regs[] =
|
||||
{
|
||||
[ACCREG_ins] = {0, (uintptr_t) &(ins)},
|
||||
[ACCREG_cycles] = {0, (uintptr_t) &(cycles)}
|
||||
};
|
||||
|
||||
@@ -22,35 +21,38 @@ void codegen_accumulate(int acc_reg, int delta)
|
||||
acc_regs[acc_reg].count += delta;
|
||||
|
||||
if ((acc_reg == ACCREG_cycles) && (delta != 0)) {
|
||||
addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t) (uintptr_t) &(acycs));
|
||||
addlong((uintptr_t) -delta);
|
||||
if (delta == -1) {
|
||||
/* -delta = 1 */
|
||||
addbyte(0xff); /*inc dword ptr[&acycs]*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t) (uintptr_t) &(acycs));
|
||||
} else if (delta == 1) {
|
||||
/* -delta = -1 */
|
||||
addbyte(0xff); /*dec dword ptr[&acycs]*/
|
||||
addbyte(0x0d);
|
||||
addlong((uint32_t) (uintptr_t) &(acycs));
|
||||
} else {
|
||||
addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t) (uintptr_t) &(acycs));
|
||||
addlong((uintptr_t) -delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void codegen_accumulate_flush(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c = 0; c < ACCREG_COUNT; c++)
|
||||
{
|
||||
if (acc_regs[c].count)
|
||||
{
|
||||
addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t) acc_regs[c].dest_reg);
|
||||
addlong(acc_regs[c].count);
|
||||
}
|
||||
if (acc_regs[0].count) {
|
||||
addbyte(0x81); /*ADD $acc_regs[0].count,acc_regs[0].dest*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t) acc_regs[0].dest_reg);
|
||||
addlong(acc_regs[0].count);
|
||||
}
|
||||
|
||||
acc_regs[c].count = 0;
|
||||
}
|
||||
acc_regs[0].count = 0;
|
||||
}
|
||||
|
||||
void codegen_accumulate_reset()
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c = 0; c < ACCREG_COUNT; c++)
|
||||
acc_regs[c].count = 0;
|
||||
acc_regs[0].count = 0;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ static uint32_t ropCLI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32
|
||||
if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI)))
|
||||
return 0;
|
||||
CLEAR_BITS((uintptr_t)&cpu_state.flags, I_FLAG);
|
||||
CLEAR_BITS((uintptr_t)&pic_pending, 0xffffffff);
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropSTI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
|
||||
@@ -49,11 +49,6 @@ int block_current = 0;
|
||||
static int block_num;
|
||||
int block_pos;
|
||||
|
||||
int cpu_recomp_flushes, cpu_recomp_flushes_latched;
|
||||
int cpu_recomp_evicted, cpu_recomp_evicted_latched;
|
||||
int cpu_recomp_reuse, cpu_recomp_reuse_latched;
|
||||
int cpu_recomp_removed, cpu_recomp_removed_latched;
|
||||
|
||||
uint32_t codegen_endpc;
|
||||
|
||||
int codegen_block_cycles;
|
||||
@@ -224,7 +219,6 @@ void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr)
|
||||
if (mask & block->page_mask)
|
||||
{
|
||||
delete_block(block);
|
||||
cpu_recomp_evicted++;
|
||||
}
|
||||
if (block == block->next)
|
||||
fatal("Broken 1\n");
|
||||
@@ -238,7 +232,6 @@ void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr)
|
||||
if (mask & block->page_mask2)
|
||||
{
|
||||
delete_block(block);
|
||||
cpu_recomp_evicted++;
|
||||
}
|
||||
if (block == block->next_2)
|
||||
fatal("Broken 2\n");
|
||||
@@ -260,7 +253,6 @@ void codegen_block_init(uint32_t phys_addr)
|
||||
if (block->valid != 0)
|
||||
{
|
||||
delete_block(block);
|
||||
cpu_recomp_reuse++;
|
||||
}
|
||||
block_num = HASH(phys_addr);
|
||||
codeblock_hash[block_num] = &codeblock[block_current];
|
||||
@@ -393,7 +385,6 @@ void codegen_block_remove()
|
||||
codeblock_t *block = &codeblock[block_current];
|
||||
|
||||
delete_block(block);
|
||||
cpu_recomp_removed++;
|
||||
|
||||
recomp_page = -1;
|
||||
}
|
||||
@@ -1049,7 +1040,6 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
||||
generate_call:
|
||||
codegen_timing_opcode(opcode, fetchdat, op_32, op_pc);
|
||||
|
||||
codegen_accumulate(ACCREG_ins, 1);
|
||||
codegen_accumulate(ACCREG_cycles, -codegen_block_cycles);
|
||||
codegen_block_cycles = 0;
|
||||
|
||||
@@ -1096,10 +1086,11 @@ generate_call:
|
||||
codegen_endpc = (cs + cpu_state.pc) + 8;
|
||||
|
||||
/* Check for interrupts. */
|
||||
call(block, (uintptr_t)int_check);
|
||||
|
||||
addbyte(0x85); /*OR %eax, %eax*/
|
||||
addbyte(0xc0);
|
||||
addbyte(0xf6); /* test byte ptr[&pic_pending],1 */
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t) (uintptr_t) &pic_pending);
|
||||
addbyte(0x01);
|
||||
addbyte(0x0F); addbyte(0x85); /*JNZ 0*/
|
||||
addlong((uint32_t)(uintptr_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(uintptr_t)(&block->data[block_pos + 4]));
|
||||
|
||||
@@ -1175,13 +1166,11 @@ generate_call:
|
||||
|
||||
block->ins++;
|
||||
|
||||
addbyte(0x85); /*OR %eax, %eax*/
|
||||
addbyte(0xc0);
|
||||
addbyte(0x0F); addbyte(0x85); /*JNZ 0*/
|
||||
addlong((uint32_t)(uintptr_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(uintptr_t)(&block->data[block_pos + 4]));
|
||||
|
||||
/* Check for interrupts. */
|
||||
call(block, (uintptr_t)int_check);
|
||||
addbyte(0x0a); /* or al,byte ptr[&pic_pending] */
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t) (uintptr_t) &pic_pending);
|
||||
|
||||
addbyte(0x85); /*OR %eax, %eax*/
|
||||
addbyte(0xc0);
|
||||
|
||||
@@ -50,6 +50,9 @@
|
||||
#include "x86_flags.h"
|
||||
#include "x86_ops.h"
|
||||
#include "x87.h"
|
||||
/*ex*/
|
||||
#include <86box/nmi.h>
|
||||
#include <86box/pic.h>
|
||||
|
||||
#include "386_common.h"
|
||||
|
||||
@@ -88,11 +91,6 @@ int block_current = 0;
|
||||
static int block_num;
|
||||
int block_pos;
|
||||
|
||||
int cpu_recomp_flushes, cpu_recomp_flushes_latched;
|
||||
int cpu_recomp_evicted, cpu_recomp_evicted_latched;
|
||||
int cpu_recomp_reuse, cpu_recomp_reuse_latched;
|
||||
int cpu_recomp_removed, cpu_recomp_removed_latched;
|
||||
|
||||
uint32_t codegen_endpc;
|
||||
|
||||
int codegen_block_cycles;
|
||||
@@ -1367,7 +1365,6 @@ void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr)
|
||||
if (mask & block->page_mask)
|
||||
{
|
||||
delete_block(block);
|
||||
cpu_recomp_evicted++;
|
||||
}
|
||||
if (block == block->next)
|
||||
fatal("Broken 1\n");
|
||||
@@ -1381,7 +1378,6 @@ void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr)
|
||||
if (mask & block->page_mask2)
|
||||
{
|
||||
delete_block(block);
|
||||
cpu_recomp_evicted++;
|
||||
}
|
||||
if (block == block->next_2)
|
||||
fatal("Broken 2\n");
|
||||
@@ -1403,7 +1399,6 @@ void codegen_block_init(uint32_t phys_addr)
|
||||
if (block->valid != 0)
|
||||
{
|
||||
delete_block(block);
|
||||
cpu_recomp_reuse++;
|
||||
}
|
||||
block_num = HASH(phys_addr);
|
||||
codeblock_hash[block_num] = &codeblock[block_current];
|
||||
@@ -1512,7 +1507,6 @@ void codegen_block_remove()
|
||||
codeblock_t *block = &codeblock[block_current];
|
||||
|
||||
delete_block(block);
|
||||
cpu_recomp_removed++;
|
||||
|
||||
recomp_page = -1;
|
||||
}
|
||||
@@ -2016,7 +2010,6 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
||||
generate_call:
|
||||
codegen_timing_opcode(opcode, fetchdat, op_32, op_pc);
|
||||
|
||||
codegen_accumulate(ACCREG_ins, 1);
|
||||
codegen_accumulate(ACCREG_cycles, -codegen_block_cycles);
|
||||
codegen_block_cycles = 0;
|
||||
|
||||
@@ -2063,11 +2056,10 @@ generate_call:
|
||||
codegen_endpc = (cs + cpu_state.pc) + 8;
|
||||
|
||||
/* Check for interrupts. */
|
||||
addbyte(0xE8); /*CALL*/
|
||||
addlong(((uint8_t *)int_check - (uint8_t *)(&block->data[block_pos + 4])));
|
||||
|
||||
addbyte(0x09); /*OR %eax, %eax*/
|
||||
addbyte(0xc0);
|
||||
addbyte(0xf6); /* test byte ptr[&pic_pending],1 */
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t) (uintptr_t) &pic_pending);
|
||||
addbyte(0x01);
|
||||
addbyte(0x0F); addbyte(0x85); /*JNZ 0*/
|
||||
addlong((uint32_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(&block->data[block_pos + 4]));
|
||||
|
||||
@@ -2154,14 +2146,10 @@ generate_call:
|
||||
|
||||
block->ins++;
|
||||
|
||||
addbyte(0x09); /*OR %eax, %eax*/
|
||||
addbyte(0xc0);
|
||||
addbyte(0x0F); addbyte(0x85); /*JNZ 0*/
|
||||
addlong((uint32_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(&block->data[block_pos + 4]));
|
||||
|
||||
/* Check for interrupts. */
|
||||
addbyte(0xE8); /*CALL*/
|
||||
addlong(((uint8_t *)int_check - (uint8_t *)(&block->data[block_pos + 4])));
|
||||
addbyte(0x0a); /* or al,byte ptr[&pic_pending] */
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t) (uintptr_t) &pic_pending);
|
||||
|
||||
addbyte(0x09); /*OR %eax, %eax*/
|
||||
addbyte(0xc0);
|
||||
|
||||
@@ -1,526 +0,0 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
extern int tempc;
|
||||
|
||||
enum
|
||||
{
|
||||
FLAGS_UNKNOWN,
|
||||
|
||||
FLAGS_ZN8,
|
||||
FLAGS_ZN16,
|
||||
FLAGS_ZN32,
|
||||
|
||||
FLAGS_ADD8,
|
||||
FLAGS_ADD16,
|
||||
FLAGS_ADD32,
|
||||
|
||||
FLAGS_SUB8,
|
||||
FLAGS_SUB16,
|
||||
FLAGS_SUB32,
|
||||
|
||||
FLAGS_SHL8,
|
||||
FLAGS_SHL16,
|
||||
FLAGS_SHL32,
|
||||
|
||||
FLAGS_SHR8,
|
||||
FLAGS_SHR16,
|
||||
FLAGS_SHR32,
|
||||
|
||||
FLAGS_SAR8,
|
||||
FLAGS_SAR16,
|
||||
FLAGS_SAR32,
|
||||
|
||||
FLAGS_INC8,
|
||||
FLAGS_INC16,
|
||||
FLAGS_INC32,
|
||||
|
||||
FLAGS_DEC8,
|
||||
FLAGS_DEC16,
|
||||
FLAGS_DEC32
|
||||
};
|
||||
|
||||
static __inline int ZF_SET()
|
||||
{
|
||||
switch (cpu_state.flags_op)
|
||||
{
|
||||
case FLAGS_ZN8:
|
||||
case FLAGS_ZN16:
|
||||
case FLAGS_ZN32:
|
||||
case FLAGS_ADD8:
|
||||
case FLAGS_ADD16:
|
||||
case FLAGS_ADD32:
|
||||
case FLAGS_SUB8:
|
||||
case FLAGS_SUB16:
|
||||
case FLAGS_SUB32:
|
||||
case FLAGS_SHL8:
|
||||
case FLAGS_SHL16:
|
||||
case FLAGS_SHL32:
|
||||
case FLAGS_SHR8:
|
||||
case FLAGS_SHR16:
|
||||
case FLAGS_SHR32:
|
||||
case FLAGS_SAR8:
|
||||
case FLAGS_SAR16:
|
||||
case FLAGS_SAR32:
|
||||
case FLAGS_INC8:
|
||||
case FLAGS_INC16:
|
||||
case FLAGS_INC32:
|
||||
case FLAGS_DEC8:
|
||||
case FLAGS_DEC16:
|
||||
case FLAGS_DEC32:
|
||||
return !cpu_state.flags_res;
|
||||
|
||||
case FLAGS_UNKNOWN:
|
||||
return cpu_state.flags & Z_FLAG;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static __inline int NF_SET()
|
||||
{
|
||||
switch (cpu_state.flags_op)
|
||||
{
|
||||
case FLAGS_ZN8:
|
||||
case FLAGS_ADD8:
|
||||
case FLAGS_SUB8:
|
||||
case FLAGS_SHL8:
|
||||
case FLAGS_SHR8:
|
||||
case FLAGS_SAR8:
|
||||
case FLAGS_INC8:
|
||||
case FLAGS_DEC8:
|
||||
return cpu_state.flags_res & 0x80;
|
||||
|
||||
case FLAGS_ZN16:
|
||||
case FLAGS_ADD16:
|
||||
case FLAGS_SUB16:
|
||||
case FLAGS_SHL16:
|
||||
case FLAGS_SHR16:
|
||||
case FLAGS_SAR16:
|
||||
case FLAGS_INC16:
|
||||
case FLAGS_DEC16:
|
||||
return cpu_state.flags_res & 0x8000;
|
||||
|
||||
case FLAGS_ZN32:
|
||||
case FLAGS_ADD32:
|
||||
case FLAGS_SUB32:
|
||||
case FLAGS_SHL32:
|
||||
case FLAGS_SHR32:
|
||||
case FLAGS_SAR32:
|
||||
case FLAGS_INC32:
|
||||
case FLAGS_DEC32:
|
||||
return cpu_state.flags_res & 0x80000000;
|
||||
|
||||
case FLAGS_UNKNOWN:
|
||||
return cpu_state.flags & N_FLAG;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static __inline int PF_SET()
|
||||
{
|
||||
switch (cpu_state.flags_op)
|
||||
{
|
||||
case FLAGS_ZN8:
|
||||
case FLAGS_ZN16:
|
||||
case FLAGS_ZN32:
|
||||
case FLAGS_ADD8:
|
||||
case FLAGS_ADD16:
|
||||
case FLAGS_ADD32:
|
||||
case FLAGS_SUB8:
|
||||
case FLAGS_SUB16:
|
||||
case FLAGS_SUB32:
|
||||
case FLAGS_SHL8:
|
||||
case FLAGS_SHL16:
|
||||
case FLAGS_SHL32:
|
||||
case FLAGS_SHR8:
|
||||
case FLAGS_SHR16:
|
||||
case FLAGS_SHR32:
|
||||
case FLAGS_SAR8:
|
||||
case FLAGS_SAR16:
|
||||
case FLAGS_SAR32:
|
||||
case FLAGS_INC8:
|
||||
case FLAGS_INC16:
|
||||
case FLAGS_INC32:
|
||||
case FLAGS_DEC8:
|
||||
case FLAGS_DEC16:
|
||||
case FLAGS_DEC32:
|
||||
return znptable8[cpu_state.flags_res & 0xff] & P_FLAG;
|
||||
|
||||
case FLAGS_UNKNOWN:
|
||||
return cpu_state.flags & P_FLAG;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static __inline int VF_SET()
|
||||
{
|
||||
switch (cpu_state.flags_op)
|
||||
{
|
||||
case FLAGS_ZN8:
|
||||
case FLAGS_ZN16:
|
||||
case FLAGS_ZN32:
|
||||
case FLAGS_SAR8:
|
||||
case FLAGS_SAR16:
|
||||
case FLAGS_SAR32:
|
||||
return 0;
|
||||
|
||||
case FLAGS_ADD8:
|
||||
case FLAGS_INC8:
|
||||
return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x80) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80);
|
||||
case FLAGS_ADD16:
|
||||
case FLAGS_INC16:
|
||||
return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x8000) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000);
|
||||
case FLAGS_ADD32:
|
||||
case FLAGS_INC32:
|
||||
return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x80000000) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80000000);
|
||||
|
||||
case FLAGS_SUB8:
|
||||
case FLAGS_DEC8:
|
||||
return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80);
|
||||
case FLAGS_SUB16:
|
||||
case FLAGS_DEC16:
|
||||
return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000);
|
||||
case FLAGS_SUB32:
|
||||
case FLAGS_DEC32:
|
||||
return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80000000);
|
||||
|
||||
case FLAGS_SHL8:
|
||||
return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x80);
|
||||
case FLAGS_SHL16:
|
||||
return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x8000);
|
||||
case FLAGS_SHL32:
|
||||
return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x80000000);
|
||||
|
||||
case FLAGS_SHR8:
|
||||
return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80));
|
||||
case FLAGS_SHR16:
|
||||
return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x8000));
|
||||
case FLAGS_SHR32:
|
||||
return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80000000));
|
||||
|
||||
case FLAGS_UNKNOWN:
|
||||
return cpu_state.flags & V_FLAG;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static __inline int AF_SET()
|
||||
{
|
||||
switch (cpu_state.flags_op)
|
||||
{
|
||||
case FLAGS_ZN8:
|
||||
case FLAGS_ZN16:
|
||||
case FLAGS_ZN32:
|
||||
case FLAGS_SHL8:
|
||||
case FLAGS_SHL16:
|
||||
case FLAGS_SHL32:
|
||||
case FLAGS_SHR8:
|
||||
case FLAGS_SHR16:
|
||||
case FLAGS_SHR32:
|
||||
case FLAGS_SAR8:
|
||||
case FLAGS_SAR16:
|
||||
case FLAGS_SAR32:
|
||||
return 0;
|
||||
|
||||
case FLAGS_ADD8:
|
||||
case FLAGS_ADD16:
|
||||
case FLAGS_ADD32:
|
||||
case FLAGS_INC8:
|
||||
case FLAGS_INC16:
|
||||
case FLAGS_INC32:
|
||||
return ((cpu_state.flags_op1 & 0xF) + (cpu_state.flags_op2 & 0xF)) & 0x10;
|
||||
|
||||
case FLAGS_SUB8:
|
||||
case FLAGS_SUB16:
|
||||
case FLAGS_SUB32:
|
||||
case FLAGS_DEC8:
|
||||
case FLAGS_DEC16:
|
||||
case FLAGS_DEC32:
|
||||
return ((cpu_state.flags_op1 & 0xF) - (cpu_state.flags_op2 & 0xF)) & 0x10;
|
||||
|
||||
case FLAGS_UNKNOWN:
|
||||
return cpu_state.flags & A_FLAG;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static __inline int CF_SET()
|
||||
{
|
||||
switch (cpu_state.flags_op)
|
||||
{
|
||||
case FLAGS_ADD8:
|
||||
return (cpu_state.flags_op1 + cpu_state.flags_op2) & 0x100;
|
||||
case FLAGS_ADD16:
|
||||
return (cpu_state.flags_op1 + cpu_state.flags_op2) & 0x10000;
|
||||
case FLAGS_ADD32:
|
||||
return (cpu_state.flags_res < cpu_state.flags_op1);
|
||||
|
||||
case FLAGS_SUB8:
|
||||
case FLAGS_SUB16:
|
||||
case FLAGS_SUB32:
|
||||
return (cpu_state.flags_op1 < cpu_state.flags_op2);
|
||||
|
||||
case FLAGS_SHL8:
|
||||
return (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80;
|
||||
case FLAGS_SHL16:
|
||||
return (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x8000;
|
||||
case FLAGS_SHL32:
|
||||
return (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80000000;
|
||||
|
||||
case FLAGS_SHR8:
|
||||
case FLAGS_SHR16:
|
||||
case FLAGS_SHR32:
|
||||
return (cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1;
|
||||
|
||||
case FLAGS_SAR8:
|
||||
return ((int8_t)cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1;
|
||||
case FLAGS_SAR16:
|
||||
return ((int16_t)cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1;
|
||||
case FLAGS_SAR32:
|
||||
return ((int32_t)cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1;
|
||||
|
||||
case FLAGS_ZN8:
|
||||
case FLAGS_ZN16:
|
||||
case FLAGS_ZN32:
|
||||
return 0;
|
||||
|
||||
case FLAGS_DEC8:
|
||||
case FLAGS_DEC16:
|
||||
case FLAGS_DEC32:
|
||||
case FLAGS_INC8:
|
||||
case FLAGS_INC16:
|
||||
case FLAGS_INC32:
|
||||
case FLAGS_UNKNOWN:
|
||||
return cpu_state.flags & C_FLAG;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void flags_rebuild()
|
||||
{
|
||||
if (cpu_state.flags_op != FLAGS_UNKNOWN)
|
||||
{
|
||||
uint16_t tempf = 0;
|
||||
if (CF_SET()) tempf |= C_FLAG;
|
||||
if (PF_SET()) tempf |= P_FLAG;
|
||||
if (AF_SET()) tempf |= A_FLAG;
|
||||
if (ZF_SET()) tempf |= Z_FLAG;
|
||||
if (NF_SET()) tempf |= N_FLAG;
|
||||
if (VF_SET()) tempf |= V_FLAG;
|
||||
cpu_state.flags = (cpu_state.flags & ~0x8d5) | tempf;
|
||||
cpu_state.flags_op = FLAGS_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void flags_extract()
|
||||
{
|
||||
cpu_state.flags_op = FLAGS_UNKNOWN;
|
||||
}
|
||||
|
||||
static __inline void flags_rebuild_c()
|
||||
{
|
||||
if (cpu_state.flags_op != FLAGS_UNKNOWN)
|
||||
{
|
||||
if (CF_SET())
|
||||
cpu_state.flags |= C_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~C_FLAG;
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void setznp8(uint8_t val)
|
||||
{
|
||||
cpu_state.flags_op = FLAGS_ZN8;
|
||||
cpu_state.flags_res = val;
|
||||
}
|
||||
static __inline void setznp16(uint16_t val)
|
||||
{
|
||||
cpu_state.flags_op = FLAGS_ZN16;
|
||||
cpu_state.flags_res = val;
|
||||
}
|
||||
static __inline void setznp32(uint32_t val)
|
||||
{
|
||||
cpu_state.flags_op = FLAGS_ZN32;
|
||||
cpu_state.flags_res = val;
|
||||
}
|
||||
|
||||
#define set_flags_shift(op, orig, shift, res) \
|
||||
cpu_state.flags_op = op; \
|
||||
cpu_state.flags_res = res; \
|
||||
cpu_state.flags_op1 = orig; \
|
||||
cpu_state.flags_op2 = shift;
|
||||
|
||||
static __inline void setadd8(uint8_t a, uint8_t b)
|
||||
{
|
||||
cpu_state.flags_op1 = a;
|
||||
cpu_state.flags_op2 = b;
|
||||
cpu_state.flags_res = (a + b) & 0xff;
|
||||
cpu_state.flags_op = FLAGS_ADD8;
|
||||
}
|
||||
static __inline void setadd16(uint16_t a, uint16_t b)
|
||||
{
|
||||
cpu_state.flags_op1 = a;
|
||||
cpu_state.flags_op2 = b;
|
||||
cpu_state.flags_res = (a + b) & 0xffff;
|
||||
cpu_state.flags_op = FLAGS_ADD16;
|
||||
}
|
||||
static __inline void setadd32(uint32_t a, uint32_t b)
|
||||
{
|
||||
cpu_state.flags_op1 = a;
|
||||
cpu_state.flags_op2 = b;
|
||||
cpu_state.flags_res = a + b;
|
||||
cpu_state.flags_op = FLAGS_ADD32;
|
||||
}
|
||||
static __inline void setadd8nc(uint8_t a, uint8_t b)
|
||||
{
|
||||
flags_rebuild_c();
|
||||
cpu_state.flags_op1 = a;
|
||||
cpu_state.flags_op2 = b;
|
||||
cpu_state.flags_res = (a + b) & 0xff;
|
||||
cpu_state.flags_op = FLAGS_INC8;
|
||||
}
|
||||
static __inline void setadd16nc(uint16_t a, uint16_t b)
|
||||
{
|
||||
flags_rebuild_c();
|
||||
cpu_state.flags_op1 = a;
|
||||
cpu_state.flags_op2 = b;
|
||||
cpu_state.flags_res = (a + b) & 0xffff;
|
||||
cpu_state.flags_op = FLAGS_INC16;
|
||||
}
|
||||
static __inline void setadd32nc(uint32_t a, uint32_t b)
|
||||
{
|
||||
flags_rebuild_c();
|
||||
cpu_state.flags_op1 = a;
|
||||
cpu_state.flags_op2 = b;
|
||||
cpu_state.flags_res = a + b;
|
||||
cpu_state.flags_op = FLAGS_INC32;
|
||||
}
|
||||
|
||||
static __inline void setsub8(uint8_t a, uint8_t b)
|
||||
{
|
||||
cpu_state.flags_op1 = a;
|
||||
cpu_state.flags_op2 = b;
|
||||
cpu_state.flags_res = (a - b) & 0xff;
|
||||
cpu_state.flags_op = FLAGS_SUB8;
|
||||
}
|
||||
static __inline void setsub16(uint16_t a, uint16_t b)
|
||||
{
|
||||
cpu_state.flags_op1 = a;
|
||||
cpu_state.flags_op2 = b;
|
||||
cpu_state.flags_res = (a - b) & 0xffff;
|
||||
cpu_state.flags_op = FLAGS_SUB16;
|
||||
}
|
||||
static __inline void setsub32(uint32_t a, uint32_t b)
|
||||
{
|
||||
cpu_state.flags_op1 = a;
|
||||
cpu_state.flags_op2 = b;
|
||||
cpu_state.flags_res = a - b;
|
||||
cpu_state.flags_op = FLAGS_SUB32;
|
||||
}
|
||||
|
||||
static __inline void setsub8nc(uint8_t a, uint8_t b)
|
||||
{
|
||||
flags_rebuild_c();
|
||||
cpu_state.flags_op1 = a;
|
||||
cpu_state.flags_op2 = b;
|
||||
cpu_state.flags_res = (a - b) & 0xff;
|
||||
cpu_state.flags_op = FLAGS_DEC8;
|
||||
}
|
||||
static __inline void setsub16nc(uint16_t a, uint16_t b)
|
||||
{
|
||||
flags_rebuild_c();
|
||||
cpu_state.flags_op1 = a;
|
||||
cpu_state.flags_op2 = b;
|
||||
cpu_state.flags_res = (a - b) & 0xffff;
|
||||
cpu_state.flags_op = FLAGS_DEC16;
|
||||
}
|
||||
static __inline void setsub32nc(uint32_t a, uint32_t b)
|
||||
{
|
||||
flags_rebuild_c();
|
||||
cpu_state.flags_op1 = a;
|
||||
cpu_state.flags_op2 = b;
|
||||
cpu_state.flags_res = a - b;
|
||||
cpu_state.flags_op = FLAGS_DEC32;
|
||||
}
|
||||
|
||||
static __inline void setadc8(uint8_t a, uint8_t b)
|
||||
{
|
||||
uint16_t c=(uint16_t)a+(uint16_t)b+tempc;
|
||||
cpu_state.flags_op = FLAGS_UNKNOWN;
|
||||
cpu_state.flags&=~0x8D5;
|
||||
cpu_state.flags|=znptable8[c&0xFF];
|
||||
if (c&0x100) cpu_state.flags|=C_FLAG;
|
||||
if (!((a^b)&0x80)&&((a^c)&0x80)) cpu_state.flags|=V_FLAG;
|
||||
if (((a&0xF)+(b&0xF))&0x10) cpu_state.flags|=A_FLAG;
|
||||
}
|
||||
static __inline void setadc16(uint16_t a, uint16_t b)
|
||||
{
|
||||
uint32_t c=(uint32_t)a+(uint32_t)b+tempc;
|
||||
cpu_state.flags_op = FLAGS_UNKNOWN;
|
||||
cpu_state.flags&=~0x8D5;
|
||||
cpu_state.flags|=znptable16[c&0xFFFF];
|
||||
if (c&0x10000) cpu_state.flags|=C_FLAG;
|
||||
if (!((a^b)&0x8000)&&((a^c)&0x8000)) cpu_state.flags|=V_FLAG;
|
||||
if (((a&0xF)+(b&0xF))&0x10) cpu_state.flags|=A_FLAG;
|
||||
}
|
||||
static __inline void setadc32(uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t c=(uint32_t)a+(uint32_t)b+tempc;
|
||||
cpu_state.flags_op = FLAGS_UNKNOWN;
|
||||
cpu_state.flags&=~0x8D5;
|
||||
cpu_state.flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0));
|
||||
cpu_state.flags|=(znptable8[c&0xFF]&P_FLAG);
|
||||
if ((c<a) || (c==a && tempc)) cpu_state.flags|=C_FLAG;
|
||||
if (!((a^b)&0x80000000)&&((a^c)&0x80000000)) cpu_state.flags|=V_FLAG;
|
||||
if (((a&0xF)+(b&0xF)+tempc)&0x10) cpu_state.flags|=A_FLAG;
|
||||
}
|
||||
|
||||
|
||||
static __inline void setsbc8(uint8_t a, uint8_t b)
|
||||
{
|
||||
uint16_t c=(uint16_t)a-(((uint16_t)b)+tempc);
|
||||
cpu_state.flags_op = FLAGS_UNKNOWN;
|
||||
cpu_state.flags&=~0x8D5;
|
||||
cpu_state.flags|=znptable8[c&0xFF];
|
||||
if (c&0x100) cpu_state.flags|=C_FLAG;
|
||||
if ((a^b)&(a^c)&0x80) cpu_state.flags|=V_FLAG;
|
||||
if (((a&0xF)-(b&0xF))&0x10) cpu_state.flags|=A_FLAG;
|
||||
}
|
||||
static __inline void setsbc16(uint16_t a, uint16_t b)
|
||||
{
|
||||
uint32_t c=(uint32_t)a-(((uint32_t)b)+tempc);
|
||||
cpu_state.flags_op = FLAGS_UNKNOWN;
|
||||
cpu_state.flags&=~0x8D5;
|
||||
cpu_state.flags|=(znptable16[c&0xFFFF]&~4);
|
||||
cpu_state.flags|=(znptable8[c&0xFF]&4);
|
||||
if (c&0x10000) cpu_state.flags|=C_FLAG;
|
||||
if ((a^b)&(a^c)&0x8000) cpu_state.flags|=V_FLAG;
|
||||
if (((a&0xF)-(b&0xF))&0x10) cpu_state.flags|=A_FLAG;
|
||||
}
|
||||
|
||||
static __inline void setsbc32(uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t c=(uint32_t)a-(((uint32_t)b)+tempc);
|
||||
cpu_state.flags_op = FLAGS_UNKNOWN;
|
||||
cpu_state.flags&=~0x8D5;
|
||||
cpu_state.flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0));
|
||||
cpu_state.flags|=(znptable8[c&0xFF]&P_FLAG);
|
||||
if ((c>a) || (c==a && tempc)) cpu_state.flags|=C_FLAG;
|
||||
if ((a^b)&(a^c)&0x80000000) cpu_state.flags|=V_FLAG;
|
||||
if (((a&0xF)-((b&0xF)+tempc))&0x10) cpu_state.flags|=A_FLAG;
|
||||
}
|
||||
|
||||
extern void cpu_386_flags_extract();
|
||||
extern void cpu_386_flags_rebuild();
|
||||
@@ -918,11 +918,9 @@ void loadcscall(uint16_t seg)
|
||||
int type;
|
||||
uint16_t tempw;
|
||||
|
||||
int csout = output;
|
||||
|
||||
if (msw&1 && !(cpu_state.eflags&VM_FLAG))
|
||||
{
|
||||
if (csout) x86seg_log("Protected mode CS load! %04X\n",seg);
|
||||
x86seg_log("Protected mode CS load! %04X\n", seg);
|
||||
if (!(seg&~3))
|
||||
{
|
||||
x86gpf("loadcscall(): Protected mode selector is zero",0);
|
||||
@@ -956,7 +954,7 @@ void loadcscall(uint16_t seg)
|
||||
newpc=segdat[0];
|
||||
if (type&0x800) newpc|=segdat[3]<<16;
|
||||
|
||||
if (csout) x86seg_log("Code seg call - %04X - %04X %04X %04X\n",seg,segdat[0],segdat[1],segdat[2]);
|
||||
x86seg_log("Code seg call - %04X - %04X %04X %04X\n",seg,segdat[0],segdat[1],segdat[2]);
|
||||
if (segdat[2]&0x1000)
|
||||
{
|
||||
if (!(segdat[2]&0x400)) /*Not conforming*/
|
||||
@@ -1001,14 +999,16 @@ void loadcscall(uint16_t seg)
|
||||
CS=seg;
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
|
||||
if (csout) x86seg_log("Complete\n");
|
||||
|
||||
#ifdef ENABLE_X86SEG_LOG
|
||||
x86seg_log("Complete\n");
|
||||
#endif
|
||||
cycles -= timing_call_pm;
|
||||
}
|
||||
else
|
||||
{
|
||||
type=segdat[2]&0xF00;
|
||||
if (csout) x86seg_log("Type %03X\n",type);
|
||||
x86seg_log("Type %03X\n",type);
|
||||
switch (type)
|
||||
{
|
||||
case 0x400: /*Call gate*/
|
||||
|
||||
@@ -599,7 +599,6 @@ generate_call:
|
||||
|
||||
codegen_timing_opcode(opcode, fetchdat, op_32, op_pc);
|
||||
|
||||
codegen_accumulate(ir, ACCREG_ins, 1);
|
||||
codegen_accumulate(ir, ACCREG_cycles, -codegen_block_cycles);
|
||||
codegen_block_cycles = 0;
|
||||
|
||||
@@ -696,9 +695,6 @@ generate_call:
|
||||
|
||||
block->ins++;
|
||||
|
||||
/* Check for interrupts. */
|
||||
uop_CALL_INSTRUCTION_FUNC(ir, int_check);
|
||||
|
||||
if (block->ins >= MAX_INSTRUCTION_COUNT)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
@@ -759,8 +755,6 @@ generate_call:
|
||||
uop_MOV_IMM(ir, IREG_ssegs, op_ssegs);
|
||||
uop_LOAD_FUNC_ARG_IMM(ir, 0, fetchdat);
|
||||
uop_CALL_INSTRUCTION_FUNC(ir, op);
|
||||
/* Check for interrupts. */
|
||||
uop_CALL_INSTRUCTION_FUNC(ir, int_check);
|
||||
codegen_mark_code_present(block, cs+cpu_state.pc, 8);
|
||||
|
||||
last_op_32 = op_32;
|
||||
|
||||
@@ -341,15 +341,8 @@ void codegen_delete_random_block(int required_mem_block);
|
||||
extern int cpu_block_end;
|
||||
extern uint32_t codegen_endpc;
|
||||
|
||||
extern int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks;
|
||||
extern int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched;
|
||||
extern int cpu_recomp_flushes, cpu_recomp_flushes_latched;
|
||||
extern int cpu_recomp_evicted, cpu_recomp_evicted_latched;
|
||||
extern int cpu_recomp_reuse, cpu_recomp_reuse_latched;
|
||||
extern int cpu_recomp_removed, cpu_recomp_removed_latched;
|
||||
|
||||
extern int cpu_reps, cpu_reps_latched;
|
||||
extern int cpu_notreps, cpu_notreps_latched;
|
||||
extern int cpu_reps;
|
||||
extern int cpu_notreps;
|
||||
|
||||
extern int codegen_block_cycles;
|
||||
|
||||
|
||||
@@ -13,8 +13,7 @@ static struct
|
||||
int dest_reg;
|
||||
} acc_regs[] =
|
||||
{
|
||||
[ACCREG_ins] = {0, IREG_ins},
|
||||
[ACCREG_cycles] = {0, IREG_cycles},
|
||||
[ACCREG_cycles] = {0, IREG_cycles}
|
||||
};
|
||||
|
||||
void codegen_accumulate(ir_data_t *ir, int acc_reg, int delta)
|
||||
@@ -28,23 +27,14 @@ void codegen_accumulate(ir_data_t *ir, int acc_reg, int delta)
|
||||
|
||||
void codegen_accumulate_flush(ir_data_t *ir)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c = 0; c < ACCREG_COUNT; c++)
|
||||
{
|
||||
if (acc_regs[c].count)
|
||||
{
|
||||
uop_ADD_IMM(ir, acc_regs[c].dest_reg, acc_regs[c].dest_reg, acc_regs[c].count);
|
||||
}
|
||||
if (acc_regs[0].count) {
|
||||
uop_ADD_IMM(ir, acc_regs[0].dest_reg, acc_regs[0].dest_reg, acc_regs[0].count);
|
||||
}
|
||||
|
||||
acc_regs[c].count = 0;
|
||||
}
|
||||
acc_regs[0].count = 0;
|
||||
}
|
||||
|
||||
void codegen_accumulate_reset()
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c = 0; c < ACCREG_COUNT; c++)
|
||||
acc_regs[c].count = 0;
|
||||
acc_regs[0].count = 0;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
enum
|
||||
{
|
||||
ACCREG_ins = 0,
|
||||
ACCREG_cycles = 1,
|
||||
ACCREG_cycles = 0,
|
||||
|
||||
ACCREG_COUNT
|
||||
};
|
||||
|
||||
@@ -37,11 +37,6 @@ int block_current = 0;
|
||||
static int block_num;
|
||||
int block_pos;
|
||||
|
||||
int cpu_recomp_flushes, cpu_recomp_flushes_latched;
|
||||
int cpu_recomp_evicted, cpu_recomp_evicted_latched;
|
||||
int cpu_recomp_reuse, cpu_recomp_reuse_latched;
|
||||
int cpu_recomp_removed, cpu_recomp_removed_latched;
|
||||
|
||||
uint32_t codegen_endpc;
|
||||
|
||||
int codegen_block_cycles;
|
||||
@@ -479,7 +474,6 @@ void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr)
|
||||
if (*block->dirty_mask & block->page_mask)
|
||||
{
|
||||
invalidate_block(block);
|
||||
cpu_recomp_evicted++;
|
||||
}
|
||||
if (block_nr == next_block)
|
||||
fatal("Broken 1\n");
|
||||
@@ -496,7 +490,6 @@ void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr)
|
||||
if (*block->dirty_mask2 & block->page_mask2)
|
||||
{
|
||||
invalidate_block(block);
|
||||
cpu_recomp_evicted++;
|
||||
}
|
||||
if (block_nr == next_block)
|
||||
fatal("Broken 2\n");
|
||||
@@ -626,7 +619,6 @@ void codegen_block_remove()
|
||||
codeblock_t *block = &codeblock[block_current];
|
||||
|
||||
delete_block(block);
|
||||
cpu_recomp_removed++;
|
||||
|
||||
recomp_page = -1;
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ int codegen_can_unroll_full(codeblock_t *block, ir_data_t *ir, uint32_t next_pc,
|
||||
return 0;
|
||||
|
||||
max_unroll = UNROLL_MAX_UOPS / ((ir->wr_pos-start)+6);
|
||||
if (max_unroll > (UNROLL_MAX_REG_REFERENCES / max_version_refcount))
|
||||
if ((max_version_refcount != 0) && (max_unroll > (UNROLL_MAX_REG_REFERENCES / max_version_refcount)))
|
||||
max_unroll = (UNROLL_MAX_REG_REFERENCES / max_version_refcount);
|
||||
if (max_unroll > UNROLL_MAX_COUNT)
|
||||
max_unroll = UNROLL_MAX_COUNT;
|
||||
|
||||
@@ -95,7 +95,7 @@ struct
|
||||
|
||||
[IREG_rm_mod_reg] = {REG_DWORD, &cpu_state.rm_data.rm_mod_reg_data, REG_INTEGER, REG_PERMANENT},
|
||||
|
||||
[IREG_ins] = {REG_DWORD, &cpu_state.cpu_recomp_ins, REG_INTEGER, REG_PERMANENT},
|
||||
[IREG_acycs] = {REG_DWORD, &acycs, REG_INTEGER, REG_PERMANENT},
|
||||
[IREG_cycles] = {REG_DWORD, &cpu_state._cycles, REG_INTEGER, REG_PERMANENT},
|
||||
|
||||
[IREG_CS_base] = {REG_DWORD, &cpu_state.seg_cs.base, REG_INTEGER, REG_PERMANENT},
|
||||
@@ -180,8 +180,6 @@ struct
|
||||
|
||||
[IREG_temp0d] = {REG_DOUBLE, (void *)40, REG_FP, REG_VOLATILE},
|
||||
[IREG_temp1d] = {REG_DOUBLE, (void *)48, REG_FP, REG_VOLATILE},
|
||||
|
||||
[IREG_acycs] = {REG_DWORD, &acycs, REG_INTEGER, REG_PERMANENT}
|
||||
};
|
||||
|
||||
void codegen_reg_mark_as_required()
|
||||
|
||||
@@ -41,7 +41,7 @@ enum
|
||||
|
||||
IREG_rm_mod_reg = 18,
|
||||
|
||||
IREG_ins = 19,
|
||||
IREG_acycs = 19,
|
||||
IREG_cycles = 20,
|
||||
|
||||
IREG_CS_base = 21,
|
||||
@@ -133,9 +133,7 @@ enum
|
||||
IREG_GS_limit_high = 86,
|
||||
IREG_SS_limit_high = 87,
|
||||
|
||||
IREG_acycs = 88,
|
||||
|
||||
IREG_COUNT = 89,
|
||||
IREG_COUNT = 88,
|
||||
|
||||
IREG_INVALID = 255,
|
||||
|
||||
|
||||
@@ -908,11 +908,9 @@ void loadcscall(uint16_t seg, uint32_t old_pc)
|
||||
int type;
|
||||
uint16_t tempw;
|
||||
|
||||
int csout = output;
|
||||
|
||||
if (msw&1 && !(cpu_state.eflags&VM_FLAG))
|
||||
{
|
||||
if (csout) x86seg_log("Protected mode CS load! %04X\n",seg);
|
||||
x86seg_log("Protected mode CS load! %04X\n", seg);
|
||||
if (!(seg&~3))
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
@@ -946,7 +944,7 @@ void loadcscall(uint16_t seg, uint32_t old_pc)
|
||||
newpc=segdat[0];
|
||||
if (type&0x800) newpc|=segdat[3]<<16;
|
||||
|
||||
if (csout) x86seg_log("Code seg call - %04X - %04X %04X %04X\n",seg,segdat[0],segdat[1],segdat[2]);
|
||||
x86seg_log("Code seg call - %04X - %04X %04X %04X\n",seg,segdat[0],segdat[1],segdat[2]);
|
||||
if (segdat[2]&0x1000)
|
||||
{
|
||||
if (!(segdat[2]&0x400)) /*Not conforming*/
|
||||
@@ -992,13 +990,15 @@ void loadcscall(uint16_t seg, uint32_t old_pc)
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
oldcpl = CPL;
|
||||
if (csout) x86seg_log("Complete\n");
|
||||
#ifdef ENABLE_X86SEG_LOG
|
||||
x86seg_log("Complete\n");
|
||||
#endif
|
||||
cycles -= timing_call_pm;
|
||||
}
|
||||
else
|
||||
{
|
||||
type=segdat[2]&0xF00;
|
||||
if (csout) x86seg_log("Type %03X\n",type);
|
||||
x86seg_log("Type %03X\n",type);
|
||||
switch (type)
|
||||
{
|
||||
case 0x400: /*Call gate*/
|
||||
|
||||
@@ -334,8 +334,6 @@ exec386(int cycs)
|
||||
}
|
||||
}
|
||||
|
||||
ins++;
|
||||
|
||||
if (timetolive) {
|
||||
timetolive--;
|
||||
if (!timetolive)
|
||||
|
||||
@@ -47,8 +47,6 @@ int nmi_enable = 1;
|
||||
|
||||
int cpl_override=0;
|
||||
|
||||
int fpucount=0;
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
uint16_t cpu_cur_status = 0;
|
||||
#else
|
||||
|
||||
@@ -36,8 +36,6 @@
|
||||
|
||||
|
||||
int inrecomp = 0, cpu_block_end = 0;
|
||||
int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks;
|
||||
int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched;
|
||||
|
||||
|
||||
#ifdef ENABLE_386_DYNAREC_LOG
|
||||
@@ -127,7 +125,6 @@ static __inline void fetch_ea_32_long(uint32_t rmdat)
|
||||
if (writelookup2[addr >> 12] != -1)
|
||||
eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
|
||||
}
|
||||
cpu_state.last_ea = cpu_state.eaaddr;
|
||||
}
|
||||
|
||||
static __inline void fetch_ea_16_long(uint32_t rmdat)
|
||||
@@ -168,7 +165,6 @@ static __inline void fetch_ea_16_long(uint32_t rmdat)
|
||||
if (writelookup2[addr >> 12] != -1)
|
||||
eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
|
||||
}
|
||||
cpu_state.last_ea = cpu_state.eaaddr;
|
||||
}
|
||||
|
||||
#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 1; }
|
||||
@@ -278,7 +274,9 @@ static uint64_t tsc_old = 0;
|
||||
|
||||
int acycs = 0;
|
||||
|
||||
void update_tsc(void)
|
||||
|
||||
void
|
||||
update_tsc(void)
|
||||
{
|
||||
int cycdiff;
|
||||
uint64_t delta;
|
||||
@@ -299,27 +297,10 @@ void update_tsc(void)
|
||||
|
||||
if (cycdiff > 0) {
|
||||
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc))
|
||||
timer_process();
|
||||
timer_process_inline();
|
||||
}
|
||||
}
|
||||
|
||||
int int_check(void)
|
||||
{
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
if (trap)
|
||||
return 1;
|
||||
else if (smi_line)
|
||||
return 1;
|
||||
else if (nmi && nmi_enable && nmi_mask)
|
||||
return 1;
|
||||
else if ((cpu_state.flags & I_FLAG) && pic_intpending)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void exec386_dynarec(int cycs)
|
||||
{
|
||||
int vector;
|
||||
@@ -406,8 +387,6 @@ void exec386_dynarec(int cycs)
|
||||
CPU_BLOCK_END();
|
||||
else if ((cpu_state.flags & I_FLAG) && pic_intpending)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
ins++;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -561,7 +540,6 @@ void exec386_dynarec(int cycs)
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
if (!use32) cpu_state.pc &= 0xffff;
|
||||
#endif
|
||||
cpu_recomp_blocks++;
|
||||
}
|
||||
else if (valid_block && !cpu_state.abrt)
|
||||
{
|
||||
@@ -574,8 +552,6 @@ void exec386_dynarec(int cycs)
|
||||
|
||||
cpu_block_end = 0;
|
||||
x86_was_reset = 0;
|
||||
|
||||
cpu_new_blocks++;
|
||||
|
||||
codegen_block_start_recompile(block);
|
||||
codegen_in_recompile = 1;
|
||||
@@ -644,7 +620,6 @@ void exec386_dynarec(int cycs)
|
||||
CPU_BLOCK_END();
|
||||
else if ((cpu_state.flags & I_FLAG) && pic_intpending)
|
||||
CPU_BLOCK_END();
|
||||
ins++;
|
||||
}
|
||||
|
||||
if (!cpu_state.abrt && !x86_was_reset)
|
||||
@@ -734,8 +709,6 @@ void exec386_dynarec(int cycs)
|
||||
CPU_BLOCK_END();
|
||||
else if ((cpu_state.flags & I_FLAG) && pic_intpending)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
ins++;
|
||||
}
|
||||
|
||||
if (!cpu_state.abrt && !x86_was_reset)
|
||||
@@ -862,7 +835,7 @@ void exec386_dynarec(int cycs)
|
||||
|
||||
if (cycdiff > 0) {
|
||||
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc))
|
||||
timer_process();
|
||||
timer_process_inline();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,6 @@ static __inline void fetch_ea_32_long(uint32_t rmdat)
|
||||
if (writelookup2[addr >> 12] != -1)
|
||||
eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
|
||||
}
|
||||
cpu_state.last_ea = cpu_state.eaaddr;
|
||||
}
|
||||
|
||||
static __inline void fetch_ea_16_long(uint32_t rmdat)
|
||||
@@ -53,7 +52,6 @@ static __inline void fetch_ea_16_long(uint32_t rmdat)
|
||||
if (writelookup2[addr >> 12] != -1)
|
||||
eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
|
||||
}
|
||||
cpu_state.last_ea = cpu_state.eaaddr;
|
||||
}
|
||||
|
||||
#define fetch_ea_16(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_16_long(rmdat);
|
||||
|
||||
@@ -58,13 +58,11 @@ static __inline void PUSH_W(uint16_t val)
|
||||
{
|
||||
writememw(ss, ESP - 2, val); if (cpu_state.abrt) return;
|
||||
ESP -= 2;
|
||||
cpu_state.last_ea = ESP;
|
||||
}
|
||||
else
|
||||
{
|
||||
writememw(ss, (SP - 2) & 0xFFFF, val); if (cpu_state.abrt) return;
|
||||
SP -= 2;
|
||||
cpu_state.last_ea = SP;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,13 +72,11 @@ static __inline void PUSH_L(uint32_t val)
|
||||
{
|
||||
writememl(ss, ESP - 4, val); if (cpu_state.abrt) return;
|
||||
ESP -= 4;
|
||||
cpu_state.last_ea = ESP;
|
||||
}
|
||||
else
|
||||
{
|
||||
writememl(ss, (SP - 4) & 0xFFFF, val); if (cpu_state.abrt) return;
|
||||
SP -= 4;
|
||||
cpu_state.last_ea = SP;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,13 +87,11 @@ static __inline uint16_t POP_W()
|
||||
{
|
||||
ret = readmemw(ss, ESP); if (cpu_state.abrt) return 0;
|
||||
ESP += 2;
|
||||
cpu_state.last_ea = ESP;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = readmemw(ss, SP); if (cpu_state.abrt) return 0;
|
||||
SP += 2;
|
||||
cpu_state.last_ea = SP;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -109,13 +103,11 @@ static __inline uint32_t POP_L()
|
||||
{
|
||||
ret = readmeml(ss, ESP); if (cpu_state.abrt) return 0;
|
||||
ESP += 4;
|
||||
cpu_state.last_ea = ESP;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = readmeml(ss, SP); if (cpu_state.abrt) return 0;
|
||||
SP += 4;
|
||||
cpu_state.last_ea = SP;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -127,13 +119,11 @@ static __inline uint16_t POP_W_seg(uint32_t seg)
|
||||
{
|
||||
ret = readmemw(seg, ESP); if (cpu_state.abrt) return 0;
|
||||
ESP += 2;
|
||||
cpu_state.last_ea = ESP;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = readmemw(seg, SP); if (cpu_state.abrt) return 0;
|
||||
SP += 2;
|
||||
cpu_state.last_ea = SP;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -145,13 +135,11 @@ static __inline uint32_t POP_L_seg(uint32_t seg)
|
||||
{
|
||||
ret = readmeml(seg, ESP); if (cpu_state.abrt) return 0;
|
||||
ESP += 4;
|
||||
cpu_state.last_ea = ESP;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = readmeml(seg, SP); if (cpu_state.abrt) return 0;
|
||||
SP += 4;
|
||||
cpu_state.last_ea = SP;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
const char *name;
|
||||
int cpu_type;
|
||||
const FPU *fpus;
|
||||
const FPU *fpus;
|
||||
int rspeed;
|
||||
double multi;
|
||||
uint32_t edx_reset;
|
||||
@@ -210,14 +210,11 @@ typedef union {
|
||||
} x86reg;
|
||||
|
||||
typedef struct {
|
||||
uint32_t base;
|
||||
uint32_t limit;
|
||||
uint8_t access;
|
||||
uint8_t ar_high;
|
||||
uint8_t access, ar_high;
|
||||
int8_t checked; /*Non-zero if selector is known to be valid*/
|
||||
uint16_t seg;
|
||||
uint32_t limit_low,
|
||||
limit_high;
|
||||
int checked; /*Non-zero if selector is known to be valid*/
|
||||
uint32_t base, limit,
|
||||
limit_low, limit_high;
|
||||
} x86seg;
|
||||
|
||||
typedef union {
|
||||
@@ -250,19 +247,24 @@ typedef struct {
|
||||
|
||||
uint8_t tag[8];
|
||||
|
||||
int8_t ssegs, ismmx,
|
||||
abrt, pad;
|
||||
|
||||
uint16_t npxs, npxc, flags, eflags,
|
||||
old_npxc, new_npxc;
|
||||
|
||||
uint16_t MM_w4[8];
|
||||
|
||||
int _cycles,
|
||||
flags_op, TOP;
|
||||
|
||||
uint32_t flags_res,
|
||||
flags_op1, flags_op2,
|
||||
pc, oldpc, eaaddr, op32;
|
||||
|
||||
cr0_t CR0;
|
||||
|
||||
x86seg *ea_seg;
|
||||
uint32_t eaaddr;
|
||||
|
||||
int flags_op;
|
||||
uint32_t flags_res;
|
||||
uint32_t flags_op1,
|
||||
flags_op2;
|
||||
|
||||
uint32_t pc;
|
||||
uint32_t oldpc;
|
||||
uint32_t op32;
|
||||
|
||||
int TOP;
|
||||
|
||||
union {
|
||||
struct {
|
||||
@@ -273,26 +275,10 @@ typedef struct {
|
||||
int32_t rm_mod_reg_data;
|
||||
} rm_data;
|
||||
|
||||
int8_t ssegs;
|
||||
int8_t ismmx;
|
||||
int8_t abrt;
|
||||
|
||||
int _cycles;
|
||||
int cpu_recomp_ins;
|
||||
|
||||
uint16_t npxs,
|
||||
npxc;
|
||||
|
||||
double ST[8];
|
||||
|
||||
uint16_t MM_w4[8];
|
||||
|
||||
MMX_REG MM[8];
|
||||
|
||||
uint16_t old_npxc,
|
||||
new_npxc;
|
||||
uint32_t last_ea;
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
uint32_t old_fp_control, new_fp_control;
|
||||
#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86
|
||||
@@ -303,16 +289,8 @@ typedef struct {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
x86seg seg_cs,
|
||||
seg_ds,
|
||||
seg_es,
|
||||
seg_ss,
|
||||
seg_fs,
|
||||
seg_gs;
|
||||
|
||||
uint16_t flags, eflags;
|
||||
|
||||
cr0_t CR0;
|
||||
x86seg seg_cs, seg_ds, seg_es, seg_ss,
|
||||
seg_fs, seg_gs;
|
||||
} cpu_state_t;
|
||||
|
||||
/*The cpu_state.flags below must match in both cpu_cur_status and block->status for a block
|
||||
@@ -345,7 +323,7 @@ typedef struct {
|
||||
# endif
|
||||
#endif
|
||||
|
||||
COMPILE_TIME_ASSERT(sizeof(cpu_state) <= 128)
|
||||
COMPILE_TIME_ASSERT(sizeof(cpu_state_t) <= 128)
|
||||
|
||||
#define cpu_state_offset(MEMBER) ((uint8_t)((uintptr_t)&cpu_state.MEMBER - (uintptr_t)&cpu_state - 128))
|
||||
|
||||
@@ -425,19 +403,14 @@ extern uint32_t cpu_cur_status;
|
||||
extern uint64_t cpu_CR4_mask;
|
||||
extern uint64_t tsc;
|
||||
extern msr_t msr;
|
||||
extern cpu_state_t cpu_state;
|
||||
extern cpu_state_t cpu_state;
|
||||
extern uint8_t opcode;
|
||||
extern int insc;
|
||||
extern int fpucount;
|
||||
extern float mips,flops;
|
||||
extern int clockrate;
|
||||
extern int cgate16;
|
||||
extern int cpl_override;
|
||||
extern int CPUID;
|
||||
extern uint64_t xt_cpu_multi;
|
||||
extern uint64_t xt_cpu_multi;
|
||||
extern int isa_cycles;
|
||||
extern uint32_t oldds,oldss,olddslimit,oldsslimit,olddslimitw,oldsslimitw;
|
||||
extern int ins,output;
|
||||
extern uint32_t pccache;
|
||||
extern uint8_t *pccache2;
|
||||
|
||||
@@ -503,7 +476,7 @@ extern int timing_misaligned;
|
||||
extern int in_sys, unmask_a20_in_smm;
|
||||
extern uint32_t old_rammask;
|
||||
|
||||
extern int acycs;
|
||||
extern int acycs, pic_pending;
|
||||
|
||||
extern uint16_t cpu_fast_off_count, cpu_fast_off_val;
|
||||
extern uint32_t cpu_fast_off_flags;
|
||||
@@ -601,6 +574,4 @@ extern const char *fpu_get_internal_name(int machine, int cpu_manufacturer, int
|
||||
extern const char *fpu_get_name_from_index(int machine, int cpu_manufacturer, int cpu, int c);
|
||||
extern int fpu_get_type_from_index(int machine, int cpu_manufacturer, int cpu, int c);
|
||||
|
||||
extern int int_check();
|
||||
|
||||
#endif /*EMU_CPU_H*/
|
||||
|
||||
@@ -11,7 +11,7 @@ extern int x86_was_reset, trap;
|
||||
extern int codegen_flat_ss, codegen_flat_ds;
|
||||
extern int timetolive, keyboardtimer, trap;
|
||||
extern int optype, stack32;
|
||||
extern int oldcpl, cgate32, cpl_override, fpucount;
|
||||
extern int oldcpl, cgate32, cpl_override;
|
||||
extern int nmi_enable;
|
||||
extern int oddeven, inttype;
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ enum
|
||||
FLAGS_SAR16,
|
||||
FLAGS_SAR32,
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
FLAGS_ROL8,
|
||||
FLAGS_ROL16,
|
||||
FLAGS_ROL32,
|
||||
@@ -35,6 +36,7 @@ enum
|
||||
FLAGS_ROR8,
|
||||
FLAGS_ROR16,
|
||||
FLAGS_ROR32,
|
||||
#endif
|
||||
|
||||
FLAGS_INC8,
|
||||
FLAGS_INC16,
|
||||
@@ -42,7 +44,9 @@ enum
|
||||
|
||||
FLAGS_DEC8,
|
||||
FLAGS_DEC16,
|
||||
FLAGS_DEC32,
|
||||
FLAGS_DEC32
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
,
|
||||
|
||||
FLAGS_ADC8,
|
||||
FLAGS_ADC16,
|
||||
@@ -51,9 +55,10 @@ enum
|
||||
FLAGS_SBC8,
|
||||
FLAGS_SBC16,
|
||||
FLAGS_SBC32
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline int ZF_SET()
|
||||
static __inline int ZF_SET()
|
||||
{
|
||||
switch (cpu_state.flags_op)
|
||||
{
|
||||
@@ -81,27 +86,38 @@ static inline int ZF_SET()
|
||||
case FLAGS_DEC8:
|
||||
case FLAGS_DEC16:
|
||||
case FLAGS_DEC32:
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
case FLAGS_ADC8:
|
||||
case FLAGS_ADC16:
|
||||
case FLAGS_ADC32:
|
||||
case FLAGS_SBC8:
|
||||
case FLAGS_SBC16:
|
||||
case FLAGS_SBC32:
|
||||
#endif
|
||||
return !cpu_state.flags_res;
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
case FLAGS_ROL8:
|
||||
case FLAGS_ROL16:
|
||||
case FLAGS_ROL32:
|
||||
case FLAGS_ROR8:
|
||||
case FLAGS_ROR16:
|
||||
case FLAGS_ROR32:
|
||||
#endif
|
||||
case FLAGS_UNKNOWN:
|
||||
return cpu_state.flags & Z_FLAG;
|
||||
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
default:
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int NF_SET()
|
||||
static __inline int NF_SET()
|
||||
{
|
||||
switch (cpu_state.flags_op)
|
||||
{
|
||||
@@ -113,8 +129,10 @@ static inline int NF_SET()
|
||||
case FLAGS_SAR8:
|
||||
case FLAGS_INC8:
|
||||
case FLAGS_DEC8:
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
case FLAGS_ADC8:
|
||||
case FLAGS_SBC8:
|
||||
#endif
|
||||
return cpu_state.flags_res & 0x80;
|
||||
|
||||
case FLAGS_ZN16:
|
||||
@@ -125,8 +143,10 @@ static inline int NF_SET()
|
||||
case FLAGS_SAR16:
|
||||
case FLAGS_INC16:
|
||||
case FLAGS_DEC16:
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
case FLAGS_ADC16:
|
||||
case FLAGS_SBC16:
|
||||
#endif
|
||||
return cpu_state.flags_res & 0x8000;
|
||||
|
||||
case FLAGS_ZN32:
|
||||
@@ -137,23 +157,34 @@ static inline int NF_SET()
|
||||
case FLAGS_SAR32:
|
||||
case FLAGS_INC32:
|
||||
case FLAGS_DEC32:
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
case FLAGS_ADC32:
|
||||
case FLAGS_SBC32:
|
||||
#endif
|
||||
return cpu_state.flags_res & 0x80000000;
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
case FLAGS_ROL8:
|
||||
case FLAGS_ROL16:
|
||||
case FLAGS_ROL32:
|
||||
case FLAGS_ROR8:
|
||||
case FLAGS_ROR16:
|
||||
case FLAGS_ROR32:
|
||||
#endif
|
||||
case FLAGS_UNKNOWN:
|
||||
return cpu_state.flags & N_FLAG;
|
||||
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
default:
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int PF_SET()
|
||||
static __inline int PF_SET()
|
||||
{
|
||||
switch (cpu_state.flags_op)
|
||||
{
|
||||
@@ -181,27 +212,38 @@ static inline int PF_SET()
|
||||
case FLAGS_DEC8:
|
||||
case FLAGS_DEC16:
|
||||
case FLAGS_DEC32:
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
case FLAGS_ADC8:
|
||||
case FLAGS_ADC16:
|
||||
case FLAGS_ADC32:
|
||||
case FLAGS_SBC8:
|
||||
case FLAGS_SBC16:
|
||||
case FLAGS_SBC32:
|
||||
#endif
|
||||
return znptable8[cpu_state.flags_res & 0xff] & P_FLAG;
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
case FLAGS_ROL8:
|
||||
case FLAGS_ROL16:
|
||||
case FLAGS_ROL32:
|
||||
case FLAGS_ROR8:
|
||||
case FLAGS_ROR16:
|
||||
case FLAGS_ROR32:
|
||||
#endif
|
||||
case FLAGS_UNKNOWN:
|
||||
return cpu_state.flags & P_FLAG;
|
||||
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
default:
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int VF_SET()
|
||||
static __inline int VF_SET()
|
||||
{
|
||||
switch (cpu_state.flags_op)
|
||||
{
|
||||
@@ -213,28 +255,40 @@ static inline int VF_SET()
|
||||
case FLAGS_SAR32:
|
||||
return 0;
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
case FLAGS_ADC8:
|
||||
#endif
|
||||
case FLAGS_ADD8:
|
||||
case FLAGS_INC8:
|
||||
return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x80) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
case FLAGS_ADC16:
|
||||
#endif
|
||||
case FLAGS_ADD16:
|
||||
case FLAGS_INC16:
|
||||
return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x8000) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
case FLAGS_ADC32:
|
||||
#endif
|
||||
case FLAGS_ADD32:
|
||||
case FLAGS_INC32:
|
||||
return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x80000000) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80000000);
|
||||
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
case FLAGS_SBC8:
|
||||
#endif
|
||||
case FLAGS_SUB8:
|
||||
case FLAGS_DEC8:
|
||||
return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
case FLAGS_SBC16:
|
||||
#endif
|
||||
case FLAGS_SUB16:
|
||||
case FLAGS_DEC16:
|
||||
return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
case FLAGS_SBC32:
|
||||
#endif
|
||||
case FLAGS_SUB32:
|
||||
case FLAGS_DEC32:
|
||||
return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80000000);
|
||||
@@ -253,6 +307,7 @@ static inline int VF_SET()
|
||||
case FLAGS_SHR32:
|
||||
return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80000000));
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
case FLAGS_ROL8:
|
||||
return (cpu_state.flags_res ^ (cpu_state.flags_res >> 7)) & 1;
|
||||
case FLAGS_ROL16:
|
||||
@@ -266,14 +321,22 @@ static inline int VF_SET()
|
||||
return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x4000;
|
||||
case FLAGS_ROR32:
|
||||
return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x40000000;
|
||||
#endif
|
||||
|
||||
case FLAGS_UNKNOWN:
|
||||
return cpu_state.flags & V_FLAG;
|
||||
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
default:
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int AF_SET()
|
||||
static __inline int AF_SET()
|
||||
{
|
||||
switch (cpu_state.flags_op)
|
||||
{
|
||||
@@ -299,6 +362,7 @@ static inline int AF_SET()
|
||||
case FLAGS_INC32:
|
||||
return ((cpu_state.flags_op1 & 0xF) + (cpu_state.flags_op2 & 0xF)) & 0x10;
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
case FLAGS_ADC8:
|
||||
return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) ||
|
||||
((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xff);
|
||||
@@ -308,6 +372,7 @@ static inline int AF_SET()
|
||||
case FLAGS_ADC32:
|
||||
return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) ||
|
||||
((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xffffffff);
|
||||
#endif
|
||||
|
||||
case FLAGS_SUB8:
|
||||
case FLAGS_SUB16:
|
||||
@@ -317,6 +382,7 @@ static inline int AF_SET()
|
||||
case FLAGS_DEC32:
|
||||
return ((cpu_state.flags_op1 & 0xF) - (cpu_state.flags_op2 & 0xF)) & 0x10;
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
case FLAGS_SBC8:
|
||||
case FLAGS_SBC16:
|
||||
case FLAGS_SBC32:
|
||||
@@ -329,13 +395,21 @@ static inline int AF_SET()
|
||||
case FLAGS_ROR8:
|
||||
case FLAGS_ROR16:
|
||||
case FLAGS_ROR32:
|
||||
#endif
|
||||
case FLAGS_UNKNOWN:
|
||||
return cpu_state.flags & A_FLAG;
|
||||
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
default:
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int CF_SET()
|
||||
static __inline int CF_SET()
|
||||
{
|
||||
switch (cpu_state.flags_op)
|
||||
{
|
||||
@@ -346,6 +420,7 @@ static inline int CF_SET()
|
||||
case FLAGS_ADD32:
|
||||
return (cpu_state.flags_res < cpu_state.flags_op1);
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
case FLAGS_ADC8:
|
||||
return (cpu_state.flags_res < cpu_state.flags_op1) ||
|
||||
(cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xff);
|
||||
@@ -355,17 +430,20 @@ static inline int CF_SET()
|
||||
case FLAGS_ADC32:
|
||||
return (cpu_state.flags_res < cpu_state.flags_op1) ||
|
||||
(cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xffffffff);
|
||||
#endif
|
||||
|
||||
case FLAGS_SUB8:
|
||||
case FLAGS_SUB16:
|
||||
case FLAGS_SUB32:
|
||||
return (cpu_state.flags_op1 < cpu_state.flags_op2);
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
case FLAGS_SBC8:
|
||||
case FLAGS_SBC16:
|
||||
case FLAGS_SBC32:
|
||||
return (cpu_state.flags_op1 < cpu_state.flags_op2) ||
|
||||
(cpu_state.flags_op1 == cpu_state.flags_op2 && cpu_state.flags_res != 0);
|
||||
#endif
|
||||
|
||||
case FLAGS_SHL8:
|
||||
return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80) ? 1 : 0;
|
||||
@@ -391,6 +469,7 @@ static inline int CF_SET()
|
||||
case FLAGS_ZN32:
|
||||
return 0;
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
case FLAGS_ROL8:
|
||||
case FLAGS_ROL16:
|
||||
case FLAGS_ROL32:
|
||||
@@ -402,7 +481,8 @@ static inline int CF_SET()
|
||||
return (cpu_state.flags_res & 0x8000) ? 1 :0;
|
||||
case FLAGS_ROR32:
|
||||
return (cpu_state.flags_res & 0x80000000) ? 1 : 0;
|
||||
|
||||
#endif
|
||||
|
||||
case FLAGS_DEC8:
|
||||
case FLAGS_DEC16:
|
||||
case FLAGS_DEC32:
|
||||
@@ -411,18 +491,18 @@ static inline int CF_SET()
|
||||
case FLAGS_INC32:
|
||||
case FLAGS_UNKNOWN:
|
||||
return cpu_state.flags & C_FLAG;
|
||||
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
default:
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
//#define ZF_SET() (flags & Z_FLAG)
|
||||
//#define NF_SET() (flags & N_FLAG)
|
||||
//#define PF_SET() (flags & P_FLAG)
|
||||
//#define VF_SET() (flags & V_FLAG)
|
||||
//#define CF_SET() (flags & C_FLAG)
|
||||
//#define AF_SET() (flags & A_FLAG)
|
||||
|
||||
static inline void flags_rebuild()
|
||||
static __inline void flags_rebuild()
|
||||
{
|
||||
if (cpu_state.flags_op != FLAGS_UNKNOWN)
|
||||
{
|
||||
@@ -438,12 +518,12 @@ static inline void flags_rebuild()
|
||||
}
|
||||
}
|
||||
|
||||
static inline void flags_extract()
|
||||
static __inline void flags_extract()
|
||||
{
|
||||
cpu_state.flags_op = FLAGS_UNKNOWN;
|
||||
}
|
||||
|
||||
static inline void flags_rebuild_c()
|
||||
static __inline void flags_rebuild_c()
|
||||
{
|
||||
if (cpu_state.flags_op != FLAGS_UNKNOWN)
|
||||
{
|
||||
@@ -451,10 +531,11 @@ static inline void flags_rebuild_c()
|
||||
cpu_state.flags |= C_FLAG;
|
||||
else
|
||||
cpu_state.flags &= ~C_FLAG;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline int flags_res_valid()
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
static __inline int flags_res_valid()
|
||||
{
|
||||
if (cpu_state.flags_op == FLAGS_UNKNOWN ||
|
||||
(cpu_state.flags_op >= FLAGS_ROL8 && cpu_state.flags_op <= FLAGS_ROR32))
|
||||
@@ -462,18 +543,19 @@ static inline int flags_res_valid()
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void setznp8(uint8_t val)
|
||||
static __inline void setznp8(uint8_t val)
|
||||
{
|
||||
cpu_state.flags_op = FLAGS_ZN8;
|
||||
cpu_state.flags_res = val;
|
||||
}
|
||||
static inline void setznp16(uint16_t val)
|
||||
static __inline void setznp16(uint16_t val)
|
||||
{
|
||||
cpu_state.flags_op = FLAGS_ZN16;
|
||||
cpu_state.flags_res = val;
|
||||
}
|
||||
static inline void setznp32(uint32_t val)
|
||||
static __inline void setznp32(uint32_t val)
|
||||
{
|
||||
cpu_state.flags_op = FLAGS_ZN32;
|
||||
cpu_state.flags_res = val;
|
||||
@@ -485,32 +567,34 @@ static inline void setznp32(uint32_t val)
|
||||
cpu_state.flags_op1 = orig; \
|
||||
cpu_state.flags_op2 = shift;
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
#define set_flags_rotate(op, res) \
|
||||
cpu_state.flags_op = op; \
|
||||
cpu_state.flags_res = res;
|
||||
#endif
|
||||
|
||||
static inline void setadd8(uint8_t a, uint8_t b)
|
||||
static __inline void setadd8(uint8_t a, uint8_t b)
|
||||
{
|
||||
cpu_state.flags_op1 = a;
|
||||
cpu_state.flags_op2 = b;
|
||||
cpu_state.flags_res = (a + b) & 0xff;
|
||||
cpu_state.flags_op = FLAGS_ADD8;
|
||||
}
|
||||
static inline void setadd16(uint16_t a, uint16_t b)
|
||||
static __inline void setadd16(uint16_t a, uint16_t b)
|
||||
{
|
||||
cpu_state.flags_op1 = a;
|
||||
cpu_state.flags_op2 = b;
|
||||
cpu_state.flags_res = (a + b) & 0xffff;
|
||||
cpu_state.flags_op = FLAGS_ADD16;
|
||||
}
|
||||
static inline void setadd32(uint32_t a, uint32_t b)
|
||||
static __inline void setadd32(uint32_t a, uint32_t b)
|
||||
{
|
||||
cpu_state.flags_op1 = a;
|
||||
cpu_state.flags_op2 = b;
|
||||
cpu_state.flags_res = a + b;
|
||||
cpu_state.flags_op = FLAGS_ADD32;
|
||||
}
|
||||
static inline void setadd8nc(uint8_t a, uint8_t b)
|
||||
static __inline void setadd8nc(uint8_t a, uint8_t b)
|
||||
{
|
||||
flags_rebuild_c();
|
||||
cpu_state.flags_op1 = a;
|
||||
@@ -518,7 +602,7 @@ static inline void setadd8nc(uint8_t a, uint8_t b)
|
||||
cpu_state.flags_res = (a + b) & 0xff;
|
||||
cpu_state.flags_op = FLAGS_INC8;
|
||||
}
|
||||
static inline void setadd16nc(uint16_t a, uint16_t b)
|
||||
static __inline void setadd16nc(uint16_t a, uint16_t b)
|
||||
{
|
||||
flags_rebuild_c();
|
||||
cpu_state.flags_op1 = a;
|
||||
@@ -526,7 +610,7 @@ static inline void setadd16nc(uint16_t a, uint16_t b)
|
||||
cpu_state.flags_res = (a + b) & 0xffff;
|
||||
cpu_state.flags_op = FLAGS_INC16;
|
||||
}
|
||||
static inline void setadd32nc(uint32_t a, uint32_t b)
|
||||
static __inline void setadd32nc(uint32_t a, uint32_t b)
|
||||
{
|
||||
flags_rebuild_c();
|
||||
cpu_state.flags_op1 = a;
|
||||
@@ -535,21 +619,21 @@ static inline void setadd32nc(uint32_t a, uint32_t b)
|
||||
cpu_state.flags_op = FLAGS_INC32;
|
||||
}
|
||||
|
||||
static inline void setsub8(uint8_t a, uint8_t b)
|
||||
static __inline void setsub8(uint8_t a, uint8_t b)
|
||||
{
|
||||
cpu_state.flags_op1 = a;
|
||||
cpu_state.flags_op2 = b;
|
||||
cpu_state.flags_res = (a - b) & 0xff;
|
||||
cpu_state.flags_op = FLAGS_SUB8;
|
||||
}
|
||||
static inline void setsub16(uint16_t a, uint16_t b)
|
||||
static __inline void setsub16(uint16_t a, uint16_t b)
|
||||
{
|
||||
cpu_state.flags_op1 = a;
|
||||
cpu_state.flags_op2 = b;
|
||||
cpu_state.flags_res = (a - b) & 0xffff;
|
||||
cpu_state.flags_op = FLAGS_SUB16;
|
||||
}
|
||||
static inline void setsub32(uint32_t a, uint32_t b)
|
||||
static __inline void setsub32(uint32_t a, uint32_t b)
|
||||
{
|
||||
cpu_state.flags_op1 = a;
|
||||
cpu_state.flags_op2 = b;
|
||||
@@ -557,7 +641,7 @@ static inline void setsub32(uint32_t a, uint32_t b)
|
||||
cpu_state.flags_op = FLAGS_SUB32;
|
||||
}
|
||||
|
||||
static inline void setsub8nc(uint8_t a, uint8_t b)
|
||||
static __inline void setsub8nc(uint8_t a, uint8_t b)
|
||||
{
|
||||
flags_rebuild_c();
|
||||
cpu_state.flags_op1 = a;
|
||||
@@ -565,7 +649,7 @@ static inline void setsub8nc(uint8_t a, uint8_t b)
|
||||
cpu_state.flags_res = (a - b) & 0xff;
|
||||
cpu_state.flags_op = FLAGS_DEC8;
|
||||
}
|
||||
static inline void setsub16nc(uint16_t a, uint16_t b)
|
||||
static __inline void setsub16nc(uint16_t a, uint16_t b)
|
||||
{
|
||||
flags_rebuild_c();
|
||||
cpu_state.flags_op1 = a;
|
||||
@@ -573,7 +657,7 @@ static inline void setsub16nc(uint16_t a, uint16_t b)
|
||||
cpu_state.flags_res = (a - b) & 0xffff;
|
||||
cpu_state.flags_op = FLAGS_DEC16;
|
||||
}
|
||||
static inline void setsub32nc(uint32_t a, uint32_t b)
|
||||
static __inline void setsub32nc(uint32_t a, uint32_t b)
|
||||
{
|
||||
flags_rebuild_c();
|
||||
cpu_state.flags_op1 = a;
|
||||
@@ -582,21 +666,22 @@ static inline void setsub32nc(uint32_t a, uint32_t b)
|
||||
cpu_state.flags_op = FLAGS_DEC32;
|
||||
}
|
||||
|
||||
static inline void setadc8(uint8_t a, uint8_t b)
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
static __inline void setadc8(uint8_t a, uint8_t b)
|
||||
{
|
||||
cpu_state.flags_op1 = a;
|
||||
cpu_state.flags_op2 = b;
|
||||
cpu_state.flags_res = (a + b + tempc) & 0xff;
|
||||
cpu_state.flags_op = FLAGS_ADC8;
|
||||
}
|
||||
static inline void setadc16(uint16_t a, uint16_t b)
|
||||
static __inline void setadc16(uint16_t a, uint16_t b)
|
||||
{
|
||||
cpu_state.flags_op1 = a;
|
||||
cpu_state.flags_op2 = b;
|
||||
cpu_state.flags_res = (a + b + tempc) & 0xffff;
|
||||
cpu_state.flags_op = FLAGS_ADC16;
|
||||
}
|
||||
static inline void setadc32(uint32_t a, uint32_t b)
|
||||
static __inline void setadc32(uint32_t a, uint32_t b)
|
||||
{
|
||||
cpu_state.flags_op1 = a;
|
||||
cpu_state.flags_op2 = b;
|
||||
@@ -604,27 +689,95 @@ static inline void setadc32(uint32_t a, uint32_t b)
|
||||
cpu_state.flags_op = FLAGS_ADC32;
|
||||
}
|
||||
|
||||
static inline void setsbc8(uint8_t a, uint8_t b)
|
||||
static __inline void setsbc8(uint8_t a, uint8_t b)
|
||||
{
|
||||
cpu_state.flags_op1 = a;
|
||||
cpu_state.flags_op2 = b;
|
||||
cpu_state.flags_res = (a - (b + tempc)) & 0xff;
|
||||
cpu_state.flags_op = FLAGS_SBC8;
|
||||
}
|
||||
static inline void setsbc16(uint16_t a, uint16_t b)
|
||||
static __inline void setsbc16(uint16_t a, uint16_t b)
|
||||
{
|
||||
cpu_state.flags_op1 = a;
|
||||
cpu_state.flags_op2 = b;
|
||||
cpu_state.flags_res = (a - (b + tempc)) & 0xffff;
|
||||
cpu_state.flags_op = FLAGS_SBC16;
|
||||
}
|
||||
static inline void setsbc32(uint32_t a, uint32_t b)
|
||||
static __inline void setsbc32(uint32_t a, uint32_t b)
|
||||
{
|
||||
cpu_state.flags_op1 = a;
|
||||
cpu_state.flags_op2 = b;
|
||||
cpu_state.flags_res = a - (b + tempc);
|
||||
cpu_state.flags_op = FLAGS_SBC32;
|
||||
}
|
||||
#else
|
||||
static __inline void setadc8(uint8_t a, uint8_t b)
|
||||
{
|
||||
uint16_t c=(uint16_t)a+(uint16_t)b+tempc;
|
||||
cpu_state.flags_op = FLAGS_UNKNOWN;
|
||||
cpu_state.flags&=~0x8D5;
|
||||
cpu_state.flags|=znptable8[c&0xFF];
|
||||
if (c&0x100) cpu_state.flags|=C_FLAG;
|
||||
if (!((a^b)&0x80)&&((a^c)&0x80)) cpu_state.flags|=V_FLAG;
|
||||
if (((a&0xF)+(b&0xF))&0x10) cpu_state.flags|=A_FLAG;
|
||||
}
|
||||
static __inline void setadc16(uint16_t a, uint16_t b)
|
||||
{
|
||||
uint32_t c=(uint32_t)a+(uint32_t)b+tempc;
|
||||
cpu_state.flags_op = FLAGS_UNKNOWN;
|
||||
cpu_state.flags&=~0x8D5;
|
||||
cpu_state.flags|=znptable16[c&0xFFFF];
|
||||
if (c&0x10000) cpu_state.flags|=C_FLAG;
|
||||
if (!((a^b)&0x8000)&&((a^c)&0x8000)) cpu_state.flags|=V_FLAG;
|
||||
if (((a&0xF)+(b&0xF))&0x10) cpu_state.flags|=A_FLAG;
|
||||
}
|
||||
static __inline void setadc32(uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t c=(uint32_t)a+(uint32_t)b+tempc;
|
||||
cpu_state.flags_op = FLAGS_UNKNOWN;
|
||||
cpu_state.flags&=~0x8D5;
|
||||
cpu_state.flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0));
|
||||
cpu_state.flags|=(znptable8[c&0xFF]&P_FLAG);
|
||||
if ((c<a) || (c==a && tempc)) cpu_state.flags|=C_FLAG;
|
||||
if (!((a^b)&0x80000000)&&((a^c)&0x80000000)) cpu_state.flags|=V_FLAG;
|
||||
if (((a&0xF)+(b&0xF)+tempc)&0x10) cpu_state.flags|=A_FLAG;
|
||||
}
|
||||
|
||||
|
||||
static __inline void setsbc8(uint8_t a, uint8_t b)
|
||||
{
|
||||
uint16_t c=(uint16_t)a-(((uint16_t)b)+tempc);
|
||||
cpu_state.flags_op = FLAGS_UNKNOWN;
|
||||
cpu_state.flags&=~0x8D5;
|
||||
cpu_state.flags|=znptable8[c&0xFF];
|
||||
if (c&0x100) cpu_state.flags|=C_FLAG;
|
||||
if ((a^b)&(a^c)&0x80) cpu_state.flags|=V_FLAG;
|
||||
if (((a&0xF)-(b&0xF))&0x10) cpu_state.flags|=A_FLAG;
|
||||
}
|
||||
static __inline void setsbc16(uint16_t a, uint16_t b)
|
||||
{
|
||||
uint32_t c=(uint32_t)a-(((uint32_t)b)+tempc);
|
||||
cpu_state.flags_op = FLAGS_UNKNOWN;
|
||||
cpu_state.flags&=~0x8D5;
|
||||
cpu_state.flags|=(znptable16[c&0xFFFF]&~4);
|
||||
cpu_state.flags|=(znptable8[c&0xFF]&4);
|
||||
if (c&0x10000) cpu_state.flags|=C_FLAG;
|
||||
if ((a^b)&(a^c)&0x8000) cpu_state.flags|=V_FLAG;
|
||||
if (((a&0xF)-(b&0xF))&0x10) cpu_state.flags|=A_FLAG;
|
||||
}
|
||||
|
||||
static __inline void setsbc32(uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t c=(uint32_t)a-(((uint32_t)b)+tempc);
|
||||
cpu_state.flags_op = FLAGS_UNKNOWN;
|
||||
cpu_state.flags&=~0x8D5;
|
||||
cpu_state.flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0));
|
||||
cpu_state.flags|=(znptable8[c&0xFF]&P_FLAG);
|
||||
if ((c>a) || (c==a && tempc)) cpu_state.flags|=C_FLAG;
|
||||
if ((a^b)&(a^c)&0x80000000) cpu_state.flags|=V_FLAG;
|
||||
if (((a&0xF)-((b&0xF)+tempc))&0x10) cpu_state.flags|=A_FLAG;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern void cpu_386_flags_extract();
|
||||
extern void cpu_386_flags_rebuild();
|
||||
@@ -201,12 +201,10 @@ static int opREP_MOVSB_ ## size(uint32_t fetchdat)
|
||||
else { DEST_REG++; SRC_REG++; } \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 3 : 4; \
|
||||
ins++; \
|
||||
reads++; writes++; total_cycles += is486 ? 3 : 4; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
ins--; \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
@@ -240,12 +238,10 @@ static int opREP_MOVSW_ ## size(uint32_t fetchdat)
|
||||
else { DEST_REG += 2; SRC_REG += 2; } \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 3 : 4; \
|
||||
ins++; \
|
||||
reads++; writes++; total_cycles += is486 ? 3 : 4; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
ins--; \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
@@ -279,12 +275,10 @@ static int opREP_MOVSL_ ## size(uint32_t fetchdat)
|
||||
else { DEST_REG += 4; SRC_REG += 4; } \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 3 : 4; \
|
||||
ins++; \
|
||||
reads++; writes++; total_cycles += is486 ? 3 : 4; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
ins--; \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
@@ -313,7 +307,6 @@ static int opREP_STOSB_ ## size(uint32_t fetchdat)
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
writes++; total_cycles += is486 ? 4 : 5; \
|
||||
ins++; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
@@ -343,7 +336,6 @@ static int opREP_STOSW_ ## size(uint32_t fetchdat)
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
writes++; total_cycles += is486 ? 4 : 5; \
|
||||
ins++; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
@@ -373,7 +365,6 @@ static int opREP_STOSL_ ## size(uint32_t fetchdat)
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
writes++; total_cycles += is486 ? 4 : 5; \
|
||||
ins++; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
@@ -404,7 +395,6 @@ static int opREP_LODSB_ ## size(uint32_t fetchdat)
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
reads++; total_cycles += is486 ? 4 : 5; \
|
||||
ins++; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
@@ -434,7 +424,6 @@ static int opREP_LODSW_ ## size(uint32_t fetchdat)
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
reads++; total_cycles += is486 ? 4 : 5; \
|
||||
ins++; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
@@ -464,7 +453,6 @@ static int opREP_LODSL_ ## size(uint32_t fetchdat)
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
reads++; total_cycles += is486 ? 4 : 5; \
|
||||
ins++; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
@@ -597,11 +585,9 @@ static int opREP_SCASB_ ## size(uint32_t fetchdat)
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 5 : 8; \
|
||||
reads++; total_cycles += is486 ? 5 : 8; \
|
||||
ins++; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
ins--; \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) \
|
||||
{ \
|
||||
@@ -631,11 +617,9 @@ static int opREP_SCASW_ ## size(uint32_t fetchdat)
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 5 : 8; \
|
||||
reads++; total_cycles += is486 ? 5 : 8; \
|
||||
ins++; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
ins--; \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) \
|
||||
{ \
|
||||
@@ -665,11 +649,9 @@ static int opREP_SCASL_ ## size(uint32_t fetchdat)
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 5 : 8; \
|
||||
reads++; total_cycles += is486 ? 5 : 8; \
|
||||
ins++; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
ins--; \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) \
|
||||
{ \
|
||||
|
||||
@@ -431,7 +431,6 @@ typedef union
|
||||
|
||||
#ifdef FPU_8087
|
||||
#define FP_ENTER() { \
|
||||
fpucount++; \
|
||||
}
|
||||
#else
|
||||
#define FP_ENTER() do \
|
||||
@@ -441,7 +440,6 @@ typedef union
|
||||
x86_int(7); \
|
||||
return 1; \
|
||||
} \
|
||||
fpucount++; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
|
||||
@@ -2246,8 +2246,8 @@ kbd_read(uint16_t port, void *priv)
|
||||
ret &= ~0x04;
|
||||
}
|
||||
#ifdef USE_DYNAREC
|
||||
flip_flop = (flip_flop + 1) & 3;
|
||||
if (cpu_use_dynarec && (flip_flop == 3))
|
||||
flip_flop = (flip_flop + 1) & 0xf;
|
||||
if (cpu_use_dynarec && (flip_flop == 0xf))
|
||||
update_tsc();
|
||||
#endif
|
||||
break;
|
||||
|
||||
@@ -1010,7 +1010,10 @@ fdc_write(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
case 0x07: /* Recalibrate */
|
||||
case 0x0f: /* Seek */
|
||||
timer_set_delay_u64(&fdc->timer, 1000 * TIMER_USEC);
|
||||
if (fdc->flags & FDC_FLAG_PCJR)
|
||||
timer_set_delay_u64(&fdc->timer, 1000 * TIMER_USEC);
|
||||
else
|
||||
timer_set_delay_u64(&fdc->timer, 256 * TIMER_USEC);
|
||||
break;
|
||||
default:
|
||||
timer_set_delay_u64(&fdc->timer, 256 * TIMER_USEC);
|
||||
|
||||
@@ -25,8 +25,10 @@ extern const device_t acc2168_device;
|
||||
extern const device_t ali1429_device;
|
||||
|
||||
/* Headland */
|
||||
extern const device_t headland_device;
|
||||
extern const device_t headland_386_device;
|
||||
extern const device_t headland_gc10x_device;
|
||||
extern const device_t headland_ht18a_device;
|
||||
extern const device_t headland_ht18b_device;
|
||||
extern const device_t headland_ht18c_device;
|
||||
|
||||
/* Intel */
|
||||
extern const device_t i82335_device;
|
||||
@@ -104,7 +106,7 @@ extern const device_t via_vt82c586b_device;
|
||||
extern const device_t via_vt82c596b_device;
|
||||
|
||||
/* AMD */
|
||||
extern const device_t amd640_device;
|
||||
extern const device_t amd640_device;
|
||||
|
||||
/* VLSI */
|
||||
extern const device_t vl82c480_device;
|
||||
|
||||
@@ -9,7 +9,7 @@ typedef struct PIC {
|
||||
|
||||
|
||||
extern PIC pic, pic2;
|
||||
extern int pic_intpending;
|
||||
extern int pic_intpending, pic_pending;
|
||||
|
||||
|
||||
extern void pic_set_shadow(int sh);
|
||||
|
||||
@@ -225,4 +225,54 @@ extern void timer_advance_ex(pc_timer_t *timer, int start);
|
||||
extern void timer_on(pc_timer_t *timer, double period, int start);
|
||||
extern void timer_on_auto(pc_timer_t *timer, double period);
|
||||
|
||||
extern void timer_remove_head(void);
|
||||
|
||||
|
||||
extern pc_timer_t * timer_head;
|
||||
extern int timer_inited;
|
||||
|
||||
|
||||
__inline void
|
||||
timer_remove_head_inline(void)
|
||||
{
|
||||
pc_timer_t *timer;
|
||||
|
||||
if (timer_inited && timer_head) {
|
||||
timer = timer_head;
|
||||
timer_head = timer->next;
|
||||
if (timer_head) {
|
||||
timer_head->prev = NULL;
|
||||
timer->next->prev = NULL;
|
||||
}
|
||||
timer->next = timer->prev = NULL;
|
||||
timer->flags &= ~TIMER_ENABLED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
__inline void
|
||||
timer_process_inline(void)
|
||||
{
|
||||
pc_timer_t *timer;
|
||||
|
||||
if (!timer_inited || !timer_head)
|
||||
return;
|
||||
|
||||
while(1) {
|
||||
timer = timer_head;
|
||||
|
||||
if (!TIMER_LESS_THAN_VAL(timer, (uint32_t)tsc))
|
||||
break;
|
||||
|
||||
timer_remove_head_inline();
|
||||
|
||||
if (timer->flags & TIMER_SPLIT)
|
||||
timer_advance_ex(timer, 0); /* We're splitting a > 1 s period into multiple <= 1 s periods. */
|
||||
else if (timer->callback != NULL) /* Make sure it's no NULL, so that we can have a NULL callback when no operation is needed. */
|
||||
timer->callback(timer->p);
|
||||
}
|
||||
|
||||
timer_target = timer_head->ts.ts32.integer;
|
||||
}
|
||||
|
||||
#endif /*_TIMER_H_*/
|
||||
|
||||
1
src/io.c
1
src/io.c
@@ -26,6 +26,7 @@
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/m_amstrad.h>
|
||||
|
||||
|
||||
@@ -65,9 +65,9 @@ machine_at_headland_common_init(int ht386)
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
if (ht386)
|
||||
device_add(&headland_386_device);
|
||||
device_add(&headland_ht18b_device);
|
||||
else
|
||||
device_add(&headland_device);
|
||||
device_add(&headland_gc10x_device);
|
||||
}
|
||||
|
||||
|
||||
@@ -139,6 +139,7 @@ machine_at_ama932j_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_quadt286_init(const machine_t *model)
|
||||
{
|
||||
@@ -154,11 +155,12 @@ machine_at_quadt286_init(const machine_t *model)
|
||||
machine_at_common_ide_init(model);
|
||||
device_add(&keyboard_at_device);
|
||||
device_add(&fdc_at_device);
|
||||
device_add(&headland_device);
|
||||
device_add(&headland_gc10x_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_neat_init(const machine_t *model)
|
||||
{
|
||||
@@ -200,6 +202,7 @@ machine_at_neat_ami_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_px286_init(const machine_t *model)
|
||||
{
|
||||
@@ -214,7 +217,7 @@ machine_at_px286_init(const machine_t *model)
|
||||
machine_at_common_init(model);
|
||||
device_add(&keyboard_at_device);
|
||||
device_add(&fdc_at_device);
|
||||
device_add(&neat_device);
|
||||
device_add(&neat_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -260,6 +263,7 @@ machine_at_micronics386_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
machine_at_scat_init(const machine_t *model, int is_v4)
|
||||
{
|
||||
@@ -404,6 +408,7 @@ machine_at_kmxc02_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_deskmaster286_init(const machine_t *model)
|
||||
{
|
||||
@@ -420,6 +425,7 @@ machine_at_deskmaster286_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_shuttle386sx_init(const machine_t *model)
|
||||
{
|
||||
@@ -441,6 +447,7 @@ machine_at_shuttle386sx_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_adi386sx_init(const machine_t *model)
|
||||
{
|
||||
@@ -462,6 +469,7 @@ machine_at_adi386sx_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_wd76c10_init(const machine_t *model)
|
||||
{
|
||||
@@ -486,12 +494,14 @@ machine_at_wd76c10_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
const device_t *
|
||||
at_commodore_sl386sx_get_device(void)
|
||||
{
|
||||
return &gd5402_onboard_device;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_commodore_sl386sx_init(const machine_t *model)
|
||||
{
|
||||
@@ -515,6 +525,8 @@ machine_at_commodore_sl386sx_init(const machine_t *model)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
machine_at_awardsx_init(const machine_t *model)
|
||||
{
|
||||
|
||||
@@ -164,7 +164,7 @@ const machine_t machines[] = {
|
||||
/* 386SX machines */
|
||||
{ "[ISA] IBM PS/1 model 2121", "ibmps1_2121", MACHINE_TYPE_386SX, {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO | MACHINE_VIDEO_FIXED, 2, 6, 1, 63, machine_ps1_m2121_init, NULL },
|
||||
{ "[ISA] IBM PS/1 m.2121+ISA", "ibmps1_2121_isa", MACHINE_TYPE_386SX, {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 2, 6, 1, 63, machine_ps1_m2121_init, NULL },
|
||||
{ "[HT18] AMA-932J", "ama932j", MACHINE_TYPE_386SX, {{"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 },
|
||||
{ "[GC103] AMA-932J", "ama932j", MACHINE_TYPE_386SX, {{"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)
|
||||
{ "[HT18] AMI Unknown 386SX", "ami386", MACHINE_TYPE_386SX, {{"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 },
|
||||
#endif
|
||||
|
||||
@@ -34,6 +34,7 @@ int output;
|
||||
int intclear;
|
||||
int keywaiting = 0;
|
||||
int pic_intpending;
|
||||
int pic_pending;
|
||||
PIC pic, pic2;
|
||||
uint16_t pic_current;
|
||||
|
||||
@@ -82,6 +83,7 @@ pic_updatepending()
|
||||
pic_intpending |= temp_pending;
|
||||
}
|
||||
}
|
||||
pic_pending = !!((cpu_state.flags & I_FLAG) && pic_intpending);
|
||||
pic_log("pic_intpending = %i %02X %02X %02X %02X\n", pic_intpending, pic.ins, pic.pend, pic.mask, pic.mask2);
|
||||
pic_log(" %02X %02X %02X %02X %i %i\n", pic2.ins, pic2.pend, pic2.mask, pic2.mask2, ((pic.mask | pic.mask2) & (1 << 2)), ((pic2.pend&~pic2.mask)&~pic2.mask2));
|
||||
}
|
||||
|
||||
@@ -295,6 +295,9 @@ midi_in_device_init()
|
||||
void
|
||||
midi_raw_out_rt_byte(uint8_t val)
|
||||
{
|
||||
if (!midi_in)
|
||||
return;
|
||||
|
||||
if (!midi_in->midi_realtime)
|
||||
return;
|
||||
|
||||
@@ -310,7 +313,7 @@ midi_raw_out_rt_byte(uint8_t val)
|
||||
void
|
||||
midi_raw_out_thru_rt_byte(uint8_t val)
|
||||
{
|
||||
if (midi_in->thruchan)
|
||||
if (midi_in && midi_in->thruchan)
|
||||
midi_raw_out_rt_byte(val);
|
||||
}
|
||||
|
||||
|
||||
@@ -820,7 +820,7 @@ void adgold_close(void *p)
|
||||
f = nvr_fopen(L"adgold.bin", L"wb");
|
||||
if (f)
|
||||
{
|
||||
fwrite(adgold->adgold_eeprom, 0x18, 1, f);
|
||||
fwrite(adgold->adgold_eeprom, 0x1a, 1, f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,10 +11,10 @@ uint32_t timer_target;
|
||||
|
||||
/*Enabled timers are stored in a linked list, with the first timer to expire at
|
||||
the head.*/
|
||||
static pc_timer_t *timer_head = NULL;
|
||||
pc_timer_t *timer_head = NULL;
|
||||
|
||||
/* Are we initialized? */
|
||||
static int timer_inited = 0;
|
||||
int timer_inited = 0;
|
||||
|
||||
|
||||
void
|
||||
@@ -99,7 +99,7 @@ timer_disable(pc_timer_t *timer)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
void
|
||||
timer_remove_head(void)
|
||||
{
|
||||
pc_timer_t *timer;
|
||||
|
||||
@@ -1651,8 +1651,13 @@ void s3_recalctimings(svga_t *svga)
|
||||
break;
|
||||
case 15:
|
||||
svga->render = svga_render_15bpp_highres;
|
||||
if (s3->chip != S3_VISION964 && s3->chip != S3_86C801 && s3->chip != S3_86C928 && s3->chip != S3_86C911)
|
||||
svga->hdisp /= 2;
|
||||
if (s3->chip != S3_VISION964 && s3->chip != S3_86C801)
|
||||
{
|
||||
if (s3->chip == S3_86C928)
|
||||
svga->hdisp *= 2;
|
||||
else
|
||||
svga->hdisp /= 2;
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
svga->render = svga_render_16bpp_highres;
|
||||
|
||||
Reference in New Issue
Block a user