diff --git a/src/emu/cpu/dsp56k/dsp56k.c b/src/emu/cpu/dsp56k/dsp56k.c index 4a9757a11e8..ba275d9dc37 100644 --- a/src/emu/cpu/dsp56k/dsp56k.c +++ b/src/emu/cpu/dsp56k/dsp56k.c @@ -39,12 +39,6 @@ using namespace DSP56K; -/*************************************************************************** - FUNCTION PROTOTYPES -***************************************************************************/ -static CPU_RESET( dsp56k ); - - /*************************************************************************** COMPONENT FUNCTIONALITY ***************************************************************************/ @@ -64,326 +58,6 @@ static CPU_RESET( dsp56k ); #include "dsp56mem.h" -/*************************************************************************** - Direct Update Handler -***************************************************************************/ -DIRECT_UPDATE_MEMBER( dsp56k_device::dsp56k_direct_handler ) -{ - if (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->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)); - - device->save_item(NAME(cpustate->peripheral_ram)); - device->save_item(NAME(cpustate->program_ram)); - - //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_device::dsp56k_direct_handler), (dsp56k_device*)device)); -} - - -/*************************************************************************** - 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.inc" - - -/*************************************************************************** - 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, dsp56k_device ) - AM_RANGE(0x0000,0x07ff) AM_READWRITE(program_r, 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, dsp56k_device ) - AM_RANGE(0x0000,0x07ff) AM_RAM /* 1-5 */ - AM_RANGE(0xffc0,0xffff) AM_READWRITE(peripheral_register_r, peripheral_register_w) /* 1-5 On-chip peripheral registers memory mapped in data space */ -ADDRESS_MAP_END - - -/************************************************************************** - * Generic set_info/get_info - **************************************************************************/ enum { // PCU @@ -424,190 +98,273 @@ enum DSP56K_ST15 }; -static CPU_SET_INFO( dsp56k ) + +const device_type DSP56156 = &device_creator; + + +/**************************************************************************** + * Internal Memory Maps + ****************************************************************************/ +static ADDRESS_MAP_START( dsp56156_program_map, AS_PROGRAM, 16, dsp56k_device ) + AM_RANGE(0x0000,0x07ff) AM_READWRITE(program_r, 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, dsp56k_device ) + AM_RANGE(0x0000,0x07ff) AM_RAM /* 1-5 */ + AM_RANGE(0xffc0,0xffff) AM_READWRITE(peripheral_register_r, peripheral_register_w) /* 1-5 On-chip peripheral registers memory mapped in data space */ +ADDRESS_MAP_END + + +dsp56k_device::dsp56k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : cpu_device(mconfig, DSP56156, "DSP56156", tag, owner, clock, "dsp56156", __FILE__) + , m_program_config("program", ENDIANNESS_LITTLE, 16, 16, -1, ADDRESS_MAP_NAME(dsp56156_program_map)) + , m_data_config("data", ENDIANNESS_LITTLE, 16, 16, -1, ADDRESS_MAP_NAME(dsp56156_x_data_map)) { - 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 ) +/*************************************************************************** + Direct Update Handler +***************************************************************************/ +DIRECT_UPDATE_MEMBER( dsp56k_device::dsp56k_direct_handler ) { - dsp56k_core* cpustate = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL; - - switch (state) + if (address <= (0x07ff<<1)) { - /* --- 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 CPUINFO_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; + direct.explicit_configure(0x0000<<1, 0x07ff<<1, (0x07ff<<1) | 1, m_dsp56k_core.program_ram); + return ~0; + } - case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 16; break; - case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 16; break; - case CPUINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM: info->i = -1; break; - case CPUINFO_INT_DATABUS_WIDTH + AS_DATA: info->i = 16; break; - case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 16; break; - case CPUINFO_INT_ADDRBUS_SHIFT + AS_DATA: info->i = -1; break; - case CPUINFO_INT_DATABUS_WIDTH + AS_IO: info->i = 0; break; - case CPUINFO_INT_ADDRBUS_WIDTH + AS_IO: info->i = 0; break; - case CPUINFO_INT_ADDRBUS_SHIFT + AS_IO: info->i = 0; break; + return address; +} - 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; +/*************************************************************************** + MEMORY ACCESSORS +***************************************************************************/ +#define ROPCODE(pc) cpustate->direct->read_decrypted_word(pc) - 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; +/*************************************************************************** + IRQ HANDLING +***************************************************************************/ +void dsp56k_device::execute_set_input(int irqline, int state) +{ + //logerror("DSP56k set irq line %d %d\n", irqline, state); - case CPUINFO_INT_REGISTER + DSP56K_OMR: info->i = OMR; break; + switch(irqline) + { + case DSP56K_IRQ_MODA: + // TODO: 1-12 Get this triggering right + if (irqa_trigger(&m_dsp56k_core)) + logerror("DSP56k IRQA is set to fire on the \"Negative Edge\".\n"); - case CPUINFO_INT_REGISTER + DSP56K_X: info->i = X; break; - case CPUINFO_INT_REGISTER + DSP56K_Y: info->i = Y; break; + if (state != CLEAR_LINE) + m_dsp56k_core.modA_state = TRUE; + else + m_dsp56k_core.modA_state = FALSE; - case CPUINFO_INT_REGISTER + DSP56K_A: info->i = A; break; - case CPUINFO_INT_REGISTER + DSP56K_B: info->i = B; break; + if (m_dsp56k_core.reset_state != TRUE) + dsp56k_add_pending_interrupt(&m_dsp56k_core, "IRQA"); + 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 DSP56K_IRQ_MODB: + // TODO: 1-12 Get this triggering right + if (irqb_trigger(&m_dsp56k_core)) + logerror("DSP56k IRQB is set to fire on the \"Negative Edge\".\n"); - 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; + if (state != CLEAR_LINE) + m_dsp56k_core.modB_state = TRUE; + else + m_dsp56k_core.modB_state = FALSE; - 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; + if (m_dsp56k_core.reset_state != TRUE) + dsp56k_add_pending_interrupt(&m_dsp56k_core, "IRQB"); + break; - /* case CPUINFO_INT_REGISTER + DSP56K_TEMP: info->i = TEMP; break; */ - /* case CPUINFO_INT_REGISTER + DSP56K_STATUS: info->i = STATUS; break; */ + case DSP56K_IRQ_MODC: + if (state != CLEAR_LINE) + m_dsp56k_core.modC_state = TRUE; + else + m_dsp56k_core.modC_state = FALSE; - /* 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; + // TODO : Set bus mode or whatever + 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 CPUINFO_PTR_INTERNAL_MEMORY_MAP + AS_DATA: - info->internal_map16 = ADDRESS_MAP_NAME(dsp56156_x_data_map); break; - case CPUINFO_PTR_INTERNAL_MEMORY_MAP + AS_PROGRAM: - info->internal_map16 = ADDRESS_MAP_NAME(dsp56156_program_map); break; + case DSP56K_IRQ_RESET: + if (state != CLEAR_LINE) + m_dsp56k_core.reset_state = TRUE; + else + { + /* If it changes state from asserted to cleared. Call the reset function. */ + if (m_dsp56k_core.reset_state == TRUE) + device_reset(); - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case CPUINFO_STR_NAME: strcpy(info->s, "DSP56156"); break; - case CPUINFO_STR_SHORTNAME: strcpy(info->s, "dsp56156"); break; - case CPUINFO_STR_FAMILY: strcpy(info->s, "Motorola DSP56156"); break; - case CPUINFO_STR_VERSION: strcpy(info->s, "0.1"); break; - case CPUINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break; - case CPUINFO_STR_CREDITS: strcpy(info->s, "Andrew Gardner"); break; + m_dsp56k_core.reset_state = FALSE; + } - case CPUINFO_STR_FLAGS: - sprintf(info->s, "%s%s %s%s%s%s%s%s%s%s %s%s", + // 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 +***************************************************************************/ +void dsp56k_device::agu_init() +{ + /* save states - dsp56k_agu members */ + save_item(NAME(m_dsp56k_core.AGU.r0)); + save_item(NAME(m_dsp56k_core.AGU.r1)); + save_item(NAME(m_dsp56k_core.AGU.r2)); + save_item(NAME(m_dsp56k_core.AGU.r3)); + save_item(NAME(m_dsp56k_core.AGU.n0)); + save_item(NAME(m_dsp56k_core.AGU.n1)); + save_item(NAME(m_dsp56k_core.AGU.n2)); + save_item(NAME(m_dsp56k_core.AGU.n3)); + save_item(NAME(m_dsp56k_core.AGU.m0)); + save_item(NAME(m_dsp56k_core.AGU.m1)); + save_item(NAME(m_dsp56k_core.AGU.m2)); + save_item(NAME(m_dsp56k_core.AGU.m3)); + save_item(NAME(m_dsp56k_core.AGU.temp)); +} + +void dsp56k_device::alu_init() +{ + /* save states - dsp56k_alu members */ + save_item(NAME(m_dsp56k_core.ALU.x)); + save_item(NAME(m_dsp56k_core.ALU.y)); + save_item(NAME(m_dsp56k_core.ALU.a)); + save_item(NAME(m_dsp56k_core.ALU.b)); +} + +void dsp56k_device::device_start() +{ + memset(&m_dsp56k_core, 0, sizeof(m_dsp56k_core)); + + m_dsp56k_core.device = this; + + /* Call specific module inits */ + pcu_init(&m_dsp56k_core, this); + agu_init(); + alu_init(); + + /* HACK - You're not in bootstrap mode upon bootup */ + m_dsp56k_core.bootstrap_mode = BOOTSTRAP_OFF; + + /* Clear the irq states */ + m_dsp56k_core.modA_state = FALSE; + m_dsp56k_core.modB_state = FALSE; + m_dsp56k_core.modC_state = FALSE; + m_dsp56k_core.reset_state = FALSE; + + /* save states - dsp56k_core members */ + save_item(NAME(m_dsp56k_core.modA_state)); + save_item(NAME(m_dsp56k_core.modB_state)); + save_item(NAME(m_dsp56k_core.modC_state)); + save_item(NAME(m_dsp56k_core.reset_state)); + save_item(NAME(m_dsp56k_core.bootstrap_mode)); + save_item(NAME(m_dsp56k_core.repFlag)); + save_item(NAME(m_dsp56k_core.repAddr)); + save_item(NAME(m_dsp56k_core.ppc)); + save_item(NAME(m_dsp56k_core.op)); + save_item(NAME(m_dsp56k_core.interrupt_cycles)); + + /* save states - dsp56k_host_interface members */ + save_item(NAME(m_dsp56k_core.HI.icr)); + save_item(NAME(m_dsp56k_core.HI.cvr)); + save_item(NAME(m_dsp56k_core.HI.isr)); + save_item(NAME(m_dsp56k_core.HI.ivr)); + save_item(NAME(m_dsp56k_core.HI.trxh)); + save_item(NAME(m_dsp56k_core.HI.trxl)); + save_item(NAME(m_dsp56k_core.HI.bootstrap_offset)); + + save_item(NAME(m_dsp56k_core.peripheral_ram)); + save_item(NAME(m_dsp56k_core.program_ram)); + + m_dsp56k_core.program = &space(AS_PROGRAM); + m_dsp56k_core.direct = &m_dsp56k_core.program->direct(); + m_dsp56k_core.data = &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! */ + m_dsp56k_core.program->set_direct_update_handler(direct_update_delegate(FUNC(dsp56k_device::dsp56k_direct_handler), this)); + + state_add(DSP56K_PC, "PC", m_dsp56k_core.PCU.pc).formatstr("%04X"); + state_add(DSP56K_SR, "SR", m_dsp56k_core.PCU.sr).formatstr("%04X"); + state_add(DSP56K_LC, "LC", m_dsp56k_core.PCU.lc).formatstr("%04X"); + state_add(DSP56K_LA, "LA", m_dsp56k_core.PCU.la).formatstr("%04X"); + state_add(DSP56K_SP, "SP", m_dsp56k_core.PCU.sp).formatstr("%02X"); + state_add(DSP56K_OMR, "OMR", m_dsp56k_core.PCU.omr).formatstr("%02X"); + + state_add(DSP56K_X, "X", m_dsp56k_core.ALU.x.d).mask(0xffffffff).formatstr("%9s"); + state_add(DSP56K_Y, "Y", m_dsp56k_core.ALU.y.d).mask(0xffffffff).formatstr("%9s"); + + state_add(DSP56K_A, "A", m_dsp56k_core.ALU.a.q).mask((UINT64)U64(0xffffffffffffffff)).formatstr("%12s"); /* could benefit from a better mask? */ + state_add(DSP56K_B, "B", m_dsp56k_core.ALU.b.q).mask((UINT64)U64(0xffffffffffffffff)).formatstr("%12s"); /* could benefit from a better mask? */ + + state_add(DSP56K_R0, "R0", m_dsp56k_core.AGU.r0).formatstr("%04X"); + state_add(DSP56K_R1, "R1", m_dsp56k_core.AGU.r1).formatstr("%04X"); + state_add(DSP56K_R2, "R2", m_dsp56k_core.AGU.r2).formatstr("%04X"); + state_add(DSP56K_R3, "R3", m_dsp56k_core.AGU.r3).formatstr("%04X"); + + state_add(DSP56K_N0, "N0", m_dsp56k_core.AGU.n0).formatstr("%04X"); + state_add(DSP56K_N1, "N1", m_dsp56k_core.AGU.n1).formatstr("%04X"); + state_add(DSP56K_N2, "N2", m_dsp56k_core.AGU.n2).formatstr("%04X"); + state_add(DSP56K_N3, "N3", m_dsp56k_core.AGU.n3).formatstr("%04X"); + + state_add(DSP56K_M0, "M0", m_dsp56k_core.AGU.m0).formatstr("%04X"); + state_add(DSP56K_M1, "M1", m_dsp56k_core.AGU.m1).formatstr("%04X"); + state_add(DSP56K_M2, "M2", m_dsp56k_core.AGU.m2).formatstr("%04X"); + state_add(DSP56K_M3, "M3", m_dsp56k_core.AGU.m3).formatstr("%04X"); + + state_add(DSP56K_TEMP, "TMP", m_dsp56k_core.AGU.temp).formatstr("%04X").noshow(); + //state_add(DSP56K_STATUS, "STS", STATUS).formatstr("%02X"); + + state_add(DSP56K_ST0, "ST0", m_dsp56k_core.PCU.ss[0].d).formatstr("%08X"); + state_add(DSP56K_ST1, "ST1", m_dsp56k_core.PCU.ss[1].d).formatstr("%08X"); + state_add(DSP56K_ST2, "ST2", m_dsp56k_core.PCU.ss[2].d).formatstr("%08X"); + state_add(DSP56K_ST3, "ST3", m_dsp56k_core.PCU.ss[3].d).formatstr("%08X"); + state_add(DSP56K_ST4, "ST4", m_dsp56k_core.PCU.ss[4].d).formatstr("%08X"); + state_add(DSP56K_ST5, "ST5", m_dsp56k_core.PCU.ss[5].d).formatstr("%08X"); + state_add(DSP56K_ST6, "ST6", m_dsp56k_core.PCU.ss[6].d).formatstr("%08X"); + state_add(DSP56K_ST7, "ST7", m_dsp56k_core.PCU.ss[7].d).formatstr("%08X"); + state_add(DSP56K_ST8, "ST8", m_dsp56k_core.PCU.ss[8].d).formatstr("%08X"); + state_add(DSP56K_ST9, "ST9", m_dsp56k_core.PCU.ss[9].d).formatstr("%08X"); + state_add(DSP56K_ST10, "ST10", m_dsp56k_core.PCU.ss[10].d).formatstr("%08X"); + state_add(DSP56K_ST11, "ST11", m_dsp56k_core.PCU.ss[11].d).formatstr("%08X"); + state_add(DSP56K_ST12, "ST12", m_dsp56k_core.PCU.ss[12].d).formatstr("%08X"); + state_add(DSP56K_ST13, "ST13", m_dsp56k_core.PCU.ss[13].d).formatstr("%08X"); + state_add(DSP56K_ST14, "ST14", m_dsp56k_core.PCU.ss[14].d).formatstr("%08X"); + state_add(DSP56K_ST15, "ST15", m_dsp56k_core.PCU.ss[15].d).formatstr("%08X"); + + state_add(STATE_GENPC, "GENPC", m_dsp56k_core.PCU.pc).noshow(); + state_add(STATE_GENSP, "GENSP", m_dsp56k_core.PCU.sp).noshow(); + state_add(STATE_GENPCBASE, "GENPCBASE", m_dsp56k_core.ppc).noshow(); + state_add(STATE_GENFLAGS, "GENFLAGS", m_dsp56k_core.PCU.sr).formatstr("%14s").noshow(); + + m_icountptr = &m_dsp56k_core.icount; +} + + +void dsp56k_device::state_string_export(const device_state_entry &entry, astring &string) +{ + dsp56k_core *cpustate = &m_dsp56k_core; + + switch (entry.index()) + { + case STATE_GENFLAGS: + string.printf("%s%s %s%s%s%s%s%s%s%s %s%s", /* Status Register */ LF_bit(cpustate) ? "L" : ".", FV_bit(cpustate) ? "F" : ".", @@ -626,55 +383,135 @@ CPU_GET_INFO( dsp56k ) 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 DSP56K_X: + string.printf("%04x %04x", X1, X0); + 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 DSP56K_Y: + string.printf("%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 DSP56K_A: + string.printf("%02x %04x %04x", A2,A1,A0); + 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; + case DSP56K_B: + string.printf("%02x %04x %04x", B2,B1,B0); + break; } } -DEFINE_LEGACY_CPU_DEVICE(DSP56156, dsp56k); +/*************************************************************************** + 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; +} + +void dsp56k_device::device_reset() +{ + logerror("Dsp56k reset\n"); + + m_dsp56k_core.interrupt_cycles = 0; + m_dsp56k_core.ppc = 0x0000; + + m_dsp56k_core.repFlag = 0; + m_dsp56k_core.repAddr = 0x0000; + + pcu_reset(&m_dsp56k_core); + mem_reset(&m_dsp56k_core); + agu_reset(&m_dsp56k_core); + alu_reset(&m_dsp56k_core); + + /* HACK - Put a jump to 0x0000 at 0x0000 - this keeps the CPU locked to the instruction at address 0x0000 */ + m_dsp56k_core.program->write_word(0x0000, 0x0124); +} + + + +/*************************************************************************** + CORE INCLUDE +***************************************************************************/ +#include "dsp56ops.inc" + + +/*************************************************************************** + 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; +} + +void dsp56k_device::execute_run() +{ + /* If reset line is asserted, do nothing */ + if (m_dsp56k_core.reset_state) + { + m_dsp56k_core.icount = 0; + return; + } + + /* HACK - if you're in bootstrap mode, simply pretend you ate up all your cycles waiting for data. */ + if (m_dsp56k_core.bootstrap_mode != BOOTSTRAP_OFF) + { + m_dsp56k_core.icount = 0; + return; + } + + //m_dsp56k_core.icount -= m_dsp56k_core.interrupt_cycles; + //m_dsp56k_core.interrupt_cycles = 0; + + while(m_dsp56k_core.icount > 0) + { + execute_one(&m_dsp56k_core); + if (0) m_dsp56k_core.icount -= execute_one_new(&m_dsp56k_core); + pcu_service_interrupts(&m_dsp56k_core); // TODO: Is it incorrect to service after each instruction? + } +} + + +offs_t dsp56k_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) +{ + extern CPU_DISASSEMBLE( dsp56k ); + return CPU_DISASSEMBLE_NAME(dsp56k)(this, buffer, pc, oprom, opram, options); +} + diff --git a/src/emu/cpu/dsp56k/dsp56k.h b/src/emu/cpu/dsp56k/dsp56k.h index 70f2890ccc0..46f497c1b67 100644 --- a/src/emu/cpu/dsp56k/dsp56k.h +++ b/src/emu/cpu/dsp56k/dsp56k.h @@ -22,23 +22,6 @@ #define DSP56K_IRQ_MODC 2 #define DSP56K_IRQ_RESET 3 /* Is this needed? */ -// Needed for MAME -CPU_GET_INFO( dsp56k ); - -class dsp56k_device : public legacy_cpu_device -{ -public: - dsp56k_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, UINT32 clock); - - DECLARE_DIRECT_UPDATE_MEMBER(dsp56k_direct_handler); - DECLARE_READ16_MEMBER( program_r ); - DECLARE_WRITE16_MEMBER( program_w ); - DECLARE_READ16_MEMBER( peripheral_register_r ); - DECLARE_WRITE16_MEMBER( peripheral_register_w ); -}; - -extern const device_type DSP56156; - /*************************************************************************** STRUCTURES & TYPEDEFS @@ -204,7 +187,7 @@ struct dsp56k_core UINT32 op; int interrupt_cycles; void (*output_pins_changed)(UINT32 pins); - legacy_cpu_device *device; + cpu_device *device; address_space *program; direct_read_data *direct; address_space *data; @@ -214,20 +197,61 @@ struct dsp56k_core }; -INLINE dsp56k_core *get_safe_token(device_t *device) +class dsp56k_device : public cpu_device { - assert(device != NULL); - assert(device->type() == DSP56156); - return (dsp56k_core *)downcast(device)->token(); -} +public: + dsp56k_device(const machine_config &mconfig, const char *_tag, device_t *_owner, UINT32 _clock); + + DECLARE_DIRECT_UPDATE_MEMBER(dsp56k_direct_handler); + DECLARE_READ16_MEMBER( program_r ); + DECLARE_WRITE16_MEMBER( program_w ); + DECLARE_READ16_MEMBER( peripheral_register_r ); + DECLARE_WRITE16_MEMBER( peripheral_register_w ); + + void host_interface_write(UINT8 offset, UINT8 data); + UINT8 host_interface_read(UINT8 offset); + + UINT16 get_peripheral_memory(UINT16 addr); + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + // device_execute_interface overrides + virtual UINT64 execute_clocks_to_cycles(UINT64 clocks) const { return (clocks + 2 - 1) / 2; } + virtual UINT64 execute_cycles_to_clocks(UINT64 cycles) const { return (cycles * 2); } + virtual UINT32 execute_min_cycles() const { return 1; } + virtual UINT32 execute_max_cycles() const { return 8; } + virtual UINT32 execute_input_lines() const { return 4; } + virtual UINT32 execute_default_irq_vector() const { return 0; } + virtual void execute_run(); + virtual void execute_set_input(int inputnum, int state); + + // device_memory_interface overrides + virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const { return (spacenum == AS_PROGRAM) ? &m_program_config : ((spacenum == AS_DATA) ? &m_data_config : NULL ); } + + // device_state_interface overrides + void state_string_export(const device_state_entry &entry, astring &string); + + // device_disasm_interface overrides + virtual UINT32 disasm_min_opcode_bytes() const { return 2; } + virtual UINT32 disasm_max_opcode_bytes() const { return 4; } + virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options); + +private: + address_space_config m_program_config; + address_space_config m_data_config; + + dsp56k_core m_dsp56k_core; + + void agu_init(); + void alu_init(); + +}; -/*************************************************************************** - PUBLIC FUNCTIONS - ACCESSIBLE TO DRIVERS -***************************************************************************/ -void dsp56k_host_interface_write(device_t* device, UINT8 offset, UINT8 data); -UINT8 dsp56k_host_interface_read(device_t* device, UINT8 offset); +extern const device_type DSP56156; -UINT16 dsp56k_get_peripheral_memory(device_t* device, UINT16 addr); #endif /* __DSP56K_H__ */ diff --git a/src/emu/cpu/dsp56k/dsp56mem.c b/src/emu/cpu/dsp56k/dsp56mem.c index 55702514c07..69c5811da84 100644 --- a/src/emu/cpu/dsp56k/dsp56mem.c +++ b/src/emu/cpu/dsp56k/dsp56mem.c @@ -488,20 +488,18 @@ void dsp56k_io_reset(dsp56k_core* cpustate) READ16_MEMBER( dsp56k_device::program_r ) { - dsp56k_core* cpustate = get_safe_token(this); - return cpustate->program_ram[offset]; + return m_dsp56k_core.program_ram[offset]; } WRITE16_MEMBER( dsp56k_device::program_w ) { - dsp56k_core* cpustate = get_safe_token(this); - cpustate->program_ram[offset] = data; + m_dsp56k_core.program_ram[offset] = data; } /* Work */ READ16_MEMBER( dsp56k_device::peripheral_register_r ) { - dsp56k_core* cpustate = get_safe_token(this); + dsp56k_core* cpustate = &m_dsp56k_core; // (printf) logerror("Peripheral read 0x%04x\n", O2A(offset)); switch (O2A(offset)) @@ -635,7 +633,7 @@ READ16_MEMBER( dsp56k_device::peripheral_register_r ) WRITE16_MEMBER( dsp56k_device::peripheral_register_w ) { - dsp56k_core* cpustate = get_safe_token(this); + dsp56k_core* cpustate = &m_dsp56k_core; // Its primary behavior is RAM // COMBINE_DATA(&cpustate->peripheral_ram[offset]); @@ -790,9 +788,9 @@ WRITE16_MEMBER( dsp56k_device::peripheral_register_w ) /* These two functions are exposed to the outside world */ /* They represent the host side of the dsp56k's host interface */ -void dsp56k_host_interface_write(device_t* device, UINT8 offset, UINT8 data) +void dsp56k_device::host_interface_write(UINT8 offset, UINT8 data) { - dsp56k_core* cpustate = get_safe_token(device); + dsp56k_core* cpustate = &m_dsp56k_core; /* Not exactly correct since the bootstrap hack doesn't need this to be true */ /* @@ -886,9 +884,9 @@ void dsp56k_host_interface_write(device_t* device, UINT8 offset, UINT8 data) } } -UINT8 dsp56k_host_interface_read(device_t* device, UINT8 offset) +UINT8 dsp56k_device::host_interface_read(UINT8 offset) { - dsp56k_core* cpustate = get_safe_token(device); + dsp56k_core* cpustate = &m_dsp56k_core; /* Not exactly correct since the bootstrap hack doesn't need this to be true */ /* @@ -951,8 +949,8 @@ UINT8 dsp56k_host_interface_read(device_t* device, UINT8 offset) } /* MISC*/ -UINT16 dsp56k_get_peripheral_memory(device_t* device, UINT16 addr) +UINT16 dsp56k_device::get_peripheral_memory(UINT16 addr) { - dsp56k_core* cpustate = get_safe_token(device); + dsp56k_core* cpustate = &m_dsp56k_core; return cpustate->peripheral_ram[A2O(addr)]; } diff --git a/src/mame/drivers/plygonet.c b/src/mame/drivers/plygonet.c index d5519ce2635..cd71d359083 100644 --- a/src/mame/drivers/plygonet.c +++ b/src/mame/drivers/plygonet.c @@ -198,7 +198,7 @@ READ32_MEMBER(polygonet_state::dsp_host_interface_r) if (mem_mask == 0x0000ff00) { hi_addr++; } /* Low byte */ if (mem_mask == 0xff000000) {} /* High byte */ - value = dsp56k_host_interface_read(m_dsp, hi_addr); + value = m_dsp->host_interface_read(hi_addr); if (mem_mask == 0x0000ff00) { value <<= 8; } if (mem_mask == 0xff000000) { value <<= 24; } @@ -278,7 +278,7 @@ WRITE32_MEMBER(polygonet_state::dsp_host_interface_w) if (mem_mask == 0xff000000) { hi_data = (data & 0xff000000) >> 24; } logerror("write (host-side) %08x %08x %08x (HI %04x)\n", offset, mem_mask, data, hi_addr); - dsp56k_host_interface_write(m_dsp, hi_addr, hi_data); + m_dsp->host_interface_write(hi_addr, hi_data); } @@ -353,7 +353,7 @@ DIRECT_UPDATE_MEMBER(polygonet_state::plygonet_dsp56k_direct_handler) static UINT8 dsp56k_bank_group(device_t* cpu) { - UINT16 portC = dsp56k_get_peripheral_memory(cpu, 0xffe3); + UINT16 portC = ((dsp56k_device *)cpu)->get_peripheral_memory(0xffe3); /* If bank group B is on, it overrides bank group A */ if (portC & 0x0002) @@ -366,7 +366,7 @@ static UINT8 dsp56k_bank_group(device_t* cpu) static UINT8 dsp56k_bank_num(device_t* cpu, UINT8 bank_group) { - UINT16 portC = dsp56k_get_peripheral_memory(cpu, 0xffe3); + UINT16 portC = ((dsp56k_device *)cpu)->get_peripheral_memory(0xffe3); if (bank_group == BANK_GROUP_A) { diff --git a/src/mame/includes/plygonet.h b/src/mame/includes/plygonet.h index 1d906819974..d4f018aae8c 100644 --- a/src/mame/includes/plygonet.h +++ b/src/mame/includes/plygonet.h @@ -1,5 +1,6 @@ #include "machine/eepromser.h" #include "video/k053936.h" +#include "cpu/dsp56k/dsp56k.h" static const UINT16 dsp56k_bank00_size = 0x1000; @@ -28,7 +29,7 @@ public: required_device m_maincpu; required_device m_audiocpu; - required_device m_dsp; + required_device m_dsp; required_device m_eeprom; required_device m_k053936;