Annotation of previous/src/dimension/i860.hpp, revision 1.1.1.2

1.1       root        1: /***************************************************************************
                      2: 
                      3:     i860.h
                      4: 
                      5:     Interface file for the Intel i860 emulator.
                      6: 
                      7:     Copyright (C) 1995-present Jason Eckhardt ([email protected])
                      8:     Released for general non-commercial use under the MAME license
                      9:     with the additional requirement that you are free to use and
                     10:     redistribute this code in modified or unmodified form, provided
                     11:     you list me in the credits.
                     12:     Visit http://mamedev.org for licensing and usage restrictions.
                     13: 
                     14:     Changes for previous/NeXTdimension by Simon Schubiger (SC)
                     15: 
                     16: ***************************************************************************/
                     17: 
                     18: #pragma once
                     19: 
                     20: #ifndef __I860_H__
                     21: #define __I860_H__
                     22: 
                     23: #include <stdint.h>
                     24: #include <stdio.h>
                     25: #include <stdarg.h>
1.1.1.2 ! root       26: #include <string.h>
1.1       root       27: #include <unistd.h>
                     28: #include <ctype.h>
1.1.1.2 ! root       29: #include <assert.h>
1.1       root       30: 
                     31: #include "i860cfg.h"
1.1.1.2 ! root       32: #include "host.h"
1.1       root       33: #include "nd_sdl.h"
                     34: 
                     35: const int LOG_WARN = 3;
1.1.1.2 ! root       36: 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
        !            37: 
1.1       root       38: extern "C" void Log_Printf(int nType, const char *psFormat, ...);
                     39: 
                     40: typedef uint64_t UINT64;
                     41: typedef int64_t INT64;
                     42: 
                     43: typedef uint32_t UINT32;
                     44: typedef int32_t INT32;
                     45: 
                     46: typedef uint16_t UINT16;
                     47: typedef int16_t INT16;
                     48: 
                     49: typedef uint8_t  UINT8;
                     50: typedef int8_t  INT8;
                     51: 
                     52: typedef int64_t offs_t;
                     53: 
                     54: extern "C" {
1.1.1.2 ! root       55: #include "dimension.h"
1.1       root       56: 
                     57:     void   nd_nbic_interrupt(void);
                     58:     bool   nd_dbg_cmd(const char* cmd);
                     59:     void   Statusbar_SetNdLed(int state);
1.1.1.2 ! root       60:     
        !            61:     void   nd_set_blank_state(int src, bool state);
        !            62: 
        !            63:     typedef void (*mem_rd_func)(UINT32, UINT32*);
        !            64:     typedef void (*mem_wr_func)(UINT32, const UINT32*);
        !            65: }
        !            66: 
        !            67: #if WITH_SOFTFLOAT_I860
        !            68: extern "C" {
        !            69: #include <softfloat.h>
1.1       root       70: }
1.1.1.2 ! root       71: typedef float32 FLOAT32;
        !            72: typedef float64 FLOAT64;
        !            73: 
        !            74: #define FLOAT32_ZERO            0x00000000
        !            75: #define FLOAT32_ONE             0x3F800000
        !            76: #define FLOAT32_IS_NEG(x)       ((x) & 0x80000000)
        !            77: #define FLOAT32_IS_ZERO(x)      (((x) & 0x7FFFFFFF) == 0x00000000)
        !            78: #define FLOAT64_ZERO            LIT64(0x0000000000000000)
        !            79: #define FLOAT64_ONE             LIT64(0x3FF0000000000000)
        !            80: #define FLOAT64_IS_NEG(x)       ((x) & LIT64(0x8000000000000000))
        !            81: #define FLOAT64_IS_ZERO(x)      (((x) & LIT64(0x7FFFFFFFFFFFFFFF)) == LIT64(0x0000000000000000))
        !            82: 
        !            83: static inline void float_set_rounding_mode (int mode) {
        !            84:     switch (mode) {
        !            85:         case 0: float_rounding_mode2 = float_round_nearest_even; break;
        !            86:         case 1: float_rounding_mode2 = float_round_down;         break;
        !            87:         case 2: float_rounding_mode2 = float_round_up;           break;
        !            88:         case 3: float_rounding_mode2 = float_round_to_zero;      break;
        !            89:     }
        !            90: }
        !            91: 
        !            92: #else // NATIVE FLOAT
        !            93: 
        !            94: #include <math.h>
        !            95: #ifdef __MINGW32__
        !            96: #define _GLIBCXX_HAVE_FENV_H 1
        !            97: #endif
        !            98: #include <fenv.h>
        !            99: #if __APPLE__
        !           100: #else
        !           101: #pragma STDC FENV_ACCESS ON
        !           102: #endif
        !           103: 
        !           104: typedef float FLOAT32;
        !           105: typedef double FLOAT64;
        !           106: 
        !           107: #define FLOAT32_ZERO            0.0
        !           108: #define FLOAT32_ONE             1.0
        !           109: #define FLOAT32_IS_NEG(x)       ((x) < 0.0)
        !           110: #define FLOAT32_IS_ZERO(x)      ((x) == 0.0)
        !           111: #define FLOAT64_ZERO            0.0
        !           112: #define FLOAT64_ONE             1.0
        !           113: #define FLOAT64_IS_NEG(x)       ((x) < 0.0)
        !           114: #define FLOAT64_IS_ZERO(x)      ((x) == 0.0)
        !           115: 
        !           116: #define float32_add(x,y)        ((x)+(y))
        !           117: #define float32_sub(x,y)        ((x)-(y))
        !           118: #define float32_mul(x,y)        ((x)*(y))
        !           119: #define float32_div(x,y)        ((x)/(y))
        !           120: #define float32_sqrt(x)         (sqrt(x))
        !           121: #define float32_to_int32(x)     (rint(x))
        !           122: #define float32_to_int32_round_to_zero(x)     ((UINT32)(x))
        !           123: #define float32_to_float64(x)   ((double)(x))
        !           124: #define float32_gt(x,y)         ((x)>(y))
        !           125: #define float32_le(x,y)         ((x)<=(y))
        !           126: #define float32_eq(x,y)         ((x)==(y))
        !           127: #define float64_add(x,y)        ((x)+(y))
        !           128: #define float64_sub(x,y)        ((x)-(y))
        !           129: #define float64_mul(x,y)        ((x)*(y))
        !           130: #define float64_div(x,y)        ((x)/(y))
        !           131: #define float64_sqrt(x)         (sqrt(x))
        !           132: #define float64_to_int32(x)     (rint(x))
        !           133: #define float64_to_int32_round_to_zero(x)     ((UINT32)(x))
        !           134: #define float64_to_float32(x)   ((float)(x))
        !           135: #define float64_gt(x,y)         ((x)>(y))
        !           136: #define float64_le(x,y)         ((x)<=(y))
        !           137: #define float64_eq(x,y)         ((x)==(y))
        !           138: 
        !           139: static inline void float_set_rounding_mode (int mode) {
        !           140:     switch (mode) {
        !           141:         case 0: fesetround(FE_TONEAREST);  break;
        !           142:         case 1: fesetround(FE_DOWNWARD);   break;
        !           143:         case 2: fesetround(FE_UPWARD);     break;
        !           144:         case 3: fesetround(FE_TOWARDZERO); break;
        !           145:     }
        !           146: }
        !           147: #endif // NATIVE FLOAT
1.1       root      148: 
                    149: 
                    150: /***************************************************************************
                    151:     REGISTER ENUMERATION
                    152: ***************************************************************************/
                    153: 
                    154: 
                    155: /* Various m_flow control flags (pending traps, pc update) */
                    156: enum {
                    157:     FLOW_CLEAR_MASK    = 0xF0000000,
                    158:     /* Indicate an instruction just generated a trap, so we know the PC
                    159:      needs to go to the trap address.  */
                    160:     TRAP_NORMAL        = 0x00000001,
                    161:     TRAP_IN_DELAY_SLOT = 0x00000002,
                    162:     TRAP_WAS_EXTERNAL  = 0x00000004,
                    163:     TRAP_MASK          = 0x00000007,
                    164:     /* Indicate a control-flow instruction, so we know the PC is updated.  */
                    165:     PC_UPDATED         = 0x00000100,
                    166:     /* Various memory access faults */
                    167:     EXITING_IFETCH     = 0x00001000,
                    168:     EXITING_READMEM    = 0x00010000,
                    169:     EXITING_WRITEMEM   = 0x00020000,
                    170:     EXITING_FPREADMEM  = 0x00030000,
                    171:     EXITING_FPWRITEMEM = 0x00040000,
                    172:     EXITING_MEMRW      = 0x00070000,
                    173:     /* This is 1 if the next fir load gets the trap address, otherwise
                    174:      it is 0 to get the ld.c address.  This is set to 1 only when a
                    175:      non-reset trap occurs.  */
                    176:     FIR_GETS_TRAP      = 0x10000000,
                    177:     /* An external interrupt occured. */
                    178:     EXT_INTR           = 0x20000000,
                    179:     /* A f-op with DIM bit set encountered. */
                    180:     DIM_OP             = 0x40000000,
                    181: };
                    182: 
                    183: enum {
1.1.1.2 ! root      184:     MSG_NONE           = 0x00,
        !           185:     MSG_I860_RESET     = 0x01,
        !           186:     MSG_I860_KILL      = 0x02,
        !           187:     MSG_DBG_BREAK      = 0x04,
        !           188:     MSG_INTR           = 0x08,
        !           189:     MSG_DISPLAY_BLANK  = 0x10,
        !           190:     MSG_VIDEO_BLANK    = 0x20,
1.1       root      191: };
                    192: 
                    193: /* dual mode instruction state */
                    194: enum {
                    195:     DIM_NONE,
                    196:     DIM_TEMP,
                    197:     DIM_FULL,
                    198: };
                    199: 
                    200: /* Macros for accessing register fields in instruction word.  */
                    201: #define get_isrc1(bits) (((bits) >> 11) & 0x1f)
                    202: #define get_isrc2(bits) (((bits) >> 21) & 0x1f)
                    203: #define get_idest(bits) (((bits) >> 16) & 0x1f)
                    204: #define get_fsrc1(bits) (((bits) >> 11) & 0x1f)
                    205: #define get_fsrc2(bits) (((bits) >> 21) & 0x1f)
                    206: #define get_fdest(bits) (((bits) >> 16) & 0x1f)
                    207: #define get_creg(bits) (((bits) >> 21) & 0x7)
                    208: 
                    209: /* Macros for accessing immediate fields.  */
                    210: /* 16-bit immediate.  */
                    211: #define get_imm16(insn) ((insn) & 0xffff)
                    212: 
                    213: /* A mask for all the trap bits of the PSR (FT, DAT, IAT, IN, IT, or
                    214:  bits [12..8]).  */
                    215: #define PSR_ALL_TRAP_BITS_MASK 0x00001f00
                    216: 
                    217: /* A mask for PSR bits which can only be changed from supervisor level.  */
                    218: #define PSR_SUPERVISOR_ONLY_MASK 0x0000fff3
                    219: 
                    220: 
                    221: /* PSR: BR flag (PSR[0]):  set/get.  */
                    222: #define GET_PSR_BR()  ((m_cregs[CR_PSR] >> 0) & 1)
                    223: #define SET_PSR_BR(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 0)) | (((val) & 1) << 0))
                    224: 
                    225: /* PSR: BW flag (PSR[1]):  set/get.  */
                    226: #define GET_PSR_BW()  ((m_cregs[CR_PSR] >> 1) & 1)
                    227: #define SET_PSR_BW(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 1)) | (((val) & 1) << 1))
                    228: 
                    229: /* PSR: Shift count (PSR[21..17]):  set/get.  */
                    230: #define GET_PSR_SC()  ((m_cregs[CR_PSR] >> 17) & 0x1f)
                    231: #define SET_PSR_SC(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~0x003e0000) | (((val) & 0x1f) << 17))
                    232: 
                    233: /* PSR: CC flag (PSR[2]):  set/get.  */
                    234: #define GET_PSR_CC()      ((m_cregs[CR_PSR] >> 2) & 1)
                    235: #define SET_PSR_CC_F(val) (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 2)) | (((val) & 1) << 2))
                    236: 
                    237: /* PSR: IT flag (PSR[8]):  set/get.  */
                    238: #define GET_PSR_IT()  ((m_cregs[CR_PSR] >> 8) & 1)
                    239: #define SET_PSR_IT(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 8)) | (((val) & 1) << 8))
                    240: 
                    241: /* PSR: IN flag (PSR[9]):  set/get.  */
                    242: #define GET_PSR_IN()  ((m_cregs[CR_PSR] >> 9) & 1)
                    243: #define SET_PSR_IN(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 9)) | (((val) & 1) << 9))
                    244: 
                    245: /* PSR: IAT flag (PSR[10]):  set/get.  */
                    246: #define GET_PSR_IAT()  ((m_cregs[CR_PSR] >> 10) & 1)
                    247: #define SET_PSR_IAT(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 10)) | (((val) & 1) << 10))
                    248: 
                    249: /* PSR: DAT flag (PSR[11]):  set/get.  */
                    250: #define GET_PSR_DAT()  ((m_cregs[CR_PSR] >> 11) & 1)
                    251: #define SET_PSR_DAT(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 11)) | (((val) & 1) << 11))
                    252: 
                    253: /* PSR: FT flag (PSR[12]):  set/get.  */
                    254: #define GET_PSR_FT()  ((m_cregs[CR_PSR] >> 12) & 1)
                    255: #define SET_PSR_FT(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 12)) | (((val) & 1) << 12))
                    256: 
                    257: /* PSR: DS flag (PSR[13]):  set/get.  */
                    258: #define GET_PSR_DS()  ((m_cregs[CR_PSR] >> 13) & 1)
                    259: #define SET_PSR_DS(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 13)) | (((val) & 1) << 13))
                    260: 
                    261: /* PSR: DIM flag (PSR[14]):  set/get.  */
                    262: #define GET_PSR_DIM()  ((m_cregs[CR_PSR] >> 14) & 1)
                    263: #define SET_PSR_DIM(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 14)) | (((val) & 1) << 14))
                    264: 
                    265: /* PSR: LCC (PSR[3]):  set/get.  */
                    266: #define GET_PSR_LCC()  ((m_cregs[CR_PSR] >> 3) & 1)
                    267: #define SET_PSR_LCC(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 3)) | (((val) & 1) << 3))
                    268: 
                    269: /* PSR: IM (PSR[4]):  set/get.  */
                    270: #define GET_PSR_IM()  ((m_cregs[CR_PSR] >> 4) & 1)
                    271: #define SET_PSR_IM(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 4)) | (((val) & 1) << 4))
                    272: 
                    273: /* PSR: PIM (PSR[5]):  set/get.  */
                    274: #define GET_PSR_PIM()  ((m_cregs[CR_PSR] >> 5) & 1)
                    275: #define SET_PSR_PIM(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 5)) | (((val) & 1) << 5))
                    276: 
                    277: /* PSR: U (PSR[6]):  set/get.  */
                    278: #define GET_PSR_U()  ((m_cregs[CR_PSR] >> 6) & 1)
                    279: #define SET_PSR_U(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 6)) | (((val) & 1) << 6))
                    280: 
                    281: /* PSR: PU (PSR[7]):  set/get.  */
                    282: #define GET_PSR_PU()  ((m_cregs[CR_PSR] >> 7) & 1)
                    283: #define SET_PSR_PU(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~(1 << 7)) | (((val) & 1) << 7))
                    284: 
                    285: /* PSR: Pixel size (PSR[23..22]):  set/get.  */
                    286: #define GET_PSR_PS()  ((m_cregs[CR_PSR] >> 22) & 0x3)
                    287: #define SET_PSR_PS(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~0x00c00000) | (((val) & 0x3) << 22))
                    288: 
                    289: /* PSR: Pixel mask (PSR[31..24]):  set/get.  */
                    290: #define GET_PSR_PM()  ((m_cregs[CR_PSR] >> 24) & 0xff)
                    291: #define SET_PSR_PM(val)  (m_cregs[CR_PSR] = (m_cregs[CR_PSR] & ~0xff000000) | (((val) & 0xff) << 24))
                    292: 
                    293: /* EPSR: WP bit (EPSR[14]):  set/get.  */
                    294: #define GET_EPSR_WP()  ((m_cregs[CR_EPSR] >> 14) & 1)
                    295: #define SET_EPSR_WP(val)  (m_cregs[CR_EPSR] = (m_cregs[CR_EPSR] & ~(1 << 14)) | (((val) & 1) << 14))
                    296: 
                    297: /* EPSR: INT bit (EPSR[17]):  set/get.  */
                    298: #define GET_EPSR_INT()  ((m_cregs[CR_EPSR] >> 17) & 1)
                    299: #define SET_EPSR_INT(val)  (m_cregs[CR_EPSR] = (m_cregs[CR_EPSR] & ~(1 << 17)) | (((val) & 1) << 17))
                    300: 
                    301: /* EPSR: OF flag (EPSR[24]):  set/get.  */
                    302: #define GET_EPSR_OF()  ((m_cregs[CR_EPSR] >> 24) & 1)
                    303: #define SET_EPSR_OF(val)  (m_cregs[CR_EPSR] = (m_cregs[CR_EPSR] & ~(1 << 24)) | (((val) & 1) << 24))
                    304: 
                    305: /* EPSR: BE flag (EPSR[23]):  set/get.  */
                    306: #define GET_EPSR_BE()  ((m_cregs[CR_EPSR] >> 23) & 1)
                    307: #define SET_EPSR_BE(val)  (m_cregs[CR_EPSR] = (m_cregs[CR_EPSR] & ~(1 << 23)) | (((val) & 1) << 23))
                    308: 
                    309: /* DIRBASE: ATE bit (DIRBASE[0]):  get.  */
                    310: #define GET_DIRBASE_ATE()  (m_cregs[CR_DIRBASE] & 1)
                    311: 
                    312: /* DIRBASE: CS8 bit (DIRBASE[7]):  get.  */
                    313: #define GET_DIRBASE_CS8()  ((m_cregs[CR_DIRBASE] >> 7) & 1)
                    314: 
                    315: /* DIRBASE: CS8 bit (DIRBASE[7]):  get.  */
                    316: #define GET_DIRBASE_ITI()  ((m_cregs[CR_DIRBASE] >> 5) & 1)
                    317: 
                    318: /* FSR: FTE bit (FSR[5]):  set/get.  */
                    319: #define GET_FSR_FTE()  ((m_cregs[CR_FSR] >> 5) & 1)
                    320: #define SET_FSR_FTE(val)  (m_cregs[CR_FSR] = (m_cregs[CR_FSR] & ~(1 << 5)) | (((val) & 1) << 5))
                    321: 
                    322: /* FSR: SE bit (FSR[8]):  set/get.  */
                    323: #define GET_FSR_SE()  ((m_cregs[CR_FSR] >> 8) & 1)
                    324: #define SET_FSR_SE(val)  (m_cregs[CR_FSR] = (m_cregs[CR_FSR] & ~(1 << 8)) | (((val) & 1) << 8))
                    325: 
                    326: /* FSR: SE bit (RM[3..2]):  set/get.  */
                    327: #define GET_FSR_RM()    ((m_cregs[CR_FSR] >> 2) & 3)
                    328: #define SET_FSR_RM(val) (m_cregs[CR_FSR] = (m_cregs[CR_FSR] & ~0xC) | (((val) & 3) << 2))
                    329: 
                    330: #define CLEAR_FLOW() (m_flow &= FLOW_CLEAR_MASK)
                    331: 
                    332: /* check for pending trap */
                    333: #define PENDING_TRAP() (m_flow & TRAP_MASK)
                    334: 
                    335: /* check for updated PC */
                    336: #define GET_PC_UPDATED() (m_flow & PC_UPDATED)
                    337: #define SET_PC_UPDATED() m_flow |= PC_UPDATED
                    338: 
                    339: /* access fault traps */
                    340: #define GET_EXITING_MEMRW()    (m_flow & EXITING_MEMRW)
                    341: #define SET_EXITING_MEMRW(val) (m_flow = (val) | (m_flow & ~EXITING_MEMRW))
                    342: 
                    343: const UINT32 INSN_NOP      = 0xA0000000;
                    344: const UINT32 INSN_DIM      = 0x00000200;
                    345: const UINT32 INSN_FNOP     = 0xB0000000;
                    346: const UINT32 INSN_FNOP_DIM = INSN_FNOP | INSN_DIM;
                    347: const UINT32 INSN_FP       = 0x48000000;
                    348: const UINT32 INSN_FP_DIM   = INSN_FP   | INSN_DIM;
                    349: const UINT32 INSN_MASK     = 0xFC000000;
                    350: const UINT32 INSN_MASK_DIM = INSN_MASK | INSN_DIM;
                    351: 
                    352: const size_t I860_ICACHE_SZ       = 9; // in powers of two lines (2^9 = 512; 512 x 2 words = 4 kbytes)
                    353: const size_t I860_ICACHE_MASK     = (1<<I860_ICACHE_SZ)-1;
                    354: const size_t I860_TLB_SZ          = 11; // in powers of two
                    355: const size_t I860_TLB_MASK        = (1<<I860_TLB_SZ)-1;
                    356: const size_t I860_PAGE_SZ         = 12; // in powers of two
                    357: const size_t I860_PAGE_OFF_MASK   = (1<<I860_PAGE_SZ)-1;
                    358: const size_t I860_PAGE_FRAME_MASK = ~I860_PAGE_OFF_MASK;
                    359: const size_t I860_TLB_FLAGS       = I860_PAGE_OFF_MASK;
                    360: 
                    361: /* Control register numbers.  */
                    362: enum {
                    363:     CR_FIR     = 0,
                    364:     CR_PSR     = 1,
                    365:     CR_DIRBASE = 2,
                    366:     CR_DB      = 3,
                    367:     CR_FSR     = 4,
                    368:     CR_EPSR    = 5
                    369: };
                    370: 
                    371: class i860_reg {
                    372:     UINT32        id;
                    373:     const char*   name;
                    374:     const char*   format;
                    375:     const UINT32* reg;
                    376: public:
                    377:     i860_reg() : id(0), name(0), format(0), reg(&id) {}
                    378:     
                    379:     bool valid() {
                    380:         return name;
                    381:     }
                    382:     
                    383:     void formatstr(const char* format) {
                    384:         this->format = format;
                    385:     }
                    386:     
                    387:     void set(int regId, const char* name, const UINT32 * reg) {
                    388:         this->id   = regId;
                    389:         this->name = name;
                    390:         this->reg  = reg;
                    391:     }
                    392:     
                    393:     UINT32 get() const {
                    394:         return *reg;
                    395:     }
                    396:     
                    397:     const char* get_name() {
                    398:         return name;
                    399:     }
                    400: };
                    401: 
                    402: class i860_cpu_device {
                    403: public:
                    404:        // construction/destruction
                    405:     i860_cpu_device();
                    406:     
                    407:     /* External interface */
                    408:     void send_msg(int msg);
                    409:     void init();
                    410:     void uninit();
                    411:     void halt(bool state);
1.1.1.2 ! root      412:     void pause(bool state);
1.1       root      413:     inline bool is_halted() {return m_halt;};
                    414: 
                    415:     /* Run one i860 cycle */
                    416:     void    run_cycle();
                    417:     /* Run the i860 thread */
                    418:     void run();
                    419:     /* i860 thread message handler */
                    420:     bool   handle_msgs();
1.1.1.2 ! root      421:     /* External interrupt for i860 emulator */
        !           422:     void   interrupt();
1.1       root      423:     
1.1.1.2 ! root      424:     const char* reports(double realTime, double hostTIme);
1.1       root      425: private:
                    426:     // debugger
                    427:     void debugger(char cmd, const char* format, ...);
                    428:     void debugger();
                    429:     
                    430:     /* Message port for host->i860 communication */
                    431:     volatile int m_port;
                    432:     lock_t       m_port_lock;
1.1.1.2 ! root      433:     thread_t*    m_thread;
1.1       root      434: 
                    435:     UINT64 m_insn_decoded;
                    436:     UINT64 m_icache_hit;
                    437:     UINT64 m_icache_miss;
                    438:     UINT64 m_icache_inval;
                    439:     UINT64 m_tlb_hit;
                    440:     UINT64 m_tlb_miss;
                    441:     UINT64 m_tlb_inval;
                    442:     UINT64 m_intrs;
1.1.1.2 ! root      443:     UINT32 m_last_rt;
        !           444:     UINT32 m_last_vt;
        !           445:     char   m_report[1024];
        !           446: 
1.1       root      447:     /* Debugger stuff */
                    448:     char   m_lastcmd;
1.1.1.2 ! root      449:     char   m_console[32*1024];
1.1       root      450:     int    m_console_idx;
                    451:     bool   m_break_on_next_msg;
                    452:     UINT32 m_traceback[256];
                    453:     int    m_traceback_idx;
                    454:     
                    455:     /* Program counter (1 x 32-bits).  Reset starts at pc=0xffffff00.  */
                    456:     UINT32 m_pc;
                    457: 
                    458:        /* Integer registers (32 x 32-bits).  */
                    459:        UINT32  m_iregs[32];
                    460:     
                    461:        /* Floating point registers (32 x 32-bits, 16 x 64 bits, or 8 x 128 bits).
                    462:           When referenced as pairs or quads, the higher numbered registers
                    463:           are the upper bits. E.g., double precision f0 is f1:f0.  */
                    464:        UINT8   m_fregs[32 * 4];
                    465: 
                    466:        /* Control registers (6 x 32-bits).  */
                    467:        UINT32 m_cregs[6];
                    468: 
                    469:     /* Dual instruction mode flags */
                    470:     int  m_dim;
                    471:     bool m_dim_cc;
                    472:     bool m_dim_cc_valid;
                    473:     int  m_save_dim;
                    474:     int  m_save_flow;
                    475:     bool m_save_cc;
                    476:     bool m_save_cc_valid;
                    477:     
                    478:        /* Special registers (4 x 64-bits).  */
                    479:        union
                    480:        {
1.1.1.2 ! root      481:                FLOAT32 s;
        !           482:                FLOAT64 d;
1.1       root      483:        } m_KR, m_KI, m_T;
                    484:     
                    485:        UINT64 m_merge;
                    486: 
                    487:        /* The adder pipeline, always 3 stages.  */
                    488:        struct
                    489:        {
                    490:                /* The stage contents.  */
                    491:                union {
1.1.1.2 ! root      492:                        FLOAT32 s;
        !           493:                        FLOAT64 d;
1.1       root      494:                } val;
                    495: 
                    496:                /* The stage status bits.  */
                    497:                struct {
                    498:                        /* Adder result precision (1 = dbl, 0 = sgl).  */
                    499:                        char arp;
                    500:                } stat;
                    501:        } m_A[3];
                    502: 
                    503:        /* The multiplier pipeline. 3 stages for single precision, 2 stages
                    504:           for double precision, and confusing for mixed precision.  */
                    505:        struct {
                    506:                /* The stage contents.  */
                    507:                union {
1.1.1.2 ! root      508:                        FLOAT32 s;
        !           509:                        FLOAT64 d;
1.1       root      510:                } val;
                    511: 
                    512:                /* The stage status bits.  */
                    513:                struct {
                    514:                        /* Multiplier result precision (1 = dbl, 0 = sgl).  */
                    515:                        char mrp;
                    516:                } stat;
                    517:        } m_M[3];
                    518: 
                    519:        /* The load pipeline, always 3 stages.  */
                    520:        struct {
                    521:                /* The stage contents.  */
                    522:                union {
1.1.1.2 ! root      523:                        FLOAT32 s;
        !           524:                        FLOAT64 d;
1.1       root      525:                } val;
                    526: 
                    527:                /* The stage status bits.  */
                    528:                struct {
                    529:                        /* Load result precision (1 = dbl, 0 = sgl).  */
                    530:                        char lrp;
                    531:                } stat;
                    532:        } m_L[3];
                    533: 
                    534:        /* The graphics/integer pipeline, always 1 stage.  */
                    535:        struct {
                    536:                /* The stage contents.  */
                    537:                union {
1.1.1.2 ! root      538:                        FLOAT32 s;
        !           539:                        FLOAT64 d;
1.1       root      540:                } val;
                    541: 
                    542:                /* The stage status bits.  */
                    543:                struct {
                    544:                        /* Integer/graphics result precision (1 = dbl, 0 = sgl).  */
                    545:                        char irp;
                    546:                } stat;
                    547:        } m_G;
                    548: 
                    549:     /* Instruction cache */
                    550:     UINT64 m_icache[1<<I860_ICACHE_SZ];
                    551:     UINT32 m_icache_vaddr[1<<I860_ICACHE_SZ];
                    552:     
                    553:     /* Translation look-aside buffer */
                    554:     UINT32 m_tlb_vaddr[1<<I860_TLB_SZ];
                    555:     UINT32 m_tlb_paddr[1<<I860_TLB_SZ];
                    556:     
                    557:        /*
                    558:         * Halt state. Can be set externally
                    559:         */
                    560:     volatile bool m_halt;
                    561:     
                    562:        /* Indicate an instruction just generated a trap,
                    563:      needs to go to the trap address or a control-flow 
                    564:      instruction, so we know the PC is updated.  */
                    565:        UINT32 m_flow;
                    566:     
                    567:     /* Single stepping state - for internal use.  */
                    568:     UINT32 m_single_stepping;
                    569: 
                    570:     /* memory access */
                    571:     mem_rd_func rdmem[17];
                    572:     mem_wr_func wrmem[17];
                    573:     
                    574:     void   set_mem_access(bool be);
                    575:     UINT8  rdcs8(UINT32 addr);
1.1.1.2 ! root      576:        inline void   writemem_emu(UINT32 addr, int size, UINT8 *data);
        !           577:        inline void   writemem_emu(UINT32 addr, int size, UINT8 *data, UINT32 wmask);
        !           578:     inline void   readmem_emu (UINT32 addr, int size, UINT8 *data);
1.1       root      579: 
                    580:     /* instructions */
                    581:        void insn_ld_ctrl (UINT32 insn);
                    582:        void insn_st_ctrl (UINT32 insn);
                    583:        void insn_ldx (UINT32 insn);
                    584:        void insn_stx (UINT32 insn);
                    585:        void insn_fsty (UINT32 insn);
                    586:        void insn_fldy (UINT32 insn);
                    587:        void insn_pstd (UINT32 insn);
                    588:        void insn_ixfr (UINT32 insn);
                    589:        void insn_addu (UINT32 insn);
                    590:        void insn_addu_imm (UINT32 insn);
                    591:        void insn_adds (UINT32 insn);
                    592:        void insn_adds_imm (UINT32 insn);
                    593:        void insn_subu (UINT32 insn);
                    594:        void insn_subu_imm (UINT32 insn);
                    595:        void insn_subs (UINT32 insn);
                    596:        void insn_subs_imm (UINT32 insn);
                    597:        void insn_shl (UINT32 insn);
                    598:        void insn_shl_imm (UINT32 insn);
                    599:        void insn_shr (UINT32 insn);
                    600:        void insn_shr_imm (UINT32 insn);
                    601:        void insn_shra (UINT32 insn);
                    602:        void insn_shra_imm (UINT32 insn);
                    603:        void insn_shrd (UINT32 insn);
                    604:        void insn_and (UINT32 insn);
                    605:        void insn_and_imm (UINT32 insn);
                    606:        void insn_andh_imm (UINT32 insn);
                    607:        void insn_andnot (UINT32 insn);
                    608:        void insn_andnot_imm (UINT32 insn);
                    609:        void insn_andnoth_imm (UINT32 insn);
                    610:        void insn_or (UINT32 insn);
                    611:        void insn_or_imm (UINT32 insn);
                    612:        void insn_orh_imm (UINT32 insn);
                    613:        void insn_xor (UINT32 insn);
                    614:        void insn_xor_imm (UINT32 insn);
                    615:        void insn_xorh_imm (UINT32 insn);
                    616:        void insn_trap (UINT32 insn);
                    617:        void insn_intovr (UINT32 insn);
                    618:        void insn_bte (UINT32 insn);
                    619:        void insn_bte_imm (UINT32 insn);
                    620:        void insn_btne (UINT32 insn);
                    621:        void insn_btne_imm (UINT32 insn);
                    622:        void insn_bc (UINT32 insn);
                    623:        void insn_bnc (UINT32 insn);
                    624:        void insn_bct (UINT32 insn);
                    625:        void insn_bnct (UINT32 insn);
                    626:        void insn_call (UINT32 insn);
                    627:        void insn_br (UINT32 insn);
                    628:        void insn_bri (UINT32 insn);
                    629:        void insn_calli (UINT32 insn);
                    630:        void insn_bla (UINT32 insn);
                    631:        void insn_flush (UINT32 insn);
                    632:        void insn_fmul (UINT32 insn);
                    633:        void insn_fmlow (UINT32 insn);
                    634:        void insn_fadd_sub (UINT32 insn);
                    635:        void insn_dualop (UINT32 insn);
                    636:        void insn_frcp (UINT32 insn);
                    637:        void insn_frsqr (UINT32 insn);
                    638:        void insn_fxfr (UINT32 insn);
                    639:        void insn_ftrunc (UINT32 insn);
                    640:     void insn_fix (UINT32 insn);
                    641:        void insn_famov (UINT32 insn);
                    642:        void insn_fiadd_sub (UINT32 insn);
                    643:        void insn_fcmp (UINT32 insn);
                    644:        void insn_fzchk (UINT32 insn);
                    645:        void insn_form (UINT32 insn);
                    646:        void insn_faddp (UINT32 insn);
                    647:        void insn_faddz (UINT32 insn);
1.1.1.2 ! root      648: 
        !           649:     void dec_unrecog (UINT32 insn);
        !           650: 
1.1       root      651:     /* register access */
                    652:     UINT32 get_iregval(int gr);
                    653:     void   set_iregval(int gr, UINT32 val);
1.1.1.2 ! root      654:     FLOAT32  get_fregval_s (int fr);
        !           655:     void   set_fregval_s (int fr, FLOAT32 s);
        !           656:     FLOAT64 get_fregval_d (int fr);
        !           657:     void   set_fregval_d (int fr, FLOAT64 d);
1.1       root      658:     void   SET_PSR_CC(int val);
                    659:     
                    660:     void   invalidate_icache();
                    661:     void   invalidate_tlb();
1.1.1.2 ! root      662:     inline UINT64 ifetch64(const UINT32 pc);
        !           663:     UINT64 ifetch64(const UINT32 pc, const UINT32 vaddr, int const cidx);
1.1       root      664:     UINT32 ifetch(const UINT32 pc);
                    665:     UINT32 ifetch_notrap(const UINT32 pc);
                    666:     void   handle_trap(UINT32 savepc);
                    667:     void   ret_from_trap();
                    668:     void   unrecog_opcode (UINT32 pc, UINT32 insn);
                    669:     
                    670:     void   decode_exec (UINT32 insn);
                    671:     void   dump_pipe (int type);
                    672:     void   dump_state ();
                    673:        UINT32 disasm (UINT32 addr, int len);
                    674:     offs_t disasm(char* buffer, offs_t pc);
1.1.1.2 ! root      675:        void   dbg_memdump (UINT32 addr, int len);
1.1       root      676:        int    delay_slots(UINT32 insn);
1.1.1.2 ! root      677:        UINT32 get_address_translation(UINT32 vaddr, int is_dataref, int is_write);
        !           678:     inline UINT32 get_address_translation(UINT32 vaddr, UINT32 voffset, UINT32 tlbidx, int is_dataref, int is_write);
        !           679:        FLOAT32  get_fval_from_optype_s (UINT32 insn, int optype);
        !           680:        FLOAT64 get_fval_from_optype_d (UINT32 insn, int optype);
1.1       root      681:     int    memtest(bool be);
                    682:     void   dbg_check_wr(UINT32 addr, int size, UINT8* data);
                    683:     
                    684:     /* This is theinterface for asserting an external interrupt to the i860.  */
                    685:     void gen_interrupt();
                    686:     /* This is the interface for clearing an external interrupt of the i860.  */
                    687:     void clr_interrupt();
                    688:     /* This is the interface for reseting the i860.  */
                    689:     void reset();
                    690:     void intr();
                    691: 
                    692:        typedef void (i860_cpu_device::*insn_func)(UINT32);
1.1.1.2 ! root      693:        static const insn_func decode_tbl[64];
        !           694:        static const insn_func core_esc_decode_tbl[8];
        !           695:        static const insn_func fp_decode_tbl[128];
        !           696:     static       insn_func decoder_tbl[8192];
1.1       root      697: };
                    698: 
                    699: /* disassembler */
                    700: int i860_disassembler(UINT32 pc, UINT32 insn, char* buffer);
                    701: 
                    702: #endif /* __I860_H__ */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.