--- previous/src/dimension/i860.hpp 2018/04/24 19:30:01 1.1 +++ previous/src/dimension/i860.hpp 2018/04/24 19:31:33 1.1.1.2 @@ -23,13 +23,18 @@ #include #include #include +#include #include #include +#include #include "i860cfg.h" +#include "host.h" #include "nd_sdl.h" const int LOG_WARN = 3; +const int ND_SLOT = 2; // HACK: one day we should put the whole ND in a C++ class or make an array of NeXTbus slots + extern "C" void Log_Printf(int nType, const char *psFormat, ...); typedef uint64_t UINT64; @@ -47,46 +52,100 @@ typedef int8_t INT8; typedef int64_t offs_t; extern "C" { - UINT8 nd_board_cs8get(UINT32 addr); - UINT8 nd_board_bget(UINT32 addr); - void nd_board_bput(UINT32 addr, UINT8 val); - UINT16 nd_board_wget(UINT32 addr); - void nd_board_wput(UINT32 addr, UINT16 val); - UINT32 nd_board_lget(UINT32 addr); - void nd_board_lput(UINT32 addr, UINT32 val); - void nd_board_put (UINT32 addr, UINT32 val); - - void nd_board_rd8_le (UINT32 addr, UINT32* val); - void nd_board_rd16_le (UINT32 addr, UINT32* val); - void nd_board_rd32_le (UINT32 addr, UINT32* val); - void nd_board_rd64_le (UINT32 addr, UINT32* val); - void nd_board_rd128_le(UINT32 addr, UINT32* val); - - void nd_board_rd8_be (UINT32 addr, UINT32* val); - void nd_board_rd16_be (UINT32 addr, UINT32* val); - void nd_board_rd32_be (UINT32 addr, UINT32* val); - void nd_board_rd64_be (UINT32 addr, UINT32* val); - void nd_board_rd128_be(UINT32 addr, UINT32* val); - - void nd_board_wr8_le (UINT32 addr, const UINT32* val); - void nd_board_wr16_le (UINT32 addr, const UINT32* val); - void nd_board_wr32_le (UINT32 addr, const UINT32* val); - void nd_board_wr64_le (UINT32 addr, const UINT32* val); - void nd_board_wr128_le(UINT32 addr, const UINT32* val); - - void nd_board_wr8_be (UINT32 addr, const UINT32* val); - void nd_board_wr16_be (UINT32 addr, const UINT32* val); - void nd_board_wr32_be (UINT32 addr, const UINT32* val); - void nd_board_wr64_be (UINT32 addr, const UINT32* val); - void nd_board_wr128_be(UINT32 addr, const UINT32* val); +#include "dimension.h" void nd_nbic_interrupt(void); bool nd_dbg_cmd(const char* cmd); void Statusbar_SetNdLed(int state); + + void nd_set_blank_state(int src, bool state); + + typedef void (*mem_rd_func)(UINT32, UINT32*); + typedef void (*mem_wr_func)(UINT32, const UINT32*); +} + +#if WITH_SOFTFLOAT_I860 +extern "C" { +#include } +typedef float32 FLOAT32; +typedef float64 FLOAT64; + +#define FLOAT32_ZERO 0x00000000 +#define FLOAT32_ONE 0x3F800000 +#define FLOAT32_IS_NEG(x) ((x) & 0x80000000) +#define FLOAT32_IS_ZERO(x) (((x) & 0x7FFFFFFF) == 0x00000000) +#define FLOAT64_ZERO LIT64(0x0000000000000000) +#define FLOAT64_ONE LIT64(0x3FF0000000000000) +#define FLOAT64_IS_NEG(x) ((x) & LIT64(0x8000000000000000)) +#define FLOAT64_IS_ZERO(x) (((x) & LIT64(0x7FFFFFFFFFFFFFFF)) == LIT64(0x0000000000000000)) + +static inline void float_set_rounding_mode (int mode) { + switch (mode) { + case 0: float_rounding_mode2 = float_round_nearest_even; break; + case 1: float_rounding_mode2 = float_round_down; break; + case 2: float_rounding_mode2 = float_round_up; break; + case 3: float_rounding_mode2 = float_round_to_zero; break; + } +} + +#else // NATIVE FLOAT + +#include +#ifdef __MINGW32__ +#define _GLIBCXX_HAVE_FENV_H 1 +#endif +#include +#if __APPLE__ +#else +#pragma STDC FENV_ACCESS ON +#endif + +typedef float FLOAT32; +typedef double FLOAT64; + +#define FLOAT32_ZERO 0.0 +#define FLOAT32_ONE 1.0 +#define FLOAT32_IS_NEG(x) ((x) < 0.0) +#define FLOAT32_IS_ZERO(x) ((x) == 0.0) +#define FLOAT64_ZERO 0.0 +#define FLOAT64_ONE 1.0 +#define FLOAT64_IS_NEG(x) ((x) < 0.0) +#define FLOAT64_IS_ZERO(x) ((x) == 0.0) + +#define float32_add(x,y) ((x)+(y)) +#define float32_sub(x,y) ((x)-(y)) +#define float32_mul(x,y) ((x)*(y)) +#define float32_div(x,y) ((x)/(y)) +#define float32_sqrt(x) (sqrt(x)) +#define float32_to_int32(x) (rint(x)) +#define float32_to_int32_round_to_zero(x) ((UINT32)(x)) +#define float32_to_float64(x) ((double)(x)) +#define float32_gt(x,y) ((x)>(y)) +#define float32_le(x,y) ((x)<=(y)) +#define float32_eq(x,y) ((x)==(y)) +#define float64_add(x,y) ((x)+(y)) +#define float64_sub(x,y) ((x)-(y)) +#define float64_mul(x,y) ((x)*(y)) +#define float64_div(x,y) ((x)/(y)) +#define float64_sqrt(x) (sqrt(x)) +#define float64_to_int32(x) (rint(x)) +#define float64_to_int32_round_to_zero(x) ((UINT32)(x)) +#define float64_to_float32(x) ((float)(x)) +#define float64_gt(x,y) ((x)>(y)) +#define float64_le(x,y) ((x)<=(y)) +#define float64_eq(x,y) ((x)==(y)) + +static inline void float_set_rounding_mode (int mode) { + switch (mode) { + case 0: fesetround(FE_TONEAREST); break; + case 1: fesetround(FE_DOWNWARD); break; + case 2: fesetround(FE_UPWARD); break; + case 3: fesetround(FE_TOWARDZERO); break; + } +} +#endif // NATIVE FLOAT -typedef void (*mem_rd_func)(UINT32, UINT32*); -typedef void (*mem_wr_func)(UINT32, const UINT32*); /*************************************************************************** REGISTER ENUMERATION @@ -122,11 +181,13 @@ enum { }; enum { - MSG_NONE = 0x00, - MSG_I860_RESET = 0x01, - MSG_I860_KILL = 0x02, - MSG_DBG_BREAK = 0x04, - MSG_INTR = 0x08, + MSG_NONE = 0x00, + MSG_I860_RESET = 0x01, + MSG_I860_KILL = 0x02, + MSG_DBG_BREAK = 0x04, + MSG_INTR = 0x08, + MSG_DISPLAY_BLANK = 0x10, + MSG_VIDEO_BLANK = 0x20, }; /* dual mode instruction state */ @@ -348,6 +409,7 @@ public: void init(); void uninit(); void halt(bool state); + void pause(bool state); inline bool is_halted() {return m_halt;}; /* Run one i860 cycle */ @@ -356,15 +418,10 @@ public: void run(); /* i860 thread message handler */ bool handle_msgs(); - /* External tick event for the i860 emulator to update real-time dependent state + interrupt flag */ - void tick(bool intr); - /* Lock acquired by debugger to block other threads (e.g. m68k) */ - lock_t m_debugger_lock; + /* External interrupt for i860 emulator */ + void interrupt(); -#if ENABLE_PERF_COUNTERS - UINT64 m_m68k_cylces; -#endif - + const char* reports(double realTime, double hostTIme); private: // debugger void debugger(char cmd, const char* format, ...); @@ -373,12 +430,8 @@ private: /* Message port for host->i860 communication */ volatile int m_port; lock_t m_port_lock; - -#if ENABLE_I860_THREAD - thread_t* m_thread; -#endif + thread_t* m_thread; -#if ENABLE_PERF_COUNTERS UINT64 m_insn_decoded; UINT64 m_icache_hit; UINT64 m_icache_miss; @@ -387,15 +440,13 @@ private: UINT64 m_tlb_miss; UINT64 m_tlb_inval; UINT64 m_intrs; - UINT32 m_time_delta_ms; - UINT32 m_abs_time_ms; - - void dump_reset_perfc(); -#endif - + UINT32 m_last_rt; + UINT32 m_last_vt; + char m_report[1024]; + /* Debugger stuff */ char m_lastcmd; - char m_console[512*1024]; + char m_console[32*1024]; int m_console_idx; bool m_break_on_next_msg; UINT32 m_traceback[256]; @@ -427,8 +478,8 @@ private: /* Special registers (4 x 64-bits). */ union { - float s; - double d; + FLOAT32 s; + FLOAT64 d; } m_KR, m_KI, m_T; UINT64 m_merge; @@ -438,8 +489,8 @@ private: { /* The stage contents. */ union { - float s; - double d; + FLOAT32 s; + FLOAT64 d; } val; /* The stage status bits. */ @@ -454,8 +505,8 @@ private: struct { /* The stage contents. */ union { - float s; - double d; + FLOAT32 s; + FLOAT64 d; } val; /* The stage status bits. */ @@ -469,8 +520,8 @@ private: struct { /* The stage contents. */ union { - float s; - double d; + FLOAT32 s; + FLOAT64 d; } val; /* The stage status bits. */ @@ -484,8 +535,8 @@ private: struct { /* The stage contents. */ union { - float s; - double d; + FLOAT32 s; + FLOAT64 d; } val; /* The stage status bits. */ @@ -522,9 +573,9 @@ private: void set_mem_access(bool be); UINT8 rdcs8(UINT32 addr); - void writemem_emu(UINT32 addr, int size, UINT8 *data); - void writemem_emu(UINT32 addr, int size, UINT8 *data, UINT32 wmask); - void readmem_emu (UINT32 addr, int size, UINT8 *data); + inline void writemem_emu(UINT32 addr, int size, UINT8 *data); + inline void writemem_emu(UINT32 addr, int size, UINT8 *data, UINT32 wmask); + inline void readmem_emu (UINT32 addr, int size, UINT8 *data); /* instructions */ void insn_ld_ctrl (UINT32 insn); @@ -594,19 +645,22 @@ private: void insn_form (UINT32 insn); void insn_faddp (UINT32 insn); void insn_faddz (UINT32 insn); - + + void dec_unrecog (UINT32 insn); + /* register access */ UINT32 get_iregval(int gr); void set_iregval(int gr, UINT32 val); - float get_fregval_s (int fr); - void set_fregval_s (int fr, float s); - double get_fregval_d (int fr); - void set_fregval_d (int fr, double d); + FLOAT32 get_fregval_s (int fr); + void set_fregval_s (int fr, FLOAT32 s); + FLOAT64 get_fregval_d (int fr); + void set_fregval_d (int fr, FLOAT64 d); void SET_PSR_CC(int val); void invalidate_icache(); void invalidate_tlb(); - UINT64 ifetch64(const UINT32 pc); + inline UINT64 ifetch64(const UINT32 pc); + UINT64 ifetch64(const UINT32 pc, const UINT32 vaddr, int const cidx); UINT32 ifetch(const UINT32 pc); UINT32 ifetch_notrap(const UINT32 pc); void handle_trap(UINT32 savepc); @@ -618,11 +672,12 @@ private: void dump_state (); UINT32 disasm (UINT32 addr, int len); offs_t disasm(char* buffer, offs_t pc); - void dbg_db (UINT32 addr, int len); + void dbg_memdump (UINT32 addr, int len); int delay_slots(UINT32 insn); - UINT32 get_address_translation (UINT32 vaddr, int is_dataref, int is_write); - float get_fval_from_optype_s (UINT32 insn, int optype); - double get_fval_from_optype_d (UINT32 insn, int optype); + UINT32 get_address_translation(UINT32 vaddr, int is_dataref, int is_write); + inline UINT32 get_address_translation(UINT32 vaddr, UINT32 voffset, UINT32 tlbidx, int is_dataref, int is_write); + FLOAT32 get_fval_from_optype_s (UINT32 insn, int optype); + FLOAT64 get_fval_from_optype_d (UINT32 insn, int optype); int memtest(bool be); void dbg_check_wr(UINT32 addr, int size, UINT8* data); @@ -635,16 +690,10 @@ private: void intr(); typedef void (i860_cpu_device::*insn_func)(UINT32); - struct decode_tbl_t - { - /* Execute function for this opcode. */ - insn_func insn_exec; - /* Flags for this opcode. */ - char flags; - }; - static const decode_tbl_t decode_tbl[64]; - static const decode_tbl_t core_esc_decode_tbl[8]; - static const decode_tbl_t fp_decode_tbl[128]; + static const insn_func decode_tbl[64]; + static const insn_func core_esc_decode_tbl[8]; + static const insn_func fp_decode_tbl[128]; + static insn_func decoder_tbl[8192]; }; /* disassembler */