summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/cpu/dsp56k/dsp56k.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/cpu/dsp56k/dsp56k.c')
-rw-r--r--trunk/src/emu/cpu/dsp56k/dsp56k.c677
1 files changed, 677 insertions, 0 deletions
diff --git a/trunk/src/emu/cpu/dsp56k/dsp56k.c b/trunk/src/emu/cpu/dsp56k/dsp56k.c
new file mode 100644
index 00000000000..565ac5484e8
--- /dev/null
+++ b/trunk/src/emu/cpu/dsp56k/dsp56k.c
@@ -0,0 +1,677 @@
+/***************************************************************************
+
+ dsp56k.c
+ Core implementation for the portable DSP56k emulator.
+ Written by Andrew Gardner
+
+****************************************************************************
+
+ Note:
+ This CPU emulator is very much a work-in-progress.
+
+ DONE:
+ 1: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, , , , , , ,18, , ,
+
+ TODO:
+ X 1-6 Explore CORE naming scheme.
+ - 1-9 paragraph 1 : memory access timings
+ - 1-9 Data ALU arithmetic operations generally use fractional two's complement arithmetic
+ (Unsigned numbers are only supported by the multiply and multiply-accumulate instruction)
+ - 1-9 For fractional arithmetic, the 31-bit product is added to the 40-bit contents of A or B. No pipeline!
+ - 1-10 Two types of rounding: convergent rounding and two's complement rounding. See status register bit R.
+ - 1-10 Logic unit is 16-bits wide and works on MSP portion of accum register
+ - 1-10 The AGU can implement three types of arithmetic: linear, modulo, and reverse carry.
+ - 1-12 "Two external interrupt pins!!!"
+ - 1-12 Take care of all interrupt priority (IPR) stuff!
+ - 1-19 Memory WAIT states
+ - 1-20 The timer's interesting!
+ - 1-21 Vectored exception requests on the Host Interface!
+***************************************************************************/
+
+#include "opcode.h"
+
+#include "emu.h"
+#include "debugger.h"
+#include "dsp56k.h"
+
+#include "dsp56def.h"
+
+using namespace DSP56K;
+
+/***************************************************************************
+ FUNCTION PROTOTYPES
+***************************************************************************/
+static CPU_RESET( dsp56k );
+
+
+/***************************************************************************
+ COMPONENT FUNCTIONALITY
+***************************************************************************/
+/* 1-9 ALU */
+// #include "dsp56alu.h"
+
+/* 1-10 Address Generation Unit (AGU) */
+// #include "dsp56agu.h"
+
+/* 1-11 Program Control Unit (PCU) */
+#include "dsp56pcu.h"
+
+/* 5-1 Host Interface (HI) */
+//#include "dsp56hi.h"
+
+/* 4-8 Memory handlers for on-chip peripheral memory. */
+#include "dsp56mem.h"
+
+
+/***************************************************************************
+ Direct Update Handler
+***************************************************************************/
+DIRECT_UPDATE_HANDLER( dsp56k_direct_handler )
+{
+ if (address >= (0x0000<<1) && address <= (0x07ff<<1))
+ {
+ dsp56k_core* cpustate = get_safe_token(&direct.space().device());
+ direct.explicit_configure(0x0000<<1, 0x07ff<<1, (0x07ff<<1) | 1, cpustate->program_ram);
+ return ~0;
+ }
+
+ return address;
+}
+
+
+/***************************************************************************
+ MEMORY ACCESSORS
+***************************************************************************/
+#define ROPCODE(pc) cpustate->direct->read_decrypted_word(pc)
+
+
+/***************************************************************************
+ IRQ HANDLING
+***************************************************************************/
+static void set_irq_line(dsp56k_core* cpustate, int irqline, int state)
+{
+ //logerror("DSP56k set irq line %d %d\n", irqline, state);
+
+ switch(irqline)
+ {
+ case DSP56K_IRQ_MODA:
+ // TODO: 1-12 Get this triggering right
+ if (irqa_trigger(cpustate))
+ logerror("DSP56k IRQA is set to fire on the \"Negative Edge\".\n");
+
+ if (state != CLEAR_LINE)
+ cpustate->modA_state = TRUE;
+ else
+ cpustate->modA_state = FALSE;
+
+ if (cpustate->reset_state != TRUE)
+ dsp56k_add_pending_interrupt(cpustate, "IRQA");
+ break;
+
+ case DSP56K_IRQ_MODB:
+ // TODO: 1-12 Get this triggering right
+ if (irqb_trigger(cpustate))
+ logerror("DSP56k IRQB is set to fire on the \"Negative Edge\".\n");
+
+ if (state != CLEAR_LINE)
+ cpustate->modB_state = TRUE;
+ else
+ cpustate->modB_state = FALSE;
+
+ if (cpustate->reset_state != TRUE)
+ dsp56k_add_pending_interrupt(cpustate, "IRQB");
+ break;
+
+ case DSP56K_IRQ_MODC:
+ if (state != CLEAR_LINE)
+ cpustate->modC_state = TRUE;
+ else
+ cpustate->modC_state = FALSE;
+
+ // TODO : Set bus mode or whatever
+ break;
+
+ case DSP56K_IRQ_RESET:
+ if (state != CLEAR_LINE)
+ cpustate->reset_state = TRUE;
+ else
+ {
+ /* If it changes state from asserted to cleared. Call the reset function. */
+ if (cpustate->reset_state == TRUE)
+ CPU_RESET_NAME(dsp56k)(cpustate->device);
+
+ cpustate->reset_state = FALSE;
+ }
+
+ // dsp56k_add_pending_interrupt("Hardware RESET");
+ break;
+
+ default:
+ logerror("DSP56k setting some weird irq line : %d", irqline);
+ break;
+ }
+
+ /* If the reset line isn't asserted, service interrupts */
+ // TODO: Is it right to immediately service interrupts?
+ //if (cpustate->reset_state != TRUE)
+ // pcu_service_interrupts();
+}
+
+
+/***************************************************************************
+ INITIALIZATION AND SHUTDOWN
+***************************************************************************/
+static void agu_init(dsp56k_core* cpustate, device_t *device)
+{
+ /* save states - dsp56k_agu members */
+ device->save_item(NAME(cpustate->AGU.r0));
+ device->save_item(NAME(cpustate->AGU.r1));
+ device->save_item(NAME(cpustate->AGU.r2));
+ device->save_item(NAME(cpustate->AGU.r3));
+ device->save_item(NAME(cpustate->AGU.n0));
+ device->save_item(NAME(cpustate->AGU.n1));
+ device->save_item(NAME(cpustate->AGU.n2));
+ device->save_item(NAME(cpustate->AGU.n3));
+ device->save_item(NAME(cpustate->AGU.m0));
+ device->save_item(NAME(cpustate->AGU.m1));
+ device->save_item(NAME(cpustate->AGU.m2));
+ device->save_item(NAME(cpustate->AGU.m3));
+ device->save_item(NAME(cpustate->AGU.temp));
+}
+
+static void alu_init(dsp56k_core* cpustate, device_t *device)
+{
+ /* save states - dsp56k_alu members */
+ device->save_item(NAME(cpustate->ALU.x));
+ device->save_item(NAME(cpustate->ALU.y));
+ device->save_item(NAME(cpustate->ALU.a));
+ device->save_item(NAME(cpustate->ALU.b));
+}
+
+static CPU_INIT( dsp56k )
+{
+ dsp56k_core* cpustate = get_safe_token(device);
+
+ /* Call specific module inits */
+ pcu_init(cpustate, device);
+ agu_init(cpustate, device);
+ alu_init(cpustate, device);
+
+ /* HACK - You're not in bootstrap mode upon bootup */
+ cpustate->bootstrap_mode = BOOTSTRAP_OFF;
+
+ /* Clear the irq states */
+ cpustate->modA_state = FALSE;
+ cpustate->modB_state = FALSE;
+ cpustate->modC_state = FALSE;
+ cpustate->reset_state = FALSE;
+
+ /* save states - dsp56k_core members */
+ device->save_item(NAME(cpustate->modA_state));
+ device->save_item(NAME(cpustate->modB_state));
+ device->save_item(NAME(cpustate->modC_state));
+ device->save_item(NAME(cpustate->reset_state));
+ device->save_item(NAME(cpustate->bootstrap_mode));
+ device->save_item(NAME(cpustate->repFlag));
+ device->save_item(NAME(cpustate->repAddr));
+ device->save_item(NAME(cpustate->icount));
+ device->save_item(NAME(cpustate->ppc));
+ device->save_item(NAME(cpustate->op));
+ device->save_item(NAME(cpustate->interrupt_cycles));
+
+ /* save states - dsp56k_host_interface members */
+ device->save_item(NAME(cpustate->HI.icr));
+ device->save_item(NAME(cpustate->HI.cvr));
+ device->save_item(NAME(cpustate->HI.isr));
+ device->save_item(NAME(cpustate->HI.ivr));
+ device->save_item(NAME(cpustate->HI.trxh));
+ device->save_item(NAME(cpustate->HI.trxl));
+ device->save_item(NAME(cpustate->HI.bootstrap_offset));
+
+ //cpustate->config = device->static_config();
+ //cpustate->irq_callback = irqcallback;
+ cpustate->device = device;
+ cpustate->program = device->space(AS_PROGRAM);
+ cpustate->direct = &cpustate->program->direct();
+ cpustate->data = device->space(AS_DATA);
+
+ /* Setup the direct memory handler for this CPU */
+ /* NOTE: Be sure to grab this guy and call him if you ever install another direct_update_hander in a driver! */
+ cpustate->program->set_direct_update_handler(direct_update_delegate(FUNC(dsp56k_direct_handler), &device->machine()));
+}
+
+
+/***************************************************************************
+ RESET BEHAVIOR
+***************************************************************************/
+static void agu_reset(dsp56k_core* cpustate)
+{
+ /* FM.4-3 */
+ R0 = 0x0000;
+ R1 = 0x0000;
+ R2 = 0x0000;
+ R3 = 0x0000;
+
+ N0 = 0x0000;
+ N1 = 0x0000;
+ N2 = 0x0000;
+ N3 = 0x0000;
+
+ M0 = 0xffff;
+ M1 = 0xffff;
+ M2 = 0xffff;
+ M3 = 0xffff;
+
+ TEMP = 0x0000;
+}
+
+static void alu_reset(dsp56k_core* cpustate)
+{
+ X = 0x00000000;
+ Y = 0x00000000;
+ A = 0x0000000000;
+ B = 0x0000000000;
+}
+
+static CPU_RESET( dsp56k )
+{
+ dsp56k_core* cpustate = get_safe_token(device);
+ logerror("Dsp56k reset\n");
+
+ cpustate->interrupt_cycles = 0;
+ cpustate->ppc = 0x0000;
+
+ cpustate->repFlag = 0;
+ cpustate->repAddr = 0x0000;
+
+ pcu_reset(cpustate);
+ mem_reset(cpustate);
+ agu_reset(cpustate);
+ alu_reset(cpustate);
+
+ /* HACK - Put a jump to 0x0000 at 0x0000 - this keeps the CPU locked to the instruction at address 0x0000 */
+ cpustate->program->write_word(0x0000, 0x0124);
+}
+
+
+static CPU_EXIT( dsp56k )
+{
+}
+
+
+
+/***************************************************************************
+ CORE INCLUDE
+***************************************************************************/
+#include "dsp56ops.c"
+
+
+/***************************************************************************
+ CORE EXECUTION LOOP
+***************************************************************************/
+// Execute a single opcode and return how many cycles it took.
+static size_t execute_one_new(dsp56k_core* cpustate)
+{
+ // For MAME
+ cpustate->op = ROPCODE(ADDRESS(PC));
+ debugger_instruction_hook(cpustate->device, PC);
+
+ UINT16 w0 = ROPCODE(ADDRESS(PC));
+ UINT16 w1 = ROPCODE(ADDRESS(PC) + ADDRESS(1));
+
+ Opcode op(w0, w1);
+ op.evaluate(cpustate);
+ PC += op.evalSize(); // Special size function needed to handle jmps, etc.
+
+ // TODO: Currently all operations take up 4 cycles (inst->cycles()).
+ return 4;
+}
+
+static CPU_EXECUTE( dsp56k )
+{
+ dsp56k_core* cpustate = get_safe_token(device);
+
+ /* If reset line is asserted, do nothing */
+ if (cpustate->reset_state)
+ {
+ cpustate->icount = 0;
+ return;
+ }
+
+ /* HACK - if you're in bootstrap mode, simply pretend you ate up all your cycles waiting for data. */
+ if (cpustate->bootstrap_mode != BOOTSTRAP_OFF)
+ {
+ cpustate->icount = 0;
+ return;
+ }
+
+ //cpustate->icount -= cpustate->interrupt_cycles;
+ //cpustate->interrupt_cycles = 0;
+
+ while(cpustate->icount > 0)
+ {
+ execute_one(cpustate);
+ if (0) cpustate->icount -= execute_one_new(cpustate);
+ pcu_service_interrupts(cpustate); // TODO: Is it incorrect to service after each instruction?
+ }
+}
+
+
+
+/***************************************************************************
+ DISASSEMBLY HOOK
+***************************************************************************/
+extern CPU_DISASSEMBLE( dsp56k );
+
+
+/****************************************************************************
+ * Internal Memory Maps
+ ****************************************************************************/
+static ADDRESS_MAP_START( dsp56156_program_map, AS_PROGRAM, 16 )
+ AM_RANGE(0x0000,0x07ff) AM_READWRITE(DSP56K::program_r, DSP56K::program_w) /* 1-5 */
+// AM_RANGE(0x2f00,0x2fff) AM_ROM /* 1-5 PROM reserved memory. Is this the right spot for it? */
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( dsp56156_x_data_map, AS_DATA, 16 )
+ AM_RANGE(0x0000,0x07ff) AM_RAM /* 1-5 */
+ AM_RANGE(0xffc0,0xffff) AM_READWRITE(DSP56K::peripheral_register_r, DSP56K::peripheral_register_w) /* 1-5 On-chip peripheral registers memory mapped in data space */
+ADDRESS_MAP_END
+
+
+/**************************************************************************
+ * Generic set_info/get_info
+ **************************************************************************/
+enum
+{
+ // PCU
+ DSP56K_PC=1,
+ DSP56K_SR,
+ DSP56K_LC,
+ DSP56K_LA,
+ DSP56K_SP,
+ DSP56K_OMR,
+
+ // ALU
+ DSP56K_X, DSP56K_Y,
+ DSP56K_A, DSP56K_B,
+
+ // AGU
+ DSP56K_R0,DSP56K_R1,DSP56K_R2,DSP56K_R3,
+ DSP56K_N0,DSP56K_N1,DSP56K_N2,DSP56K_N3,
+ DSP56K_M0,DSP56K_M1,DSP56K_M2,DSP56K_M3,
+ DSP56K_TEMP,
+ DSP56K_STATUS,
+
+ // CPU STACK
+ DSP56K_ST0,
+ DSP56K_ST1,
+ DSP56K_ST2,
+ DSP56K_ST3,
+ DSP56K_ST4,
+ DSP56K_ST5,
+ DSP56K_ST6,
+ DSP56K_ST7,
+ DSP56K_ST8,
+ DSP56K_ST9,
+ DSP56K_ST10,
+ DSP56K_ST11,
+ DSP56K_ST12,
+ DSP56K_ST13,
+ DSP56K_ST14,
+ DSP56K_ST15
+};
+
+static CPU_SET_INFO( dsp56k )
+{
+ dsp56k_core* cpustate = get_safe_token(device);
+
+ switch (state)
+ {
+ case CPUINFO_INT_INPUT_STATE + DSP56K_IRQ_MODA: set_irq_line(cpustate, DSP56K_IRQ_MODA, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + DSP56K_IRQ_MODB: set_irq_line(cpustate, DSP56K_IRQ_MODB, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + DSP56K_IRQ_MODC: set_irq_line(cpustate, DSP56K_IRQ_MODC, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + DSP56K_IRQ_RESET: set_irq_line(cpustate, DSP56K_IRQ_RESET, info->i); break;
+
+ case CPUINFO_INT_PC:
+ case CPUINFO_INT_REGISTER + DSP56K_PC: PC = info->i & 0xffff; break;
+
+ case CPUINFO_INT_REGISTER + DSP56K_SR: SR = info->i & 0xffff; break;
+ case CPUINFO_INT_REGISTER + DSP56K_LC: LC = info->i & 0xffff; break;
+ case CPUINFO_INT_REGISTER + DSP56K_LA: LA = info->i & 0xffff; break;
+
+ case CPUINFO_INT_SP:
+ case CPUINFO_INT_REGISTER + DSP56K_SP: SP = info->i & 0xff; break;
+
+ case CPUINFO_INT_REGISTER + DSP56K_OMR: OMR = info->i & 0xff; break;
+
+ case CPUINFO_INT_REGISTER + DSP56K_X: X = info->i & 0xffffffff; break;
+ case CPUINFO_INT_REGISTER + DSP56K_Y: Y = info->i & 0xffffffff; break;
+
+ case CPUINFO_INT_REGISTER + DSP56K_A: A = info->i & (UINT64)U64(0xffffffffffffffff); break; /* could benefit from a better mask? */
+ case CPUINFO_INT_REGISTER + DSP56K_B: B = info->i & (UINT64)U64(0xffffffffffffffff); break; /* could benefit from a better mask? */
+
+ case CPUINFO_INT_REGISTER + DSP56K_R0: R0 = info->i & 0xffff; break;
+ case CPUINFO_INT_REGISTER + DSP56K_R1: R1 = info->i & 0xffff; break;
+ case CPUINFO_INT_REGISTER + DSP56K_R2: R2 = info->i & 0xffff; break;
+ case CPUINFO_INT_REGISTER + DSP56K_R3: R3 = info->i & 0xffff; break;
+
+ case CPUINFO_INT_REGISTER + DSP56K_N0: N0 = info->i & 0xffff; break;
+ case CPUINFO_INT_REGISTER + DSP56K_N1: N1 = info->i & 0xffff; break;
+ case CPUINFO_INT_REGISTER + DSP56K_N2: N2 = info->i & 0xffff; break;
+ case CPUINFO_INT_REGISTER + DSP56K_N3: N3 = info->i & 0xffff; break;
+
+ case CPUINFO_INT_REGISTER + DSP56K_M0: M0 = info->i & 0xffff; break;
+ case CPUINFO_INT_REGISTER + DSP56K_M1: M1 = info->i & 0xffff; break;
+ case CPUINFO_INT_REGISTER + DSP56K_M2: M2 = info->i & 0xffff; break;
+ case CPUINFO_INT_REGISTER + DSP56K_M3: M3 = info->i & 0xffff; break;
+
+ /* case CPUINFO_INT_REGISTER + DSP56K_TEMP: TEMP = info->i & 0xffff; break; */
+ /* case CPUINFO_INT_REGISTER + DSP56K_STATUS: STATUS = info->i & 0xff; break; */
+
+ /* The CPU stack */
+ case CPUINFO_INT_REGISTER + DSP56K_ST0: ST0 = info->i & 0xffffffff; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST1: ST1 = info->i & 0xffffffff; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST2: ST2 = info->i & 0xffffffff; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST3: ST3 = info->i & 0xffffffff; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST4: ST4 = info->i & 0xffffffff; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST5: ST5 = info->i & 0xffffffff; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST6: ST6 = info->i & 0xffffffff; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST7: ST7 = info->i & 0xffffffff; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST8: ST8 = info->i & 0xffffffff; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST9: ST9 = info->i & 0xffffffff; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST10: ST10 = info->i & 0xffffffff; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST11: ST11 = info->i & 0xffffffff; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST12: ST12 = info->i & 0xffffffff; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST13: ST13 = info->i & 0xffffffff; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST14: ST14 = info->i & 0xffffffff; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST15: ST15 = info->i & 0xffffffff; break;
+ }
+}
+
+
+CPU_GET_INFO( dsp56k )
+{
+ dsp56k_core* cpustate = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL;
+
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(dsp56k_core); break;
+ case CPUINFO_INT_INPUT_LINES: info->i = 4; break;
+ case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0x0000; break;
+ case DEVINFO_INT_ENDIANNESS: info->i = ENDIANNESS_LITTLE; break;
+ case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break;
+ case CPUINFO_INT_CLOCK_DIVIDER: info->i = 2; break;
+ case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 2; 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 = 8; // ? break;
+
+ case DEVINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 16; break;
+ case DEVINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 16; break;
+ case DEVINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM: info->i = -1; break;
+ case DEVINFO_INT_DATABUS_WIDTH + AS_DATA: info->i = 16; break;
+ case DEVINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 16; break;
+ case DEVINFO_INT_ADDRBUS_SHIFT + AS_DATA: info->i = -1; break;
+ case DEVINFO_INT_DATABUS_WIDTH + AS_IO: info->i = 0; break;
+ case DEVINFO_INT_ADDRBUS_WIDTH + AS_IO: info->i = 0; break;
+ case DEVINFO_INT_ADDRBUS_SHIFT + AS_IO: info->i = 0; break;
+
+ case CPUINFO_INT_INPUT_STATE + DSP56K_IRQ_MODA: info->i = DSP56K_IRQ_MODA; break;
+ case CPUINFO_INT_INPUT_STATE + DSP56K_IRQ_MODB: info->i = DSP56K_IRQ_MODB; break;
+ case CPUINFO_INT_INPUT_STATE + DSP56K_IRQ_MODC: info->i = DSP56K_IRQ_MODC; break;
+
+ case CPUINFO_INT_PC:
+ case CPUINFO_INT_REGISTER + DSP56K_PC: info->i = PC; break;
+ case CPUINFO_INT_PREVIOUSPC: info->i = cpustate->ppc; break;
+
+ case CPUINFO_INT_REGISTER + DSP56K_SR: info->i = SR; break;
+ case CPUINFO_INT_REGISTER + DSP56K_LC: info->i = LC; break;
+ case CPUINFO_INT_REGISTER + DSP56K_LA: info->i = LA; break;
+
+ case CPUINFO_INT_SP:
+ case CPUINFO_INT_REGISTER + DSP56K_SP: info->i = SP; break;
+
+ case CPUINFO_INT_REGISTER + DSP56K_OMR: info->i = OMR; break;
+
+ case CPUINFO_INT_REGISTER + DSP56K_X: info->i = X; break;
+ case CPUINFO_INT_REGISTER + DSP56K_Y: info->i = Y; break;
+
+ case CPUINFO_INT_REGISTER + DSP56K_A: info->i = A; break;
+ case CPUINFO_INT_REGISTER + DSP56K_B: info->i = B; break;
+
+ case CPUINFO_INT_REGISTER + DSP56K_R0: info->i = R0; break;
+ case CPUINFO_INT_REGISTER + DSP56K_R1: info->i = R1; break;
+ case CPUINFO_INT_REGISTER + DSP56K_R2: info->i = R2; break;
+ case CPUINFO_INT_REGISTER + DSP56K_R3: info->i = R3; break;
+
+ case CPUINFO_INT_REGISTER + DSP56K_N0: info->i = N0; break;
+ case CPUINFO_INT_REGISTER + DSP56K_N1: info->i = N1; break;
+ case CPUINFO_INT_REGISTER + DSP56K_N2: info->i = N2; break;
+ case CPUINFO_INT_REGISTER + DSP56K_N3: info->i = N3; break;
+
+ case CPUINFO_INT_REGISTER + DSP56K_M0: info->i = M0; break;
+ case CPUINFO_INT_REGISTER + DSP56K_M1: info->i = M1; break;
+ case CPUINFO_INT_REGISTER + DSP56K_M2: info->i = M2; break;
+ case CPUINFO_INT_REGISTER + DSP56K_M3: info->i = M3; break;
+
+ /* case CPUINFO_INT_REGISTER + DSP56K_TEMP: info->i = TEMP; break; */
+ /* case CPUINFO_INT_REGISTER + DSP56K_STATUS: info->i = STATUS; break; */
+
+ /* The CPU stack */
+ case CPUINFO_INT_REGISTER + DSP56K_ST0: info->i = ST0; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST1: info->i = ST1; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST2: info->i = ST2; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST3: info->i = ST3; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST4: info->i = ST4; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST5: info->i = ST5; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST6: info->i = ST6; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST7: info->i = ST7; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST8: info->i = ST8; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST9: info->i = ST9; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST10: info->i = ST10; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST11: info->i = ST11; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST12: info->i = ST12; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST13: info->i = ST13; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST14: info->i = ST14; break;
+ case CPUINFO_INT_REGISTER + DSP56K_ST15: info->i = ST15; break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(dsp56k); break;
+ case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(dsp56k); break;
+ case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(dsp56k); break;
+ case CPUINFO_FCT_EXIT: info->exit = CPU_EXIT_NAME(dsp56k); break;
+ case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(dsp56k); break;
+ case CPUINFO_FCT_BURN: info->burn = NULL; break;
+ case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(dsp56k); break;
+ case CPUINFO_FCT_DEBUG_INIT: info->debug_init = NULL; break;
+ case CPUINFO_FCT_TRANSLATE: info->translate = NULL; break;
+ case CPUINFO_FCT_READ: info->read = NULL; break;
+ case CPUINFO_FCT_WRITE: info->write = NULL; break;
+ case CPUINFO_FCT_READOP: info->readop = NULL; break;
+ case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cpustate->icount; break;
+ case DEVINFO_PTR_INTERNAL_MEMORY_MAP + AS_DATA:
+ info->internal_map16 = ADDRESS_MAP_NAME(dsp56156_x_data_map); break;
+ case DEVINFO_PTR_INTERNAL_MEMORY_MAP + AS_PROGRAM:
+ info->internal_map16 = ADDRESS_MAP_NAME(dsp56156_program_map); break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "DSP56156"); break;
+ case DEVINFO_STR_FAMILY: strcpy(info->s, "Motorola DSP56156"); break;
+ case DEVINFO_STR_VERSION: strcpy(info->s, "0.1"); break;
+ case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
+ case DEVINFO_STR_CREDITS: strcpy(info->s, "Andrew Gardner"); break;
+
+ case CPUINFO_STR_FLAGS:
+ sprintf(info->s, "%s%s %s%s%s%s%s%s%s%s %s%s",
+ /* Status Register */
+ LF_bit(cpustate) ? "L" : ".",
+ FV_bit(cpustate) ? "F" : ".",
+
+ S_bit(cpustate) ? "S" : ".",
+ L_bit(cpustate) ? "L" : ".",
+ E_bit(cpustate) ? "E" : ".",
+ U_bit(cpustate) ? "U" : ".",
+ N_bit(cpustate) ? "N" : ".",
+ Z_bit(cpustate) ? "Z" : ".",
+ V_bit(cpustate) ? "V" : ".",
+ C_bit(cpustate) ? "C" : ".",
+
+ /* Stack Pointer */
+ UF_bit(cpustate) ? "U" : ".",
+ SE_bit(cpustate) ? "S" : ".");
+ break;
+
+ case CPUINFO_STR_REGISTER + DSP56K_PC: sprintf(info->s, "PC : %04x", PC); break;
+ case CPUINFO_STR_REGISTER + DSP56K_SR: sprintf(info->s, "SR : %04x", SR); break;
+ case CPUINFO_STR_REGISTER + DSP56K_LC: sprintf(info->s, "LC : %04x", LC); break;
+ case CPUINFO_STR_REGISTER + DSP56K_LA: sprintf(info->s, "LA : %04x", LA); break;
+ case CPUINFO_STR_REGISTER + DSP56K_SP: sprintf(info->s, "SP : %02x", SP); break;
+ case CPUINFO_STR_REGISTER + DSP56K_OMR: sprintf(info->s, "OMR: %02x", OMR); break;
+
+ case CPUINFO_STR_REGISTER + DSP56K_X: sprintf(info->s, "X : %04x %04x", X1, X0); break;
+ case CPUINFO_STR_REGISTER + DSP56K_Y: sprintf(info->s, "Y : %04x %04x", Y1, Y0); break;
+
+ case CPUINFO_STR_REGISTER + DSP56K_A: sprintf(info->s, "A : %02x %04x %04x", A2,A1,A0); break;
+ case CPUINFO_STR_REGISTER + DSP56K_B: sprintf(info->s, "B : %02x %04x %04x", B2,B1,B0); break;
+
+ case CPUINFO_STR_REGISTER + DSP56K_R0: sprintf(info->s, "R0 : %04x", R0); break;
+ case CPUINFO_STR_REGISTER + DSP56K_R1: sprintf(info->s, "R1 : %04x", R1); break;
+ case CPUINFO_STR_REGISTER + DSP56K_R2: sprintf(info->s, "R2 : %04x", R2); break;
+ case CPUINFO_STR_REGISTER + DSP56K_R3: sprintf(info->s, "R3 : %04x", R3); break;
+
+ case CPUINFO_STR_REGISTER + DSP56K_N0: sprintf(info->s, "N0 : %04x", N0); break;
+ case CPUINFO_STR_REGISTER + DSP56K_N1: sprintf(info->s, "N1 : %04x", N1); break;
+ case CPUINFO_STR_REGISTER + DSP56K_N2: sprintf(info->s, "N2 : %04x", N2); break;
+ case CPUINFO_STR_REGISTER + DSP56K_N3: sprintf(info->s, "N3 : %04x", N3); break;
+
+ case CPUINFO_STR_REGISTER + DSP56K_M0: sprintf(info->s, "M0 : %04x", M0); break;
+ case CPUINFO_STR_REGISTER + DSP56K_M1: sprintf(info->s, "M1 : %04x", M1); break;
+ case CPUINFO_STR_REGISTER + DSP56K_M2: sprintf(info->s, "M2 : %04x", M2); break;
+ case CPUINFO_STR_REGISTER + DSP56K_M3: sprintf(info->s, "M3 : %04x", M3); break;
+
+ /* case CPUINFO_STR_REGISTER + DSP56K_TEMP: sprintf(info->s, "TMP: %04x", TEMP); break; */
+ /* case CPUINFO_STR_REGISTER + DSP56K_STATUS: sprintf(info->s, "STS: %02x", STATUS); break; */
+
+ /* The CPU stack */
+ case CPUINFO_STR_REGISTER + DSP56K_ST0: sprintf(info->s, "ST0 : %08x", ST0); break;
+ case CPUINFO_STR_REGISTER + DSP56K_ST1: sprintf(info->s, "ST1 : %08x", ST1); break;
+ case CPUINFO_STR_REGISTER + DSP56K_ST2: sprintf(info->s, "ST2 : %08x", ST2); break;
+ case CPUINFO_STR_REGISTER + DSP56K_ST3: sprintf(info->s, "ST3 : %08x", ST3); break;
+ case CPUINFO_STR_REGISTER + DSP56K_ST4: sprintf(info->s, "ST4 : %08x", ST4); break;
+ case CPUINFO_STR_REGISTER + DSP56K_ST5: sprintf(info->s, "ST5 : %08x", ST5); break;
+ case CPUINFO_STR_REGISTER + DSP56K_ST6: sprintf(info->s, "ST6 : %08x", ST6); break;
+ case CPUINFO_STR_REGISTER + DSP56K_ST7: sprintf(info->s, "ST7 : %08x", ST7); break;
+ case CPUINFO_STR_REGISTER + DSP56K_ST8: sprintf(info->s, "ST8 : %08x", ST8); break;
+ case CPUINFO_STR_REGISTER + DSP56K_ST9: sprintf(info->s, "ST9 : %08x", ST9); break;
+ case CPUINFO_STR_REGISTER + DSP56K_ST10: sprintf(info->s, "ST10: %08x", ST10); break;
+ case CPUINFO_STR_REGISTER + DSP56K_ST11: sprintf(info->s, "ST11: %08x", ST11); break;
+ case CPUINFO_STR_REGISTER + DSP56K_ST12: sprintf(info->s, "ST12: %08x", ST12); break;
+ case CPUINFO_STR_REGISTER + DSP56K_ST13: sprintf(info->s, "ST13: %08x", ST13); break;
+ case CPUINFO_STR_REGISTER + DSP56K_ST14: sprintf(info->s, "ST14: %08x", ST14); break;
+ case CPUINFO_STR_REGISTER + DSP56K_ST15: sprintf(info->s, "ST15: %08x", ST15); break;
+ }
+}
+
+DEFINE_LEGACY_CPU_DEVICE(DSP56156, dsp56k);