Adds save state support to plygonet.c and the DSP56156 CPU core.

This commit is contained in:
Andrew Gardner 2009-11-04 05:20:00 +00:00
parent 831ee03acf
commit 45dfc2315a
6 changed files with 206 additions and 134 deletions

View File

@ -992,6 +992,8 @@ endif
$(CPUOBJ)/dsp56k/dsp56k.o: $(CPUSRC)/dsp56k/dsp56k.c \ $(CPUOBJ)/dsp56k/dsp56k.o: $(CPUSRC)/dsp56k/dsp56k.c \
$(CPUSRC)/dsp56k/dsp56ops.c \ $(CPUSRC)/dsp56k/dsp56ops.c \
$(CPUSRC)/dsp56k/dsp56mem.c \
$(CPUSRC)/dsp56k/dsp56pcu.c \
$(CPUSRC)/dsp56k/dsp56k.h $(CPUSRC)/dsp56k/dsp56k.h

View File

@ -51,19 +51,19 @@ static UINT16 *dsp56k_program_ram;
/*************************************************************************** /***************************************************************************
COMPONENT FUNCTIONALITY COMPONENT FUNCTIONALITY
***************************************************************************/ ***************************************************************************/
// 1-9 ALU /* 1-9 ALU */
// #include "dsp56alu.c" // #include "dsp56alu.c"
// 1-10 Address Generation Unit (AGU) /* 1-10 Address Generation Unit (AGU) */
// #include "dsp56agu.c" // #include "dsp56agu.c"
// 1-11 Program Control Unit (PCU) /* 1-11 Program Control Unit (PCU) */
#include "dsp56pcu.c" #include "dsp56pcu.c"
// 5-1 Host Interface (HI) /* 5-1 Host Interface (HI) */
//#include "dsp56hi.c" //#include "dsp56hi.c"
// 4-8 Memory handlers for on-chip peripheral memory. /* 4-8 Memory handlers for on-chip peripheral memory. */
#include "dsp56mem.c" #include "dsp56mem.c"
@ -154,7 +154,7 @@ static void set_irq_line(dsp56k_core* cpustate, int irqline, int state)
break; break;
} }
// If the reset line isn't asserted, service interrupts /* If the reset line isn't asserted, service interrupts */
// TODO: Is it right to immediately service interrupts? // TODO: Is it right to immediately service interrupts?
//if (cpustate->reset_state != TRUE) //if (cpustate->reset_state != TRUE)
// pcu_service_interrupts(); // pcu_service_interrupts();
@ -164,27 +164,72 @@ static void set_irq_line(dsp56k_core* cpustate, int irqline, int state)
/*************************************************************************** /***************************************************************************
INITIALIZATION AND SHUTDOWN INITIALIZATION AND SHUTDOWN
***************************************************************************/ ***************************************************************************/
static void agu_init(dsp56k_core* cpustate, const device_config *device)
{
/* save states - dsp56k_agu members */
state_save_register_device_item(device, 0, cpustate->AGU.r0);
state_save_register_device_item(device, 0, cpustate->AGU.r1);
state_save_register_device_item(device, 0, cpustate->AGU.r2);
state_save_register_device_item(device, 0, cpustate->AGU.r3);
state_save_register_device_item(device, 0, cpustate->AGU.n0);
state_save_register_device_item(device, 0, cpustate->AGU.n1);
state_save_register_device_item(device, 0, cpustate->AGU.n2);
state_save_register_device_item(device, 0, cpustate->AGU.n3);
state_save_register_device_item(device, 0, cpustate->AGU.m0);
state_save_register_device_item(device, 0, cpustate->AGU.m1);
state_save_register_device_item(device, 0, cpustate->AGU.m2);
state_save_register_device_item(device, 0, cpustate->AGU.m3);
state_save_register_device_item(device, 0, cpustate->AGU.temp);
}
static void alu_init(dsp56k_core* cpustate, const device_config *device)
{
/* save states - dsp56k_alu members */
state_save_register_device_item(device, 0, cpustate->ALU.x);
state_save_register_device_item(device, 0, cpustate->ALU.y);
state_save_register_device_item(device, 0, cpustate->ALU.a);
state_save_register_device_item(device, 0, cpustate->ALU.b);
}
static CPU_INIT( dsp56k ) static CPU_INIT( dsp56k )
{ {
dsp56k_core* cpustate = get_safe_token(device); dsp56k_core* cpustate = get_safe_token(device);
// Call specific module inits /* Call specific module inits */
pcu_init(cpustate); pcu_init(cpustate, device);
// agu_init(cpustate); agu_init(cpustate, device);
// alu_init(cpustate); alu_init(cpustate, device);
// HACK - You're not in bootstrap mode upon bootup /* HACK - You're not in bootstrap mode upon bootup */
cpustate->bootstrap_mode = BOOTSTRAP_OFF; cpustate->bootstrap_mode = BOOTSTRAP_OFF;
// Clear the irq states /* Clear the irq states */
cpustate->modA_state = FALSE; cpustate->modA_state = FALSE;
cpustate->modB_state = FALSE; cpustate->modB_state = FALSE;
cpustate->modC_state = FALSE; cpustate->modC_state = FALSE;
cpustate->reset_state = FALSE; cpustate->reset_state = FALSE;
/* Save the core's state */ /* save states - dsp56k_core members */
// state_save_register_device_item(device, 0, modA_state); state_save_register_device_item(device, 0, cpustate->modA_state);
// ... state_save_register_device_item(device, 0, cpustate->modB_state);
state_save_register_device_item(device, 0, cpustate->modC_state);
state_save_register_device_item(device, 0, cpustate->reset_state);
state_save_register_device_item(device, 0, cpustate->bootstrap_mode);
state_save_register_device_item(device, 0, cpustate->repFlag);
state_save_register_device_item(device, 0, cpustate->repAddr);
state_save_register_device_item(device, 0, cpustate->icount);
state_save_register_device_item(device, 0, cpustate->ppc);
state_save_register_device_item(device, 0, cpustate->op);
state_save_register_device_item(device, 0, cpustate->interrupt_cycles);
/* save states - dsp56k_host_interface members */
state_save_register_device_item(device, 0, cpustate->HI.icr);
state_save_register_device_item(device, 0, cpustate->HI.cvr);
state_save_register_device_item(device, 0, cpustate->HI.isr);
state_save_register_device_item(device, 0, cpustate->HI.ivr);
state_save_register_device_item(device, 0, cpustate->HI.trxh);
state_save_register_device_item(device, 0, cpustate->HI.trxl);
state_save_register_device_item(device, 0, cpustate->HI.bootstrap_offset);
//cpustate->config = device->static_config; //cpustate->config = device->static_config;
//cpustate->irq_callback = irqcallback; //cpustate->irq_callback = irqcallback;
@ -197,9 +242,13 @@ static CPU_INIT( dsp56k )
memory_set_direct_update_handler(cpustate->program, dsp56k_direct_handler); memory_set_direct_update_handler(cpustate->program, dsp56k_direct_handler);
} }
/***************************************************************************
RESET BEHAVIOR
***************************************************************************/
static void agu_reset(dsp56k_core* cpustate) static void agu_reset(dsp56k_core* cpustate)
{ {
// FM.4-3 /* FM.4-3 */
R0 = 0x0000; R0 = 0x0000;
R1 = 0x0000; R1 = 0x0000;
R2 = 0x0000; R2 = 0x0000;
@ -263,7 +312,6 @@ static CPU_EXIT( dsp56k )
/*************************************************************************** /***************************************************************************
CORE EXECUTION LOOP CORE EXECUTION LOOP
***************************************************************************/ ***************************************************************************/
static CPU_EXECUTE( dsp56k ) static CPU_EXECUTE( dsp56k )
{ {
dsp56k_core* cpustate = get_safe_token(device); dsp56k_core* cpustate = get_safe_token(device);
@ -272,7 +320,7 @@ static CPU_EXECUTE( dsp56k )
if (cpustate->reset_state) if (cpustate->reset_state)
return cycles; return cycles;
// HACK - if you're in bootstrap mode, simply pretend you ate up all your cycles waiting for data. /* HACK - if you're in bootstrap mode, simply pretend you ate up all your cycles waiting for data. */
if (cpustate->bootstrap_mode != BOOTSTRAP_OFF) if (cpustate->bootstrap_mode != BOOTSTRAP_OFF)
return cycles; return cycles;
@ -304,20 +352,19 @@ extern CPU_DISASSEMBLE( dsp56k );
* Internal Memory Maps * Internal Memory Maps
****************************************************************************/ ****************************************************************************/
static ADDRESS_MAP_START( dsp56156_program_map, ADDRESS_SPACE_PROGRAM, 16 ) static ADDRESS_MAP_START( dsp56156_program_map, ADDRESS_SPACE_PROGRAM, 16 )
AM_RANGE(0x0000,0x07ff) AM_RAM AM_BASE(&dsp56k_program_ram) // 1-5 AM_RANGE(0x0000,0x07ff) AM_RAM AM_BASE(&dsp56k_program_ram) /* 1-5 */
// AM_RANGE(0x2f00,0x2fff) AM_ROM // 1-5 PROM reserved memory. Is this the right spot for it? // AM_RANGE(0x2f00,0x2fff) AM_ROM /* 1-5 PROM reserved memory. Is this the right spot for it? */
ADDRESS_MAP_END ADDRESS_MAP_END
static ADDRESS_MAP_START( dsp56156_x_data_map, ADDRESS_SPACE_DATA, 16 ) static ADDRESS_MAP_START( dsp56156_x_data_map, ADDRESS_SPACE_DATA, 16 )
AM_RANGE(0x0000,0x07ff) AM_RAM // 1-5 AM_RANGE(0x0000,0x07ff) AM_RAM /* 1-5 */
AM_RANGE(0xffc0,0xffff) AM_READWRITE(peripheral_register_r, peripheral_register_w) AM_BASE(&dsp56k_peripheral_ram) // 1-5 On-chip peripheral registers memory mapped in data space AM_RANGE(0xffc0,0xffff) AM_READWRITE(peripheral_register_r, peripheral_register_w) AM_BASE(&dsp56k_peripheral_ram) /* 1-5 On-chip peripheral registers memory mapped in data space */
ADDRESS_MAP_END ADDRESS_MAP_END
/************************************************************************** /**************************************************************************
* Generic set_info/get_info * Generic set_info/get_info
**************************************************************************/ **************************************************************************/
static CPU_SET_INFO( dsp56k ) static CPU_SET_INFO( dsp56k )
{ {
dsp56k_core* cpustate = get_safe_token(device); dsp56k_core* cpustate = get_safe_token(device);
@ -344,8 +391,8 @@ static CPU_SET_INFO( dsp56k )
case CPUINFO_INT_REGISTER + DSP56K_X: X = info->i & 0xffffffff; 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_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_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_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_R0: R0 = info->i & 0xffff; break;
case CPUINFO_INT_REGISTER + DSP56K_R1: R1 = info->i & 0xffff; break; case CPUINFO_INT_REGISTER + DSP56K_R1: R1 = info->i & 0xffff; break;
@ -392,7 +439,7 @@ CPU_GET_INFO( dsp56k )
switch (state) switch (state)
{ {
// --- the following bits of info are returned as 64-bit signed integers --- /* --- 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_CONTEXT_SIZE: info->i = sizeof(dsp56k_core); break;
case CPUINFO_INT_INPUT_LINES: info->i = 4; break; case CPUINFO_INT_INPUT_LINES: info->i = 4; break;
case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0x0000; break; case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0x0000; break;
@ -404,8 +451,8 @@ CPU_GET_INFO( dsp56k )
case CPUINFO_INT_MIN_CYCLES: info->i = 1; break; // ? case CPUINFO_INT_MIN_CYCLES: info->i = 1; break; // ?
case CPUINFO_INT_MAX_CYCLES: info->i = 8; break; // ? case CPUINFO_INT_MAX_CYCLES: info->i = 8; break; // ?
case CPUINFO_INT_DATABUS_WIDTH_PROGRAM: info->i = 16; break; // 1-5 case CPUINFO_INT_DATABUS_WIDTH_PROGRAM: info->i = 16; break; /* 1-5 */
case CPUINFO_INT_ADDRBUS_WIDTH_PROGRAM: info->i = 16; break; // 1-5 case CPUINFO_INT_ADDRBUS_WIDTH_PROGRAM: info->i = 16; break; /* 1-5 */
case CPUINFO_INT_ADDRBUS_SHIFT_PROGRAM: info->i = -1; break; case CPUINFO_INT_ADDRBUS_SHIFT_PROGRAM: info->i = -1; break;
case CPUINFO_INT_DATABUS_WIDTH_DATA: info->i = 16; break; case CPUINFO_INT_DATABUS_WIDTH_DATA: info->i = 16; break;
case CPUINFO_INT_ADDRBUS_WIDTH_DATA: info->i = 16; break; case CPUINFO_INT_ADDRBUS_WIDTH_DATA: info->i = 16; break;
@ -455,7 +502,7 @@ CPU_GET_INFO( dsp56k )
/* case CPUINFO_INT_REGISTER + DSP56K_TEMP: info->i = TEMP; break; */ /* case CPUINFO_INT_REGISTER + DSP56K_TEMP: info->i = TEMP; break; */
/* case CPUINFO_INT_REGISTER + DSP56K_STATUS: info->i = STATUS; break; */ /* case CPUINFO_INT_REGISTER + DSP56K_STATUS: info->i = STATUS; break; */
// The CPU stack /* The CPU stack */
case CPUINFO_INT_REGISTER + DSP56K_ST0: info->i = ST0; break; 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_ST1: info->i = ST1; break;
case CPUINFO_INT_REGISTER + DSP56K_ST2: info->i = ST2; break; case CPUINFO_INT_REGISTER + DSP56K_ST2: info->i = ST2; break;
@ -473,7 +520,7 @@ CPU_GET_INFO( dsp56k )
case CPUINFO_INT_REGISTER + DSP56K_ST14: info->i = ST14; break; case CPUINFO_INT_REGISTER + DSP56K_ST14: info->i = ST14; break;
case CPUINFO_INT_REGISTER + DSP56K_ST15: info->i = ST15; break; case CPUINFO_INT_REGISTER + DSP56K_ST15: info->i = ST15; break;
// --- the following bits of info are returned as pointers to data or functions --- /* --- 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_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(dsp56k); break;
case CPUINFO_FCT_INIT: info->init = CPU_INIT_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_RESET: info->reset = CPU_RESET_NAME(dsp56k); break;
@ -492,7 +539,7 @@ CPU_GET_INFO( dsp56k )
case CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM: case CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM:
info->internal_map16 = ADDRESS_MAP_NAME(dsp56156_program_map); break; info->internal_map16 = ADDRESS_MAP_NAME(dsp56156_program_map); break;
// --- the following bits of info are returned as NULL-terminated strings --- /* --- the following bits of info are returned as NULL-terminated strings --- */
case DEVINFO_STR_NAME: strcpy(info->s, "DSP56156"); break; case DEVINFO_STR_NAME: strcpy(info->s, "DSP56156"); break;
case DEVINFO_STR_FAMILY: strcpy(info->s, "Motorola 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_VERSION: strcpy(info->s, "0.1"); break;
@ -550,7 +597,7 @@ CPU_GET_INFO( dsp56k )
/* case CPUINFO_STR_REGISTER + DSP56K_TEMP: sprintf(info->s, "TMP: %04x", TEMP); 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; */ /* case CPUINFO_STR_REGISTER + DSP56K_STATUS: sprintf(info->s, "STS: %02x", STATUS); break; */
// The CPU stack /* The CPU stack */
case CPUINFO_STR_REGISTER + DSP56K_ST0: sprintf(info->s, "ST0 : %08x", ST0); break; 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_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_ST2: sprintf(info->s, "ST2 : %08x", ST2); break;

View File

@ -2865,8 +2865,8 @@ static size_t dsp56k_op_do_2(dsp56k_core* cpustate, const UINT16 op, const UINT1
/* HACK */ /* HACK */
if (lValue >= 0xfff0) if (lValue >= 0xfff0)
{ {
lValue = 0x0000;
logerror("Dsp56k : DO_2 operation changed %04x to 0000.\n", lValue); logerror("Dsp56k : DO_2 operation changed %04x to 0000.\n", lValue);
lValue = 0x0000;
} }
/* TODO: Fix for special cased SP S */ /* TODO: Fix for special cased SP S */

View File

@ -90,52 +90,63 @@ static UINT8 SE_bit(dsp56k_core* cpustate) { return ((SP & 0x0010) != 0); }
/*************************************************************************** /***************************************************************************
INITIALIZATION AND RESET INITIALIZATION AND RESET
***************************************************************************/ ***************************************************************************/
static void pcu_init(dsp56k_core* cpustate) static void pcu_init(dsp56k_core* cpustate, const device_config *device)
{ {
// Init the irq table /* Init the irq table */
dsp56k_irq_table_init(); dsp56k_irq_table_init();
/* save states - dsp56k_pcu members */
state_save_register_device_item(device, 0, cpustate->PCU.pc);
state_save_register_device_item(device, 0, cpustate->PCU.la);
state_save_register_device_item(device, 0, cpustate->PCU.lc);
state_save_register_device_item(device, 0, cpustate->PCU.sr);
state_save_register_device_item(device, 0, cpustate->PCU.omr);
state_save_register_device_item(device, 0, cpustate->PCU.sp);
state_save_register_device_item_array(device, 0, cpustate->PCU.ss);
state_save_register_device_item_array(device, 0, cpustate->PCU.pending_interrupts);
state_save_register_device_item(device, 0, cpustate->PCU.reset_vector);
} }
static void pcu_reset(dsp56k_core* cpustate) static void pcu_reset(dsp56k_core* cpustate)
{ {
int i; int i;
// When reset is deasserted, set MA, MB, and MC from MODA, MODB, and MODC lines. /* When reset is deasserted, set MA, MB, and MC from MODA, MODB, and MODC lines. */
MA_bit_set(cpustate, cpustate->modA_state); MA_bit_set(cpustate, cpustate->modA_state);
MB_bit_set(cpustate, cpustate->modB_state); MB_bit_set(cpustate, cpustate->modB_state);
MC_bit_set(cpustate, cpustate->modC_state); MC_bit_set(cpustate, cpustate->modC_state);
// Reset based on the operating mode. /* Reset based on the operating mode. */
switch(dsp56k_operating_mode(cpustate)) switch(dsp56k_operating_mode(cpustate))
{ {
case 0x00: case 0x00:
logerror("Dsp56k in Special Bootstrap Mode 1\n"); logerror("Dsp56k in Special Bootstrap Mode 1\n");
// HACK - We don't need to put the bootstrap mode on here since /* HACK - We don't need to put the bootstrap mode on here since */
// we'll simulate it entirely in this function /* we'll simulate it entirely in this function */
cpustate->bootstrap_mode = BOOTSTRAP_OFF; cpustate->bootstrap_mode = BOOTSTRAP_OFF;
// HACK - Simply copy over 0x1000 bytes of data located at program memory 0xc000. /* HACK - Simply copy over 0x1000 bytes of data located at program memory 0xc000. */
// This, in actuality, is handled with the internal boot ROM. /* This, in actuality, is handled with the internal boot ROM. */
for (i = 0; i < 0x800; i++) for (i = 0; i < 0x800; i++)
{ {
UINT32 mem_offset = (0xc000<<1) + (i<<1); /* TODO: TEST */ UINT32 mem_offset = (0xc000<<1) + (i<<1); /* TODO: TEST */
// TODO - DO I HAVE TO FLIP THIS WORD? /* TODO - DO I HAVE TO FLIP THIS WORD? */
// P:$c000 -> Internal P:$0000 low byte /* P:$c000 -> Internal P:$0000 low byte */
// P:$c001 -> Internal P:$0000 high byte /* P:$c001 -> Internal P:$0000 high byte */
// ... /* ... */
// P:$cffe -> Internal P:$07ff low byte /* P:$cffe -> Internal P:$07ff low byte */
// P:$cfff -> Internal P:$07ff high byte /* P:$cfff -> Internal P:$07ff high byte */
UINT8 mem_value_low = memory_read_byte_16le(cpustate->program, mem_offset); /* TODO: IS THIS READING RIGHT? */ UINT8 mem_value_low = memory_read_byte_16le(cpustate->program, mem_offset); /* TODO: IS THIS READING RIGHT? */
UINT8 mem_value_high = memory_read_byte_16be(cpustate->program, mem_offset); UINT8 mem_value_high = memory_read_byte_16be(cpustate->program, mem_offset);
dsp56k_program_ram[i] = (mem_value_high << 8) || mem_value_low; dsp56k_program_ram[i] = (mem_value_high << 8) || mem_value_low;
} }
// HACK - Set the PC to 0x0000 as per the boot ROM. /* HACK - Set the PC to 0x0000 as per the boot ROM. */
PC = 0x0000; PC = 0x0000;
// HACK - All done! Set the Operating Mode to 2 as per the boot ROM. /* HACK - All done! Set the Operating Mode to 2 as per the boot ROM. */
MB_bit_set(cpustate, 1); MB_bit_set(cpustate, 1);
MA_bit_set(cpustate, 0); MA_bit_set(cpustate, 0);
cpustate->PCU.reset_vector = 0xe000; cpustate->PCU.reset_vector = 0xe000;
@ -144,11 +155,11 @@ static void pcu_reset(dsp56k_core* cpustate)
case 0x01: case 0x01:
logerror("Dsp56k in Special Bootstrap Mode 2\n"); logerror("Dsp56k in Special Bootstrap Mode 2\n");
// HACK - Turn bootstrap mode on. This hijacks the CPU execute loop and lets /* HACK - Turn bootstrap mode on. This hijacks the CPU execute loop and lets */
// Either the host interface or the SSIO interface suck in all the data /* Either the host interface or the SSIO interface suck in all the data */
// they need. Once they've had their fill, they turn bootstrap mode off /* they need. Once they've had their fill, they turn bootstrap mode off */
// and the CPU begins execution at 0x0000; /* and the CPU begins execution at 0x0000; */
// HACK - Read bit 15 at 0xc000 to see if we're working with the SSIO or host interface. /* HACK - Read bit 15 at 0xc000 to see if we're working with the SSIO or host interface. */
if (memory_read_word_16le(cpustate->program, 0xc000<<1) & 0x8000) if (memory_read_word_16le(cpustate->program, 0xc000<<1) & 0x8000)
{ {
cpustate->bootstrap_mode = BOOTSTRAP_SSIX; cpustate->bootstrap_mode = BOOTSTRAP_SSIX;
@ -160,10 +171,10 @@ static void pcu_reset(dsp56k_core* cpustate)
logerror("DSP56k : Currently in (hacked) bootstrap mode - reading from Host Interface.\n"); logerror("DSP56k : Currently in (hacked) bootstrap mode - reading from Host Interface.\n");
} }
// HACK - Set the PC to 0x0000 as per the boot ROM. /* HACK - Set the PC to 0x0000 as per the boot ROM. */
PC = 0x0000; PC = 0x0000;
// HACK - Not done yet, but set the Operating Mode to 2 in preparation. /* HACK - Not done yet, but set the Operating Mode to 2 in preparation. */
MB_bit_set(cpustate, 1); MB_bit_set(cpustate, 1);
MA_bit_set(cpustate, 0); MA_bit_set(cpustate, 0);
cpustate->PCU.reset_vector = 0xe000; cpustate->PCU.reset_vector = 0xe000;
@ -177,42 +188,42 @@ static void pcu_reset(dsp56k_core* cpustate)
case 0x03: case 0x03:
logerror("Dsp56k in Development Expanded Mode\n"); logerror("Dsp56k in Development Expanded Mode\n");
// TODO: Disable internal ROM, etc. Likely a tricky thing for MAME? /* TODO: Disable internal ROM, etc. Likely a tricky thing for MAME? */
PC = 0x0000; PC = 0x0000;
cpustate->PCU.reset_vector = 0x0000; cpustate->PCU.reset_vector = 0x0000;
break; break;
} }
// Set registers properly /* Set registers properly */
// 1-17 Clear Interrupt Priority Register (IPR) /* 1-17 Clear Interrupt Priority Register (IPR) */
IPR = 0x0000; IPR = 0x0000;
// FM.5-4 /* FM.5-4 */
I_bits_set(cpustate, 0x03); I_bits_set(cpustate, 0x03);
S_bits_set(cpustate, 0); S_bits_set(cpustate, 0);
L_bit_set(cpustate, 0); L_bit_set(cpustate, 0);
S_bit_set(cpustate, 0); S_bit_set(cpustate, 0);
FV_bit_set(cpustate, 0); FV_bit_set(cpustate, 0);
// FM.7-25 /* FM.7-25 */
E_bit_set(cpustate, 0); E_bit_set(cpustate, 0);
U_bit_set(cpustate, 0); U_bit_set(cpustate, 0);
N_bit_set(cpustate, 0); N_bit_set(cpustate, 0);
V_bit_set(cpustate, 0); V_bit_set(cpustate, 0);
Z_bit_set(cpustate, 0); Z_bit_set(cpustate, 0);
// FM.5-4+ /* FM.5-4+ */
C_bit_set(cpustate, 0); C_bit_set(cpustate, 0);
LF_bit_set(cpustate, 0); LF_bit_set(cpustate, 0);
SP = 0x0000; SP = 0x0000;
// FM.5-14 (OMR) /* FM.5-14 (OMR) */
SA_bit_set(cpustate, 0); SA_bit_set(cpustate, 0);
R_bit_set(cpustate, 0); R_bit_set(cpustate, 0);
SD_bit_set(cpustate, 0); SD_bit_set(cpustate, 0);
CD_bit_set(cpustate, 0); CD_bit_set(cpustate, 0);
// Clear out the pending interrupt list /* Clear out the pending interrupt list */
dsp56k_clear_pending_interrupts(cpustate); dsp56k_clear_pending_interrupts(cpustate);
} }
@ -227,50 +238,50 @@ typedef struct
static dsp56k_irq_data dsp56k_interrupt_sources[32]; static dsp56k_irq_data dsp56k_interrupt_sources[32];
// TODO: Figure out how to switch on level versus edge-triggered. /* TODO: Figure out how to switch on level versus edge-triggered. */
static void pcu_service_interrupts(dsp56k_core* cpustate) static void pcu_service_interrupts(dsp56k_core* cpustate)
{ {
int i; int i;
// Count list of pending interrupts /* Count list of pending interrupts */
int num_servicable = dsp56k_count_pending_interrupts(cpustate); int num_servicable = dsp56k_count_pending_interrupts(cpustate);
if (num_servicable == 0) if (num_servicable == 0)
return; return;
// Sort list according to priority /* Sort list according to priority */
dsp56k_sort_pending_interrupts(cpustate, num_servicable); dsp56k_sort_pending_interrupts(cpustate, num_servicable);
// Service each interrupt in order /* Service each interrupt in order */
// TODO: This just *can't* be right :) /* TODO: This just *can't* be right :) */
for (i = 0; i < num_servicable; i++) for (i = 0; i < num_servicable; i++)
{ {
const int interrupt_index = cpustate->PCU.pending_interrupts[i]; const int interrupt_index = cpustate->PCU.pending_interrupts[i];
// Get the priority of the interrupt - a return value of -1 means disabled! /* Get the priority of the interrupt - a return value of -1 means disabled! */
INT8 priority = dsp56k_get_irq_priority(cpustate, interrupt_index); INT8 priority = dsp56k_get_irq_priority(cpustate, interrupt_index);
// 1-12 Make sure you're not masked out against the Interrupt Mask Bits (disabled is handled for free here) /* 1-12 Make sure you're not masked out against the Interrupt Mask Bits (disabled is handled for free here) */
if (priority >= I_bits(cpustate)) if (priority >= I_bits(cpustate))
{ {
// TODO: Implement long interrupts & fast interrupts correctly! /* TODO: Implement long interrupts & fast interrupts correctly! */
// Right now they are handled in the JSR & BSR ops. SupahLame. /* Right now they are handled in the JSR & BSR ops. SupahLame. */
cpustate->ppc = PC; cpustate->ppc = PC;
// Are you anything but the Host Command interrupt? /* Are you anything but the Host Command interrupt? */
if (interrupt_index != 22) if (interrupt_index != 22)
{ {
// Execute a normal interrupt /* Execute a normal interrupt */
PC = dsp56k_interrupt_sources[interrupt_index].irq_vector; PC = dsp56k_interrupt_sources[interrupt_index].irq_vector;
} }
else else
{ {
// The host command input has a floating vector. /* The host command input has a floating vector. */
const UINT16 irq_vector = HV_bits(cpustate) << 1; const UINT16 irq_vector = HV_bits(cpustate) << 1;
PC = irq_vector; PC = irq_vector;
// TODO: 5-9 5-11 Gotta' Clear HC (HCP gets it too) when taking this exception! /* TODO: 5-9 5-11 Gotta' Clear HC (HCP gets it too) when taking this exception! */
HC_bit_set(cpustate, 0); HC_bit_set(cpustate, 0);
} }
} }
@ -306,8 +317,8 @@ static void dsp56k_set_irq_source(UINT8 irq_num, UINT16 iv, const char* source)
/* Construct a table containing pertient IRQ information */ /* Construct a table containing pertient IRQ information */
static void dsp56k_irq_table_init(void) static void dsp56k_irq_table_init(void)
{ {
// 1-14 + 1-18 /* 1-14 + 1-18 */
// TODO: Cull host command stuff appropriately /* TODO: Cull host command stuff appropriately */
/* array index . vector . token */ /* array index . vector . token */
dsp56k_set_irq_source(0, 0x0000, "Hardware RESET"); dsp56k_set_irq_source(0, 0x0000, "Hardware RESET");
dsp56k_set_irq_source(1, 0x0002, "Illegal Instruction"); dsp56k_set_irq_source(1, 0x0002, "Illegal Instruction");
@ -370,14 +381,14 @@ static void dsp56k_sort_pending_interrupts(dsp56k_core* cpustate, int num)
{ {
int i, j; int i, j;
// We're going to be sorting the priorities /* We're going to be sorting the priorities */
int priority_list[32]; int priority_list[32];
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
{ {
priority_list[i] = dsp56k_get_irq_priority(cpustate, cpustate->PCU.pending_interrupts[i]); priority_list[i] = dsp56k_get_irq_priority(cpustate, cpustate->PCU.pending_interrupts[i]);
} }
// Bubble sort should be good enough for us /* Bubble sort should be good enough for us */
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
{ {
for(j = 0; j < num-1; j++) for(j = 0; j < num-1; j++)
@ -386,12 +397,12 @@ static void dsp56k_sort_pending_interrupts(dsp56k_core* cpustate, int num)
{ {
int holder; int holder;
// Swap priorities /* Swap priorities */
holder = priority_list[j+1]; holder = priority_list[j+1];
priority_list[j+1] = priority_list[j]; priority_list[j+1] = priority_list[j];
priority_list[j] = holder; priority_list[j] = holder;
// Swap irq indices. /* Swap irq indices. */
holder = cpustate->PCU.pending_interrupts[j+1]; holder = cpustate->PCU.pending_interrupts[j+1];
cpustate->PCU.pending_interrupts[j+1] = cpustate->PCU.pending_interrupts[j]; cpustate->PCU.pending_interrupts[j+1] = cpustate->PCU.pending_interrupts[j];
cpustate->PCU.pending_interrupts[j] = holder; cpustate->PCU.pending_interrupts[j] = holder;
@ -399,50 +410,50 @@ static void dsp56k_sort_pending_interrupts(dsp56k_core* cpustate, int num)
} }
} }
// TODO: 1-17 Now sort each of the priority levels within their categories. /* TODO: 1-17 Now sort each of the priority levels within their categories. */
} }
/* Given an index into the irq table, return the interrupt's current priority */ /* Given an index into the irq table, return the interrupt's current priority */
static INT8 dsp56k_get_irq_priority(dsp56k_core* cpustate, int index) static INT8 dsp56k_get_irq_priority(dsp56k_core* cpustate, int index)
{ {
// 1-12 /* 1-12 */
switch (index) switch (index)
{ {
// Non-maskable /* Non-maskable */
case 0: return 3; // Hardware RESET case 0: return 3; /* Hardware RESET */
case 1: return 3; // Illegal Instruction case 1: return 3; /* Illegal Instruction */
case 2: return 3; // Stack Error case 2: return 3; /* Stack Error */
case 3: return 3; // Reserved case 3: return 3; /* Reserved */
case 4: return 3; // SWI case 4: return 3; /* SWI */
// Poll the IPR for these guys. /* Poll the IPR for these guys. */
case 5: return irqa_ipl(cpustate); // IRQA case 5: return irqa_ipl(cpustate); /* IRQA */
case 6: return irqb_ipl(cpustate); // IRQB case 6: return irqb_ipl(cpustate); /* IRQB */
case 7: return -1; // Reserved case 7: return -1; /* Reserved */
case 8: return ssi0_ipl(cpustate); // SSI0 Receive Data with Exception case 8: return ssi0_ipl(cpustate); /* SSI0 Receive Data with Exception */
case 9: return ssi0_ipl(cpustate); // SSI0 Receive Data case 9: return ssi0_ipl(cpustate); /* SSI0 Receive Data */
case 10: return ssi0_ipl(cpustate); // SSI0 Transmit Data with Exception case 10: return ssi0_ipl(cpustate); /* SSI0 Transmit Data with Exception */
case 11: return ssi0_ipl(cpustate); // SSI0 Transmit Data case 11: return ssi0_ipl(cpustate); /* SSI0 Transmit Data */
case 12: return ssi1_ipl(cpustate); // SSI1 Receive Data with Exception case 12: return ssi1_ipl(cpustate); /* SSI1 Receive Data with Exception */
case 13: return ssi1_ipl(cpustate); // SSI1 Receive Data case 13: return ssi1_ipl(cpustate); /* SSI1 Receive Data */
case 14: return ssi1_ipl(cpustate); // SSI1 Transmit Data with Exception case 14: return ssi1_ipl(cpustate); /* SSI1 Transmit Data with Exception */
case 15: return ssi1_ipl(cpustate); // SSI1 Transmit Data case 15: return ssi1_ipl(cpustate); /* SSI1 Transmit Data */
case 16: return tm_ipl(cpustate); // Timer Overflow case 16: return tm_ipl(cpustate); /* Timer Overflow */
case 17: return tm_ipl(cpustate); // Timer Compare case 17: return tm_ipl(cpustate); /* Timer Compare */
case 18: return host_ipl(cpustate); // Host DMA Receive Data case 18: return host_ipl(cpustate); /* Host DMA Receive Data */
case 19: return host_ipl(cpustate); // Host DMA Transmit Data case 19: return host_ipl(cpustate); /* Host DMA Transmit Data */
case 20: return host_ipl(cpustate); // Host Receive Data case 20: return host_ipl(cpustate); /* Host Receive Data */
case 21: return host_ipl(cpustate); // Host Transmit Data case 21: return host_ipl(cpustate); /* Host Transmit Data */
case 22: return host_ipl(cpustate); // Host Command 0 (Default) case 22: return host_ipl(cpustate); /* Host Command 0 (Default) */
case 23: return codec_ipl(cpustate); // Codec Receive/Transmit case 23: return codec_ipl(cpustate); /* Codec Receive/Transmit */
case 24: return host_ipl(cpustate); // Host Command 1 // TODO: Are all host ipl's the same? case 24: return host_ipl(cpustate); /* Host Command 1 // TODO: Are all host ipl's the same? */
case 25: return host_ipl(cpustate); // Host Command 2 case 25: return host_ipl(cpustate); /* Host Command 2 */
case 26: return host_ipl(cpustate); // Host Command 3 case 26: return host_ipl(cpustate); /* Host Command 3 */
case 27: return host_ipl(cpustate); // Host Command 4 case 27: return host_ipl(cpustate); /* Host Command 4 */
case 28: return host_ipl(cpustate); // Host Command 5 case 28: return host_ipl(cpustate); /* Host Command 5 */
case 29: return host_ipl(cpustate); // Host Command 6 case 29: return host_ipl(cpustate); /* Host Command 6 */
case 30: return host_ipl(cpustate); // Host Command 7 case 30: return host_ipl(cpustate); /* Host Command 7 */
case 31: return host_ipl(cpustate); // Host Command 8 case 31: return host_ipl(cpustate); /* Host Command 8 */
default: break; default: break;
} }

View File

@ -763,6 +763,15 @@ static DRIVER_INIT(polygonet)
/* The dsp56k occasionally executes out of mapped memory */ /* The dsp56k occasionally executes out of mapped memory */
dsp56k_update_handler = memory_set_direct_update_handler(cputag_get_address_space(machine, "dsp", ADDRESS_SPACE_PROGRAM), plygonet_dsp56k_direct_handler); dsp56k_update_handler = memory_set_direct_update_handler(cputag_get_address_space(machine, "dsp", ADDRESS_SPACE_PROGRAM), plygonet_dsp56k_direct_handler);
/* save states */
state_save_register_global(machine, init_eeprom_count);
state_save_register_global_pointer(machine, dsp56k_bank00_ram, 2 * 8 * dsp56k_bank00_size);
state_save_register_global_pointer(machine, dsp56k_bank01_ram, 2 * 8 * dsp56k_bank01_size);
state_save_register_global_pointer(machine, dsp56k_bank02_ram, 2 * 8 * dsp56k_bank02_size);
state_save_register_global_pointer(machine, dsp56k_shared_ram_16, 2 * 8 * dsp56k_shared_ram_16_size);
state_save_register_global_pointer(machine, dsp56k_bank04_ram, 2 * 8 * dsp56k_bank04_size);
state_save_register_global(machine, cur_sound_region);
} }
@ -821,6 +830,6 @@ ROM_START( polynetw )
ROM_END ROM_END
/* ROM parent machine inp init */ /* ROM parent machine inp init */
GAME( 1993, plygonet, 0, plygonet, polygonet, polygonet, ROT90, "Konami", "Polygonet Commanders (ver UAA)", GAME_NOT_WORKING | GAME_NO_SOUND ) GAME( 1993, plygonet, 0, plygonet, polygonet, polygonet, ROT90, "Konami", "Polygonet Commanders (ver UAA)", GAME_NOT_WORKING | GAME_SUPPORTS_SAVE )
GAME( 1993, polynetw, 0, plygonet, polynetw, polygonet, ROT90, "Konami", "Poly-Net Warriors (ver JAA)", GAME_NOT_WORKING | GAME_NO_SOUND ) GAME( 1993, polynetw, 0, plygonet, polynetw, polygonet, ROT90, "Konami", "Poly-Net Warriors (ver JAA)", GAME_NOT_WORKING | GAME_SUPPORTS_SAVE )

View File

@ -24,7 +24,7 @@ static TILE_GET_INFO( ttl_get_tile_info )
code = ttl_vram[tile_index]&0xfff; code = ttl_vram[tile_index]&0xfff;
attr = ttl_vram[tile_index]>>12; // palette in all 4 bits? attr = ttl_vram[tile_index]>>12; /* palette in all 4 bits? */
SET_TILE_INFO(ttl_gfx_index, code, attr, 0); SET_TILE_INFO(ttl_gfx_index, code, attr, 0);
} }
@ -33,7 +33,7 @@ static TILE_GET_INFO( roz_get_tile_info )
{ {
int attr, code; int attr, code;
attr = (roz_vram[tile_index] >> 12) + 16; // roz base palette is palette 16 attr = (roz_vram[tile_index] >> 12) + 16; /* roz base palette is palette 16 */
code = roz_vram[tile_index] & 0x3ff; code = roz_vram[tile_index] & 0x3ff;
SET_TILE_INFO(0, code, attr, 0); SET_TILE_INFO(0, code, attr, 0);
@ -87,12 +87,12 @@ VIDEO_START( polygonet )
{ {
static const gfx_layout charlayout = static const gfx_layout charlayout =
{ {
8, 8, // 8x8 8, 8, /* 8x8 */
4096, // # of tiles 4096, /* # of tiles */
4, // 4bpp 4, /* 4bpp */
{ 0, 1, 2, 3 }, // plane offsets { 0, 1, 2, 3 }, /* plane offsets */
{ 0*4, 1*4, 2*4, 3*4, 4*4, 5*4, 6*4, 7*4 }, // X offsets { 0*4, 1*4, 2*4, 3*4, 4*4, 5*4, 6*4, 7*4 }, /* X offsets */
{ 0*8*4, 1*8*4, 2*8*4, 3*8*4, 4*8*4, 5*8*4, 6*8*4, 7*8*4 }, // Y offsets { 0*8*4, 1*8*4, 2*8*4, 3*8*4, 4*8*4, 5*8*4, 6*8*4, 7*8*4 }, /* Y offsets */
8*8*4 8*8*4
}; };
@ -103,19 +103,22 @@ VIDEO_START( polygonet )
assert(ttl_gfx_index != MAX_GFX_ELEMENTS); assert(ttl_gfx_index != MAX_GFX_ELEMENTS);
// decode the ttl layer's gfx /* decode the ttl layer's gfx */
machine->gfx[ttl_gfx_index] = gfx_element_alloc(machine, &charlayout, memory_region(machine, "gfx1"), machine->config->total_colors / 16, 0); machine->gfx[ttl_gfx_index] = gfx_element_alloc(machine, &charlayout, memory_region(machine, "gfx1"), machine->config->total_colors / 16, 0);
// create the tilemap /* create the tilemap */
ttl_tilemap = tilemap_create(machine, ttl_get_tile_info, plygonet_scan, 8, 8, 64, 32); ttl_tilemap = tilemap_create(machine, ttl_get_tile_info, plygonet_scan, 8, 8, 64, 32);
tilemap_set_transparent_pen(ttl_tilemap, 0); tilemap_set_transparent_pen(ttl_tilemap, 0);
state_save_register_global_array(machine, ttl_vram); /* set up the roz t-map too */
// set up the roz t-map too
roz_tilemap = tilemap_create(machine, roz_get_tile_info, plygonet_scan_cols, 16, 16, 32, 64); roz_tilemap = tilemap_create(machine, roz_get_tile_info, plygonet_scan_cols, 16, 16, 32, 64);
tilemap_set_transparent_pen(roz_tilemap, 0); tilemap_set_transparent_pen(roz_tilemap, 0);
/* save states */
state_save_register_global(machine, ttl_gfx_index);
state_save_register_global_array(machine, ttl_vram);
state_save_register_global_array(machine, roz_vram);
} }
VIDEO_UPDATE( polygonet ) VIDEO_UPDATE( polygonet )