dsp56k.c: Modernised cpu core (nw)

This commit is contained in:
Wilbert Pol 2014-09-12 19:30:27 +00:00
parent ad52cefa2e
commit f11344542e
5 changed files with 440 additions and 580 deletions

View File

@ -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<dsp56k_device>;
/****************************************************************************
* 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);
}

View File

@ -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<legacy_cpu_device *>(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__ */

View File

@ -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)];
}

View File

@ -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)
{

View File

@ -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<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
required_device<cpu_device> m_dsp;
required_device<dsp56k_device> m_dsp;
required_device<eeprom_serial_er5911_device> m_eeprom;
required_device<k053936_device> m_k053936;