summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/dsp32/dsp32.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/cpu/dsp32/dsp32.c')
-rw-r--r--src/emu/cpu/dsp32/dsp32.c952
1 files changed, 952 insertions, 0 deletions
diff --git a/src/emu/cpu/dsp32/dsp32.c b/src/emu/cpu/dsp32/dsp32.c
new file mode 100644
index 00000000000..1c65533a8bd
--- /dev/null
+++ b/src/emu/cpu/dsp32/dsp32.c
@@ -0,0 +1,952 @@
+/***************************************************************************
+
+ dsp32.c
+ Core implementation for the portable DSP32 emulator.
+ Written by Aaron Giles
+
+****************************************************************************
+
+ Important note:
+
+ At this time, the emulator is rather incomplete. However, it is
+ sufficiently complete to run both Race Drivin' and Hard Drivin's
+ Airborne, which is all I was after.
+
+ Things that still need to be implemented:
+
+ * interrupts
+ * carry-reverse add operations
+ * do loops
+ * ieee/dsp conversions
+ * input/output conversion
+ * serial I/O
+
+ In addition, there are several optimizations enabled which make
+ assumptions about the code which may not be valid for other
+ applications. Check dsp32ops.c for details.
+
+***************************************************************************/
+
+#include <math.h>
+#include "debugger.h"
+#include "dsp32.h"
+
+
+
+/***************************************************************************
+ DEBUGGING
+***************************************************************************/
+
+#define DETECT_MISALIGNED_MEMORY 0
+
+
+
+/***************************************************************************
+ CONSTANTS
+***************************************************************************/
+
+/* internal register numbering for PIO registers */
+#define PIO_PAR 0
+#define PIO_PDR 1
+#define PIO_EMR 2
+#define PIO_ESR 3
+#define PIO_PCR 4
+#define PIO_PIR 5
+#define PIO_PARE 6
+#define PIO_PDR2 7
+#define PIO_RESERVED 8
+
+#define UPPER (0x00ff << 8)
+#define LOWER (0xff00 << 8)
+
+/* bits in the PCR register */
+#define PCR_RESET 0x001
+#define PCR_REGMAP 0x002
+#define PCR_ENI 0x004
+#define PCR_DMA 0x008
+#define PCR_AUTO 0x010
+#define PCR_PDFs 0x020
+#define PCR_PIFs 0x040
+#define PCR_RES 0x080
+#define PCR_DMA32 0x100
+#define PCR_PIO16 0x200
+#define PCR_FLG 0x400
+
+/* internal flag bits */
+#define UFLAGBIT 1
+#define VFLAGBIT 2
+
+
+
+/***************************************************************************
+ MACROS
+***************************************************************************/
+
+/* register mapping */
+#define R0 r[0]
+#define R1 r[1]
+#define R2 r[2]
+#define R3 r[3]
+#define R4 r[4]
+#define R5 r[5]
+#define R6 r[6]
+#define R7 r[7]
+#define R8 r[8]
+#define R9 r[9]
+#define R10 r[10]
+#define R11 r[11]
+#define R12 r[12]
+#define R13 r[13]
+#define R14 r[14]
+#define PC r[15]
+#define R0_ALT r[16]
+#define R15 r[17]
+#define R16 r[18]
+#define R17 r[19]
+#define R18 r[20]
+#define R19 r[21]
+#define RMM r[22]
+#define RPP r[23]
+#define R20 r[24]
+#define R21 r[25]
+#define DAUC r[26]
+#define IOC r[27]
+#define R22 r[29]
+#define PCSH r[30]
+
+#define A0 a[0]
+#define A1 a[1]
+#define A2 a[2]
+#define A3 a[3]
+#define A_0 a[4]
+#define A_1 a[5]
+
+#define OP dsp32.op
+
+#define zFLAG ((dsp32.nzcflags & 0xffffff) == 0)
+#define nFLAG ((dsp32.nzcflags & 0x800000) != 0)
+#define cFLAG ((dsp32.nzcflags & 0x1000000) != 0)
+#define vFLAG ((dsp32.vflags & 0x800000) != 0)
+#define ZFLAG (dsp32.NZflags == 0)
+#define NFLAG (dsp32.NZflags < 0)
+#define UFLAG (dsp32.VUflags & UFLAGBIT)
+#define VFLAG (dsp32.VUflags & VFLAGBIT)
+
+
+
+/***************************************************************************
+ STRUCTURES & TYPEDEFS
+***************************************************************************/
+
+/* DSP32 Registers */
+typedef struct
+{
+ /* core registers */
+ UINT32 r[32];
+ UINT32 pin, pout;
+ UINT32 ivtp;
+ UINT32 nzcflags;
+ UINT32 vflags;
+
+ double a[6];
+ double NZflags;
+ UINT8 VUflags;
+
+ double abuf[4];
+ UINT8 abufreg[4];
+ UINT8 abufVUflags[4];
+ UINT8 abufNZflags[4];
+ int abufcycle[4];
+ int abuf_index;
+
+ INT32 mbufaddr[4];
+ UINT32 mbufdata[4];
+ int mbuf_index;
+
+ UINT16 par;
+ UINT8 pare;
+ UINT16 pdr;
+ UINT16 pdr2;
+ UINT16 pir;
+ UINT16 pcr;
+ UINT16 emr;
+ UINT8 esr;
+ UINT16 pcw;
+ UINT8 piop;
+
+ UINT32 ibuf;
+ UINT32 isr;
+ UINT32 obuf;
+ UINT32 osr;
+
+ /* internal stuff */
+ UINT8 lastpins;
+ UINT32 ppc;
+ UINT32 op;
+ int interrupt_cycles;
+ void (*output_pins_changed)(UINT32 pins);
+} dsp32_regs;
+
+
+
+/***************************************************************************
+ FUNCTION PROTOTYPES
+***************************************************************************/
+
+static void dsp32c_reset(void);
+
+
+
+/***************************************************************************
+ PRIVATE GLOBAL VARIABLES
+***************************************************************************/
+
+static dsp32_regs dsp32;
+static int dsp32_icount;
+
+
+
+/***************************************************************************
+ MEMORY ACCESSORS
+***************************************************************************/
+
+#define ROPCODE(pc) cpu_readop32(pc)
+
+#define RBYTE(addr) program_read_byte_32le(addr)
+#define WBYTE(addr,data) program_write_byte_32le((addr), data)
+
+#if (!DETECT_MISALIGNED_MEMORY)
+
+#define RWORD(addr) program_read_word_32le(addr)
+#define WWORD(addr,data) program_write_word_32le((addr), data)
+#define RLONG(addr) program_read_dword_32le(addr)
+#define WLONG(addr,data) program_write_dword_32le((addr), data)
+
+#else
+
+INLINE UINT16 RWORD(offs_t addr)
+{
+ UINT16 data;
+ if (addr & 1) fprintf(stderr, "Unaligned word read @ %06X, PC=%06X\n", addr, dsp32.PC);
+ data = program_read_word_32le(addr);
+ return data;
+}
+
+INLINE UINT32 RLONG(offs_t addr)
+{
+ UINT32 data;
+ if (addr & 3) fprintf(stderr, "Unaligned long read @ %06X, PC=%06X\n", addr, dsp32.PC);
+ data = program_write_word_32le(addr);
+ return data;
+}
+
+INLINE void WWORD(offs_t addr, UINT16 data)
+{
+ if (addr & 1) fprintf(stderr, "Unaligned word write @ %06X, PC=%06X\n", addr, dsp32.PC);
+ program_read_dword_32le((addr), data);
+}
+
+INLINE void WLONG(offs_t addr, UINT32 data)
+{
+ if (addr & 3) fprintf(stderr, "Unaligned long write @ %06X, PC=%06X\n", addr, dsp32.PC);
+ program_write_dword_32le((addr), data);
+}
+
+#endif
+
+
+
+/***************************************************************************
+ EXECEPTION HANDLING
+***************************************************************************/
+
+INLINE void generate_exception(int exception)
+{
+}
+
+
+INLINE void invalid_instruction(UINT32 op)
+{
+}
+
+
+
+/***************************************************************************
+ IRQ HANDLING
+***************************************************************************/
+
+static void check_irqs(void)
+{
+ /* finish me! */
+}
+
+
+static void set_irq_line(int irqline, int state)
+{
+ /* finish me! */
+}
+
+
+
+/***************************************************************************
+ REGISTER HANDLING
+***************************************************************************/
+
+static void update_pcr(UINT16 newval)
+{
+ UINT16 oldval = dsp32.pcr;
+ dsp32.pcr = newval;
+
+ /* reset the chip if we get a reset */
+ if ((oldval & PCR_RESET) == 0 && (newval & PCR_RESET) != 0)
+ dsp32c_reset();
+
+ /* track the state of the output pins */
+ if (dsp32.output_pins_changed)
+ {
+ UINT16 newoutput = ((newval & (PCR_PIFs | PCR_ENI)) == (PCR_PIFs | PCR_ENI)) ? DSP32_OUTPUT_PIF : 0;
+ if (newoutput != dsp32.lastpins)
+ {
+ dsp32.lastpins = newoutput;
+ (*dsp32.output_pins_changed)(newoutput);
+ }
+ }
+}
+
+
+
+/***************************************************************************
+ CONTEXT SWITCHING
+***************************************************************************/
+
+static void dsp32c_get_context(void *dst)
+{
+ /* copy the context */
+ if (dst)
+ *(dsp32_regs *)dst = dsp32;
+}
+
+
+static void dsp32c_set_context(void *src)
+{
+ /* copy the context */
+ if (src)
+ dsp32 = *(dsp32_regs *)src;
+ memory_set_opbase(dsp32.PC);
+
+ /* check for IRQs */
+ check_irqs();
+}
+
+
+
+/***************************************************************************
+ INITIALIZATION AND SHUTDOWN
+***************************************************************************/
+
+static void dsp32c_init(int index, int clock, const void *_config, int (*irqcallback)(int))
+{
+ const struct dsp32_config *config = _config;
+
+ /* copy in config data */
+ if (config)
+ dsp32.output_pins_changed = config->output_pins_changed;
+}
+
+
+static void dsp32c_reset(void)
+{
+ /* reset goes to 0 */
+ dsp32.PC = 0;
+ memory_set_opbase(dsp32.PC);
+
+ /* clear some registers */
+ dsp32.pcw &= 0x03ff;
+ update_pcr(dsp32.pcr & PCR_RESET);
+ dsp32.esr = 0;
+ dsp32.emr = 0xffff;
+
+ /* initialize fixed registers */
+ dsp32.R0 = dsp32.R0_ALT = 0;
+ dsp32.RMM = -1;
+ dsp32.RPP = 1;
+ dsp32.A_0 = 0.0;
+ dsp32.A_1 = 1.0;
+
+ /* init internal stuff */
+ dsp32.abufcycle[0] = dsp32.abufcycle[1] = dsp32.abufcycle[2] = dsp32.abufcycle[3] = 12345678;
+ dsp32.mbufaddr[0] = dsp32.mbufaddr[1] = dsp32.mbufaddr[2] = dsp32.mbufaddr[3] = 1;
+}
+
+
+static void dsp32c_exit(void)
+{
+}
+
+
+
+/***************************************************************************
+ CORE INCLUDE
+***************************************************************************/
+
+#include "dsp32ops.c"
+
+
+
+/***************************************************************************
+ CORE EXECUTION LOOP
+***************************************************************************/
+
+static int dsp32c_execute(int cycles)
+{
+ /* skip if halted */
+ if ((dsp32.pcr & PCR_RESET) == 0)
+ return cycles;
+
+ /* count cycles and interrupt cycles */
+ dsp32_icount = cycles;
+ dsp32_icount -= dsp32.interrupt_cycles;
+ dsp32.interrupt_cycles = 0;
+
+ /* update buffered accumulator values */
+ dsp32.abufcycle[0] += dsp32_icount;
+ dsp32.abufcycle[1] += dsp32_icount;
+ dsp32.abufcycle[2] += dsp32_icount;
+ dsp32.abufcycle[3] += dsp32_icount;
+
+ while (dsp32_icount > 0)
+ execute_one();
+
+ dsp32_icount -= dsp32.interrupt_cycles;
+ dsp32.interrupt_cycles = 0;
+
+ /* normalize buffered accumulator values */
+ dsp32.abufcycle[0] -= dsp32_icount;
+ dsp32.abufcycle[1] -= dsp32_icount;
+ dsp32.abufcycle[2] -= dsp32_icount;
+ dsp32.abufcycle[3] -= dsp32_icount;
+
+ return cycles - dsp32_icount;
+}
+
+
+
+/***************************************************************************
+ DISASSEMBLY HOOK
+***************************************************************************/
+
+#ifdef MAME_DEBUG
+static offs_t dsp32c_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram)
+{
+ extern unsigned dasm_dsp32(char *, unsigned, UINT32);
+ return dasm_dsp32(buffer, pc, oprom[0] | (oprom[1] << 8) | (oprom[2] << 16) | (oprom[3] << 24));
+}
+#endif /* MAME_DEBUG */
+
+
+
+/***************************************************************************
+ PARALLEL INTERFACE WRITES
+***************************************************************************/
+
+/* context finder */
+INLINE dsp32_regs *FINDCONTEXT(int cpu)
+{
+ dsp32_regs *context = cpunum_get_context_ptr(cpu);
+ if (!context)
+ context = &dsp32;
+ return context;
+}
+
+static UINT32 regmap[4][16] =
+{
+ { /* DSP32 compatible mode */
+ PIO_PAR|LOWER, PIO_PAR|UPPER, PIO_PDR|LOWER, PIO_PDR|UPPER,
+ PIO_EMR|LOWER, PIO_EMR|UPPER, PIO_ESR|LOWER, PIO_PCR|LOWER,
+ PIO_PIR|UPPER, PIO_PIR|UPPER, PIO_PIR|UPPER, PIO_PIR|UPPER,
+ PIO_PIR|UPPER, PIO_PIR|UPPER, PIO_PIR|UPPER, PIO_PIR|UPPER
+ },
+ { /* DSP32C 8-bit mode */
+ PIO_PAR|LOWER, PIO_PAR|UPPER, PIO_PDR|LOWER, PIO_PDR|UPPER,
+ PIO_EMR|LOWER, PIO_EMR|UPPER, PIO_ESR|LOWER, PIO_PCR|LOWER,
+ PIO_PIR|LOWER, PIO_PIR|UPPER, PIO_PCR|UPPER, PIO_PARE|LOWER,
+ PIO_PDR2|LOWER,PIO_PDR2|UPPER,PIO_RESERVED, PIO_RESERVED
+ },
+ { /* DSP32C illegal mode */
+ PIO_RESERVED, PIO_RESERVED, PIO_RESERVED, PIO_RESERVED,
+ PIO_RESERVED, PIO_RESERVED, PIO_RESERVED, PIO_RESERVED,
+ PIO_RESERVED, PIO_RESERVED, PIO_RESERVED, PIO_RESERVED,
+ PIO_RESERVED, PIO_RESERVED, PIO_RESERVED, PIO_RESERVED
+ },
+ { /* DSP32C 16-bit mode */
+ PIO_PAR, PIO_RESERVED, PIO_PDR, PIO_RESERVED,
+ PIO_EMR, PIO_RESERVED, PIO_ESR|LOWER, PIO_PCR,
+ PIO_PIR, PIO_RESERVED, PIO_RESERVED, PIO_PARE|LOWER,
+ PIO_PDR2, PIO_RESERVED, PIO_RESERVED, PIO_RESERVED
+ }
+};
+
+
+
+/***************************************************************************
+ PARALLEL INTERFACE WRITES
+***************************************************************************/
+
+INLINE void dma_increment(void)
+{
+ if (dsp32.pcr & PCR_AUTO)
+ {
+ int amount = (dsp32.pcr & PCR_DMA32) ? 4 : 2;
+ dsp32.par += amount;
+ if (dsp32.par < amount)
+ dsp32.pare++;
+ }
+}
+
+
+INLINE void dma_load(void)
+{
+ /* only process if DMA is enabled */
+ if (dsp32.pcr & PCR_DMA)
+ {
+ UINT32 addr = dsp32.par | (dsp32.pare << 16);
+
+ /* 16-bit case */
+ if (!(dsp32.pcr & PCR_DMA32))
+ dsp32.pdr = RWORD(addr & 0xfffffe);
+
+ /* 32-bit case */
+ else
+ {
+ UINT32 temp = RLONG(addr & 0xfffffc);
+ dsp32.pdr = temp >> 16;
+ dsp32.pdr2 = temp & 0xffff;
+ }
+
+ /* set the PDF flag to indicate we have data ready */
+ update_pcr(dsp32.pcr | PCR_PDFs);
+ }
+}
+
+
+INLINE void dma_store(void)
+{
+ /* only process if DMA is enabled */
+ if (dsp32.pcr & PCR_DMA)
+ {
+ UINT32 addr = dsp32.par | (dsp32.pare << 16);
+
+ /* 16-bit case */
+ if (!(dsp32.pcr & PCR_DMA32))
+ WWORD(addr & 0xfffffe, dsp32.pdr);
+
+ /* 32-bit case */
+ else
+ WLONG(addr & 0xfffffc, (dsp32.pdr << 16) | dsp32.pdr2);
+
+ /* clear the PDF flag to indicate we have taken the data */
+ update_pcr(dsp32.pcr & ~PCR_PDFs);
+ }
+}
+
+
+void dsp32c_pio_w(int cpunum, int reg, int data)
+{
+ UINT16 mask;
+ UINT8 mode;
+
+ cpuintrf_push_context(cpunum);
+
+ /* look up register and mask */
+ mode = ((dsp32.pcr >> 8) & 2) | ((dsp32.pcr >> 1) & 1);
+ reg = regmap[mode][reg];
+ mask = reg >> 8;
+ if (mask == 0x00ff) data <<= 8;
+ data &= ~mask;
+ reg &= 0xff;
+
+ /* switch off the register */
+ switch (reg)
+ {
+ case PIO_PAR:
+ dsp32.par = (dsp32.par & mask) | data;
+
+ /* trigger a load on the upper half */
+ if (!(mask & 0xff00))
+ dma_load();
+ break;
+
+ case PIO_PARE:
+ dsp32.pare = (dsp32.pare & mask) | data;
+ break;
+
+ case PIO_PDR:
+ dsp32.pdr = (dsp32.pdr & mask) | data;
+
+ /* trigger a write and PDF setting on the upper half */
+ if (!(mask & 0xff00))
+ {
+ dma_store();
+ dma_increment();
+ }
+ break;
+
+ case PIO_PDR2:
+ dsp32.pdr2 = (dsp32.pdr2 & mask) | data;
+ break;
+
+ case PIO_EMR:
+ dsp32.emr = (dsp32.emr & mask) | data;
+ break;
+
+ case PIO_ESR:
+ dsp32.esr = (dsp32.esr & mask) | data;
+ break;
+
+ case PIO_PCR:
+ mask |= 0x0060;
+ data &= ~mask;
+ update_pcr((dsp32.pcr & mask) | data);
+ break;
+
+ case PIO_PIR:
+ dsp32.pir = (dsp32.pir & mask) | data;
+
+ /* set PIF on upper half */
+ if (!(mask & 0xff00))
+ update_pcr(dsp32.pcr | PCR_PIFs);
+ break;
+
+ /* error case */
+ default:
+ logerror("dsp32_pio_w called on invalid register %d\n", reg);
+ break;
+ }
+
+ cpuintrf_pop_context();
+}
+
+
+
+/***************************************************************************
+ PARALLEL INTERFACE READS
+***************************************************************************/
+
+int dsp32c_pio_r(int cpunum, int reg)
+{
+ UINT16 mask, result = 0xffff;
+ UINT8 mode, shift = 0;
+
+ cpuintrf_push_context(cpunum);
+
+ /* look up register and mask */
+ mode = ((dsp32.pcr >> 8) & 2) | ((dsp32.pcr >> 1) & 1);
+ reg = regmap[mode][reg];
+ mask = reg >> 8;
+ if (mask == 0x00ff) mask = 0xff00, shift = 8;
+ reg &= 0xff;
+
+ /* switch off the register */
+ switch (reg)
+ {
+ case PIO_PAR:
+ result = dsp32.par | 1;
+ break;
+
+ case PIO_PARE:
+ result = dsp32.pare;
+ break;
+
+ case PIO_PDR:
+ result = dsp32.pdr;
+
+ /* trigger an increment on the lower half */
+ if (shift != 8)
+ dma_increment();
+
+ /* trigger a fetch on the upper half */
+ if (!(mask & 0xff00))
+ dma_load();
+ break;
+
+ case PIO_PDR2:
+ result = dsp32.pdr2;
+ break;
+
+ case PIO_EMR:
+ result = dsp32.emr;
+ break;
+
+ case PIO_ESR:
+ result = dsp32.esr;
+ break;
+
+ case PIO_PCR:
+ result = dsp32.pcr;
+ break;
+
+ case PIO_PIR:
+ if (!(mask & 0xff00))
+ update_pcr(dsp32.pcr & ~PCR_PIFs); /* clear PIFs */
+ result = dsp32.pir;
+ break;
+
+ /* error case */
+ default:
+ logerror("dsp32_pio_w called on invalid register %d\n", reg);
+ break;
+ }
+
+ cpuintrf_pop_context();
+ return (result >> shift) & ~mask;
+}
+
+
+
+/**************************************************************************
+ * Generic set_info
+ **************************************************************************/
+
+static void dsp32c_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 + DSP32_IRQ0: set_irq_line(DSP32_IRQ0, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + DSP32_IRQ1: set_irq_line(DSP32_IRQ1, info->i); break;
+
+ /* CAU */
+ case CPUINFO_INT_PC:
+ case CPUINFO_INT_REGISTER + DSP32_PC: dsp32.PC = info->i & 0xffffff; break;
+ case CPUINFO_INT_REGISTER + DSP32_R0: dsp32.R0 = info->i & 0xffffff; break;
+ case CPUINFO_INT_REGISTER + DSP32_R1: dsp32.R1 = info->i & 0xffffff; break;
+ case CPUINFO_INT_REGISTER + DSP32_R2: dsp32.R2 = info->i & 0xffffff; break;
+ case CPUINFO_INT_REGISTER + DSP32_R3: dsp32.R3 = info->i & 0xffffff; break;
+ case CPUINFO_INT_REGISTER + DSP32_R4: dsp32.R4 = info->i & 0xffffff; break;
+ case CPUINFO_INT_REGISTER + DSP32_R5: dsp32.R5 = info->i & 0xffffff; break;
+ case CPUINFO_INT_REGISTER + DSP32_R6: dsp32.R6 = info->i & 0xffffff; break;
+ case CPUINFO_INT_REGISTER + DSP32_R7: dsp32.R7 = info->i & 0xffffff; break;
+ case CPUINFO_INT_REGISTER + DSP32_R8: dsp32.R8 = info->i & 0xffffff; break;
+ case CPUINFO_INT_REGISTER + DSP32_R9: dsp32.R9 = info->i & 0xffffff; break;
+ case CPUINFO_INT_REGISTER + DSP32_R10: dsp32.R10 = info->i & 0xffffff; break;
+ case CPUINFO_INT_REGISTER + DSP32_R11: dsp32.R11 = info->i & 0xffffff; break;
+ case CPUINFO_INT_REGISTER + DSP32_R12: dsp32.R12 = info->i & 0xffffff; break;
+ case CPUINFO_INT_REGISTER + DSP32_R13: dsp32.R13 = info->i & 0xffffff; break;
+ case CPUINFO_INT_REGISTER + DSP32_R14: dsp32.R14 = info->i & 0xffffff; break;
+ case CPUINFO_INT_REGISTER + DSP32_R15: dsp32.R15 = info->i & 0xffffff; break;
+ case CPUINFO_INT_REGISTER + DSP32_R16: dsp32.R16 = info->i & 0xffffff; break;
+ case CPUINFO_INT_REGISTER + DSP32_R17: dsp32.R17 = info->i & 0xffffff; break;
+ case CPUINFO_INT_REGISTER + DSP32_R18: dsp32.R18 = info->i & 0xffffff; break;
+ case CPUINFO_INT_REGISTER + DSP32_R19: dsp32.R19 = info->i & 0xffffff; break;
+ case CPUINFO_INT_REGISTER + DSP32_R20: dsp32.R20 = info->i & 0xffffff; break;
+ case CPUINFO_INT_SP:
+ case CPUINFO_INT_REGISTER + DSP32_R21: dsp32.R21 = info->i & 0xffffff; break;
+ case CPUINFO_INT_REGISTER + DSP32_R22: dsp32.R22 = info->i & 0xffffff; break;
+ case CPUINFO_INT_REGISTER + DSP32_PIN: dsp32.pin = info->i & 0xffffff; break;
+ case CPUINFO_INT_REGISTER + DSP32_POUT: dsp32.pout = info->i & 0xffffff; break;
+ case CPUINFO_INT_REGISTER + DSP32_IVTP: dsp32.ivtp = info->i & 0xffffff; break;
+
+ /* DAU */
+ case CPUINFO_INT_REGISTER + DSP32_A0: dsp32.A0 = info->i; /* fix me -- very wrong */ break;
+ case CPUINFO_INT_REGISTER + DSP32_A1: dsp32.A1 = info->i; /* fix me -- very wrong */ break;
+ case CPUINFO_INT_REGISTER + DSP32_A2: dsp32.A2 = info->i; /* fix me -- very wrong */ break;
+ case CPUINFO_INT_REGISTER + DSP32_A3: dsp32.A3 = info->i; /* fix me -- very wrong */ break;
+ case CPUINFO_INT_REGISTER + DSP32_DAUC: dsp32.DAUC = info->i; break;
+
+ /* PIO */
+ case CPUINFO_INT_REGISTER + DSP32_PAR: dsp32.par = info->i; break;
+ case CPUINFO_INT_REGISTER + DSP32_PDR: dsp32.pdr = info->i; break;
+ case CPUINFO_INT_REGISTER + DSP32_PIR: dsp32.pir = info->i; break;
+ case CPUINFO_INT_REGISTER + DSP32_PCR: update_pcr(info->i & 0x3ff); break;
+ case CPUINFO_INT_REGISTER + DSP32_EMR: dsp32.emr = info->i; break;
+ case CPUINFO_INT_REGISTER + DSP32_ESR: dsp32.esr = info->i; break;
+ case CPUINFO_INT_REGISTER + DSP32_PCW: dsp32.pcw = info->i; break;
+ case CPUINFO_INT_REGISTER + DSP32_PIOP: dsp32.piop = info->i; break;
+
+ /* SIO */
+ case CPUINFO_INT_REGISTER + DSP32_IBUF: dsp32.ibuf = info->i; break;
+ case CPUINFO_INT_REGISTER + DSP32_ISR: dsp32.isr = info->i; break;
+ case CPUINFO_INT_REGISTER + DSP32_OBUF: dsp32.obuf = info->i; break;
+ case CPUINFO_INT_REGISTER + DSP32_OSR: dsp32.osr = info->i; break;
+ case CPUINFO_INT_REGISTER + DSP32_IOC: dsp32.IOC = info->i & 0xfffff; break;
+ }
+}
+
+
+
+/**************************************************************************
+ * Generic get_info
+ **************************************************************************/
+
+void dsp32c_get_info(UINT32 state, cpuinfo *info)
+{
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(dsp32); break;
+ case CPUINFO_INT_INPUT_LINES: info->i = 2; 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 = 4; 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 = 0; 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 + DSP32_IRQ0: info->i = 0; break;
+ case CPUINFO_INT_INPUT_STATE + DSP32_IRQ1: info->i = 0; break;
+
+ case CPUINFO_INT_PREVIOUSPC: info->i = dsp32.ppc; break;
+
+ /* CAU */
+ case CPUINFO_INT_PC:
+ case CPUINFO_INT_REGISTER + DSP32_PC: info->i = dsp32.PC; break;
+ case CPUINFO_INT_REGISTER + DSP32_R0: info->i = dsp32.R0; break;
+ case CPUINFO_INT_REGISTER + DSP32_R1: info->i = dsp32.R1; break;
+ case CPUINFO_INT_REGISTER + DSP32_R2: info->i = dsp32.R2; break;
+ case CPUINFO_INT_REGISTER + DSP32_R3: info->i = dsp32.R3; break;
+ case CPUINFO_INT_REGISTER + DSP32_R4: info->i = dsp32.R4; break;
+ case CPUINFO_INT_REGISTER + DSP32_R5: info->i = dsp32.R5; break;
+ case CPUINFO_INT_REGISTER + DSP32_R6: info->i = dsp32.R6; break;
+ case CPUINFO_INT_REGISTER + DSP32_R7: info->i = dsp32.R7; break;
+ case CPUINFO_INT_REGISTER + DSP32_R8: info->i = dsp32.R8; break;
+ case CPUINFO_INT_REGISTER + DSP32_R9: info->i = dsp32.R9; break;
+ case CPUINFO_INT_REGISTER + DSP32_R10: info->i = dsp32.R10; break;
+ case CPUINFO_INT_REGISTER + DSP32_R11: info->i = dsp32.R11; break;
+ case CPUINFO_INT_REGISTER + DSP32_R12: info->i = dsp32.R12; break;
+ case CPUINFO_INT_REGISTER + DSP32_R13: info->i = dsp32.R13; break;
+ case CPUINFO_INT_REGISTER + DSP32_R14: info->i = dsp32.R14; break;
+ case CPUINFO_INT_REGISTER + DSP32_R15: info->i = dsp32.R15; break;
+ case CPUINFO_INT_REGISTER + DSP32_R16: info->i = dsp32.R16; break;
+ case CPUINFO_INT_REGISTER + DSP32_R17: info->i = dsp32.R17; break;
+ case CPUINFO_INT_REGISTER + DSP32_R18: info->i = dsp32.R18; break;
+ case CPUINFO_INT_REGISTER + DSP32_R19: info->i = dsp32.R19; break;
+ case CPUINFO_INT_REGISTER + DSP32_R20: info->i = dsp32.R20; break;
+ case CPUINFO_INT_SP:
+ case CPUINFO_INT_REGISTER + DSP32_R21: info->i = dsp32.R21; break;
+ case CPUINFO_INT_REGISTER + DSP32_R22: info->i = dsp32.R22; break;
+ case CPUINFO_INT_REGISTER + DSP32_PIN: info->i = dsp32.pin; break;
+ case CPUINFO_INT_REGISTER + DSP32_POUT: info->i = dsp32.pout; break;
+ case CPUINFO_INT_REGISTER + DSP32_IVTP: info->i = dsp32.ivtp; break;
+
+ /* DAU */
+ case CPUINFO_INT_REGISTER + DSP32_A0: info->i = dsp32.A0; /* fix me -- very wrong */ break;
+ case CPUINFO_INT_REGISTER + DSP32_A1: info->i = dsp32.A1; /* fix me -- very wrong */ break;
+ case CPUINFO_INT_REGISTER + DSP32_A2: info->i = dsp32.A2; /* fix me -- very wrong */ break;
+ case CPUINFO_INT_REGISTER + DSP32_A3: info->i = dsp32.A3; /* fix me -- very wrong */ break;
+ case CPUINFO_INT_REGISTER + DSP32_DAUC: info->i = dsp32.DAUC; break;
+
+ /* PIO */
+ case CPUINFO_INT_REGISTER + DSP32_PAR: info->i = dsp32.par; break;
+ case CPUINFO_INT_REGISTER + DSP32_PDR: info->i = dsp32.pdr; break;
+ case CPUINFO_INT_REGISTER + DSP32_PIR: info->i = dsp32.pir; break;
+ case CPUINFO_INT_REGISTER + DSP32_PCR: info->i = dsp32.pcr; break;
+ case CPUINFO_INT_REGISTER + DSP32_EMR: info->i = dsp32.emr; break;
+ case CPUINFO_INT_REGISTER + DSP32_ESR: info->i = dsp32.esr; break;
+ case CPUINFO_INT_REGISTER + DSP32_PCW: info->i = dsp32.pcw; break;
+ case CPUINFO_INT_REGISTER + DSP32_PIOP: info->i = dsp32.piop; break;
+
+ /* SIO */
+ case CPUINFO_INT_REGISTER + DSP32_IBUF: info->i = dsp32.ibuf; break;
+ case CPUINFO_INT_REGISTER + DSP32_ISR: info->i = dsp32.isr; break;
+ case CPUINFO_INT_REGISTER + DSP32_OBUF: info->i = dsp32.obuf; break;
+ case CPUINFO_INT_REGISTER + DSP32_OSR: info->i = dsp32.osr; break;
+ case CPUINFO_INT_REGISTER + DSP32_IOC: info->i = dsp32.IOC; break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_PTR_SET_INFO: info->setinfo = dsp32c_set_info; break;
+ case CPUINFO_PTR_GET_CONTEXT: info->getcontext = dsp32c_get_context; break;
+ case CPUINFO_PTR_SET_CONTEXT: info->setcontext = dsp32c_set_context; break;
+ case CPUINFO_PTR_INIT: info->init = dsp32c_init; break;
+ case CPUINFO_PTR_RESET: info->reset = dsp32c_reset; break;
+ case CPUINFO_PTR_EXIT: info->exit = dsp32c_exit; break;
+ case CPUINFO_PTR_EXECUTE: info->execute = dsp32c_execute; break;
+ case CPUINFO_PTR_BURN: info->burn = NULL; break;
+#ifdef MAME_DEBUG
+ case CPUINFO_PTR_DISASSEMBLE: info->disassemble = dsp32c_dasm; break;
+#endif /* MAME_DEBUG */
+ case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &dsp32_icount; break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case CPUINFO_STR_NAME: strcpy(info->s, "DSP32C"); break;
+ case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "Lucent DSP32"); 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, "Aaron Giles"); break;
+
+ case CPUINFO_STR_FLAGS:
+ sprintf(info->s, "%c%c%c%c%c%c%c%c",
+ NFLAG ? 'N':'.',
+ ZFLAG ? 'Z':'.',
+ UFLAG ? 'U':'.',
+ VFLAG ? 'V':'.',
+ nFLAG ? 'n':'.',
+ zFLAG ? 'z':'.',
+ cFLAG ? 'c':'.',
+ vFLAG ? 'v':'.');
+ break;
+
+ /* CAU */
+ case CPUINFO_STR_REGISTER + DSP32_PC: sprintf(info->s, "PC: %06X", dsp32.PC); break;
+ case CPUINFO_STR_REGISTER + DSP32_R0: sprintf(info->s, "R0: %06X", dsp32.R0); break;
+ case CPUINFO_STR_REGISTER + DSP32_R1: sprintf(info->s, "R1: %06X", dsp32.R1); break;
+ case CPUINFO_STR_REGISTER + DSP32_R2: sprintf(info->s, "R2: %06X", dsp32.R2); break;
+ case CPUINFO_STR_REGISTER + DSP32_R3: sprintf(info->s, "R3: %06X", dsp32.R3); break;
+ case CPUINFO_STR_REGISTER + DSP32_R4: sprintf(info->s, "R4: %06X", dsp32.R4); break;
+ case CPUINFO_STR_REGISTER + DSP32_R5: sprintf(info->s, "R5: %06X", dsp32.R5); break;
+ case CPUINFO_STR_REGISTER + DSP32_R6: sprintf(info->s, "R6: %06X", dsp32.R6); break;
+ case CPUINFO_STR_REGISTER + DSP32_R7: sprintf(info->s, "R7: %06X", dsp32.R7); break;
+ case CPUINFO_STR_REGISTER + DSP32_R8: sprintf(info->s, "R8: %06X", dsp32.R8); break;
+ case CPUINFO_STR_REGISTER + DSP32_R9: sprintf(info->s, "R9: %06X", dsp32.R9); break;
+ case CPUINFO_STR_REGISTER + DSP32_R10: sprintf(info->s, "R10:%06X", dsp32.R10); break;
+ case CPUINFO_STR_REGISTER + DSP32_R11: sprintf(info->s, "R11:%06X", dsp32.R11); break;
+ case CPUINFO_STR_REGISTER + DSP32_R12: sprintf(info->s, "R12:%06X", dsp32.R12); break;
+ case CPUINFO_STR_REGISTER + DSP32_R13: sprintf(info->s, "R13:%06X", dsp32.R13); break;
+ case CPUINFO_STR_REGISTER + DSP32_R14: sprintf(info->s, "R14:%06X", dsp32.R14); break;
+ case CPUINFO_STR_REGISTER + DSP32_R15: sprintf(info->s, "R15:%06X", dsp32.R15); break;
+ case CPUINFO_STR_REGISTER + DSP32_R16: sprintf(info->s, "R16:%06X", dsp32.R16); break;
+ case CPUINFO_STR_REGISTER + DSP32_R17: sprintf(info->s, "R17:%06X", dsp32.R17); break;
+ case CPUINFO_STR_REGISTER + DSP32_R18: sprintf(info->s, "R18:%06X", dsp32.R18); break;
+ case CPUINFO_STR_REGISTER + DSP32_R19: sprintf(info->s, "R19:%06X", dsp32.R19); break;
+ case CPUINFO_STR_REGISTER + DSP32_R20: sprintf(info->s, "R20:%06X", dsp32.R20); break;
+ case CPUINFO_STR_REGISTER + DSP32_R21: sprintf(info->s, "R21:%06X", dsp32.R21); break;
+ case CPUINFO_STR_REGISTER + DSP32_R22: sprintf(info->s, "R22:%06X", dsp32.R22); break;
+ case CPUINFO_STR_REGISTER + DSP32_PIN: sprintf(info->s, "PIN:%06X", dsp32.pin); break;
+ case CPUINFO_STR_REGISTER + DSP32_POUT: sprintf(info->s, "POUT:%06X", dsp32.pout); break;
+ case CPUINFO_STR_REGISTER + DSP32_IVTP: sprintf(info->s, "IVTP:%06X", dsp32.ivtp); break;
+
+ /* DAU */
+ case CPUINFO_STR_REGISTER + DSP32_A0: sprintf(info->s, "A0:%8g", dsp32.A0); break;
+ case CPUINFO_STR_REGISTER + DSP32_A1: sprintf(info->s, "A1:%8g", dsp32.A1); break;
+ case CPUINFO_STR_REGISTER + DSP32_A2: sprintf(info->s, "A2:%8g", dsp32.A2); break;
+ case CPUINFO_STR_REGISTER + DSP32_A3: sprintf(info->s, "A3:%8g", dsp32.A3); break;
+ case CPUINFO_STR_REGISTER + DSP32_DAUC: sprintf(info->s, "DAUC:%02X", dsp32.DAUC); break;
+
+ /* PIO */
+ case CPUINFO_STR_REGISTER + DSP32_PAR: sprintf(info->s, "PAR:%08X", dsp32.par); break;
+ case CPUINFO_STR_REGISTER + DSP32_PDR: sprintf(info->s, "PDR:%08X", dsp32.pdr); break;
+ case CPUINFO_STR_REGISTER + DSP32_PIR: sprintf(info->s, "PIR:%04X", dsp32.pir); break;
+ case CPUINFO_STR_REGISTER + DSP32_PCR: sprintf(info->s, "PCR:%03X", dsp32.pcr); break;
+ case CPUINFO_STR_REGISTER + DSP32_EMR: sprintf(info->s, "EMR:%04X", dsp32.emr); break;
+ case CPUINFO_STR_REGISTER + DSP32_ESR: sprintf(info->s, "ESR:%02X", dsp32.esr); break;
+ case CPUINFO_STR_REGISTER + DSP32_PCW: sprintf(info->s, "PCW:%04X", dsp32.pcw); break;
+ case CPUINFO_STR_REGISTER + DSP32_PIOP: sprintf(info->s, "PIOP:%02X", dsp32.piop); break;
+
+ /* SIO */
+ case CPUINFO_STR_REGISTER + DSP32_IBUF: sprintf(info->s, "IBUF:%08X", dsp32.ibuf); break;
+ case CPUINFO_STR_REGISTER + DSP32_ISR: sprintf(info->s, "ISR:%08X", dsp32.isr); break;
+ case CPUINFO_STR_REGISTER + DSP32_OBUF: sprintf(info->s, "OBUF:%08X", dsp32.obuf); break;
+ case CPUINFO_STR_REGISTER + DSP32_OSR: sprintf(info->s, "OSR:%08X", dsp32.osr); break;
+ case CPUINFO_STR_REGISTER + DSP32_IOC: sprintf(info->s, "IOC:%05X", dsp32.IOC); break;
+ }
+}