diff --git a/src/chipset/scamp.c b/src/chipset/scamp.c index 35e97714e..bed13ab0f 100644 --- a/src/chipset/scamp.c +++ b/src/chipset/scamp.c @@ -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]); } diff --git a/src/chipset/stpc.c b/src/chipset/stpc.c index c3b7d7cc2..bf14981fc 100644 --- a/src/chipset/stpc.c +++ b/src/chipset/stpc.c @@ -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 +}; diff --git a/src/codegen/codegen_ops_arith.h b/src/codegen/codegen_ops_arith.h index ed2ce1ece..e2eb9baef 100644 --- a/src/codegen/codegen_ops_arith.h +++ b/src/codegen/codegen_ops_arith.h @@ -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); diff --git a/src/codegen/codegen_ops_x86-64.h b/src/codegen/codegen_ops_x86-64.h index 178f0f868..3dae840f5 100644 --- a/src/codegen/codegen_ops_x86-64.h +++ b/src/codegen/codegen_ops_x86-64.h @@ -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) diff --git a/src/codegen/codegen_ops_x86.h b/src/codegen/codegen_ops_x86.h index 5dcfdef87..737efe03a 100644 --- a/src/codegen/codegen_ops_x86.h +++ b/src/codegen/codegen_ops_x86.h @@ -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); diff --git a/src/codegen/codegen_x86-64.c b/src/codegen/codegen_x86-64.c index c03d0767c..29de95b6b 100644 --- a/src/codegen/codegen_x86-64.c +++ b/src/codegen/codegen_x86-64.c @@ -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*/ diff --git a/src/codegen/codegen_x86.c b/src/codegen/codegen_x86.c index 0c69e7d71..3415d642b 100644 --- a/src/codegen/codegen_x86.c +++ b/src/codegen/codegen_x86.c @@ -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); diff --git a/src/codegen/codegen_x86.h b/src/codegen/codegen_x86.h index 3a3662d32..369614329 100644 --- a/src/codegen/codegen_x86.h +++ b/src/codegen/codegen_x86.h @@ -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 diff --git a/src/codegen/x86_flags.h b/src/codegen/x86_flags.h deleted file mode 100644 index 7068a243d..000000000 --- a/src/codegen/x86_flags.h +++ /dev/null @@ -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 ((ca) || (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(); \ No newline at end of file diff --git a/src/codegen/x86_ops_call.h b/src/codegen/x86_ops_call.h deleted file mode 100644 index 8c52e632e..000000000 --- a/src/codegen/x86_ops_call.h +++ /dev/null @@ -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; -} diff --git a/src/codegen_new/x86_flags.h b/src/cpu/x86_flags.h similarity index 77% rename from src/codegen_new/x86_flags.h rename to src/cpu/x86_flags.h index 9a9983926..bf160390c 100644 --- a/src/codegen_new/x86_flags.h +++ b/src/cpu/x86_flags.h @@ -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 ((ca) || (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(); diff --git a/src/codegen_new/x86_ops_call.h b/src/cpu/x86_ops_call.h similarity index 80% rename from src/codegen_new/x86_ops_call.h rename to src/cpu/x86_ops_call.h index a11bc9c97..57a5995b0 100644 --- a/src/codegen_new/x86_ops_call.h +++ b/src/cpu/x86_ops_call.h @@ -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(); diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index e58d9f664..dfcc1947b 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -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: diff --git a/src/device/postcard.c b/src/device/postcard.c index 91eb29fcd..df2c1f96d 100644 --- a/src/device/postcard.c +++ b/src/device/postcard.c @@ -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); } } diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 894266032..20aafc2ed 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -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 */ diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 9183fe2ba..c7affdfe4 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -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 *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index e19bd448f..1cd7b60fa 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -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; diff --git a/src/pic.c b/src/pic.c index 24644ffe3..cd52c7f29 100644 --- a/src/pic.c +++ b/src/pic.c @@ -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)); }