Merge branch 'master' of github.com:86Box/86Box into tc1995

This commit is contained in:
TC1995
2020-07-15 13:11:34 +02:00
18 changed files with 635 additions and 1064 deletions

View File

@@ -333,7 +333,7 @@ recalc_mappings(void *priv)
case BANK_256K:
if (phys_bank != BANK_NONE) {
mem_mapping_set_addr(&ram_low_mapping, 0, 0x80000);
mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr);
mem_mapping_set_p(&ram_low_mapping, (void *)&dev->ram_struct[bank_nr]);
}
virt_base += 512*1024;
dev->row_virt_shift[bank_nr] = 10;
@@ -342,7 +342,7 @@ recalc_mappings(void *priv)
case BANK_256K_INTERLEAVED:
if (phys_bank != BANK_NONE) {
mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000);
mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr);
mem_mapping_set_p(&ram_low_mapping, (void *)&dev->ram_struct[bank_nr]);
}
virt_base += 512*1024*2;
dev->row_virt_shift[bank_nr] = 10;
@@ -351,7 +351,7 @@ recalc_mappings(void *priv)
case BANK_1M:
if (phys_bank != BANK_NONE) {
mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000);
mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr);
mem_mapping_set_p(&ram_low_mapping, (void *)&dev->ram_struct[bank_nr]);
mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0x100000);
mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]);
}
@@ -362,7 +362,7 @@ recalc_mappings(void *priv)
case BANK_1M_INTERLEAVED:
if (phys_bank != BANK_NONE) {
mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000);
mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr);
mem_mapping_set_p(&ram_low_mapping, (void *)&dev->ram_struct[bank_nr]);
mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0x300000);
mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]);
}
@@ -373,7 +373,7 @@ recalc_mappings(void *priv)
case BANK_4M:
if (phys_bank != BANK_NONE) {
mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000);
mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr);
mem_mapping_set_p(&ram_low_mapping, (void *)&dev->ram_struct[bank_nr]);
mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0x700000);
mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]);
}
@@ -384,7 +384,7 @@ recalc_mappings(void *priv)
case BANK_4M_INTERLEAVED:
if (phys_bank != BANK_NONE) {
mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000);
mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr);
mem_mapping_set_p(&ram_low_mapping, (void *)&dev->ram_struct[bank_nr]);
mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0xf00000);
mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]);
}

View File

@@ -6,7 +6,7 @@
*
* This file is part of the 86Box distribution.
*
* Implementation of the STPC series of SoCs.
* Implementation of the STMicroelectronics STPC series of SoCs.
*
*
*
@@ -35,6 +35,8 @@
#include <86box/usb.h>
#include <86box/hdc_ide.h>
#include <86box/hdc_ide_sff8038i.h>
#include <86box/serial.h>
#include <86box/lpt.h>
#include <86box/chipset.h>
@@ -70,6 +72,19 @@ typedef struct stpc_t
sff8038i_t *bm[2];
} stpc_t;
typedef struct stpc_serial_t
{
serial_t *uart[2];
} stpc_serial_t;
typedef struct stpc_lpt_t
{
uint8_t unlocked;
uint8_t offset;
uint8_t reg1;
uint8_t reg4;
} stpc_lpt_t;
#ifdef ENABLE_STPC_LOG
int stpc_do_log = ENABLE_STPC_LOG;
@@ -576,6 +591,50 @@ stpc_remap_localbus(stpc_t *dev, uint16_t localbus_base)
}
static uint8_t
stpc_serial_handlers(uint8_t val)
{
stpc_serial_t *dev;
if (!(dev = device_get_priv(&stpc_serial_device))) {
stpc_log("STPC: Not remapping UARTs, disabled by strap (raw %02X)\n", val);
return 0;
}
uint16_t uart0_io = 0x3f8, uart0_irq = 4, uart1_io = 0x3f8, uart1_irq = 3;
if (val & 0x10)
uart1_io -= 0x100;
if (val & 0x20)
uart1_io -= 0x10;
if (val & 0x40)
uart0_io -= 0x100;
if (val & 0x80)
uart0_io -= 0x10;
if (uart0_io == uart1_io) {
/* Apply defaults if both UARTs are set to the same address. */
stpc_log("STPC: Both UARTs set to %02X, resetting to defaults\n", uart0_io);
uart0_io = 0x3f8;
uart1_io = 0x2f8;
}
if ((uart0_io & 0x0f00) < 0x300) {
/* The address for UART0 defines the IRQs for both ports. */
uart0_irq = 3;
uart1_irq = 4;
}
stpc_log("STPC: Remapping UART0 to %04X %d and UART1 to %04X %d (raw %02X)\n", uart0_io, uart0_irq, uart1_io, uart1_irq, val);
serial_remove(dev->uart[0]);
serial_setup(dev->uart[0], uart0_io, uart0_irq);
serial_remove(dev->uart[1]);
serial_setup(dev->uart[1], uart1_io, uart1_irq);
return 1;
}
static void
stpc_reg_write(uint16_t addr, uint8_t val, void *priv)
{
@@ -635,11 +694,15 @@ stpc_reg_write(uint16_t addr, uint8_t val, void *priv)
break;
case 0x56: case 0x57:
/* ELCR goes here */
elcr_write(dev->reg_offset, val, NULL);
if (dev->reg_offset == 0x57)
refresh_at_enable = val & 0x01;
break;
case 0x59:
val &= 0xf1;
stpc_serial_handlers(val);
break;
}
dev->regs[dev->reg_offset] = val;
@@ -678,11 +741,10 @@ stpc_reset(void *priv)
memset(dev->regs, 0, sizeof(dev->regs));
dev->regs[0x7b] = 0xff;
io_removehandler(0x22, 2,
stpc_reg_read, NULL, NULL, stpc_reg_write, NULL, NULL, dev);
io_sethandler(0x22, 2,
stpc_reg_read, NULL, NULL, stpc_reg_write, NULL, NULL, dev);
if (device_get_priv(&stpc_lpt_device))
dev->regs[0x4c] |= 0x80; /* LPT strap */
if (stpc_serial_handlers(0))
dev->regs[0x4c] |= 0x03; /* UART straps */
}
@@ -691,6 +753,10 @@ stpc_setup(stpc_t *dev)
{
stpc_log("STPC: setup()\n");
/* Main register interface */
io_sethandler(0x22, 2,
stpc_reg_read, NULL, NULL, stpc_reg_write, NULL, NULL, dev);
/* Northbridge */
if (dev->local & STPC_NB_CLIENT) {
/* Client */
@@ -832,6 +898,9 @@ stpc_close(void *priv)
stpc_log("STPC: close()\n");
io_removehandler(0x22, 2,
stpc_reg_read, NULL, NULL, stpc_reg_write, NULL, NULL, dev);
free(dev);
}
@@ -886,6 +955,152 @@ stpc_init(const device_t *info)
}
static void
stpc_serial_close(void *priv)
{
stpc_serial_t *dev = (stpc_serial_t *) priv;
stpc_log("STPC: serial_close()\n");
free(dev);
}
static void *
stpc_serial_init(const device_t *info)
{
stpc_log("STPC: serial_init()\n");
stpc_serial_t *dev = (stpc_serial_t *) malloc(sizeof(stpc_serial_t));
memset(dev, 0, sizeof(stpc_serial_t));
dev->uart[0] = device_add_inst(&ns16550_device, 1);
dev->uart[1] = device_add_inst(&ns16550_device, 2);
/* Initialization is performed by stpc_reset. */
return dev;
}
static void
stpc_lpt_handlers(stpc_lpt_t *dev, uint8_t val)
{
uint8_t old_addr = (dev->reg1 & 0x03), new_addr = (val & 0x03);
switch (old_addr) {
case 0x1:
lpt3_remove();
break;
case 0x2:
lpt1_remove();
break;
case 0x3:
lpt2_remove();
break;
}
switch (new_addr) {
case 0x1:
stpc_log("STPC: Remapping parallel port to LPT3\n");
lpt3_init(0x3bc);
break;
case 0x2:
stpc_log("STPC: Remapping parallel port to LPT1\n");
lpt1_init(0x378);
break;
case 0x3:
stpc_log("STPC: Remapping parallel port to LPT2\n");
lpt2_init(0x278);
break;
default:
stpc_log("STPC: Disabling parallel port\n");
break;
}
dev->reg1 = (val & 0x08);
dev->reg1 |= new_addr;
dev->reg1 |= 0x84; /* reserved bits that default to 1 - hardwired? */
}
static void
stpc_lpt_write(uint16_t addr, uint8_t val, void *priv)
{
stpc_lpt_t *dev = (stpc_lpt_t *) priv;
if (dev->unlocked < 2) {
if (addr == 0x3f0) {
if (val == 0x55)
dev->unlocked++;
else
dev->unlocked = 0;
}
} else if (addr == 0x3f0) {
if (val == 0xaa)
dev->unlocked = 0;
else
dev->offset = val;
} else if (dev->offset == 1) {
stpc_lpt_handlers(dev, val);
} else if (dev->offset == 4) {
dev->reg4 = (val & 0x03);
}
}
static void
stpc_lpt_reset(void *priv)
{
stpc_lpt_t *dev = (stpc_lpt_t *) priv;
stpc_log("STPC: lpt_reset()\n");
dev->unlocked = 0;
dev->offset = 0x00;
dev->reg1 = 0x9f;
dev->reg4 = 0x00;
stpc_lpt_handlers(dev, dev->reg1);
}
static void
stpc_lpt_close(void *priv)
{
stpc_lpt_t *dev = (stpc_lpt_t *) priv;
stpc_log("STPC: lpt_close()\n");
io_removehandler(0x3f0, 2,
NULL, NULL, NULL, stpc_lpt_write, NULL, NULL, dev);
free(dev);
}
static void *
stpc_lpt_init(const device_t *info)
{
stpc_log("STPC: lpt_init()\n");
stpc_lpt_t *dev = (stpc_lpt_t *) malloc(sizeof(stpc_lpt_t));
memset(dev, 0, sizeof(stpc_lpt_t));
stpc_lpt_reset(dev);
io_sethandler(0x3f0, 2,
NULL, NULL, NULL, stpc_lpt_write, NULL, NULL, dev);
return dev;
}
/* STPC SoCs */
const device_t stpc_client_device =
{
"STPC Client",
@@ -941,3 +1156,32 @@ const device_t stpc_atlas_device =
NULL,
NULL
};
/* Auxiliary devices */
const device_t stpc_serial_device =
{
"STPC Serial UARTs",
0,
0,
stpc_serial_init,
stpc_serial_close,
NULL,
NULL,
NULL,
NULL,
NULL
};
const device_t stpc_lpt_device =
{
"STPC Parallel Port",
0,
0,
stpc_lpt_init,
stpc_lpt_close,
stpc_lpt_reset,
NULL,
NULL,
NULL,
NULL
};

View File

@@ -7,7 +7,8 @@ static uint32_t ropINC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
host_reg = LOAD_REG_W(opcode & 7);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg);
ADD_HOST_REG_IMM_W(host_reg, 1);
// ADD_HOST_REG_IMM_W(host_reg, 1);
INC_HOST_REG_W(host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC16);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg);
@@ -26,7 +27,8 @@ static uint32_t ropINC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
host_reg = LOAD_REG_L(opcode & 7);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg);
ADD_HOST_REG_IMM(host_reg, 1);
// ADD_HOST_REG_IMM(host_reg, 1);
INC_HOST_REG(host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC32);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg);
@@ -45,7 +47,8 @@ static uint32_t ropDEC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
host_reg = LOAD_REG_W(opcode & 7);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg);
SUB_HOST_REG_IMM_W(host_reg, 1);
// SUB_HOST_REG_IMM_W(host_reg, 1);
DEC_HOST_REG_W(host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC16);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg);
@@ -64,7 +67,8 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
host_reg = LOAD_REG_L(opcode & 7);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg);
SUB_HOST_REG_IMM(host_reg, 1);
// SUB_HOST_REG_IMM(host_reg, 1);
DEC_HOST_REG(host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC32);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg);

View File

@@ -2967,6 +2967,29 @@ static inline void SUB_HOST_REG_IMM(int host_reg, uint32_t imm)
addlong(imm);
}
static inline void INC_HOST_REG_W(int host_reg)
{
addbyte(0x66); /*DECW host_reg*/
addbyte(0xff);
addbyte(0xc0 | (host_reg & 7));
}
static inline void INC_HOST_REG(int host_reg)
{
addbyte(0xff); /*DECL host_reg*/
addbyte(0xc0 | (host_reg & 7));
}
static inline void DEC_HOST_REG_W(int host_reg)
{
addbyte(0x66); /*DECW host_reg*/
addbyte(0xff);
addbyte(0xc8 | (host_reg & 7));
}
static inline void DEC_HOST_REG(int host_reg)
{
addbyte(0xff); /*DECL host_reg*/
addbyte(0xc8 | (host_reg & 7));
}
static inline int CMP_HOST_REG_IMM_B(int host_reg, uint8_t imm)
{
if (host_reg & 8)

View File

@@ -483,6 +483,25 @@ static inline void SUB_HOST_REG_IMM(int host_reg, uint32_t imm)
}
}
static inline void INC_HOST_REG_W(int host_reg)
{
addbyte(0x66); /*DECW host_reg*/
addbyte(0x40 | host_reg);
}
static inline void INC_HOST_REG(int host_reg)
{
addbyte(0x40 | host_reg); /*DECL host_reg*/
}
static inline void DEC_HOST_REG_W(int host_reg)
{
addbyte(0x66); /*DECW host_reg*/
addbyte(0x48 | host_reg);
}
static inline void DEC_HOST_REG(int host_reg)
{
addbyte(0x48 | host_reg); /*DECL host_reg*/
}
static inline int CMP_HOST_REG_B(int dst_reg, int src_reg)
{
SUB_HOST_REG_B(dst_reg, src_reg);

View File

@@ -294,6 +294,7 @@ void codegen_block_start_recompile(codeblock_t *block)
block->status = cpu_cur_status;
block_pos = BLOCK_GPF_OFFSET;
#ifdef OLD_GPF
#if WIN64
addbyte(0x48); /*XOR RCX, RCX*/
addbyte(0x31);
@@ -308,6 +309,17 @@ void codegen_block_start_recompile(codeblock_t *block)
addbyte(0xf6);
#endif
call(block, (uintptr_t)x86gpf);
#else
addbyte(0xc6); /* mov byte ptr[&(cpu_state.abrt)],ABRT_GPF */
addbyte(0x05);
addlong((uint32_t) (uintptr_t) &(cpu_state.abrt));
addbyte(ABRT_GPF);
addbyte(0x31); /* xor eax,eax */
addbyte(0xc0);
addbyte(0x67); /* mov [&(abrt_error)],eax */
addbyte(0xa3);
addlong((uint32_t) (uintptr_t) &(abrt_error));
#endif
while (block_pos < BLOCK_EXIT_OFFSET)
addbyte(0x90); /*NOP*/
block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/

View File

@@ -1440,6 +1440,7 @@ void codegen_block_start_recompile(codeblock_t *block)
block->status = cpu_cur_status;
block_pos = BLOCK_GPF_OFFSET;
#ifdef OLD_GPF
addbyte(0xc7); /*MOV [ESP],0*/
addbyte(0x04);
addbyte(0x24);
@@ -1451,6 +1452,16 @@ void codegen_block_start_recompile(codeblock_t *block)
addlong(0);
addbyte(0xe8); /*CALL x86gpf*/
addlong((uint32_t)x86gpf - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
#else
addbyte(0xc6); /* mov byte ptr[&(cpu_state.abrt)],ABRT_GPF */
addbyte(0x05);
addlong((uint32_t) (uintptr_t) &(cpu_state.abrt));
addbyte(ABRT_GPF);
addbyte(0x31); /* xor eax,eax */
addbyte(0xc0);
addbyte(0xa3); /* mov [&(abrt_error)],eax */
addlong((uint32_t) (uintptr_t) &(abrt_error));
#endif
block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/
addbyte(0x83); /*ADDL $16,%esp*/
addbyte(0xC4);

View File

@@ -8,7 +8,11 @@
#define HASH(l) ((l) & 0x1ffff)
#define BLOCK_EXIT_OFFSET 0x7f0
#ifdef OLD_GPF
#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20)
#else
#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 14)
#endif
#define BLOCK_MAX 1720

View File

@@ -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();

View File

@@ -1,457 +0,0 @@
#define CALL_FAR_w(new_seg, new_pc) \
old_cs = CS; \
old_pc = cpu_state.pc; \
oxpc = cpu_state.pc; \
cpu_state.pc = new_pc; \
optype = CALL; \
cgate16 = cgate32 = 0; \
if (msw & 1) loadcscall(new_seg); \
else \
{ \
loadcs(new_seg); \
cycles -= timing_call_rm; \
} \
optype = 0; \
if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \
oldss = ss; \
if (cgate32) \
{ \
uint32_t old_esp = ESP; \
PUSH_L(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \
PUSH_L(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \
} \
else \
{ \
uint32_t old_esp = ESP; \
PUSH_W(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \
PUSH_W(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \
}
#define CALL_FAR_l(new_seg, new_pc) \
old_cs = CS; \
old_pc = cpu_state.pc; \
oxpc = cpu_state.pc; \
cpu_state.pc = new_pc; \
optype = CALL; \
cgate16 = cgate32 = 0; \
if (msw & 1) loadcscall(new_seg); \
else \
{ \
loadcs(new_seg); \
cycles -= timing_call_rm; \
} \
optype = 0; \
if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \
oldss = ss; \
if (cgate16) \
{ \
uint32_t old_esp = ESP; \
PUSH_W(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \
PUSH_W(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \
} \
else \
{ \
uint32_t old_esp = ESP; \
PUSH_L(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \
PUSH_L(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \
}
static int opCALL_far_w(uint32_t fetchdat)
{
uint32_t old_cs, old_pc;
uint16_t new_cs, new_pc;
int cycles_old = cycles; UN_USED(cycles_old);
new_pc = getwordf();
new_cs = getword(); if (cpu_state.abrt) return 1;
CALL_FAR_w(new_cs, new_pc);
CPU_BLOCK_END();
PREFETCH_RUN(cycles_old-cycles, 5, -1, 0,0,cgate16 ? 2:0,cgate16 ? 0:2, 0);
PREFETCH_FLUSH();
return 0;
}
static int opCALL_far_l(uint32_t fetchdat)
{
uint32_t old_cs, old_pc;
uint32_t new_cs, new_pc;
int cycles_old = cycles; UN_USED(cycles_old);
new_pc = getlong();
new_cs = getword(); if (cpu_state.abrt) return 1;
CALL_FAR_l(new_cs, new_pc);
CPU_BLOCK_END();
PREFETCH_RUN(cycles_old-cycles, 7, -1, 0,0,cgate16 ? 2:0,cgate16 ? 0:2, 0);
PREFETCH_FLUSH();
return 0;
}
static int opFF_w_a16(uint32_t fetchdat)
{
uint16_t old_cs, new_cs;
uint32_t old_pc, new_pc;
int cycles_old = cycles; UN_USED(cycles_old);
uint16_t temp;
fetch_ea_16(fetchdat);
switch (rmdat & 0x38)
{
case 0x00: /*INC w*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
seteaw(temp + 1); if (cpu_state.abrt) return 1;
setadd16nc(temp, 1);
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0);
break;
case 0x08: /*DEC w*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
seteaw(temp - 1); if (cpu_state.abrt) return 1;
setsub16nc(temp, 1);
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0);
break;
case 0x10: /*CALL*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_pc = geteaw(); if (cpu_state.abrt) return 1;
PUSH_W(cpu_state.pc);
cpu_state.pc = new_pc;
CPU_BLOCK_END();
if (is486) CLOCK_CYCLES(5);
else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10);
PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,1,0, 0);
PREFETCH_FLUSH();
break;
case 0x18: /*CALL far*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_pc = readmemw(easeg, cpu_state.eaaddr);
new_cs = readmemw(easeg, (cpu_state.eaaddr + 2)); if (cpu_state.abrt) return 1;
CALL_FAR_w(new_cs, new_pc);
CPU_BLOCK_END();
PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 2,0,cgate16 ? 2:0,cgate16 ? 0:2, 0);
PREFETCH_FLUSH();
break;
case 0x20: /*JMP*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_pc = geteaw(); if (cpu_state.abrt) return 1;
cpu_state.pc = new_pc;
CPU_BLOCK_END();
if (is486) CLOCK_CYCLES(5);
else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10);
PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
PREFETCH_FLUSH();
break;
case 0x28: /*JMP far*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
oxpc = cpu_state.pc;
new_pc = readmemw(easeg, cpu_state.eaaddr);
new_cs = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
cpu_state.pc = new_pc;
loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1;
CPU_BLOCK_END();
PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 2,0,0,0, 0);
PREFETCH_FLUSH();
break;
case 0x30: /*PUSH w*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
PUSH_W(temp);
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,1,0, 0);
break;
default:
// fatal("Bad FF opcode %02X\n",rmdat&0x38);
x86illegal();
}
return cpu_state.abrt;
}
static int opFF_w_a32(uint32_t fetchdat)
{
uint16_t old_cs, new_cs;
uint32_t old_pc, new_pc;
int cycles_old = cycles; UN_USED(cycles_old);
uint16_t temp;
fetch_ea_32(fetchdat);
switch (rmdat & 0x38)
{
case 0x00: /*INC w*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
seteaw(temp + 1); if (cpu_state.abrt) return 1;
setadd16nc(temp, 1);
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1);
break;
case 0x08: /*DEC w*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
seteaw(temp - 1); if (cpu_state.abrt) return 1;
setsub16nc(temp, 1);
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1);
break;
case 0x10: /*CALL*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_pc = geteaw(); if (cpu_state.abrt) return 1;
PUSH_W(cpu_state.pc);
cpu_state.pc = new_pc;
CPU_BLOCK_END();
if (is486) CLOCK_CYCLES(5);
else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10);
PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,1,0, 1);
PREFETCH_FLUSH();
break;
case 0x18: /*CALL far*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_pc = readmemw(easeg, cpu_state.eaaddr);
new_cs = readmemw(easeg, (cpu_state.eaaddr + 2)); if (cpu_state.abrt) return 1;
CALL_FAR_w(new_cs, new_pc);
CPU_BLOCK_END();
PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 2,0,cgate16 ? 2:0,cgate16 ? 0:2, 1);
PREFETCH_FLUSH();
break;
case 0x20: /*JMP*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_pc = geteaw(); if (cpu_state.abrt) return 1;
cpu_state.pc = new_pc;
CPU_BLOCK_END();
if (is486) CLOCK_CYCLES(5);
else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10);
PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,0,0,0, 1);
PREFETCH_FLUSH();
break;
case 0x28: /*JMP far*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
oxpc = cpu_state.pc;
new_pc = readmemw(easeg, cpu_state.eaaddr);
new_cs = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
cpu_state.pc = new_pc;
loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1;
CPU_BLOCK_END();
PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 2,0,0,0, 1);
PREFETCH_FLUSH();
break;
case 0x30: /*PUSH w*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteaw(); if (cpu_state.abrt) return 1;
PUSH_W(temp);
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,1,0, 1);
break;
default:
// fatal("Bad FF opcode %02X\n",rmdat&0x38);
x86illegal();
}
return cpu_state.abrt;
}
static int opFF_l_a16(uint32_t fetchdat)
{
uint16_t old_cs, new_cs;
uint32_t old_pc, new_pc;
int cycles_old = cycles; UN_USED(cycles_old);
uint32_t temp;
fetch_ea_16(fetchdat);
switch (rmdat & 0x38)
{
case 0x00: /*INC l*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal(); if (cpu_state.abrt) return 1;
seteal(temp + 1); if (cpu_state.abrt) return 1;
setadd32nc(temp, 1);
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0);
break;
case 0x08: /*DEC l*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal(); if (cpu_state.abrt) return 1;
seteal(temp - 1); if (cpu_state.abrt) return 1;
setsub32nc(temp, 1);
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0);
break;
case 0x10: /*CALL*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_pc = geteal(); if (cpu_state.abrt) return 1;
PUSH_L(cpu_state.pc);
cpu_state.pc = new_pc;
CPU_BLOCK_END();
if (is486) CLOCK_CYCLES(5);
else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10);
PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 0);
PREFETCH_FLUSH();
break;
case 0x18: /*CALL far*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_pc = readmeml(easeg, cpu_state.eaaddr);
new_cs = readmemw(easeg, (cpu_state.eaaddr + 4)); if (cpu_state.abrt) return 1;
CALL_FAR_l(new_cs, new_pc);
CPU_BLOCK_END();
PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,cgate16 ? 2:0,cgate16 ? 0:2, 0);
PREFETCH_FLUSH();
break;
case 0x20: /*JMP*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_pc = geteal(); if (cpu_state.abrt) return 1;
cpu_state.pc = new_pc;
CPU_BLOCK_END();
if (is486) CLOCK_CYCLES(5);
else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10);
PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 0,1,0,0, 0);
PREFETCH_FLUSH();
break;
case 0x28: /*JMP far*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
oxpc = cpu_state.pc;
new_pc = readmeml(easeg, cpu_state.eaaddr);
new_cs = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1;
cpu_state.pc = new_pc;
loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1;
CPU_BLOCK_END();
PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,0,0, 0);
PREFETCH_FLUSH();
break;
case 0x30: /*PUSH l*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteal(); if (cpu_state.abrt) return 1;
PUSH_L(temp);
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 0);
break;
default:
// fatal("Bad FF opcode %02X\n",rmdat&0x38);
x86illegal();
}
return cpu_state.abrt;
}
static int opFF_l_a32(uint32_t fetchdat)
{
uint16_t old_cs, new_cs;
uint32_t old_pc, new_pc;
int cycles_old = cycles; UN_USED(cycles_old);
uint32_t temp;
fetch_ea_32(fetchdat);
switch (rmdat & 0x38)
{
case 0x00: /*INC l*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal(); if (cpu_state.abrt) return 1;
seteal(temp + 1); if (cpu_state.abrt) return 1;
setadd32nc(temp, 1);
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1);
break;
case 0x08: /*DEC l*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
temp = geteal(); if (cpu_state.abrt) return 1;
seteal(temp - 1); if (cpu_state.abrt) return 1;
setsub32nc(temp, 1);
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1);
break;
case 0x10: /*CALL*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_pc = geteal(); if (cpu_state.abrt) return 1;
PUSH_L(cpu_state.pc); if (cpu_state.abrt) return 1;
cpu_state.pc = new_pc;
CPU_BLOCK_END();
if (is486) CLOCK_CYCLES(5);
else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10);
PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 1);
PREFETCH_FLUSH();
break;
case 0x18: /*CALL far*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_pc = readmeml(easeg, cpu_state.eaaddr);
new_cs = readmemw(easeg, (cpu_state.eaaddr + 4)); if (cpu_state.abrt) return 1;
CALL_FAR_l(new_cs, new_pc);
CPU_BLOCK_END();
PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,cgate16 ? 2:0,cgate16 ? 0:2, 1);
PREFETCH_FLUSH();
break;
case 0x20: /*JMP*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
new_pc = geteal(); if (cpu_state.abrt) return 1;
cpu_state.pc = new_pc;
CPU_BLOCK_END();
if (is486) CLOCK_CYCLES(5);
else CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10);
PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,0,0, 1);
PREFETCH_FLUSH();
break;
case 0x28: /*JMP far*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
oxpc = cpu_state.pc;
new_pc = readmeml(easeg, cpu_state.eaaddr);
new_cs = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1;
cpu_state.pc = new_pc;
loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1;
CPU_BLOCK_END();
PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,0,0, 1);
PREFETCH_FLUSH();
break;
case 0x30: /*PUSH l*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
temp = geteal(); if (cpu_state.abrt) return 1;
PUSH_L(temp);
PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 1);
break;
default:
// fatal("Bad FF opcode %02X\n",rmdat&0x38);
x86illegal();
}
return cpu_state.abrt;
}

View File

@@ -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();

View File

@@ -1,3 +1,4 @@
#ifdef USE_NEW_DYNAREC
#define CALL_FAR_w(new_seg, new_pc) \
old_cs = CS; \
old_pc = cpu_state.pc; \
@@ -53,6 +54,65 @@
PUSH_L(old_cs); if (cpu_state.abrt) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } \
PUSH_L(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \
}
#else
#define CALL_FAR_w(new_seg, new_pc) \
old_cs = CS; \
old_pc = cpu_state.pc; \
oxpc = cpu_state.pc; \
cpu_state.pc = new_pc; \
optype = CALL; \
cgate16 = cgate32 = 0; \
if (msw & 1) loadcscall(new_seg); \
else \
{ \
loadcs(new_seg); \
cycles -= timing_call_rm; \
} \
optype = 0; \
if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \
oldss = ss; \
if (cgate32) \
{ \
uint32_t old_esp = ESP; \
PUSH_L(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \
PUSH_L(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \
} \
else \
{ \
uint32_t old_esp = ESP; \
PUSH_W(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \
PUSH_W(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \
}
#define CALL_FAR_l(new_seg, new_pc) \
old_cs = CS; \
old_pc = cpu_state.pc; \
oxpc = cpu_state.pc; \
cpu_state.pc = new_pc; \
optype = CALL; \
cgate16 = cgate32 = 0; \
if (msw & 1) loadcscall(new_seg); \
else \
{ \
loadcs(new_seg); \
cycles -= timing_call_rm; \
} \
optype = 0; \
if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \
oldss = ss; \
if (cgate16) \
{ \
uint32_t old_esp = ESP; \
PUSH_W(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \
PUSH_W(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \
} \
else \
{ \
uint32_t old_esp = ESP; \
PUSH_L(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \
PUSH_L(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \
}
#endif
static int opCALL_far_w(uint32_t fetchdat)
@@ -156,11 +216,19 @@ static int opFF_w_a16(uint32_t fetchdat)
case 0x28: /*JMP far*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
#ifdef USE_NEW_DYNAREC
old_pc = cpu_state.pc;
#else
oxpc = cpu_state.pc;
#endif
new_pc = readmemw(easeg, cpu_state.eaaddr);
new_cs = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
cpu_state.pc = new_pc;
#ifdef USE_NEW_DYNAREC
loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1;
#else
loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1;
#endif
CPU_BLOCK_END();
PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 2,0,0,0, 0);
PREFETCH_FLUSH();
@@ -247,11 +315,19 @@ static int opFF_w_a32(uint32_t fetchdat)
case 0x28: /*JMP far*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
#ifdef USE_NEW_DYNAREC
old_pc = cpu_state.pc;
#else
oxpc = cpu_state.pc;
#endif
new_pc = readmemw(easeg, cpu_state.eaaddr);
new_cs = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
cpu_state.pc = new_pc;
#ifdef USE_NEW_DYNAREC
loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1;
#else
loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1;
#endif
CPU_BLOCK_END();
PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 2,0,0,0, 1);
PREFETCH_FLUSH();
@@ -339,11 +415,19 @@ static int opFF_l_a16(uint32_t fetchdat)
case 0x28: /*JMP far*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
#ifdef USE_NEW_DYNAREC
old_pc = cpu_state.pc;
#else
oxpc = cpu_state.pc;
#endif
new_pc = readmeml(easeg, cpu_state.eaaddr);
new_cs = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1;
cpu_state.pc = new_pc;
loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1;
#ifdef USE_NEW_DYNAREC
loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1;
#else
loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1;
#endif
CPU_BLOCK_END();
PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,0,0, 0);
PREFETCH_FLUSH();
@@ -430,11 +514,19 @@ static int opFF_l_a32(uint32_t fetchdat)
case 0x28: /*JMP far*/
if (cpu_mod != 3)
SEG_CHECK_READ(cpu_state.ea_seg);
#ifdef USE_NEW_DYNAREC
old_pc = cpu_state.pc;
#else
oxpc = cpu_state.pc;
#endif
new_pc = readmeml(easeg, cpu_state.eaaddr);
new_cs = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1;
cpu_state.pc = new_pc;
loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1;
#ifdef USE_NEW_DYNAREC
loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1;
#else
loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1;
#endif
CPU_BLOCK_END();
PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,0,0, 1);
PREFETCH_FLUSH();

View File

@@ -2207,7 +2207,6 @@ kbd_read(uint16_t port, void *priv)
{
atkbd_t *dev = (atkbd_t *)priv;
uint8_t ret = 0xff;
static int flip_flop = 0;
if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF)
sub_cycles(ISA_CYCLES(8));
@@ -2245,11 +2244,6 @@ kbd_read(uint16_t port, void *priv)
else
ret &= ~0x04;
}
#ifdef USE_DYNAREC
flip_flop = (flip_flop + 1) & 0xf;
if (cpu_use_dynarec && (flip_flop == 0xf))
update_tsc();
#endif
break;
case 0x64:

View File

@@ -76,11 +76,7 @@ postcard_setui(void)
if (postcard_do_log) {
/* log same string sent to the UI */
int len = strlen(postcard_str);
postcard_str[len + 1] = '\0';
postcard_str[len] = '\n';
postcard_log("[%04X:%08X] ", CS, cpu_state.pc);
postcard_log(postcard_str);
postcard_log("[%04X:%08X] %s\n", CS, cpu_state.pc, postcard_str);
}
}

View File

@@ -92,6 +92,8 @@ extern const device_t stpc_client_device;
extern const device_t stpc_consumer2_device;
extern const device_t stpc_elite_device;
extern const device_t stpc_atlas_device;
extern const device_t stpc_serial_device;
extern const device_t stpc_lpt_device;
#endif
/* VIA */

View File

@@ -251,7 +251,7 @@ extern const device_t *at_commodore_sl386sx_get_device(void);
extern int machine_at_acc386_init(const machine_t *);
extern int machine_at_asus386_init(const machine_t *);
extern int machine_at_ecs386_init(const machine_t *);
extern int machine_at_ecs386_init(const machine_t *);
extern int machine_at_micronics386_init(const machine_t *);
extern int machine_at_rycleopardlx_init(const machine_t *);
@@ -305,7 +305,7 @@ extern const device_t *at_cpqiii_get_device(void);
#endif
/* m_at_socket4_5.c */
extern int machine_at_excalibur_init(const machine_t *);
extern int machine_at_excalibur_init(const machine_t *);
extern int machine_at_batman_init(const machine_t *);
extern int machine_at_ambradp60_init(const machine_t *);

View File

@@ -634,7 +634,6 @@ machine_at_itoxstar_init(const machine_t *model)
device_add(&w83977f_device);
device_add(&keyboard_ps2_ami_pci_device);
device_add(&stpc_client_device);
device_add(&ide_vlb_device);
device_add(&sst_flash_29ee020_device);
hwm_values_t machine_hwm = {
@@ -683,7 +682,6 @@ machine_at_arb1479_init(const machine_t *model)
device_add(&w83977f_device);
device_add(&keyboard_ps2_ami_pci_device);
device_add(&stpc_consumer2_device);
device_add(&ide_vlb_2ch_device);
device_add(&sst_flash_29ee020_device);
return ret;
@@ -709,10 +707,10 @@ machine_at_pcm9340_init(const machine_t *model)
pci_register_slot(0x1D, PCI_CARD_NORMAL, 4, 1, 2, 3);
pci_register_slot(0x1E, PCI_CARD_NORMAL, 3, 4, 1, 2);
pci_register_slot(0x1F, PCI_CARD_NORMAL, 2, 3, 4, 1);
device_add(&w83977f_device);
device_add_inst(&w83977f_device, 1);
device_add_inst(&w83977f_device, 2);
device_add(&keyboard_ps2_ami_pci_device);
device_add(&stpc_elite_device);
device_add(&ide_vlb_device);
device_add(&sst_flash_29ee020_device);
return ret;
@@ -738,10 +736,10 @@ machine_at_pcm5330_init(const machine_t *model)
pci_register_slot(0x0D, PCI_CARD_SPECIAL, 0, 0, 0, 0);
pci_register_slot(0x0E, PCI_CARD_SPECIAL, 1, 2, 3, 4);
pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 2, 3, 4);
device_add(&stpc_serial_device);
device_add(&w83977f_370_device);
device_add(&keyboard_ps2_ami_pci_device);
device_add(&stpc_atlas_device);
device_add(&ide_vlb_device);
device_add(&sst_flash_29ee020_device);
return ret;

View File

@@ -54,7 +54,7 @@ pic_log(const char *fmt, ...)
if (pic_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
ic_u va_end(ap);
}
}
#else
@@ -83,7 +83,9 @@ pic_updatepending()
pic_intpending |= temp_pending;
}
}
pic_pending = !!((cpu_state.flags & I_FLAG) && pic_intpending);
/* This is a variable needed by the compiler to know when to force interpret a block,
only do this for FDC IRQ's. */
pic_pending = !!((cpu_state.flags & I_FLAG) && (pic_intpending & (1 << 6)));
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));
}