Viewing File: <root>/src/emu/cpu/tms32031/tms32031.c

    1  /***************************************************************************
    2  
    3      tms32031.c
    4  
    5      TMS32031/2 emulator
    6  
    7  ****************************************************************************
    8  
    9      Copyright Aaron Giles
   10      All rights reserved.
   11  
   12      Redistribution and use in source and binary forms, with or without
   13      modification, are permitted provided that the following conditions are
   14      met:
   15  
   16          * Redistributions of source code must retain the above copyright
   17            notice, this list of conditions and the following disclaimer.
   18          * Redistributions in binary form must reproduce the above copyright
   19            notice, this list of conditions and the following disclaimer in
   20            the documentation and/or other materials provided with the
   21            distribution.
   22          * Neither the name 'MAME' nor the names of its contributors may be
   23            used to endorse or promote products derived from this software
   24            without specific prior written permission.
   25  
   26      THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
   27      IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   28      WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   29      DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
   30      INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   31      (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   32      SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   33      HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   34      STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
   35      IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36      POSSIBILITY OF SUCH DAMAGE.
   37  
   38  ***************************************************************************/
   39  
   40  #include "emu.h"
   41  #include "debugger.h"
   42  #include "tms32031.h"
   43  
   44  
   45  //**************************************************************************
   46  //  CONSTANTS
   47  //**************************************************************************
   48  
   49  // indexes into the register file
   50  enum
   51  {
   52      TMR_R0 = 0,
   53      TMR_R1,
   54      TMR_R2,
   55      TMR_R3,
   56      TMR_R4,
   57      TMR_R5,
   58      TMR_R6,
   59      TMR_R7,
   60      TMR_AR0,
   61      TMR_AR1,
   62      TMR_AR2,
   63      TMR_AR3,
   64      TMR_AR4,
   65      TMR_AR5,
   66      TMR_AR6,
   67      TMR_AR7,
   68      TMR_DP,
   69      TMR_IR0,
   70      TMR_IR1,
   71      TMR_BK,
   72      TMR_SP,
   73      TMR_ST,
   74      TMR_IE,
   75      TMR_IF,
   76      TMR_IOF,
   77      TMR_RS,
   78      TMR_RE,
   79      TMR_RC,
   80      TMR_R8,     // 3204x only
   81      TMR_R9,     // 3204x only
   82      TMR_R10,    // 3204x only
   83      TMR_R11,    // 3204x only
   84      TMR_TEMP1,  // used by the interpreter
   85      TMR_TEMP2,  // used by the interpreter
   86      TMR_TEMP3   // used by the interpreter
   87  };
   88  
   89  // flags
   90  const int CFLAG     = 0x0001;
   91  const int VFLAG     = 0x0002;
   92  const int ZFLAG     = 0x0004;
   93  const int NFLAG     = 0x0008;
   94  const int UFFLAG    = 0x0010;
   95  const int LVFLAG    = 0x0020;
   96  const int LUFFLAG   = 0x0040;
   97  const int OVMFLAG   = 0x0080;
   98  const int RMFLAG    = 0x0100;
   99  const int CFFLAG    = 0x0400;
  100  const int CEFLAG    = 0x0800;
  101  const int CCFLAG    = 0x1000;
  102  const int GIEFLAG   = 0x2000;
  103  
  104  
  105  
  106  //**************************************************************************
  107  //  MACROS
  108  //**************************************************************************
  109  
  110  #define IREG(rnum)  (m_r[rnum].i32[0])
  111  
  112  
  113  
  114  //**************************************************************************
  115  //  GLOBAL VARIABLES
  116  //**************************************************************************
  117  
  118  // device type definition
  119  const device_type TMS32031 = &device_creator<tms32031_device>;
  120  const device_type TMS32032 = &device_creator<tms32032_device>;
  121  
  122  
  123  // internal memory maps
  124  static ADDRESS_MAP_START( internal_32031, AS_PROGRAM, 32, tms32031_device )
  125      AM_RANGE(0x809800, 0x809fff) AM_RAM
  126  ADDRESS_MAP_END
  127  
  128  static ADDRESS_MAP_START( internal_32032, AS_PROGRAM, 32, tms32032_device )
  129      AM_RANGE(0x87fe00, 0x87ffff) AM_RAM
  130  ADDRESS_MAP_END
  131  
  132  
  133  // ROM definitions for the internal boot loader programs
  134  // (Using assembled versions until the code ROMs are extracted from both DSPs)
  135  ROM_START( tms32031 )
  136      ROM_REGION(0x4000, "tms32031", 0)
  137      ROM_LOAD( "c31boot.bin", 0x0000, 0x4000, BAD_DUMP CRC(bddc2763) SHA1(96b2170ecee5bec5abaa1741bb2d3b6096ecc262) ) // Assembled from c31boot.asm (02-07-92)
  138  ROM_END
  139  
  140  ROM_START( tms32032 )
  141      ROM_REGION(0x4000, "tms32032", 0)
  142      ROM_LOAD( "c32boot.bin", 0x0000, 0x4000, BAD_DUMP CRC(ecf84729) SHA1(4d32ead450f921f563514b061ea561a222283616) ) // Assembled from c32boot.asm (03-04-96)
  143  ROM_END
  144  
  145  
  146  
  147  //**************************************************************************
  148  //  TMSREG REGISTER
  149  //**************************************************************************
  150  
  151  //-------------------------------------------------
  152  //  as_float - interpret the contents of a tmsreg
  153  //  as a DSP-encoded floating-point value, and
  154  //  extract a 32-bit IEEE float from it
  155  //-------------------------------------------------
  156  
  157  float tms3203x_device::tmsreg::as_float() const
  158  {
  159      int_double id;
  160  
  161      // map 0 to 0
  162      if (mantissa() == 0 && exponent() == -128)
  163          return 0;
  164  
  165      // handle positive numbers
  166      else if (mantissa() >= 0)
  167      {
  168          int exp = (exponent() + 127) << 23;
  169          id.i[0] = exp + (mantissa() >> 8);
  170      }
  171  
  172      // handle negative numbers
  173      else
  174      {
  175          int exp = (exponent() + 127) << 23;
  176          INT32 man = -mantissa();
  177          id.i[0] = 0x80000000 + exp + ((man >> 8) & 0x00ffffff);
  178      }
  179  
  180      // return the converted float
  181      return id.f[0];
  182  }
  183  
  184  
  185  //-------------------------------------------------
  186  //  as_double - interpret the contents of a tmsreg
  187  //  as a DSP-encoded floating-point value, and
  188  //  extract a 64-bit IEEE double from it
  189  //-------------------------------------------------
  190  
  191  double tms3203x_device::tmsreg::as_double() const
  192  {
  193      int_double id;
  194  
  195      // map 0 to 0
  196      if (mantissa() == 0 && exponent() == -128)
  197          return 0;
  198  
  199      // handle positive numbers
  200      else if (mantissa() >= 0)
  201      {
  202          int exp = (exponent() + 1023) << 20;
  203          id.i[BYTE_XOR_BE(0)] = exp + (mantissa() >> 11);
  204          id.i[BYTE_XOR_BE(1)] = (mantissa() << 21) & 0xffe00000;
  205      }
  206  
  207      // handle negative numbers
  208      else
  209      {
  210          int exp = (exponent() + 1023) << 20;
  211          INT32 man = -mantissa();
  212          id.i[BYTE_XOR_BE(0)] = 0x80000000 + exp + ((man >> 11) & 0x001fffff);
  213          id.i[BYTE_XOR_BE(1)] = (man << 21) & 0xffe00000;
  214      }
  215  
  216      // return the converted double
  217      return id.d;
  218  }
  219  
  220  
  221  //-------------------------------------------------
  222  //  from_double - import a 64-bit IEEE double into
  223  //  the DSP's internal floating point format
  224  //-------------------------------------------------
  225  
  226  void tms3203x_device::tmsreg::from_double(double val)
  227  {
  228      // extract mantissa and exponent from the IEEE input
  229      int_double id;
  230      id.d = val;
  231      INT32 mantissa = ((id.i[BYTE_XOR_BE(0)] & 0x000fffff) << 11) | ((id.i[BYTE_XOR_BE(1)] & 0xffe00000) >> 21);
  232      INT32 exponent = ((id.i[BYTE_XOR_BE(0)] & 0x7ff00000) >> 20) - 1023;
  233  
  234      // if we're too small, map to 0
  235      if (exponent < -128)
  236      {
  237          set_mantissa(0);
  238          set_exponent(-128);
  239      }
  240  
  241      // if we're too large, map to the maximum value
  242      else if (exponent > 127)
  243      {
  244          if ((INT32)id.i[BYTE_XOR_BE(0)] >= 0)
  245              set_mantissa(0x7fffffff);
  246          else
  247              set_mantissa(0x80000001);
  248          set_exponent(127);
  249      }
  250  
  251      // if we're positive, map directly
  252      else if ((INT32)id.i[BYTE_XOR_BE(0)] >= 0)
  253      {
  254          set_mantissa(mantissa);
  255          set_exponent(exponent);
  256      }
  257  
  258      // if we're negative with a non-zero mantissa, remove the leading sign bit
  259      else if (mantissa != 0)
  260      {
  261          set_mantissa(0x80000000 | -mantissa);
  262          set_exponent(exponent);
  263      }
  264  
  265      // if we're negative with a zero mantissa, normalize
  266      else
  267      {
  268          set_mantissa(0x80000000);
  269          set_exponent(exponent - 1);
  270      }
  271  }
  272  
  273  
  274  
  275  //**************************************************************************
  276  //  DEVICE INTERFACE
  277  //**************************************************************************
  278  
  279  //-------------------------------------------------
  280  //  tms3203x_device - constructor
  281  //-------------------------------------------------
  282  
  283  tms3203x_device::tms3203x_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT32 chiptype, address_map_constructor internal_map)
  284      : cpu_device(mconfig, type, name, tag, owner, clock),
  285          m_program_config("program", ENDIANNESS_LITTLE, 32, 24, -2, internal_map),
  286          m_chip_type(chiptype),
  287          m_pc(0),
  288          m_bkmask(0),
  289          m_irq_state(0),
  290          m_delayed(false),
  291          m_irq_pending(false),
  292          m_is_idling(false),
  293          m_icount(0),
  294          m_irq_callback(0),
  295          m_program(0),
  296          m_direct(0)
  297  {
  298      m_mcbl_mode = false;
  299      m_xf0_w = NULL;
  300      m_xf1_w = NULL;
  301      m_iack_w = NULL;
  302  
  303      // initialize remaining state
  304      memset(&m_r, 0, sizeof(m_r));
  305  
  306      // set our instruction counter
  307      m_icountptr = &m_icount;
  308  
  309  #if (TMS_3203X_LOG_OPCODE_USAGE)
  310      memset(m_hits, 0, sizeof(m_hits));
  311  #endif
  312  }
  313  
  314  tms32031_device::tms32031_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
  315      : tms3203x_device(mconfig, TMS32031, "TMS32031", tag, owner, clock, CHIP_TYPE_TMS32031, ADDRESS_MAP_NAME(internal_32031))
  316  {
  317      m_shortname = "tms32031";
  318  }
  319  
  320  tms32032_device::tms32032_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
  321      : tms3203x_device(mconfig, TMS32032, "TMS32032", tag, owner, clock, CHIP_TYPE_TMS32032, ADDRESS_MAP_NAME(internal_32032))
  322  {
  323      m_shortname = "tms32032";
  324  }
  325  
  326  
  327  DIRECT_UPDATE_MEMBER( tms3203x_device::direct_handler )
  328  {
  329      // internal boot loader ROM
  330      if (m_mcbl_mode && address < (0x1000 << 2))
  331      {
  332          direct.explicit_configure(0x000000, 0x003fff, 0x003fff, m_bootrom);
  333          return (offs_t)-1;
  334      }
  335  
  336      return address;
  337  }
  338  
  339  
  340  //-------------------------------------------------
  341  //  ~tms3203x_device - destructor
  342  //-------------------------------------------------
  343  
  344  tms3203x_device::~tms3203x_device()
  345  {
  346  #if (TMS_3203X_LOG_OPCODE_USAGE)
  347      for (int i = 0; i < ARRAY_LENGTH(m_hits); i++)
  348          if (m_hits[i] != 0)
  349              printf("%10d - %03X.%X\n", m_hits[i], i / 4, i % 4);
  350  #endif
  351  }
  352  
  353  
  354  //-------------------------------------------------
  355  //  static_set_config - set the configuration
  356  //  structure
  357  //-------------------------------------------------
  358  
  359  void tms3203x_device::static_set_config(device_t &device, const tms3203x_config &config)
  360  {
  361      tms3203x_device &tms = downcast<tms3203x_device &>(device);
  362      static_cast<tms3203x_config &>(tms) = config;
  363  }
  364  
  365  
  366  //-------------------------------------------------
  367  //  rom_region - return a pointer to the device's
  368  //  internal ROM region
  369  //-------------------------------------------------
  370  
  371  const rom_entry *tms3203x_device::device_rom_region() const
  372  {
  373      switch (m_chip_type)
  374      {
  375          default:
  376          case CHIP_TYPE_TMS32031:    return ROM_NAME( tms32031 );
  377          case CHIP_TYPE_TMS32032:    return ROM_NAME( tms32032 );
  378      }
  379  }
  380  
  381  //-------------------------------------------------
  382  //  ROPCODE - fetch an opcode
  383  //-------------------------------------------------
  384  
  385  inline UINT32 tms3203x_device::ROPCODE(offs_t pc)
  386  {
  387      return m_direct->read_decrypted_dword(pc << 2);
  388  }
  389  
  390  
  391  //-------------------------------------------------
  392  //  RMEM - read memory
  393  //-------------------------------------------------
  394  
  395  inline UINT32 tms3203x_device::RMEM(offs_t addr)
  396  {
  397      if (m_mcbl_mode && addr < 0x1000)
  398          return m_bootrom[addr];
  399  
  400      return m_program->read_dword(addr << 2);
  401  }
  402  
  403  
  404  //-------------------------------------------------
  405  //  WMEM - write memory
  406  //-------------------------------------------------
  407  
  408  inline void tms3203x_device::WMEM(offs_t addr, UINT32 data)
  409  {
  410      m_program->write_dword(addr << 2, data);
  411  }
  412  
  413  
  414  //-------------------------------------------------
  415  //  device_start - start up the device
  416  //-------------------------------------------------
  417  
  418  void tms3203x_device::device_start()
  419  {
  420      // find address spaces
  421      m_program = &space(AS_PROGRAM);
  422      m_direct = &m_program->direct();
  423  
  424      // set up the internal boot loader ROM
  425      m_bootrom = reinterpret_cast<UINT32*>(memregion(m_shortname)->base());
  426      m_direct->set_direct_update(direct_update_delegate(FUNC(tms3203x_device::direct_handler), this));
  427  
  428      // save state
  429      save_item(NAME(m_pc));
  430      for (int regnum = 0; regnum < 36; regnum++)
  431          save_item(NAME(m_r[regnum].i32), regnum);
  432      save_item(NAME(m_bkmask));
  433      save_item(NAME(m_irq_state));
  434      save_item(NAME(m_delayed));
  435      save_item(NAME(m_irq_pending));
  436      save_item(NAME(m_is_idling));
  437  
  438      // register our state for the debugger
  439      state_add(TMS3203X_PC,      "PC",        m_pc);
  440      state_add(STATE_GENPC,      "GENPC",     m_pc).noshow();
  441      state_add(STATE_GENFLAGS,   "GENFLAGS",  m_r[TMR_ST].i32[0]).mask(0xff).noshow().formatstr("%8s");
  442      state_add(TMS3203X_R0,      "R0",        m_r[TMR_R0].i32[0]);
  443      state_add(TMS3203X_R1,      "R1",        m_r[TMR_R1].i32[0]);
  444      state_add(TMS3203X_R2,      "R2",        m_r[TMR_R2].i32[0]);
  445      state_add(TMS3203X_R3,      "R3",        m_r[TMR_R3].i32[0]);
  446      state_add(TMS3203X_R4,      "R4",        m_r[TMR_R4].i32[0]);
  447      state_add(TMS3203X_R5,      "R5",        m_r[TMR_R5].i32[0]);
  448      state_add(TMS3203X_R6,      "R6",        m_r[TMR_R6].i32[0]);
  449      state_add(TMS3203X_R7,      "R7",        m_r[TMR_R7].i32[0]);
  450      state_add(TMS3203X_R0F,     "R0F",       m_iotemp).callimport().callexport().formatstr("%12s");
  451      state_add(TMS3203X_R1F,     "R1F",       m_iotemp).callimport().callexport().formatstr("%12s");
  452      state_add(TMS3203X_R2F,     "R2F",       m_iotemp).callimport().callexport().formatstr("%12s");
  453      state_add(TMS3203X_R3F,     "R3F",       m_iotemp).callimport().callexport().formatstr("%12s");
  454      state_add(TMS3203X_R4F,     "R4F",       m_iotemp).callimport().callexport().formatstr("%12s");
  455      state_add(TMS3203X_R5F,     "R5F",       m_iotemp).callimport().callexport().formatstr("%12s");
  456      state_add(TMS3203X_R6F,     "R6F",       m_iotemp).callimport().callexport().formatstr("%12s");
  457      state_add(TMS3203X_R7F,     "R7F",       m_iotemp).callimport().callexport().formatstr("%12s");
  458      state_add(TMS3203X_AR0,     "AR0",       m_r[TMR_AR0].i32[0]);
  459      state_add(TMS3203X_AR1,     "AR1",       m_r[TMR_AR1].i32[0]);
  460      state_add(TMS3203X_AR2,     "AR2",       m_r[TMR_AR2].i32[0]);
  461      state_add(TMS3203X_AR3,     "AR3",       m_r[TMR_AR3].i32[0]);
  462      state_add(TMS3203X_AR4,     "AR4",       m_r[TMR_AR4].i32[0]);
  463      state_add(TMS3203X_AR5,     "AR5",       m_r[TMR_AR5].i32[0]);
  464      state_add(TMS3203X_AR6,     "AR6",       m_r[TMR_AR6].i32[0]);
  465      state_add(TMS3203X_AR7,     "AR7",       m_r[TMR_AR7].i32[0]);
  466      state_add(TMS3203X_DP,      "DP",        m_r[TMR_DP].i32[0]).mask(0xff);
  467      state_add(TMS3203X_IR0,     "IR0",       m_r[TMR_IR0].i32[0]);
  468      state_add(TMS3203X_IR1,     "IR1",       m_r[TMR_IR1].i32[0]);
  469      state_add(TMS3203X_BK,      "BK",        m_r[TMR_BK].i32[0]);
  470      state_add(TMS3203X_SP,      "SP",        m_r[TMR_SP].i32[0]);
  471      state_add(TMS3203X_ST,      "ST",        m_r[TMR_ST].i32[0]);
  472      state_add(TMS3203X_IE,      "IE",        m_r[TMR_IE].i32[0]);
  473      state_add(TMS3203X_IF,      "IF",        m_r[TMR_IF].i32[0]);
  474      state_add(TMS3203X_IOF,     "IOF",       m_r[TMR_IOF].i32[0]);
  475      state_add(TMS3203X_RS,      "RS",        m_r[TMR_RS].i32[0]);
  476      state_add(TMS3203X_RE,      "RE",        m_r[TMR_RE].i32[0]);
  477      state_add(TMS3203X_RC,      "RC",        m_r[TMR_RC].i32[0]);
  478  }
  479  
  480  
  481  //-------------------------------------------------
  482  //  device_reset - reset the device
  483  //-------------------------------------------------
  484  
  485  void tms3203x_device::device_reset()
  486  {
  487      m_pc = RMEM(0);
  488  
  489      // reset some registers
  490      IREG(TMR_IE) = 0;
  491      IREG(TMR_IF) = 0;
  492      IREG(TMR_ST) = 0;
  493      IREG(TMR_IOF) = 0;
  494  
  495      // update IF with the external interrupt state (required for boot loader operation)
  496      IREG(TMR_IF) |= m_irq_state & 0x0f;
  497  
  498      // reset internal stuff
  499      m_delayed = m_irq_pending = m_is_idling = false;
  500  }
  501  
  502  
  503  //-------------------------------------------------
  504  //  memory_space_config - return the configuration
  505  //  of the specified address space, or NULL if
  506  //  the space doesn't exist
  507  //-------------------------------------------------
  508  
  509  const address_space_config *tms3203x_device::memory_space_config(address_spacenum spacenum) const
  510  {
  511      return (spacenum == AS_PROGRAM) ? &m_program_config : NULL;
  512  }
  513  
  514  
  515  //-------------------------------------------------
  516  //  state_import - import state into the device,
  517  //  after it has been set
  518  //-------------------------------------------------
  519  
  520  void tms3203x_device::state_import(const device_state_entry &entry)
  521  {
  522      switch (entry.index())
  523      {
  524          case TMS3203X_R0F:
  525          case TMS3203X_R1F:
  526          case TMS3203X_R2F:
  527          case TMS3203X_R3F:
  528          case TMS3203X_R4F:
  529          case TMS3203X_R5F:
  530          case TMS3203X_R6F:
  531          case TMS3203X_R7F:
  532              m_r[TMR_R0 + (entry.index() - TMS3203X_R0F)].from_double(*(float *)&m_iotemp);
  533              break;
  534  
  535          default:
  536              fatalerror("CPU_IMPORT_STATE(tms3203x) called for unexpected value\n");
  537              break;
  538      }
  539  }
  540  
  541  
  542  //-------------------------------------------------
  543  //  state_export - export state into the device,
  544  //  before returning it to the caller
  545  //-------------------------------------------------
  546  
  547  void tms3203x_device::state_export(const device_state_entry &entry)
  548  {
  549      switch (entry.index())
  550      {
  551          case TMS3203X_R0F:
  552          case TMS3203X_R1F:
  553          case TMS3203X_R2F:
  554          case TMS3203X_R3F:
  555          case TMS3203X_R4F:
  556          case TMS3203X_R5F:
  557          case TMS3203X_R6F:
  558          case TMS3203X_R7F:
  559              *(float *)&m_iotemp = m_r[TMR_R0 + (entry.index() - TMS3203X_R0F)].as_float();
  560              break;
  561  
  562          default:
  563              fatalerror("CPU_IMPORT_STATE(tms3203x) called for unexpected value\n");
  564              break;
  565      }
  566  }
  567  
  568  
  569  //-------------------------------------------------
  570  //  state_string_export - export state as a string
  571  //  for the debugger
  572  //-------------------------------------------------
  573  
  574  void tms3203x_device::state_string_export(const device_state_entry &entry, astring &string)
  575  {
  576      switch (entry.index())
  577      {
  578          case TMS3203X_R0F:
  579          case TMS3203X_R1F:
  580          case TMS3203X_R2F:
  581          case TMS3203X_R3F:
  582          case TMS3203X_R4F:
  583          case TMS3203X_R5F:
  584          case TMS3203X_R6F:
  585          case TMS3203X_R7F:
  586              string.printf("%12g", m_r[TMR_R0 + (entry.index() - TMS3203X_R0F)].as_double());
  587              break;
  588  
  589          case STATE_GENFLAGS:
  590              UINT32 temp = m_r[TMR_ST].i32[0];
  591              string.printf("%c%c%c%c%c%c%c%c",
  592                  (temp & 0x80) ? 'O':'.',
  593                  (temp & 0x40) ? 'U':'.',
  594                  (temp & 0x20) ? 'V':'.',
  595                  (temp & 0x10) ? 'u':'.',
  596                  (temp & 0x08) ? 'n':'.',
  597                  (temp & 0x04) ? 'z':'.',
  598                  (temp & 0x02) ? 'v':'.',
  599                  (temp & 0x01) ? 'c':'.');
  600              break;
  601      }
  602  }
  603  
  604  
  605  //-------------------------------------------------
  606  //  disasm_min_opcode_bytes - return the length
  607  //  of the shortest instruction, in bytes
  608  //-------------------------------------------------
  609  
  610  UINT32 tms3203x_device::disasm_min_opcode_bytes() const
  611  {
  612      return 4;
  613  }
  614  
  615  
  616  //-------------------------------------------------
  617  //  disasm_max_opcode_bytes - return the length
  618  //  of the longest instruction, in bytes
  619  //-------------------------------------------------
  620  
  621  UINT32 tms3203x_device::disasm_max_opcode_bytes() const
  622  {
  623      return 4;
  624  }
  625  
  626  
  627  //-------------------------------------------------
  628  //  disasm_disassemble - call the disassembly
  629  //  helper function
  630  //-------------------------------------------------
  631  
  632  offs_t tms3203x_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
  633  {
  634      extern CPU_DISASSEMBLE( tms3203x );
  635      return CPU_DISASSEMBLE_NAME(tms3203x)(NULL, buffer, pc, oprom, opram, 0);
  636  }
  637  
  638  
  639  
  640  //**************************************************************************
  641  //  PUBLIC INTERFACES
  642  //**************************************************************************
  643  
  644  //-------------------------------------------------
  645  //  fp_to_float - convert a 32-bit value from DSP
  646  //  floating-point format a 32-bit IEEE float
  647  //-------------------------------------------------
  648  
  649  float tms3203x_device::fp_to_float(UINT32 floatdata)
  650  {
  651      tmsreg gen(floatdata << 8, (INT32)floatdata >> 24);
  652      return gen.as_float();
  653  }
  654  
  655  
  656  //-------------------------------------------------
  657  //  fp_to_double - convert a 32-bit value from DSP
  658  //  floating-point format a 64-bit IEEE double
  659  //-------------------------------------------------
  660  
  661  double tms3203x_device::fp_to_double(UINT32 floatdata)
  662  {
  663      tmsreg gen(floatdata << 8, (INT32)floatdata >> 24);
  664      return gen.as_double();
  665  }
  666  
  667  
  668  //-------------------------------------------------
  669  //  float_to_fp - convert a 32-bit IEEE float to
  670  //  a 32-bit DSP floating-point value
  671  //-------------------------------------------------
  672  
  673  UINT32 tms3203x_device::float_to_fp(float fval)
  674  {
  675      tmsreg gen(fval);
  676      return (gen.exponent() << 24) | ((UINT32)gen.mantissa() >> 8);
  677  }
  678  
  679  
  680  //-------------------------------------------------
  681  //  double_to_fp - convert a 64-bit IEEE double to
  682  //  a 32-bit DSP floating-point value
  683  //-------------------------------------------------
  684  
  685  UINT32 tms3203x_device::double_to_fp(double dval)
  686  {
  687      tmsreg gen(dval);
  688      return (gen.exponent() << 24) | ((UINT32)gen.mantissa() >> 8);
  689  }
  690  
  691  
  692  
  693  //**************************************************************************
  694  //  EXECUTION
  695  //**************************************************************************
  696  
  697  //-------------------------------------------------
  698  //  check_irqs - check for pending IRQs and take
  699  //  them if enabled
  700  //-------------------------------------------------
  701  
  702  void tms3203x_device::check_irqs()
  703  {
  704      // determine if we have any live interrupts
  705      UINT16 validints = IREG(TMR_IF) & IREG(TMR_IE) & 0x0fff;
  706      if (validints == 0 || (IREG(TMR_ST) & GIEFLAG) == 0)
  707          return;
  708  
  709      // find the lowest signalled value
  710      int whichtrap = 0;
  711      for (int i = 0; i < 12; i++)
  712          if (validints & (1 << i))
  713          {
  714              whichtrap = i + 1;
  715              break;
  716          }
  717  
  718      // no longer idling if we get here
  719      m_is_idling = false;
  720      if (!m_delayed)
  721      {
  722          UINT16 intmask = 1 << (whichtrap - 1);
  723  
  724          // bit in IF is cleared when interrupt is taken
  725          IREG(TMR_IF) &= ~intmask;
  726          trap(whichtrap);
  727  
  728          // after auto-clearing the interrupt bit, we need to re-trigger
  729          // level-sensitive interrupts
  730          if (m_chip_type == CHIP_TYPE_TMS32031 || (IREG(TMR_ST) & 0x4000) == 0)
  731              IREG(TMR_IF) |= m_irq_state & 0x0f;
  732      }
  733      else
  734          m_irq_pending = true;
  735  }
  736  
  737  
  738  //-------------------------------------------------
  739  //  execute_min_cycles - return minimum number of
  740  //  cycles it takes for one instruction to execute
  741  //-------------------------------------------------
  742  
  743  UINT32 tms3203x_device::execute_min_cycles() const
  744  {
  745      return 1;
  746  }
  747  
  748  
  749  //-------------------------------------------------
  750  //  execute_max_cycles - return maximum number of
  751  //  cycles it takes for one instruction to execute
  752  //-------------------------------------------------
  753  
  754  UINT32 tms3203x_device::execute_max_cycles() const
  755  {
  756      return 4;
  757  }
  758  
  759  
  760  //-------------------------------------------------
  761  //  execute_input_lines - return the number of
  762  //  input/interrupt lines
  763  //-------------------------------------------------
  764  
  765  UINT32 tms3203x_device::execute_input_lines() const
  766  {
  767      return (m_chip_type == CHIP_TYPE_TMS32032) ? 13 : 12;
  768  }
  769  
  770  
  771  //-------------------------------------------------
  772  //  execute_set_input - set input and IRQ lines
  773  //-------------------------------------------------
  774  
  775  void tms3203x_device::execute_set_input(int inputnum, int state)
  776  {
  777      // ignore anything out of range
  778      if (inputnum >= 13)
  779          return;
  780  
  781      if (inputnum == TMS3203X_MCBL)
  782      {
  783          // switch between microcomputer/boot loader and microprocessor modes
  784          m_mcbl_mode = (state == ASSERT_LINE);
  785          m_direct->force_update();
  786          return;
  787      }
  788  
  789      // update the external state
  790      UINT16 intmask = 1 << inputnum;
  791      if (state == ASSERT_LINE)
  792      {
  793          m_irq_state |= intmask;
  794          IREG(TMR_IF) |= intmask;
  795      }
  796      else
  797          m_irq_state &= ~intmask;
  798  
  799      // external interrupts are level-sensitive on the '31 and can be
  800      // configured as such on the '32; in that case, if the external
  801      // signal is high, we need to update the value in IF accordingly
  802      if (m_chip_type == CHIP_TYPE_TMS32031 || (IREG(TMR_ST) & 0x4000) == 0)
  803          IREG(TMR_IF) |= m_irq_state & 0x0f;
  804  }
  805  
  806  
  807  //-------------------------------------------------
  808  //  execute_run - execute until our icount expires
  809  //-------------------------------------------------
  810  
  811  void tms3203x_device::execute_run()
  812  {
  813      // check IRQs up front
  814      check_irqs();
  815  
  816      // if we're idling, just eat the cycles
  817      if (m_is_idling)
  818      {
  819          m_icount = 0;
  820          return;
  821      }
  822  
  823      // non-debug case
  824      if ((machine().debug_flags & DEBUG_FLAG_ENABLED) == 0)
  825      {
  826          while (m_icount > 0)
  827          {
  828              if ((IREG(TMR_ST) & RMFLAG) && m_pc == IREG(TMR_RE) + 1)
  829              {
  830                  if ((INT32)--IREG(TMR_RC) >= 0)
  831                      m_pc = IREG(TMR_RS);
  832                  else
  833                  {
  834                      IREG(TMR_ST) &= ~RMFLAG;
  835                      if (m_delayed)
  836                      {
  837                          m_delayed = false;
  838                          if (m_irq_pending)
  839                          {
  840                              m_irq_pending = false;
  841                              check_irqs();
  842                          }
  843                      }
  844                  }
  845                  continue;
  846              }
  847  
  848              execute_one();
  849          }
  850      }
  851  
  852      // debugging case
  853      else
  854      {
  855          while (m_icount > 0)
  856          {
  857              // watch for out-of-range stack pointers
  858              if (IREG(TMR_SP) & 0xff000000)
  859                  debugger_break(machine());
  860              if ((IREG(TMR_ST) & RMFLAG) && m_pc == IREG(TMR_RE) + 1)
  861              {
  862                  if ((INT32)--IREG(TMR_RC) >= 0)
  863                      m_pc = IREG(TMR_RS);
  864                  else
  865                  {
  866                      IREG(TMR_ST) &= ~RMFLAG;
  867                      if (m_delayed)
  868                      {
  869                          m_delayed = false;
  870                          if (m_irq_pending)
  871                          {
  872                              m_irq_pending = false;
  873                              check_irqs();
  874                          }
  875                      }
  876                  }
  877                  continue;
  878              }
  879  
  880              debugger_instruction_hook(this, m_pc);
  881              execute_one();
  882          }
  883      }
  884  }
  885  
  886  
  887  //**************************************************************************
  888  //  CORE OPCODES
  889  //**************************************************************************
  890  
  891  #include "32031ops.c"