mirror of
https://github.com/holub/mame
synced 2025-05-25 23:35:26 +03:00
Adds save state support to plygonet.c and the DSP56156 CPU core.
This commit is contained in:
parent
831ee03acf
commit
45dfc2315a
@ -992,6 +992,8 @@ endif
|
||||
|
||||
$(CPUOBJ)/dsp56k/dsp56k.o: $(CPUSRC)/dsp56k/dsp56k.c \
|
||||
$(CPUSRC)/dsp56k/dsp56ops.c \
|
||||
$(CPUSRC)/dsp56k/dsp56mem.c \
|
||||
$(CPUSRC)/dsp56k/dsp56pcu.c \
|
||||
$(CPUSRC)/dsp56k/dsp56k.h
|
||||
|
||||
|
||||
|
@ -51,19 +51,19 @@ static UINT16 *dsp56k_program_ram;
|
||||
/***************************************************************************
|
||||
COMPONENT FUNCTIONALITY
|
||||
***************************************************************************/
|
||||
// 1-9 ALU
|
||||
/* 1-9 ALU */
|
||||
// #include "dsp56alu.c"
|
||||
|
||||
// 1-10 Address Generation Unit (AGU)
|
||||
/* 1-10 Address Generation Unit (AGU) */
|
||||
// #include "dsp56agu.c"
|
||||
|
||||
// 1-11 Program Control Unit (PCU)
|
||||
/* 1-11 Program Control Unit (PCU) */
|
||||
#include "dsp56pcu.c"
|
||||
|
||||
// 5-1 Host Interface (HI)
|
||||
/* 5-1 Host Interface (HI) */
|
||||
//#include "dsp56hi.c"
|
||||
|
||||
// 4-8 Memory handlers for on-chip peripheral memory.
|
||||
/* 4-8 Memory handlers for on-chip peripheral memory. */
|
||||
#include "dsp56mem.c"
|
||||
|
||||
|
||||
@ -154,7 +154,7 @@ static void set_irq_line(dsp56k_core* cpustate, int irqline, int state)
|
||||
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?
|
||||
//if (cpustate->reset_state != TRUE)
|
||||
// pcu_service_interrupts();
|
||||
@ -164,27 +164,72 @@ static void set_irq_line(dsp56k_core* cpustate, int irqline, int state)
|
||||
/***************************************************************************
|
||||
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 )
|
||||
{
|
||||
dsp56k_core* cpustate = get_safe_token(device);
|
||||
|
||||
// Call specific module inits
|
||||
pcu_init(cpustate);
|
||||
// agu_init(cpustate);
|
||||
// alu_init(cpustate);
|
||||
/* 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
|
||||
/* HACK - You're not in bootstrap mode upon bootup */
|
||||
cpustate->bootstrap_mode = BOOTSTRAP_OFF;
|
||||
|
||||
// Clear the irq states
|
||||
/* Clear the irq states */
|
||||
cpustate->modA_state = FALSE;
|
||||
cpustate->modB_state = FALSE;
|
||||
cpustate->modC_state = FALSE;
|
||||
cpustate->reset_state = FALSE;
|
||||
|
||||
/* Save the core's state */
|
||||
// state_save_register_device_item(device, 0, modA_state);
|
||||
// ...
|
||||
/* save states - dsp56k_core members */
|
||||
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->irq_callback = irqcallback;
|
||||
@ -197,9 +242,13 @@ static CPU_INIT( dsp56k )
|
||||
memory_set_direct_update_handler(cpustate->program, dsp56k_direct_handler);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
RESET BEHAVIOR
|
||||
***************************************************************************/
|
||||
static void agu_reset(dsp56k_core* cpustate)
|
||||
{
|
||||
// FM.4-3
|
||||
/* FM.4-3 */
|
||||
R0 = 0x0000;
|
||||
R1 = 0x0000;
|
||||
R2 = 0x0000;
|
||||
@ -263,7 +312,6 @@ static CPU_EXIT( dsp56k )
|
||||
/***************************************************************************
|
||||
CORE EXECUTION LOOP
|
||||
***************************************************************************/
|
||||
|
||||
static CPU_EXECUTE( dsp56k )
|
||||
{
|
||||
dsp56k_core* cpustate = get_safe_token(device);
|
||||
@ -272,7 +320,7 @@ static CPU_EXECUTE( dsp56k )
|
||||
if (cpustate->reset_state)
|
||||
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)
|
||||
return cycles;
|
||||
|
||||
@ -304,20 +352,19 @@ extern CPU_DISASSEMBLE( dsp56k );
|
||||
* Internal Memory Maps
|
||||
****************************************************************************/
|
||||
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(0x2f00,0x2fff) AM_ROM // 1-5 PROM reserved memory. Is this the right spot for it?
|
||||
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? */
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START( dsp56156_x_data_map, ADDRESS_SPACE_DATA, 16 )
|
||||
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(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 */
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Generic set_info/get_info
|
||||
**************************************************************************/
|
||||
|
||||
static CPU_SET_INFO( dsp56k )
|
||||
{
|
||||
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_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_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;
|
||||
@ -392,7 +439,7 @@ CPU_GET_INFO( dsp56k )
|
||||
|
||||
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_INPUT_LINES: info->i = 4; 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_MAX_CYCLES: info->i = 8; break; // ?
|
||||
|
||||
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_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_SHIFT_PROGRAM: info->i = -1; break;
|
||||
case CPUINFO_INT_DATABUS_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_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_ST1: info->i = ST1; 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_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_INIT: info->init = CPU_INIT_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:
|
||||
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_FAMILY: strcpy(info->s, "Motorola DSP56156"); 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_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_ST1: sprintf(info->s, "ST1 : %08x", ST1); break;
|
||||
case CPUINFO_STR_REGISTER + DSP56K_ST2: sprintf(info->s, "ST2 : %08x", ST2); break;
|
||||
|
@ -2865,8 +2865,8 @@ static size_t dsp56k_op_do_2(dsp56k_core* cpustate, const UINT16 op, const UINT1
|
||||
/* HACK */
|
||||
if (lValue >= 0xfff0)
|
||||
{
|
||||
lValue = 0x0000;
|
||||
logerror("Dsp56k : DO_2 operation changed %04x to 0000.\n", lValue);
|
||||
lValue = 0x0000;
|
||||
}
|
||||
|
||||
/* TODO: Fix for special cased SP S */
|
||||
|
@ -90,52 +90,63 @@ static UINT8 SE_bit(dsp56k_core* cpustate) { return ((SP & 0x0010) != 0); }
|
||||
/***************************************************************************
|
||||
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();
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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);
|
||||
MB_bit_set(cpustate, cpustate->modB_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))
|
||||
{
|
||||
case 0x00:
|
||||
logerror("Dsp56k in Special Bootstrap Mode 1\n");
|
||||
|
||||
// HACK - We don't need to put the bootstrap mode on here since
|
||||
// we'll simulate it entirely in this function
|
||||
/* HACK - We don't need to put the bootstrap mode on here since */
|
||||
/* we'll simulate it entirely in this function */
|
||||
cpustate->bootstrap_mode = BOOTSTRAP_OFF;
|
||||
|
||||
// HACK - Simply copy over 0x1000 bytes of data located at program memory 0xc000.
|
||||
// This, in actuality, is handled with the internal boot ROM.
|
||||
/* HACK - Simply copy over 0x1000 bytes of data located at program memory 0xc000. */
|
||||
/* This, in actuality, is handled with the internal boot ROM. */
|
||||
for (i = 0; i < 0x800; i++)
|
||||
{
|
||||
UINT32 mem_offset = (0xc000<<1) + (i<<1); /* TODO: TEST */
|
||||
|
||||
// TODO - DO I HAVE TO FLIP THIS WORD?
|
||||
// P:$c000 -> Internal P:$0000 low byte
|
||||
// P:$c001 -> Internal P:$0000 high byte
|
||||
// ...
|
||||
// P:$cffe -> Internal P:$07ff low byte
|
||||
// P:$cfff -> Internal P:$07ff high byte
|
||||
/* TODO - DO I HAVE TO FLIP THIS WORD? */
|
||||
/* P:$c000 -> Internal P:$0000 low byte */
|
||||
/* P:$c001 -> Internal P:$0000 high byte */
|
||||
/* ... */
|
||||
/* P:$cffe -> Internal P:$07ff low 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_high = memory_read_byte_16be(cpustate->program, mem_offset);
|
||||
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;
|
||||
|
||||
// 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);
|
||||
MA_bit_set(cpustate, 0);
|
||||
cpustate->PCU.reset_vector = 0xe000;
|
||||
@ -144,11 +155,11 @@ static void pcu_reset(dsp56k_core* cpustate)
|
||||
case 0x01:
|
||||
logerror("Dsp56k in Special Bootstrap Mode 2\n");
|
||||
|
||||
// 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
|
||||
// they need. Once they've had their fill, they turn bootstrap mode off
|
||||
// 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 - 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 */
|
||||
/* they need. Once they've had their fill, they turn bootstrap mode off */
|
||||
/* 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. */
|
||||
if (memory_read_word_16le(cpustate->program, 0xc000<<1) & 0x8000)
|
||||
{
|
||||
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");
|
||||
}
|
||||
|
||||
// HACK - Set the PC to 0x0000 as per the boot ROM.
|
||||
/* HACK - Set the PC to 0x0000 as per the boot ROM. */
|
||||
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);
|
||||
MA_bit_set(cpustate, 0);
|
||||
cpustate->PCU.reset_vector = 0xe000;
|
||||
@ -177,42 +188,42 @@ static void pcu_reset(dsp56k_core* cpustate)
|
||||
|
||||
case 0x03:
|
||||
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;
|
||||
cpustate->PCU.reset_vector = 0x0000;
|
||||
break;
|
||||
}
|
||||
|
||||
// Set registers properly
|
||||
// 1-17 Clear Interrupt Priority Register (IPR)
|
||||
/* Set registers properly */
|
||||
/* 1-17 Clear Interrupt Priority Register (IPR) */
|
||||
IPR = 0x0000;
|
||||
|
||||
// FM.5-4
|
||||
/* FM.5-4 */
|
||||
I_bits_set(cpustate, 0x03);
|
||||
S_bits_set(cpustate, 0);
|
||||
L_bit_set(cpustate, 0);
|
||||
S_bit_set(cpustate, 0);
|
||||
FV_bit_set(cpustate, 0);
|
||||
|
||||
// FM.7-25
|
||||
/* FM.7-25 */
|
||||
E_bit_set(cpustate, 0);
|
||||
U_bit_set(cpustate, 0);
|
||||
N_bit_set(cpustate, 0);
|
||||
V_bit_set(cpustate, 0);
|
||||
Z_bit_set(cpustate, 0);
|
||||
|
||||
// FM.5-4+
|
||||
/* FM.5-4+ */
|
||||
C_bit_set(cpustate, 0);
|
||||
LF_bit_set(cpustate, 0);
|
||||
SP = 0x0000;
|
||||
|
||||
// FM.5-14 (OMR)
|
||||
/* FM.5-14 (OMR) */
|
||||
SA_bit_set(cpustate, 0);
|
||||
R_bit_set(cpustate, 0);
|
||||
SD_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);
|
||||
}
|
||||
|
||||
@ -227,50 +238,50 @@ typedef struct
|
||||
|
||||
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)
|
||||
{
|
||||
int i;
|
||||
|
||||
// Count list of pending interrupts
|
||||
/* Count list of pending interrupts */
|
||||
int num_servicable = dsp56k_count_pending_interrupts(cpustate);
|
||||
|
||||
if (num_servicable == 0)
|
||||
return;
|
||||
|
||||
// Sort list according to priority
|
||||
/* Sort list according to priority */
|
||||
dsp56k_sort_pending_interrupts(cpustate, num_servicable);
|
||||
|
||||
// Service each interrupt in order
|
||||
// TODO: This just *can't* be right :)
|
||||
/* Service each interrupt in order */
|
||||
/* TODO: This just *can't* be right :) */
|
||||
for (i = 0; i < num_servicable; 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);
|
||||
|
||||
// 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))
|
||||
{
|
||||
// TODO: Implement long interrupts & fast interrupts correctly!
|
||||
// Right now they are handled in the JSR & BSR ops. SupahLame.
|
||||
/* TODO: Implement long interrupts & fast interrupts correctly! */
|
||||
/* Right now they are handled in the JSR & BSR ops. SupahLame. */
|
||||
cpustate->ppc = PC;
|
||||
|
||||
// Are you anything but the Host Command interrupt?
|
||||
/* Are you anything but the Host Command interrupt? */
|
||||
if (interrupt_index != 22)
|
||||
{
|
||||
// Execute a normal interrupt
|
||||
/* Execute a normal interrupt */
|
||||
PC = dsp56k_interrupt_sources[interrupt_index].irq_vector;
|
||||
}
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -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 */
|
||||
static void dsp56k_irq_table_init(void)
|
||||
{
|
||||
// 1-14 + 1-18
|
||||
// TODO: Cull host command stuff appropriately
|
||||
/* 1-14 + 1-18 */
|
||||
/* TODO: Cull host command stuff appropriately */
|
||||
/* array index . vector . token */
|
||||
dsp56k_set_irq_source(0, 0x0000, "Hardware RESET");
|
||||
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;
|
||||
|
||||
// We're going to be sorting the priorities
|
||||
/* We're going to be sorting the priorities */
|
||||
int priority_list[32];
|
||||
for (i = 0; i < num; 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(j = 0; j < num-1; j++)
|
||||
@ -386,12 +397,12 @@ static void dsp56k_sort_pending_interrupts(dsp56k_core* cpustate, int num)
|
||||
{
|
||||
int holder;
|
||||
|
||||
// Swap priorities
|
||||
/* Swap priorities */
|
||||
holder = priority_list[j+1];
|
||||
priority_list[j+1] = priority_list[j];
|
||||
priority_list[j] = holder;
|
||||
|
||||
// Swap irq indices.
|
||||
/* Swap irq indices. */
|
||||
holder = cpustate->PCU.pending_interrupts[j+1];
|
||||
cpustate->PCU.pending_interrupts[j+1] = cpustate->PCU.pending_interrupts[j];
|
||||
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 */
|
||||
static INT8 dsp56k_get_irq_priority(dsp56k_core* cpustate, int index)
|
||||
{
|
||||
// 1-12
|
||||
/* 1-12 */
|
||||
switch (index)
|
||||
{
|
||||
// Non-maskable
|
||||
case 0: return 3; // Hardware RESET
|
||||
case 1: return 3; // Illegal Instruction
|
||||
case 2: return 3; // Stack Error
|
||||
case 3: return 3; // Reserved
|
||||
case 4: return 3; // SWI
|
||||
/* Non-maskable */
|
||||
case 0: return 3; /* Hardware RESET */
|
||||
case 1: return 3; /* Illegal Instruction */
|
||||
case 2: return 3; /* Stack Error */
|
||||
case 3: return 3; /* Reserved */
|
||||
case 4: return 3; /* SWI */
|
||||
|
||||
// Poll the IPR for these guys.
|
||||
case 5: return irqa_ipl(cpustate); // IRQA
|
||||
case 6: return irqb_ipl(cpustate); // IRQB
|
||||
case 7: return -1; // Reserved
|
||||
case 8: return ssi0_ipl(cpustate); // SSI0 Receive Data with Exception
|
||||
case 9: return ssi0_ipl(cpustate); // SSI0 Receive Data
|
||||
case 10: return ssi0_ipl(cpustate); // SSI0 Transmit Data with Exception
|
||||
case 11: return ssi0_ipl(cpustate); // SSI0 Transmit Data
|
||||
case 12: return ssi1_ipl(cpustate); // SSI1 Receive Data with Exception
|
||||
case 13: return ssi1_ipl(cpustate); // SSI1 Receive Data
|
||||
case 14: return ssi1_ipl(cpustate); // SSI1 Transmit Data with Exception
|
||||
case 15: return ssi1_ipl(cpustate); // SSI1 Transmit Data
|
||||
case 16: return tm_ipl(cpustate); // Timer Overflow
|
||||
case 17: return tm_ipl(cpustate); // Timer Compare
|
||||
case 18: return host_ipl(cpustate); // Host DMA Receive Data
|
||||
case 19: return host_ipl(cpustate); // Host DMA Transmit Data
|
||||
case 20: return host_ipl(cpustate); // Host Receive Data
|
||||
case 21: return host_ipl(cpustate); // Host Transmit Data
|
||||
case 22: return host_ipl(cpustate); // Host Command 0 (Default)
|
||||
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 25: return host_ipl(cpustate); // Host Command 2
|
||||
case 26: return host_ipl(cpustate); // Host Command 3
|
||||
case 27: return host_ipl(cpustate); // Host Command 4
|
||||
case 28: return host_ipl(cpustate); // Host Command 5
|
||||
case 29: return host_ipl(cpustate); // Host Command 6
|
||||
case 30: return host_ipl(cpustate); // Host Command 7
|
||||
case 31: return host_ipl(cpustate); // Host Command 8
|
||||
/* Poll the IPR for these guys. */
|
||||
case 5: return irqa_ipl(cpustate); /* IRQA */
|
||||
case 6: return irqb_ipl(cpustate); /* IRQB */
|
||||
case 7: return -1; /* Reserved */
|
||||
case 8: return ssi0_ipl(cpustate); /* SSI0 Receive Data with Exception */
|
||||
case 9: return ssi0_ipl(cpustate); /* SSI0 Receive Data */
|
||||
case 10: return ssi0_ipl(cpustate); /* SSI0 Transmit Data with Exception */
|
||||
case 11: return ssi0_ipl(cpustate); /* SSI0 Transmit Data */
|
||||
case 12: return ssi1_ipl(cpustate); /* SSI1 Receive Data with Exception */
|
||||
case 13: return ssi1_ipl(cpustate); /* SSI1 Receive Data */
|
||||
case 14: return ssi1_ipl(cpustate); /* SSI1 Transmit Data with Exception */
|
||||
case 15: return ssi1_ipl(cpustate); /* SSI1 Transmit Data */
|
||||
case 16: return tm_ipl(cpustate); /* Timer Overflow */
|
||||
case 17: return tm_ipl(cpustate); /* Timer Compare */
|
||||
case 18: return host_ipl(cpustate); /* Host DMA Receive Data */
|
||||
case 19: return host_ipl(cpustate); /* Host DMA Transmit Data */
|
||||
case 20: return host_ipl(cpustate); /* Host Receive Data */
|
||||
case 21: return host_ipl(cpustate); /* Host Transmit Data */
|
||||
case 22: return host_ipl(cpustate); /* Host Command 0 (Default) */
|
||||
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 25: return host_ipl(cpustate); /* Host Command 2 */
|
||||
case 26: return host_ipl(cpustate); /* Host Command 3 */
|
||||
case 27: return host_ipl(cpustate); /* Host Command 4 */
|
||||
case 28: return host_ipl(cpustate); /* Host Command 5 */
|
||||
case 29: return host_ipl(cpustate); /* Host Command 6 */
|
||||
case 30: return host_ipl(cpustate); /* Host Command 7 */
|
||||
case 31: return host_ipl(cpustate); /* Host Command 8 */
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
@ -763,6 +763,15 @@ static DRIVER_INIT(polygonet)
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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 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, polynetw, 0, plygonet, polynetw, polygonet, ROT90, "Konami", "Poly-Net Warriors (ver JAA)", 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_SUPPORTS_SAVE )
|
||||
|
||||
|
@ -24,7 +24,7 @@ static TILE_GET_INFO( ttl_get_tile_info )
|
||||
|
||||
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);
|
||||
}
|
||||
@ -33,7 +33,7 @@ static TILE_GET_INFO( roz_get_tile_info )
|
||||
{
|
||||
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;
|
||||
|
||||
SET_TILE_INFO(0, code, attr, 0);
|
||||
@ -87,12 +87,12 @@ VIDEO_START( polygonet )
|
||||
{
|
||||
static const gfx_layout charlayout =
|
||||
{
|
||||
8, 8, // 8x8
|
||||
4096, // # of tiles
|
||||
4, // 4bpp
|
||||
{ 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*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, /* 8x8 */
|
||||
4096, /* # of tiles */
|
||||
4, /* 4bpp */
|
||||
{ 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*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
|
||||
};
|
||||
|
||||
@ -103,19 +103,22 @@ VIDEO_START( polygonet )
|
||||
|
||||
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);
|
||||
|
||||
// create the tilemap
|
||||
/* create the tilemap */
|
||||
ttl_tilemap = tilemap_create(machine, ttl_get_tile_info, plygonet_scan, 8, 8, 64, 32);
|
||||
|
||||
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);
|
||||
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 )
|
||||
|
Loading…
Reference in New Issue
Block a user