summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/tms32031/tms32031.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/cpu/tms32031/tms32031.c')
-rw-r--r--src/emu/cpu/tms32031/tms32031.c829
1 files changed, 829 insertions, 0 deletions
diff --git a/src/emu/cpu/tms32031/tms32031.c b/src/emu/cpu/tms32031/tms32031.c
new file mode 100644
index 00000000000..3545bc9e7fb
--- /dev/null
+++ b/src/emu/cpu/tms32031/tms32031.c
@@ -0,0 +1,829 @@
+/***************************************************************************
+
+ tms32031.c
+ Core implementation for the portable TMS32C031 emulator.
+ Written by Aaron Giles
+
+***************************************************************************/
+
+#include "debugger.h"
+#include "tms32031.h"
+#include "eminline.h"
+
+
+#define LOG_OPCODE_USAGE (0)
+
+
+/***************************************************************************
+ CONSTANTS
+***************************************************************************/
+
+enum
+{
+ TMR_R0 = 0,
+ TMR_R1,
+ TMR_R2,
+ TMR_R3,
+ TMR_R4,
+ TMR_R5,
+ TMR_R6,
+ TMR_R7,
+ TMR_AR0,
+ TMR_AR1,
+ TMR_AR2,
+ TMR_AR3,
+ TMR_AR4,
+ TMR_AR5,
+ TMR_AR6,
+ TMR_AR7,
+ TMR_DP,
+ TMR_IR0,
+ TMR_IR1,
+ TMR_BK,
+ TMR_SP,
+ TMR_ST,
+ TMR_IE,
+ TMR_IF,
+ TMR_IOF,
+ TMR_RS,
+ TMR_RE,
+ TMR_RC,
+ TMR_R8, /* 3204x only */
+ TMR_R9, /* 3204x only */
+ TMR_R10, /* 3204x only */
+ TMR_R11, /* 3204x only */
+ TMR_TEMP1, /* used by the interpreter */
+ TMR_TEMP2, /* used by the interpreter */
+ TMR_TEMP3 /* used by the interpreter */
+};
+
+#define CFLAG 0x0001
+#define VFLAG 0x0002
+#define ZFLAG 0x0004
+#define NFLAG 0x0008
+#define UFFLAG 0x0010
+#define LVFLAG 0x0020
+#define LUFFLAG 0x0040
+#define OVMFLAG 0x0080
+#define RMFLAG 0x0100
+#define CFFLAG 0x0400
+#define CEFLAG 0x0800
+#define CCFLAG 0x1000
+#define GIEFLAG 0x2000
+
+#define IREG(rnum) (tms32031.r[rnum].i32[0])
+
+
+
+/***************************************************************************
+ STRUCTURES & TYPEDEFS
+***************************************************************************/
+
+union genreg
+{
+ UINT32 i32[2];
+ UINT16 i16[4];
+ UINT8 i8[8];
+};
+
+/* TMS34031 Registers */
+typedef struct
+{
+ /* core registers */
+ UINT32 pc;
+ union genreg r[36];
+ UINT32 bkmask;
+
+ /* internal stuff */
+ UINT32 ppc;
+ UINT32 op;
+ UINT8 delayed;
+ UINT8 irq_pending;
+ UINT8 mcu_mode;
+ UINT8 is_idling;
+ int interrupt_cycles;
+
+ UINT32 bootoffset;
+ void (*xf0_w)(UINT8 val);
+ void (*xf1_w)(UINT8 val);
+ void (*iack_w)(UINT8 val, offs_t addr);
+ int (*irq_callback)(int state);
+} tms32031_regs;
+
+
+
+/***************************************************************************
+ FUNCTION PROTOTYPES
+***************************************************************************/
+
+static void trap(int trapnum);
+static UINT32 boot_loader(UINT32 boot_rom_addr);
+
+
+
+/***************************************************************************
+ PUBLIC GLOBAL VARIABLES
+***************************************************************************/
+
+static int tms32031_icount;
+
+
+
+/***************************************************************************
+ PRIVATE GLOBAL VARIABLES
+***************************************************************************/
+
+static tms32031_regs tms32031;
+
+
+
+/***************************************************************************
+ MEMORY ACCESSORS
+***************************************************************************/
+
+#define ROPCODE(pc) cpu_readop32((pc) << 2)
+#define OP tms32031.op
+
+#define RMEM(addr) program_read_dword_32le((addr) << 2)
+#define WMEM(addr,data) program_write_dword_32le((addr) << 2, data)
+#define UPDATEPC(addr) change_pc((addr) << 2)
+
+
+
+/***************************************************************************
+ HELPER MACROS
+***************************************************************************/
+
+#define MANTISSA(r) ((INT32)(r)->i32[0])
+#define EXPONENT(r) ((INT8)(r)->i32[1])
+#define SET_MANTISSA(r,v) ((r)->i32[0] = (v))
+#define SET_EXPONENT(r,v) ((r)->i32[1] = (v))
+
+typedef union int_double
+{
+ double d;
+ float f[2];
+ UINT32 i[2];
+} int_double;
+
+
+#if 0
+static float dsp_to_float(union genreg *fp)
+{
+ int_double id;
+
+ if (MANTISSA(fp) == 0 && EXPONENT(fp) == -128)
+ return 0;
+ else if (MANTISSA(fp) >= 0)
+ {
+ int exponent = (EXPONENT(fp) + 127) << 23;
+ id.i[0] = exponent + (MANTISSA(fp) >> 8);
+ }
+ else
+ {
+ int exponent = (EXPONENT(fp) + 127) << 23;
+ INT32 man = -MANTISSA(fp);
+ id.i[0] = 0x80000000 + exponent + ((man >> 8) & 0x00ffffff);
+ }
+ return id.f[0];
+}
+#endif
+
+
+static double dsp_to_double(union genreg *fp)
+{
+ int_double id;
+
+ if (MANTISSA(fp) == 0 && EXPONENT(fp) == -128)
+ return 0;
+ else if (MANTISSA(fp) >= 0)
+ {
+ int exponent = (EXPONENT(fp) + 1023) << 20;
+ id.i[BYTE_XOR_BE(0)] = exponent + (MANTISSA(fp) >> 11);
+ id.i[BYTE_XOR_BE(1)] = (MANTISSA(fp) << 21) & 0xffe00000;
+ }
+ else
+ {
+ int exponent = (EXPONENT(fp) + 1023) << 20;
+ INT32 man = -MANTISSA(fp);
+ id.i[BYTE_XOR_BE(0)] = 0x80000000 + exponent + ((man >> 11) & 0x001fffff);
+ id.i[BYTE_XOR_BE(1)] = (man << 21) & 0xffe00000;
+ }
+ return id.d;
+}
+
+
+static void double_to_dsp(double val, union genreg *result)
+{
+ int mantissa, exponent;
+ int_double id;
+ id.d = val;
+
+ mantissa = ((id.i[BYTE_XOR_BE(0)] & 0x000fffff) << 11) | ((id.i[BYTE_XOR_BE(1)] & 0xffe00000) >> 21);
+ exponent = ((id.i[BYTE_XOR_BE(0)] & 0x7ff00000) >> 20) - 1023;
+ if (exponent < -128)
+ {
+ SET_MANTISSA(result, 0);
+ SET_EXPONENT(result, -128);
+ }
+ else if (exponent > 127)
+ {
+ if ((INT32)id.i[BYTE_XOR_BE(0)] >= 0)
+ SET_MANTISSA(result, 0x7fffffff);
+ else
+ SET_MANTISSA(result, 0x80000001);
+ SET_EXPONENT(result, 127);
+ }
+ else if ((INT32)id.i[BYTE_XOR_BE(0)] >= 0)
+ {
+ SET_MANTISSA(result, mantissa);
+ SET_EXPONENT(result, exponent);
+ }
+ else if (mantissa != 0)
+ {
+ SET_MANTISSA(result, 0x80000000 | -mantissa);
+ SET_EXPONENT(result, exponent);
+ }
+ else
+ {
+ SET_MANTISSA(result, 0x80000000);
+ SET_EXPONENT(result, exponent - 1);
+ }
+}
+
+
+
+/***************************************************************************
+ EXECEPTION HANDLING
+***************************************************************************/
+
+INLINE void generate_exception(int exception)
+{
+}
+
+
+INLINE void invalid_instruction(UINT32 op)
+{
+}
+
+
+
+/***************************************************************************
+ IRQ HANDLING
+***************************************************************************/
+
+static void check_irqs(void)
+{
+ int validints = IREG(TMR_IF) & IREG(TMR_IE) & 0x07ff;
+ if (validints && (IREG(TMR_ST) & GIEFLAG))
+ {
+ int whichtrap = 0;
+ int i;
+
+ for (i = 0; i < 11; i++)
+ if (validints & (1 << i))
+ {
+ whichtrap = i + 1;
+ break;
+ }
+
+ if (whichtrap)
+ {
+ tms32031.is_idling = 0;
+ if (!tms32031.delayed)
+ {
+ trap(whichtrap);
+
+ /* for internal sources, clear the interrupt when taken */
+ if (whichtrap > 4)
+ IREG(TMR_IF) &= ~(1 << (whichtrap - 1));
+ }
+ else
+ tms32031.irq_pending = 1;
+ }
+ }
+}
+
+
+static void set_irq_line(int irqline, int state)
+{
+ if (irqline < 11)
+ {
+ /* update the state */
+ if (state == ASSERT_LINE)
+ IREG(TMR_IF) |= 1 << irqline;
+ else
+ IREG(TMR_IF) &= ~(1 << irqline);
+
+ /* check for IRQs */
+ if (state != CLEAR_LINE)
+ check_irqs();
+ }
+}
+
+
+
+/***************************************************************************
+ CONTEXT SWITCHING
+***************************************************************************/
+
+static void tms32031_get_context(void *dst)
+{
+ /* copy the context */
+ if (dst)
+ *(tms32031_regs *)dst = tms32031;
+}
+
+
+static void tms32031_set_context(void *src)
+{
+ /* copy the context */
+ if (src)
+ tms32031 = *(tms32031_regs *)src;
+ UPDATEPC(tms32031.pc);
+
+ /* check for IRQs */
+ check_irqs();
+}
+
+
+
+/***************************************************************************
+ INITIALIZATION AND SHUTDOWN
+***************************************************************************/
+
+static void tms32031_init(int index, int clock, const void *_config, int (*irqcallback)(int))
+{
+ const struct tms32031_config *config = _config;
+ int i;
+ char namebuf[30];
+
+ tms32031.irq_callback = irqcallback;
+
+ /* copy in the xf write routines */
+ tms32031.bootoffset = config ? config->bootoffset : 0;
+ if (config)
+ {
+ tms32031.xf0_w = config->xf0_w;
+ tms32031.xf1_w = config->xf1_w;
+ tms32031.iack_w = config->iack_w;
+ }
+
+ state_save_register_item("tms32031", index, tms32031.pc);
+ for (i=0;i<36;i++)
+ {
+ sprintf(namebuf,"tms32031.r[%d]",i);
+ state_save_register_generic("tms32031", index, namebuf, tms32031.r[i].i8, UINT8, 8);
+ }
+ state_save_register_item("tms32031", index, tms32031.bkmask);
+ state_save_register_item("tms32031", index, tms32031.ppc);
+ state_save_register_item("tms32031", index, tms32031.op);
+ state_save_register_item("tms32031", index, tms32031.delayed);
+ state_save_register_item("tms32031", index, tms32031.irq_pending);
+ state_save_register_item("tms32031", index, tms32031.mcu_mode);
+ state_save_register_item("tms32031", index, tms32031.is_idling);
+ state_save_register_item("tms32031", index, tms32031.interrupt_cycles);
+
+}
+
+static void tms32031_reset(void)
+{
+ /* if we have a config struct, get the boot ROM address */
+ if (tms32031.bootoffset)
+ {
+ tms32031.mcu_mode = 1;
+ tms32031.pc = boot_loader(tms32031.bootoffset);
+ }
+ else
+ {
+ tms32031.mcu_mode = 0;
+ tms32031.pc = RMEM(0);
+ }
+
+ /* reset some registers */
+ IREG(TMR_IE) = 0;
+ IREG(TMR_IF) = 0;
+ IREG(TMR_ST) = 0;
+ IREG(TMR_IOF) = 0;
+
+ /* reset internal stuff */
+ tms32031.delayed = tms32031.irq_pending = 0;
+ tms32031.is_idling = 0;
+}
+
+
+#if (LOG_OPCODE_USAGE)
+static UINT32 hits[0x200*4];
+#endif
+
+void tms32031_exit(void)
+{
+#if (LOG_OPCODE_USAGE)
+ int i;
+ for (i = 0; i < 0x200*4; i++)
+ if (hits[i])
+ mame_printf_debug("%10d - %03X.%X\n", hits[i], i / 4, i % 4);
+#endif
+}
+
+
+
+/***************************************************************************
+ CORE OPCODES
+***************************************************************************/
+
+#include "32031ops.c"
+
+
+
+/***************************************************************************
+ CORE EXECUTION LOOP
+***************************************************************************/
+
+static int tms32031_execute(int cycles)
+{
+ /* count cycles and interrupt cycles */
+ tms32031_icount = cycles;
+ tms32031_icount -= tms32031.interrupt_cycles;
+ tms32031.interrupt_cycles = 0;
+
+ /* check IRQs up front */
+ check_irqs();
+
+ /* if we're idling, just eat the cycles */
+ if (tms32031.is_idling)
+ return tms32031_icount;
+
+ while (tms32031_icount > 0)
+ {
+ if ((IREG(TMR_ST) & RMFLAG) && tms32031.pc == IREG(TMR_RE) + 1)
+ {
+ if ((INT32)--IREG(TMR_RC) >= 0)
+ tms32031.pc = IREG(TMR_RS);
+ else
+ {
+ IREG(TMR_ST) &= ~RMFLAG;
+ if (tms32031.delayed)
+ {
+ tms32031.delayed = 0;
+ if (tms32031.irq_pending)
+ {
+ tms32031.irq_pending = 0;
+ check_irqs();
+ }
+ }
+ }
+ continue;
+ }
+
+ execute_one();
+ }
+
+ tms32031_icount -= tms32031.interrupt_cycles;
+ tms32031.interrupt_cycles = 0;
+
+ return cycles - tms32031_icount;
+}
+
+
+
+/***************************************************************************
+ DISASSEMBLY HOOK
+***************************************************************************/
+
+#ifdef MAME_DEBUG
+static offs_t tms32031_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram)
+{
+ UINT32 op = oprom[0] | (oprom[1] << 8) | (oprom[2] << 16) | (oprom[3] << 24);
+ extern unsigned dasm_tms32031(char *, unsigned, UINT32);
+ return dasm_tms32031(buffer, pc, op);
+}
+#endif /* MAME_DEBUG */
+
+
+
+/***************************************************************************
+ BOOT LOADER
+***************************************************************************/
+
+static UINT32 boot_loader(UINT32 boot_rom_addr)
+{
+ UINT32 bits, control, advance;
+ UINT32 start_offset = 0;
+ UINT32 datamask;
+ int first = 1, i;
+
+ /* read the size of the data */
+ bits = RMEM(boot_rom_addr);
+ if (bits != 8 && bits != 16 && bits != 32)
+ return 0;
+ datamask = 0xffffffffUL >> (32 - bits);
+ advance = 32 / bits;
+ boot_rom_addr += advance;
+
+ /* read the control register */
+ control = RMEM(boot_rom_addr++) & datamask;
+ for (i = 1; i < advance; i++)
+ control |= (RMEM(boot_rom_addr++) & datamask) << (bits * i);
+
+ /* now parse the data */
+ while (1)
+ {
+ UINT32 offs, len;
+
+ /* read the length of this section */
+ len = RMEM(boot_rom_addr++) & datamask;
+ for (i = 1; i < advance; i++)
+ len |= (RMEM(boot_rom_addr++) & datamask) << (bits * i);
+
+ /* stop at 0 */
+ if (len == 0)
+ return start_offset;
+
+ /* read the destination offset of this section */
+ offs = RMEM(boot_rom_addr++) & datamask;
+ for (i = 1; i < advance; i++)
+ offs |= (RMEM(boot_rom_addr++) & datamask) << (bits * i);
+
+ /* if this is the first block, that's where we boot to */
+ if (first)
+ {
+ start_offset = offs;
+ first = 0;
+ }
+
+ /* now copy the data */
+ while (len--)
+ {
+ UINT32 data;
+
+ /* extract the 32-bit word */
+ data = RMEM(boot_rom_addr++) & datamask;
+ for (i = 1; i < advance; i++)
+ data |= (RMEM(boot_rom_addr++) & datamask) << (bits * i);
+
+ /* write it out */
+ WMEM(offs++, data);
+ }
+ }
+
+ /* keep the compiler happy */
+ return 0;
+}
+
+
+
+/**************************************************************************
+ * Generic set_info
+ **************************************************************************/
+
+static void tms32031_set_info(UINT32 state, cpuinfo *info)
+{
+ switch (state)
+ {
+ /* --- the following bits of info are set as 64-bit signed integers --- */
+ case CPUINFO_INT_INPUT_STATE + TMS32031_IRQ0: set_irq_line(TMS32031_IRQ0, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + TMS32031_IRQ1: set_irq_line(TMS32031_IRQ1, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + TMS32031_IRQ2: set_irq_line(TMS32031_IRQ2, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + TMS32031_IRQ3: set_irq_line(TMS32031_IRQ3, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + TMS32031_XINT0: set_irq_line(TMS32031_XINT0, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + TMS32031_RINT0: set_irq_line(TMS32031_RINT0, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + TMS32031_XINT1: set_irq_line(TMS32031_XINT1, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + TMS32031_RINT1: set_irq_line(TMS32031_RINT1, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + TMS32031_TINT0: set_irq_line(TMS32031_TINT0, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + TMS32031_TINT1: set_irq_line(TMS32031_TINT1, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + TMS32031_DINT: set_irq_line(TMS32031_DINT, info->i); break;
+
+ case CPUINFO_INT_PC:
+ case CPUINFO_INT_REGISTER + TMS32031_PC: tms32031.pc = info->i; break;
+ case CPUINFO_INT_REGISTER + TMS32031_R0: IREG(TMR_R0) = info->i; break;
+ case CPUINFO_INT_REGISTER + TMS32031_R1: IREG(TMR_R1) = info->i; break;
+ case CPUINFO_INT_REGISTER + TMS32031_R2: IREG(TMR_R2) = info->i; break;
+ case CPUINFO_INT_REGISTER + TMS32031_R3: IREG(TMR_R3) = info->i; break;
+ case CPUINFO_INT_REGISTER + TMS32031_R4: IREG(TMR_R4) = info->i; break;
+ case CPUINFO_INT_REGISTER + TMS32031_R5: IREG(TMR_R5) = info->i; break;
+ case CPUINFO_INT_REGISTER + TMS32031_R6: IREG(TMR_R6) = info->i; break;
+ case CPUINFO_INT_REGISTER + TMS32031_R7: IREG(TMR_R7) = info->i; break;
+ case CPUINFO_INT_REGISTER + TMS32031_R0F: double_to_dsp(*(float *)&info->i, &tms32031.r[TMR_R0]); break;
+ case CPUINFO_INT_REGISTER + TMS32031_R1F: double_to_dsp(*(float *)&info->i, &tms32031.r[TMR_R1]); break;
+ case CPUINFO_INT_REGISTER + TMS32031_R2F: double_to_dsp(*(float *)&info->i, &tms32031.r[TMR_R2]); break;
+ case CPUINFO_INT_REGISTER + TMS32031_R3F: double_to_dsp(*(float *)&info->i, &tms32031.r[TMR_R3]); break;
+ case CPUINFO_INT_REGISTER + TMS32031_R4F: double_to_dsp(*(float *)&info->i, &tms32031.r[TMR_R4]); break;
+ case CPUINFO_INT_REGISTER + TMS32031_R5F: double_to_dsp(*(float *)&info->i, &tms32031.r[TMR_R5]); break;
+ case CPUINFO_INT_REGISTER + TMS32031_R6F: double_to_dsp(*(float *)&info->i, &tms32031.r[TMR_R6]); break;
+ case CPUINFO_INT_REGISTER + TMS32031_R7F: double_to_dsp(*(float *)&info->i, &tms32031.r[TMR_R7]); break;
+ case CPUINFO_INT_REGISTER + TMS32031_AR0: IREG(TMR_AR0) = info->i; break;
+ case CPUINFO_INT_REGISTER + TMS32031_AR1: IREG(TMR_AR1) = info->i; break;
+ case CPUINFO_INT_REGISTER + TMS32031_AR2: IREG(TMR_AR2) = info->i; break;
+ case CPUINFO_INT_REGISTER + TMS32031_AR3: IREG(TMR_AR3) = info->i; break;
+ case CPUINFO_INT_REGISTER + TMS32031_AR4: IREG(TMR_AR4) = info->i; break;
+ case CPUINFO_INT_REGISTER + TMS32031_AR5: IREG(TMR_AR5) = info->i; break;
+ case CPUINFO_INT_REGISTER + TMS32031_AR6: IREG(TMR_AR6) = info->i; break;
+ case CPUINFO_INT_REGISTER + TMS32031_AR7: IREG(TMR_AR7) = info->i; break;
+ case CPUINFO_INT_REGISTER + TMS32031_DP: IREG(TMR_DP) = info->i; break;
+ case CPUINFO_INT_REGISTER + TMS32031_IR0: IREG(TMR_IR0) = info->i; break;
+ case CPUINFO_INT_REGISTER + TMS32031_IR1: IREG(TMR_IR1) = info->i; break;
+ case CPUINFO_INT_REGISTER + TMS32031_BK: IREG(TMR_BK) = info->i; break;
+ case CPUINFO_INT_SP:
+ case CPUINFO_INT_REGISTER + TMS32031_SP: IREG(TMR_SP) = info->i; break;
+ case CPUINFO_INT_REGISTER + TMS32031_ST: IREG(TMR_ST) = info->i; break;
+ case CPUINFO_INT_REGISTER + TMS32031_IE: IREG(TMR_IE) = info->i; break;
+ case CPUINFO_INT_REGISTER + TMS32031_IF: IREG(TMR_IF) = info->i; break;
+ case CPUINFO_INT_REGISTER + TMS32031_IOF: IREG(TMR_IOF) = info->i; break;
+ case CPUINFO_INT_REGISTER + TMS32031_RS: IREG(TMR_RS) = info->i; break;
+ case CPUINFO_INT_REGISTER + TMS32031_RE: IREG(TMR_RE) = info->i; break;
+ case CPUINFO_INT_REGISTER + TMS32031_RC: IREG(TMR_RC) = info->i; break;
+ }
+}
+
+
+/**************************************************************************
+ * Internal memory map
+ **************************************************************************/
+
+static ADDRESS_MAP_START( internal_32031, ADDRESS_SPACE_PROGRAM, 32 )
+ AM_RANGE(0x809800, 0x809fff) AM_RAM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( internal_32032, ADDRESS_SPACE_PROGRAM, 32 )
+ AM_RANGE(0x87fe00, 0x87ffff) AM_RAM
+ADDRESS_MAP_END
+
+
+/**************************************************************************
+ * Generic get_info
+ **************************************************************************/
+
+void tms32031_get_info(UINT32 state, cpuinfo *info)
+{
+ float ftemp;
+
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(tms32031); break;
+ case CPUINFO_INT_INPUT_LINES: info->i = 11; break;
+ case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break;
+ case CPUINFO_INT_ENDIANNESS: info->i = CPU_IS_LE; break;
+ case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break;
+ case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 4; break;
+ case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 4; break;
+ case CPUINFO_INT_MIN_CYCLES: info->i = 1; break;
+ case CPUINFO_INT_MAX_CYCLES: info->i = 4; break;
+
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 24; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = -2; break;
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO: info->i = 0; break;
+
+ case CPUINFO_INT_INPUT_STATE + TMS32031_IRQ0: info->i = (IREG(TMR_IF) & (1 << TMS32031_IRQ0)) ? ASSERT_LINE : CLEAR_LINE; break;
+ case CPUINFO_INT_INPUT_STATE + TMS32031_IRQ1: info->i = (IREG(TMR_IF) & (1 << TMS32031_IRQ1)) ? ASSERT_LINE : CLEAR_LINE; break;
+ case CPUINFO_INT_INPUT_STATE + TMS32031_IRQ2: info->i = (IREG(TMR_IF) & (1 << TMS32031_IRQ2)) ? ASSERT_LINE : CLEAR_LINE; break;
+ case CPUINFO_INT_INPUT_STATE + TMS32031_IRQ3: info->i = (IREG(TMR_IF) & (1 << TMS32031_IRQ3)) ? ASSERT_LINE : CLEAR_LINE; break;
+ case CPUINFO_INT_INPUT_STATE + TMS32031_XINT0: info->i = (IREG(TMR_IF) & (1 << TMS32031_XINT0)) ? ASSERT_LINE : CLEAR_LINE; break;
+ case CPUINFO_INT_INPUT_STATE + TMS32031_RINT0: info->i = (IREG(TMR_IF) & (1 << TMS32031_RINT0)) ? ASSERT_LINE : CLEAR_LINE; break;
+ case CPUINFO_INT_INPUT_STATE + TMS32031_XINT1: info->i = (IREG(TMR_IF) & (1 << TMS32031_XINT1)) ? ASSERT_LINE : CLEAR_LINE; break;
+ case CPUINFO_INT_INPUT_STATE + TMS32031_RINT1: info->i = (IREG(TMR_IF) & (1 << TMS32031_RINT1)) ? ASSERT_LINE : CLEAR_LINE; break;
+ case CPUINFO_INT_INPUT_STATE + TMS32031_TINT0: info->i = (IREG(TMR_IF) & (1 << TMS32031_TINT0)) ? ASSERT_LINE : CLEAR_LINE; break;
+ case CPUINFO_INT_INPUT_STATE + TMS32031_TINT1: info->i = (IREG(TMR_IF) & (1 << TMS32031_TINT1)) ? ASSERT_LINE : CLEAR_LINE; break;
+ case CPUINFO_INT_INPUT_STATE + TMS32031_DINT: info->i = (IREG(TMR_IF) & (1 << TMS32031_DINT)) ? ASSERT_LINE : CLEAR_LINE; break;
+
+ case CPUINFO_INT_PREVIOUSPC: info->i = tms32031.ppc; break;
+
+ case CPUINFO_INT_PC:
+ case CPUINFO_INT_REGISTER + TMS32031_PC: info->i = tms32031.pc; break;
+
+ case CPUINFO_INT_REGISTER + TMS32031_R0: info->i = IREG(TMR_R0); break;
+ case CPUINFO_INT_REGISTER + TMS32031_R1: info->i = IREG(TMR_R1); break;
+ case CPUINFO_INT_REGISTER + TMS32031_R2: info->i = IREG(TMR_R2); break;
+ case CPUINFO_INT_REGISTER + TMS32031_R3: info->i = IREG(TMR_R3); break;
+ case CPUINFO_INT_REGISTER + TMS32031_R4: info->i = IREG(TMR_R4); break;
+ case CPUINFO_INT_REGISTER + TMS32031_R5: info->i = IREG(TMR_R5); break;
+ case CPUINFO_INT_REGISTER + TMS32031_R6: info->i = IREG(TMR_R6); break;
+ case CPUINFO_INT_REGISTER + TMS32031_R7: info->i = IREG(TMR_R7); break;
+ case CPUINFO_INT_REGISTER + TMS32031_R0F: ftemp = dsp_to_double(&tms32031.r[TMR_R0]); info->i = f2u(ftemp); break;
+ case CPUINFO_INT_REGISTER + TMS32031_R1F: ftemp = dsp_to_double(&tms32031.r[TMR_R1]); info->i = f2u(ftemp); break;
+ case CPUINFO_INT_REGISTER + TMS32031_R2F: ftemp = dsp_to_double(&tms32031.r[TMR_R2]); info->i = f2u(ftemp); break;
+ case CPUINFO_INT_REGISTER + TMS32031_R3F: ftemp = dsp_to_double(&tms32031.r[TMR_R3]); info->i = f2u(ftemp); break;
+ case CPUINFO_INT_REGISTER + TMS32031_R4F: ftemp = dsp_to_double(&tms32031.r[TMR_R4]); info->i = f2u(ftemp); break;
+ case CPUINFO_INT_REGISTER + TMS32031_R5F: ftemp = dsp_to_double(&tms32031.r[TMR_R5]); info->i = f2u(ftemp); break;
+ case CPUINFO_INT_REGISTER + TMS32031_R6F: ftemp = dsp_to_double(&tms32031.r[TMR_R6]); info->i = f2u(ftemp); break;
+ case CPUINFO_INT_REGISTER + TMS32031_R7F: ftemp = dsp_to_double(&tms32031.r[TMR_R7]); info->i = f2u(ftemp); break;
+ case CPUINFO_INT_REGISTER + TMS32031_AR0: info->i = IREG(TMR_AR0); break;
+ case CPUINFO_INT_REGISTER + TMS32031_AR1: info->i = IREG(TMR_AR1); break;
+ case CPUINFO_INT_REGISTER + TMS32031_AR2: info->i = IREG(TMR_AR2); break;
+ case CPUINFO_INT_REGISTER + TMS32031_AR3: info->i = IREG(TMR_AR3); break;
+ case CPUINFO_INT_REGISTER + TMS32031_AR4: info->i = IREG(TMR_AR4); break;
+ case CPUINFO_INT_REGISTER + TMS32031_AR5: info->i = IREG(TMR_AR5); break;
+ case CPUINFO_INT_REGISTER + TMS32031_AR6: info->i = IREG(TMR_AR6); break;
+ case CPUINFO_INT_REGISTER + TMS32031_AR7: info->i = IREG(TMR_AR7); break;
+ case CPUINFO_INT_REGISTER + TMS32031_DP: info->i = IREG(TMR_DP); break;
+ case CPUINFO_INT_REGISTER + TMS32031_IR0: info->i = IREG(TMR_IR0); break;
+ case CPUINFO_INT_REGISTER + TMS32031_IR1: info->i = IREG(TMR_IR1); break;
+ case CPUINFO_INT_REGISTER + TMS32031_BK: info->i = IREG(TMR_BK); break;
+ case CPUINFO_INT_SP:
+ case CPUINFO_INT_REGISTER + TMS32031_SP: info->i = IREG(TMR_SP); break;
+ case CPUINFO_INT_REGISTER + TMS32031_ST: info->i = IREG(TMR_ST); break;
+ case CPUINFO_INT_REGISTER + TMS32031_IE: info->i = IREG(TMR_IE); break;
+ case CPUINFO_INT_REGISTER + TMS32031_IF: info->i = IREG(TMR_IF); break;
+ case CPUINFO_INT_REGISTER + TMS32031_IOF: info->i = IREG(TMR_IOF); break;
+ case CPUINFO_INT_REGISTER + TMS32031_RS: info->i = IREG(TMR_RS); break;
+ case CPUINFO_INT_REGISTER + TMS32031_RE: info->i = IREG(TMR_RE); break;
+ case CPUINFO_INT_REGISTER + TMS32031_RC: info->i = IREG(TMR_RC); break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_PTR_SET_INFO: info->setinfo = tms32031_set_info; break;
+ case CPUINFO_PTR_GET_CONTEXT: info->getcontext = tms32031_get_context; break;
+ case CPUINFO_PTR_SET_CONTEXT: info->setcontext = tms32031_set_context; break;
+ case CPUINFO_PTR_INIT: info->init = tms32031_init; break;
+ case CPUINFO_PTR_RESET: info->reset = tms32031_reset; break;
+ case CPUINFO_PTR_EXIT: info->exit = tms32031_exit; break;
+ case CPUINFO_PTR_EXECUTE: info->execute = tms32031_execute; break;
+ case CPUINFO_PTR_BURN: info->burn = NULL; break;
+#ifdef MAME_DEBUG
+ case CPUINFO_PTR_DISASSEMBLE: info->disassemble = tms32031_dasm; break;
+#endif /* MAME_DEBUG */
+ case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &tms32031_icount; break;
+ case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map = construct_map_internal_32031; break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case CPUINFO_STR_NAME: strcpy(info->s, "TMS32031"); break;
+ case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "Texas Instruments TMS32031"); break;
+ case CPUINFO_STR_CORE_VERSION: strcpy(info->s, "1.0"); break;
+ case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break;
+ case CPUINFO_STR_CORE_CREDITS: strcpy(info->s, "Copyright (C) Aaron Giles 2002"); break;
+
+ case CPUINFO_STR_FLAGS:
+ {
+ UINT32 temp = tms32031.r[TMR_ST].i32[0];
+ sprintf(info->s, "%c%c%c%c%c%c%c%c",
+ (temp & 0x80) ? 'O':'.',
+ (temp & 0x40) ? 'U':'.',
+ (temp & 0x20) ? 'V':'.',
+ (temp & 0x10) ? 'u':'.',
+ (temp & 0x08) ? 'n':'.',
+ (temp & 0x04) ? 'z':'.',
+ (temp & 0x02) ? 'v':'.',
+ (temp & 0x01) ? 'c':'.');
+ break;
+ }
+
+ case CPUINFO_STR_REGISTER + TMS32031_PC: sprintf(info->s, "PC: %08X", tms32031.pc); break;
+
+ case CPUINFO_STR_REGISTER + TMS32031_R0: sprintf(info->s, " R0:%08X", tms32031.r[TMR_R0].i32[0]); break;
+ case CPUINFO_STR_REGISTER + TMS32031_R1: sprintf(info->s, " R1:%08X", tms32031.r[TMR_R1].i32[0]); break;
+ case CPUINFO_STR_REGISTER + TMS32031_R2: sprintf(info->s, " R2:%08X", tms32031.r[TMR_R2].i32[0]); break;
+ case CPUINFO_STR_REGISTER + TMS32031_R3: sprintf(info->s, " R3:%08X", tms32031.r[TMR_R3].i32[0]); break;
+ case CPUINFO_STR_REGISTER + TMS32031_R4: sprintf(info->s, " R4:%08X", tms32031.r[TMR_R4].i32[0]); break;
+ case CPUINFO_STR_REGISTER + TMS32031_R5: sprintf(info->s, " R5:%08X", tms32031.r[TMR_R5].i32[0]); break;
+ case CPUINFO_STR_REGISTER + TMS32031_R6: sprintf(info->s, " R6:%08X", tms32031.r[TMR_R6].i32[0]); break;
+ case CPUINFO_STR_REGISTER + TMS32031_R7: sprintf(info->s, " R7:%08X", tms32031.r[TMR_R7].i32[0]); break;
+ case CPUINFO_STR_REGISTER + TMS32031_R0F: sprintf(info->s, "R0F:!%12g", dsp_to_double(&tms32031.r[TMR_R0])); break;
+ case CPUINFO_STR_REGISTER + TMS32031_R1F: sprintf(info->s, "R1F:!%12g", dsp_to_double(&tms32031.r[TMR_R1])); break;
+ case CPUINFO_STR_REGISTER + TMS32031_R2F: sprintf(info->s, "R2F:!%12g", dsp_to_double(&tms32031.r[TMR_R2])); break;
+ case CPUINFO_STR_REGISTER + TMS32031_R3F: sprintf(info->s, "R3F:!%12g", dsp_to_double(&tms32031.r[TMR_R3])); break;
+ case CPUINFO_STR_REGISTER + TMS32031_R4F: sprintf(info->s, "R4F:!%12g", dsp_to_double(&tms32031.r[TMR_R4])); break;
+ case CPUINFO_STR_REGISTER + TMS32031_R5F: sprintf(info->s, "R5F:!%12g", dsp_to_double(&tms32031.r[TMR_R5])); break;
+ case CPUINFO_STR_REGISTER + TMS32031_R6F: sprintf(info->s, "R6F:!%12g", dsp_to_double(&tms32031.r[TMR_R6])); break;
+ case CPUINFO_STR_REGISTER + TMS32031_R7F: sprintf(info->s, "R7F:!%12g", dsp_to_double(&tms32031.r[TMR_R7])); break;
+ case CPUINFO_STR_REGISTER + TMS32031_AR0: sprintf(info->s, "AR0:%08X", tms32031.r[TMR_AR0].i32[0]); break;
+ case CPUINFO_STR_REGISTER + TMS32031_AR1: sprintf(info->s, "AR1:%08X", tms32031.r[TMR_AR1].i32[0]); break;
+ case CPUINFO_STR_REGISTER + TMS32031_AR2: sprintf(info->s, "AR2:%08X", tms32031.r[TMR_AR2].i32[0]); break;
+ case CPUINFO_STR_REGISTER + TMS32031_AR3: sprintf(info->s, "AR3:%08X", tms32031.r[TMR_AR3].i32[0]); break;
+ case CPUINFO_STR_REGISTER + TMS32031_AR4: sprintf(info->s, "AR4:%08X", tms32031.r[TMR_AR4].i32[0]); break;
+ case CPUINFO_STR_REGISTER + TMS32031_AR5: sprintf(info->s, "AR5:%08X", tms32031.r[TMR_AR5].i32[0]); break;
+ case CPUINFO_STR_REGISTER + TMS32031_AR6: sprintf(info->s, "AR6:%08X", tms32031.r[TMR_AR6].i32[0]); break;
+ case CPUINFO_STR_REGISTER + TMS32031_AR7: sprintf(info->s, "AR7:%08X", tms32031.r[TMR_AR7].i32[0]); break;
+ case CPUINFO_STR_REGISTER + TMS32031_DP: sprintf(info->s, " DP:%02X", tms32031.r[TMR_DP].i8[0]); break;
+ case CPUINFO_STR_REGISTER + TMS32031_IR0: sprintf(info->s, "IR0:%08X", tms32031.r[TMR_IR0].i32[0]); break;
+ case CPUINFO_STR_REGISTER + TMS32031_IR1: sprintf(info->s, "IR1:%08X", tms32031.r[TMR_IR1].i32[0]); break;
+ case CPUINFO_STR_REGISTER + TMS32031_BK: sprintf(info->s, " BK:%08X", tms32031.r[TMR_BK].i32[0]); break;
+ case CPUINFO_STR_REGISTER + TMS32031_SP: sprintf(info->s, " SP:%08X", tms32031.r[TMR_SP].i32[0]); break;
+ case CPUINFO_STR_REGISTER + TMS32031_ST: sprintf(info->s, " ST:%08X", tms32031.r[TMR_ST].i32[0]); break;
+ case CPUINFO_STR_REGISTER + TMS32031_IE: sprintf(info->s, " IE:%08X", tms32031.r[TMR_IE].i32[0]); break;
+ case CPUINFO_STR_REGISTER + TMS32031_IF: sprintf(info->s, " IF:%08X", tms32031.r[TMR_IF].i32[0]); break;
+ case CPUINFO_STR_REGISTER + TMS32031_IOF: sprintf(info->s, "IOF:%08X", tms32031.r[TMR_IOF].i32[0]); break;
+ case CPUINFO_STR_REGISTER + TMS32031_RS: sprintf(info->s, " RS:%08X", tms32031.r[TMR_RS].i32[0]); break;
+ case CPUINFO_STR_REGISTER + TMS32031_RE: sprintf(info->s, " RE:%08X", tms32031.r[TMR_RE].i32[0]); break;
+ case CPUINFO_STR_REGISTER + TMS32031_RC: sprintf(info->s, " RC:%08X", tms32031.r[TMR_RC].i32[0]); break;
+ }
+}
+
+void tms32032_get_info(UINT32 state, cpuinfo *info)
+{
+ switch (state)
+ {
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map = construct_map_internal_32032; break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case CPUINFO_STR_NAME: strcpy(info->s, "TMS32032"); break;
+
+ default: tms32031_get_info(state, info); break;
+ }
+}