--- previous/src/dimension/i860.cpp 2018/04/24 19:30:01 1.1 +++ previous/src/dimension/i860.cpp 2018/04/24 19:33:26 1.1.1.3 @@ -15,122 +15,101 @@ ***************************************************************************/ -#include #include -#include -#include -#include -#include "i860.hpp" - -static i860_cpu_device nd_i860; +#if defined _WIN32 +#undef mkdir +#endif +#include + +#include "i860.hpp" +#include "dimension.hpp" +#include "log.h" extern "C" { - void nd_i860_init() { - nd_i860.init(); + static void i860_run_nop(int nHostCycles) {} + + i860_run_func i860_Run = i860_run_nop; + + static void i860_run_thread(int nHostCycles) { + nd_nbic_interrupt(); } - - void nd_i860_uninit() { - nd_i860.uninit(); - } - - int nd_speed_hack; - - void nd_set_speed_hack(int state) { - nd_speed_hack = state; - } - - void nd_start_debugger(void) { - nd_i860.send_msg(MSG_DBG_BREAK); - } - - static int checklock_cnt = 0; - void i860_Run(int nHostCycles) { -#if ENABLE_PERF_COUNTERS - nd_i860.m_m68k_cylces += nHostCycles; -#endif -#if ENABLE_I860_THREAD - if(nd_speed_hack) { - // while spped-hack is on, slow down m68k a bit - for(int i = 10; --i >= 0;) - checklock(&nd_i860.m_debugger_lock); - } - if(checklock_cnt <= 0) { - checklock(&nd_i860.m_debugger_lock); - // optimzation: check the debugger lock only all 10000 cycles - checklock_cnt = 10000; - } - else - checklock_cnt -= nHostCycles; -#else - nd_i860.handle_msgs(); - - if(nd_i860.is_halted()) return; - - if (nd_speed_hack) { - while(nHostCycles) { - nd_i860.run_cycle(); - nHostCycles -= 2; + + static void i860_run_no_thread(int nHostCycles) { + int cycles; + + FOR_EACH_SLOT(slot) { + IF_NEXT_DIMENSION(slot, nd) { + nd->handle_msgs(); + + if(nd->i860.is_halted()) return; + + cycles = nHostCycles * 33; // i860 @ 33MHz + cycles /= ConfigureParams.System.nCpuFreq; + while (cycles > 0) { + nd->i860.run_cycle(); + cycles --; + } } - } else - nd_i860.run_cycle(); -#endif + } nd_nbic_interrupt(); - } - - int i860_thread(void* data) { - ((i860_cpu_device*)data)->run(); - return 0; - } - - void i860_reset() { - nd_i860.send_msg(MSG_I860_RESET); - } + } +} + +i860_cpu_device::i860_cpu_device(NextDimension* nd) : nd(nd) { + m_thread = NULL; + m_halt = true; - void i860_tick(bool intr) { - nd_i860.tick(intr); + for(int i = 0; i < 8192; i++) { + int upper6 = i >> 7; + switch (upper6) { + case 0x12: + decoder_tbl[i] = fp_decode_tbl[i & 0x7f]; + break; + case 0x13: + decoder_tbl[i] = core_esc_decode_tbl[i&3]; + break; + default: + decoder_tbl[i] = decode_tbl[upper6]; + } } } -i860_cpu_device::i860_cpu_device() { -#if ENABLE_I860_THREAD - m_thread = NULL; -#endif -#if ENABLE_PERF_COUNTERS - dump_reset_perfc(); -#endif - m_halt = true; +int i860_cpu_device::thread(void* data) { + SDL_SetThreadPriority(SDL_THREAD_PRIORITY_LOW); + ((i860_cpu_device*)data)->run(); + return 0; } void i860_cpu_device::set_mem_access(bool be) { if(be) { - rdmem[1] = nd_board_rd8_be; - rdmem[2] = nd_board_rd16_be; - rdmem[4] = nd_board_rd32_be; - rdmem[8] = nd_board_rd64_be; - rdmem[16] = nd_board_rd128_be; - - wrmem[1] = nd_board_wr8_be; - wrmem[2] = nd_board_wr16_be; - wrmem[4] = nd_board_wr32_be; - wrmem[8] = nd_board_wr64_be; - wrmem[16] = nd_board_wr128_be; + rdmem[1] = NextDimension::i860_rd8_be; + rdmem[2] = NextDimension::i860_rd16_be; + rdmem[4] = NextDimension::i860_rd32_be; + rdmem[8] = NextDimension::i860_rd64_be; + rdmem[16] = NextDimension::i860_rd128_be; + + wrmem[1] = NextDimension::i860_wr8_be; + wrmem[2] = NextDimension::i860_wr16_be; + wrmem[4] = NextDimension::i860_wr32_be; + wrmem[8] = NextDimension::i860_wr64_be; + wrmem[16] = NextDimension::i860_wr128_be; } else { - rdmem[1] = nd_board_rd8_le; - rdmem[2] = nd_board_rd16_le; - rdmem[4] = nd_board_rd32_le; - rdmem[8] = nd_board_rd64_le; - rdmem[16] = nd_board_rd128_le; - - wrmem[1] = nd_board_wr8_le; - wrmem[2] = nd_board_wr16_le; - wrmem[4] = nd_board_wr32_le; - wrmem[8] = nd_board_wr64_le; - wrmem[16] = nd_board_wr128_le; + rdmem[1] = NextDimension::i860_rd8_le; + rdmem[2] = NextDimension::i860_rd16_le; + rdmem[4] = NextDimension::i860_rd32_le; + rdmem[8] = NextDimension::i860_rd64_le; + rdmem[16] = NextDimension::i860_rd128_le; + + wrmem[1] = NextDimension::i860_wr8_le; + wrmem[2] = NextDimension::i860_wr16_le; + wrmem[4] = NextDimension::i860_wr32_le; + wrmem[8] = NextDimension::i860_wr64_le; + wrmem[16] = NextDimension::i860_wr128_le; } } inline UINT8 i860_cpu_device::rdcs8(UINT32 addr) { - return nd_board_cs8get(addr); + return NextDimension::i860_cs8get(nd, addr); } inline UINT32 i860_cpu_device::get_iregval(int gr) { @@ -142,57 +121,55 @@ inline void i860_cpu_device::set_iregval m_iregs[0] = 0; // make sure r0 is always 0 } -inline float i860_cpu_device::get_fregval_s (int fr) { - return *(float*)(&m_fregs[fr * 4]); +inline FLOAT32 i860_cpu_device::get_fregval_s (int fr) { + return *(FLOAT32*)(&m_fregs[fr * 4]); } -inline void i860_cpu_device::set_fregval_s (int fr, float s) { +inline void i860_cpu_device::set_fregval_s (int fr, FLOAT32 s) { if(fr > 1) - *(float*)(&m_fregs[fr * 4]) = s; + *(FLOAT32*)(&m_fregs[fr * 4]) = s; } -inline double i860_cpu_device::get_fregval_d (int fr) { - return *(double*)(&m_fregs[fr * 4]); +inline FLOAT64 i860_cpu_device::get_fregval_d (int fr) { + return *(FLOAT64*)(&m_fregs[fr * 4]); } -inline void i860_cpu_device::set_fregval_d (int fr, double d) { +inline void i860_cpu_device::set_fregval_d (int fr, FLOAT64 d) { if(fr > 1) - *(double*)(&m_fregs[fr * 4]) = d; + *(FLOAT64*)(&m_fregs[fr * 4]) = d; } inline void i860_cpu_device::SET_PSR_CC(int val) { if(!(m_dim_cc_valid)) m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 2)) | ((val & 1) << 2); } - -void i860_cpu_device::send_msg(int msg) { - lock(&m_port_lock); - m_port |= msg; - unlock(&m_port_lock); -} + +const char* i860_cpu_device::trap_info() { + static char buffer[256]; + buffer[0] = 0; + strcat(buffer, "TRAP"); + if(m_flow & TRAP_NORMAL) strcat(buffer, " [Normal]"); + if(m_flow & TRAP_IN_DELAY_SLOT) strcat(buffer, " [Delay Slot]"); + if(m_flow & TRAP_WAS_EXTERNAL) strcat(buffer, " [External]"); + if(!(GET_PSR_IT() || GET_PSR_FT() || GET_PSR_IAT() || GET_PSR_DAT() || GET_PSR_IN())) + strcat(buffer, " >Reset<"); + else { + if(GET_PSR_IT()) strcat(buffer, " >Instruction Fault<"); + if(GET_PSR_FT()) strcat(buffer, " >Floating Point Fault<"); + if(GET_PSR_IAT()) strcat(buffer, " >Instruction Access Fault<"); + if(GET_PSR_DAT()) strcat(buffer, " >Data Access Fault<"); + if(GET_PSR_IN()) strcat(buffer, " >Interrupt<"); + } + + return buffer; +} void i860_cpu_device::handle_trap(UINT32 savepc) { - static char buffer[256]; - buffer[0] = 0; - strcat(buffer, "TRAP"); - if(m_flow & TRAP_NORMAL) strcat(buffer, " [Normal]"); - if(m_flow & TRAP_IN_DELAY_SLOT) strcat(buffer, " [Delay Slot]"); - if(m_flow & TRAP_WAS_EXTERNAL) strcat(buffer, " [External]"); - if(!(GET_PSR_IT() || GET_PSR_FT() || GET_PSR_IAT() || GET_PSR_DAT() || GET_PSR_IN())) - strcat(buffer, " >Reset<"); - else { - if(GET_PSR_IT()) strcat(buffer, " >Instruction Fault<"); - if(GET_PSR_FT()) strcat(buffer, " >Floating Point Fault<"); - if(GET_PSR_IAT()) strcat(buffer, " >Instruction Access Fault<"); - if(GET_PSR_DAT()) strcat(buffer, " >Data Access Fault<"); - if(GET_PSR_IN()) strcat(buffer, " >Interrupt<"); - } - if(!(m_single_stepping) && !((GET_PSR_IAT() || GET_PSR_DAT() || GET_PSR_IN()))) - debugger('d', buffer); + debugger('d', trap_info()); if(m_dim) - Log_Printf(LOG_WARN, "[i860] Trap while DIM %s pc=%08X m_flow=%08X", buffer, savepc, m_flow); + Log_Printf(LOG_WARN, "[i860] Trap while DIM %s pc=%08X m_flow=%08X", trap_info(), savepc, m_flow); /* If we need to trap, change PC to trap address. Also set supervisor mode, copy U and IM to their @@ -339,86 +316,86 @@ int i860_cpu_device::memtest(bool be) { SET_EPSR_BE(0); set_mem_access(false); - tmp8 = 'A'; wrmem[1](P_TEST_ADDR+0, (UINT32*)&tmp8); - tmp8 = 'B'; wrmem[1](P_TEST_ADDR+1, (UINT32*)&tmp8); - tmp8 = 'C'; wrmem[1](P_TEST_ADDR+2, (UINT32*)&tmp8); - tmp8 = 'D'; wrmem[1](P_TEST_ADDR+3, (UINT32*)&tmp8); - tmp8 = 'E'; wrmem[1](P_TEST_ADDR+4, (UINT32*)&tmp8); - tmp8 = 'F'; wrmem[1](P_TEST_ADDR+5, (UINT32*)&tmp8); - tmp8 = 'G'; wrmem[1](P_TEST_ADDR+6, (UINT32*)&tmp8); - tmp8 = 'H'; wrmem[1](P_TEST_ADDR+7, (UINT32*)&tmp8); - - rdmem[1](P_TEST_ADDR+0, (UINT32*)&tmp8); if(tmp8 != 'A') return err + 100; - rdmem[1](P_TEST_ADDR+1, (UINT32*)&tmp8); if(tmp8 != 'B') return err + 101; - rdmem[1](P_TEST_ADDR+2, (UINT32*)&tmp8); if(tmp8 != 'C') return err + 102; - rdmem[1](P_TEST_ADDR+3, (UINT32*)&tmp8); if(tmp8 != 'D') return err + 103; - rdmem[1](P_TEST_ADDR+4, (UINT32*)&tmp8); if(tmp8 != 'E') return err + 104; - rdmem[1](P_TEST_ADDR+5, (UINT32*)&tmp8); if(tmp8 != 'F') return err + 105; - rdmem[1](P_TEST_ADDR+6, (UINT32*)&tmp8); if(tmp8 != 'G') return err + 106; - rdmem[1](P_TEST_ADDR+7, (UINT32*)&tmp8); if(tmp8 != 'H') return err + 107; - - rdmem[2](P_TEST_ADDR+0, (UINT32*)&tmp16); if(tmp16 != (('B'<<8)|('A'))) return err + 110; - rdmem[2](P_TEST_ADDR+2, (UINT32*)&tmp16); if(tmp16 != (('D'<<8)|('C'))) return err + 111; - rdmem[2](P_TEST_ADDR+4, (UINT32*)&tmp16); if(tmp16 != (('F'<<8)|('E'))) return err + 112; - rdmem[2](P_TEST_ADDR+6, (UINT32*)&tmp16); if(tmp16 != (('H'<<8)|('G'))) return err + 113; + tmp8 = 'A'; wrmem[1](nd, P_TEST_ADDR+0, (UINT32*)&tmp8); + tmp8 = 'B'; wrmem[1](nd, P_TEST_ADDR+1, (UINT32*)&tmp8); + tmp8 = 'C'; wrmem[1](nd, P_TEST_ADDR+2, (UINT32*)&tmp8); + tmp8 = 'D'; wrmem[1](nd, P_TEST_ADDR+3, (UINT32*)&tmp8); + tmp8 = 'E'; wrmem[1](nd, P_TEST_ADDR+4, (UINT32*)&tmp8); + tmp8 = 'F'; wrmem[1](nd, P_TEST_ADDR+5, (UINT32*)&tmp8); + tmp8 = 'G'; wrmem[1](nd, P_TEST_ADDR+6, (UINT32*)&tmp8); + tmp8 = 'H'; wrmem[1](nd, P_TEST_ADDR+7, (UINT32*)&tmp8); + + rdmem[1](nd, P_TEST_ADDR+0, (UINT32*)&tmp8); if(tmp8 != 'A') return err + 100; + rdmem[1](nd, P_TEST_ADDR+1, (UINT32*)&tmp8); if(tmp8 != 'B') return err + 101; + rdmem[1](nd, P_TEST_ADDR+2, (UINT32*)&tmp8); if(tmp8 != 'C') return err + 102; + rdmem[1](nd, P_TEST_ADDR+3, (UINT32*)&tmp8); if(tmp8 != 'D') return err + 103; + rdmem[1](nd, P_TEST_ADDR+4, (UINT32*)&tmp8); if(tmp8 != 'E') return err + 104; + rdmem[1](nd, P_TEST_ADDR+5, (UINT32*)&tmp8); if(tmp8 != 'F') return err + 105; + rdmem[1](nd, P_TEST_ADDR+6, (UINT32*)&tmp8); if(tmp8 != 'G') return err + 106; + rdmem[1](nd, P_TEST_ADDR+7, (UINT32*)&tmp8); if(tmp8 != 'H') return err + 107; + + rdmem[2](nd, P_TEST_ADDR+0, (UINT32*)&tmp16); if(tmp16 != (('B'<<8)|('A'))) return err + 110; + rdmem[2](nd, P_TEST_ADDR+2, (UINT32*)&tmp16); if(tmp16 != (('D'<<8)|('C'))) return err + 111; + rdmem[2](nd, P_TEST_ADDR+4, (UINT32*)&tmp16); if(tmp16 != (('F'<<8)|('E'))) return err + 112; + rdmem[2](nd, P_TEST_ADDR+6, (UINT32*)&tmp16); if(tmp16 != (('H'<<8)|('G'))) return err + 113; - rdmem[4](P_TEST_ADDR+0, &tmp32); if(tmp32 != (('D'<<24)|('C'<<16)|('B'<<8)|('A'))) return err + 120; - rdmem[4](P_TEST_ADDR+4, &tmp32); if(tmp32 != (('H'<<24)|('G'<<16)|('F'<<8)|('E'))) return err + 121; + rdmem[4](nd, P_TEST_ADDR+0, &tmp32); if(tmp32 != (('D'<<24)|('C'<<16)|('B'<<8)|('A'))) return err + 120; + rdmem[4](nd, P_TEST_ADDR+4, &tmp32); if(tmp32 != (('H'<<24)|('G'<<16)|('F'<<8)|('E'))) return err + 121; SET_EPSR_BE(1); set_mem_access(true); - rdmem[1](P_TEST_ADDR+0, (UINT32*)&tmp8); if(tmp8 != 'H') return err + 200; - rdmem[1](P_TEST_ADDR+1, (UINT32*)&tmp8); if(tmp8 != 'G') return err + 201; - rdmem[1](P_TEST_ADDR+2, (UINT32*)&tmp8); if(tmp8 != 'F') return err + 202; - rdmem[1](P_TEST_ADDR+3, (UINT32*)&tmp8); if(tmp8 != 'E') return err + 203; - rdmem[1](P_TEST_ADDR+4, (UINT32*)&tmp8); if(tmp8 != 'D') return err + 204; - rdmem[1](P_TEST_ADDR+5, (UINT32*)&tmp8); if(tmp8 != 'C') return err + 205; - rdmem[1](P_TEST_ADDR+6, (UINT32*)&tmp8); if(tmp8 != 'B') return err + 206; - rdmem[1](P_TEST_ADDR+7, (UINT32*)&tmp8); if(tmp8 != 'A') return err + 207; - - rdmem[2](P_TEST_ADDR+0, (UINT32*)&tmp16); if(tmp16 != (('H'<<8)|('G'))) return err + 210; - rdmem[2](P_TEST_ADDR+2, (UINT32*)&tmp16); if(tmp16 != (('F'<<8)|('E'))) return err + 211; - rdmem[2](P_TEST_ADDR+4, (UINT32*)&tmp16); if(tmp16 != (('D'<<8)|('C'))) return err + 212; - rdmem[2](P_TEST_ADDR+6, (UINT32*)&tmp16); if(tmp16 != (('B'<<8)|('A'))) return err + 213; + rdmem[1](nd, P_TEST_ADDR+0, (UINT32*)&tmp8); if(tmp8 != 'H') return err + 200; + rdmem[1](nd, P_TEST_ADDR+1, (UINT32*)&tmp8); if(tmp8 != 'G') return err + 201; + rdmem[1](nd, P_TEST_ADDR+2, (UINT32*)&tmp8); if(tmp8 != 'F') return err + 202; + rdmem[1](nd, P_TEST_ADDR+3, (UINT32*)&tmp8); if(tmp8 != 'E') return err + 203; + rdmem[1](nd, P_TEST_ADDR+4, (UINT32*)&tmp8); if(tmp8 != 'D') return err + 204; + rdmem[1](nd, P_TEST_ADDR+5, (UINT32*)&tmp8); if(tmp8 != 'C') return err + 205; + rdmem[1](nd, P_TEST_ADDR+6, (UINT32*)&tmp8); if(tmp8 != 'B') return err + 206; + rdmem[1](nd, P_TEST_ADDR+7, (UINT32*)&tmp8); if(tmp8 != 'A') return err + 207; + + rdmem[2](nd, P_TEST_ADDR+0, (UINT32*)&tmp16); if(tmp16 != (('H'<<8)|('G'))) return err + 210; + rdmem[2](nd, P_TEST_ADDR+2, (UINT32*)&tmp16); if(tmp16 != (('F'<<8)|('E'))) return err + 211; + rdmem[2](nd, P_TEST_ADDR+4, (UINT32*)&tmp16); if(tmp16 != (('D'<<8)|('C'))) return err + 212; + rdmem[2](nd, P_TEST_ADDR+6, (UINT32*)&tmp16); if(tmp16 != (('B'<<8)|('A'))) return err + 213; - rdmem[4](P_TEST_ADDR+0, &tmp32); if(tmp32 != (('H'<<24)|('G'<<16)|('F'<<8)|('E'))) return err + 220; - rdmem[4](P_TEST_ADDR+4, &tmp32); if(tmp32 != (('D'<<24)|('C'<<16)|('B'<<8)|('A'))) return err + 221; + rdmem[4](nd, P_TEST_ADDR+0, &tmp32); if(tmp32 != (('H'<<24)|('G'<<16)|('F'<<8)|('E'))) return err + 220; + rdmem[4](nd, P_TEST_ADDR+4, &tmp32); if(tmp32 != (('D'<<24)|('C'<<16)|('B'<<8)|('A'))) return err + 221; // some register and mem r/w tests SET_EPSR_BE(be); set_mem_access(be); - wrmem[1](P_TEST_ADDR, (UINT32*)&uint8); - rdmem[1](P_TEST_ADDR, (UINT32*)&tmp8); + wrmem[1](nd, P_TEST_ADDR, (UINT32*)&uint8); + rdmem[1](nd, P_TEST_ADDR, (UINT32*)&tmp8); if(tmp8 != 0x01) return err; - wrmem[2](P_TEST_ADDR, (UINT32*)&uint16); - rdmem[2](P_TEST_ADDR, (UINT32*)&tmp16); + wrmem[2](nd, P_TEST_ADDR, (UINT32*)&uint16); + rdmem[2](nd, P_TEST_ADDR, (UINT32*)&tmp16); if(tmp16 != 0x0123) return err+1; - wrmem[4](P_TEST_ADDR, &uint32); - rdmem[4](P_TEST_ADDR, &tmp32); if(tmp32 != 0x01234567) return err+2; + wrmem[4](nd, P_TEST_ADDR, &uint32); + rdmem[4](nd, P_TEST_ADDR, &tmp32); if(tmp32 != 0x01234567) return err+2; readmem_emu(P_TEST_ADDR, 4, (UINT8*)&uint32); if(uint32 != 0x01234567) return err+3; writemem_emu(P_TEST_ADDR, 4, (UINT8*)&uint32, 0xff); - rdmem[4](P_TEST_ADDR+0, &tmp32); if(tmp32 != 0x01234567) return err+4; + rdmem[4](nd, P_TEST_ADDR+0, &tmp32); if(tmp32 != 0x01234567) return err+4; UINT8* uint8p = (UINT8*)&uint64; - set_fregval_d(2, *((double*)uint8p)); + set_fregval_d(2, *((FLOAT64*)uint8p)); writemem_emu(P_TEST_ADDR, 8, &m_fregs[8], 0xff); readmem_emu (P_TEST_ADDR, 8, &m_fregs[8]); - *((double*)&uint64) = get_fregval_d(2); + *((FLOAT64*)&uint64) = get_fregval_d(2); if(uint64 != 0x0123456789ABCDEFLL) return err+5; UINT32 lo; UINT32 hi; - rdmem[4](P_TEST_ADDR+0, &lo); - rdmem[4](P_TEST_ADDR+4, &hi); + rdmem[4](nd, P_TEST_ADDR+0, &lo); + rdmem[4](nd, P_TEST_ADDR+4, &hi); if(lo != 0x01234567) return err+6; if(hi != 0x89ABCDEF) return err+7; @@ -426,14 +403,22 @@ int i860_cpu_device::memtest(bool be) { return 0; } -void i860_cpu_device::init() { +void i860_cpu_device::set_run_func(void) { + i860_Run = ConfigureParams.Dimension.bI860Thread ? i860_run_thread : i860_run_no_thread; +} + +void i860_cpu_device::init(void) { /* Configurations - keep in sync with i860cfg.h */ static const char* CFGS[8]; for(int i = 0; i < 8; i++) CFGS[i] = "Unknown emulator configuration"; CFGS[CONF_I860_SPEED] = CONF_STR(CONF_I860_SPEED); CFGS[CONF_I860_DEV] = CONF_STR(CONF_I860_DEV); CFGS[CONF_I860_NO_THREAD] = CONF_STR(CONF_I860_NO_THREAD); - Log_Printf(LOG_WARN, "[i860] Emulator configured for %s", CFGS[CONF_I860]); + Log_Printf(LOG_WARN, "[i860] Emulator configured for %s, %d logical cores detected, %s", + CFGS[CONF_I860], host_num_cpus(), + ConfigureParams.Dimension.bI860Thread ? "using seperate thread for i860" : "i860 running on m68k thread. WARNING: expect slow emulation"); + + reset_fpcs(&m_fpcs); m_single_stepping = 0; m_lastcmd = 0; @@ -441,7 +426,7 @@ void i860_cpu_device::init() { m_break_on_next_msg = false; m_dim = DIM_NONE; m_traceback_idx = 0; - + set_mem_access(false); // some sanity checks for endianess @@ -456,13 +441,13 @@ void i860_cpu_device::init() { for(int i = 0; i < 32; i++) { uint8p[3] = i; - set_fregval_s(i, *((float*)uint8p)); + set_fregval_s(i, *((FLOAT32*)uint8p)); } if(get_fregval_s(0) != 0) {err = 198; goto error;} if(get_fregval_s(1) != 0) {err = 199; goto error;} for(int i = 2; i < 32; i++) { uint8p[3] = i; - if(get_fregval_s(i) != *((float*)uint8p)) + if(get_fregval_s(i) != *((FLOAT32*)uint8p)) {err = 100+i; goto error;} } for(int i = 2; i < 32; i++) { @@ -487,18 +472,18 @@ void i860_cpu_device::init() { for(int i = 0; i < 16; i++) { uint8p[7] = i; - set_fregval_d(i*2, *((double*)uint8p)); + set_fregval_d(i*2, *((FLOAT64*)uint8p)); } if(get_fregval_d(0) != 0) {err = 10199; goto error;} for(int i = 1; i < 16; i++) { uint8p[7] = i; - if(get_fregval_d(i*2) != *((double*)uint8p)) + if(get_fregval_d(i*2) != *((FLOAT64*)uint8p)) {err = 10100+i; goto error;} } for(int i = 2; i < 32; i += 2) { - float hi = get_fregval_s(i+1); - float lo = get_fregval_s(i+0); + FLOAT32 hi = get_fregval_s(i+1); + FLOAT32 lo = get_fregval_s(i+0); if((*(UINT32*)&hi) != (0x00234567 | (i<<23))) {err = 10100+i; goto error;} if((*(UINT32*)&lo) != 0x89ABCDEF) {err = 10100+i; goto error;} } @@ -524,35 +509,31 @@ error: exit(err); } - send_msg(MSG_I860_RESET); -#if ENABLE_I860_THREAD - m_thread = thread_create(i860_thread, this); -#endif + nd->send_msg(MSG_I860_RESET); + if(ConfigureParams.Dimension.bI860Thread) { + i860_Run = i860_run_thread; + m_thread = host_thread_create(i860_cpu_device::thread, this); + } else { + i860_Run = i860_run_no_thread; + } } void i860_cpu_device::uninit() { - if(is_halted()) return; - halt(true); - send_msg(MSG_I860_KILL); -#if ENABLE_I860_THREAD + if(m_thread) { - thread_wait(m_thread); + nd->send_msg(MSG_I860_KILL); + host_thread_wait(m_thread); m_thread = NULL; } - send_msg(MSG_NONE); -#endif + nd->send_msg(MSG_NONE); } /* Message disaptcher - executed on i860 thread, safe to call i860 methods */ -bool i860_cpu_device::handle_msgs() { - lock(&m_port_lock); - int msg = m_port; - m_port = 0; - unlock(&m_port_lock); - +bool i860_cpu_device::handle_msgs(int msg) { if(msg & MSG_I860_KILL) return false; + if(msg & MSG_I860_RESET) reset(); else if(msg & MSG_INTR) @@ -563,68 +544,57 @@ bool i860_cpu_device::handle_msgs() { } void i860_cpu_device::run() { - while(handle_msgs()) { + while(nd->handle_msgs()) { /* Sleep a bit if halted */ if(is_halted()) { - sleep_ms(100); + host_sleep_ms(100); continue; } - /* Run some i860 cycles before re-checking messages*/ - for(int i = 10; --i >= 0;) - run_cycle(); + if (i860cycles > 0) { + /* Run some i860 cycles before re-checking messages */ + for(int i = 16; --i >= 0;) + run_cycle(); + + i860cycles -= 16; + } else { + host_sleep_ms(1); + } } } -void i860_cpu_device::tick(bool intr) { - if(intr) send_msg(MSG_INTR); -#if ENABLE_PERF_COUNTERS - UINT32 now = time_ms(); - m_time_delta_ms += now - m_abs_time_ms; - m_abs_time_ms = now; - if(m_time_delta_ms > 5000) - dump_reset_perfc(); -#endif -} - -#if ENABLE_PERF_COUNTERS -void i860_cpu_device::dump_reset_perfc() { - static bool dump = false; - if(dump) { - UINT32 dt = m_time_delta_ms; - if(dt) { - if(trylock(&m_debugger_lock)) { - Log_Printf(LOG_WARN, "[i860] Stats: MIPS=%lld.%lld icache_hit=%lld%% tlb_hit=%lld%% icach_inval/s=%lld tlb_inval/s=%lld intr/s=%lld", - (m_insn_decoded / (dt * 100)) / 10, (m_insn_decoded / (dt * 100)) % 10, - m_icache_hit+m_icache_miss == 0 ? 0 : (100 * m_icache_hit) / (m_icache_hit+m_icache_miss) , - m_tlb_hit+m_tlb_miss == 0 ? 0 : (100 * m_tlb_hit) / (m_tlb_hit+m_tlb_miss), - (1000*m_icache_inval)/dt, - (1000*m_tlb_inval)/dt, - (1000*m_intrs)/dt - ); - Log_Printf(LOG_WARN, "[m68k] Stats: Mcycles/s=%lld.%lld", - (m_m68k_cylces / (dt * 100)) / 10, (m_insn_decoded / (dt * 100)) % 10); - - m_m68k_cylces = 0; - m_insn_decoded = 0; - m_icache_hit = 0; - m_icache_miss = 0; - m_icache_inval = 0; - m_tlb_hit = 0; - m_tlb_miss = 0; - m_tlb_inval = 0; - m_time_delta_ms = 0; - m_intrs = 0; +const char* i860_cpu_device::reports(double realTime, double hostTime) { + double dVT = hostTime - m_last_vt; + + if(is_halted()) { + m_report[0] = 0; + } else { + if(dVT == 0) dVT = 0.0001; + sprintf(m_report, "i860:{MIPS=%.1f icache_hit=%lld%% tlb_hit=%lld%% icach_inval/s=%.0f tlb_inval/s=%.0f intr/s=%0.f}", + (m_insn_decoded / (dVT*1000*1000)), + m_icache_hit+m_icache_miss == 0 ? 0 : (100 * m_icache_hit) / (m_icache_hit+m_icache_miss) , + m_tlb_hit+m_tlb_miss == 0 ? 0 : (100 * m_tlb_hit) / (m_tlb_hit+m_tlb_miss), + (m_icache_inval)/dVT, + (m_tlb_inval)/dVT, + (m_intrs)/dVT + ); + + m_insn_decoded = 0; + m_icache_hit = 0; + m_icache_miss = 0; + m_icache_inval = 0; + m_tlb_hit = 0; + m_tlb_miss = 0; + m_tlb_inval = 0; + m_intrs = 0; - unlock(&m_debugger_lock); - } - } + m_last_rt = realTime; + m_last_vt = hostTime; } - dump = true; + return m_report; } -#endif offs_t i860_cpu_device::disasm(char* buffer, offs_t pc) { return pc + i860_disassembler(pc, ifetch_notrap(pc), buffer); @@ -638,4 +608,4 @@ offs_t i860_cpu_device::disasm(char* buf /************************************************************************** * The debugger code. **************************************************************************/ -#include "i860dbg.cpp" \ No newline at end of file +#include "i860dbg.cpp"