mirror of
https://github.com/holub/mame
synced 2025-05-29 17:13:05 +03:00
Improved Dsp56k CPU interrupt handling. Polygonet Commanders now advances past its first dsp handshake.
This commit is contained in:
parent
77e548383a
commit
d20e6b6151
@ -294,7 +294,7 @@ static void RREQ_bit_set(UINT8 value);
|
||||
static void CVR_set(UINT8 value);
|
||||
|
||||
//static UINT8 HC_bit();
|
||||
//static UINT8 HV_bits();
|
||||
static UINT8 HV_bits();
|
||||
|
||||
static void HC_bit_set(UINT8 value);
|
||||
static void HV_bits_set(UINT8 value);
|
||||
|
@ -344,8 +344,8 @@ static void set_irq_line(int irqline, int state)
|
||||
|
||||
// If the reset line isn't asserted, service interrupts
|
||||
// TODO: Is it right to immediately service interrupts?
|
||||
if (core.reset_state != TRUE)
|
||||
pcu_service_interrupts();
|
||||
//if (core.reset_state != TRUE)
|
||||
// pcu_service_interrupts();
|
||||
}
|
||||
|
||||
|
||||
@ -451,7 +451,10 @@ static int dsp56k_execute(int cycles)
|
||||
core.interrupt_cycles = 0;
|
||||
|
||||
while(dsp56k_icount > 0)
|
||||
{
|
||||
execute_one();
|
||||
pcu_service_interrupts(); /* TODO: There is definitely something un-right about this */
|
||||
}
|
||||
|
||||
dsp56k_icount -= core.interrupt_cycles;
|
||||
core.interrupt_cycles = 0;
|
||||
|
@ -409,7 +409,6 @@ static void HCP_bit_set(UINT16 value)
|
||||
HSR &= ~(0x0004);
|
||||
HSR |= (value << 2);
|
||||
|
||||
// TODO: Define Host Command through the IRQ structure
|
||||
if (value && HCIE_bit())
|
||||
dsp56k_add_pending_interrupt("Host Command");
|
||||
}
|
||||
@ -509,6 +508,8 @@ static void RREQ_bit_set(UINT8 value)
|
||||
/**************************************/
|
||||
/* Command Vector Register (CVR) Bits */
|
||||
/**************************************/
|
||||
static UINT8 HV_bits() { return (CVR & 0x1f); }
|
||||
|
||||
static void CVR_set(UINT8 value)
|
||||
{
|
||||
/* A single, unified place to run all callbacks for each of the bits */
|
||||
@ -522,9 +523,6 @@ static void HC_bit_set(UINT8 value)
|
||||
CVR &= ~(0x80);
|
||||
CVR |= (value << 7);
|
||||
|
||||
// TODO: 5-9 Do I push a host-command interrupt here? Doesn't seem like it, but maybe i'll have to poll for it somewhere else?
|
||||
// TODO: 5-9 The exception routine clears this bit after it executes.
|
||||
|
||||
HCP_bit_set(value); // 5-9 & 5-11
|
||||
}
|
||||
static void HV_bits_set(UINT8 value)
|
||||
|
@ -172,6 +172,13 @@ static void pcu_reset(void)
|
||||
/***************************************************************************
|
||||
INTERRUPT HANDLING
|
||||
***************************************************************************/
|
||||
typedef struct
|
||||
{
|
||||
UINT16 irq_vector;
|
||||
char irq_source[128];
|
||||
} dsp56k_irq_data;
|
||||
|
||||
static dsp56k_irq_data dsp56k_interrupt_sources[32];
|
||||
|
||||
// TODO: Figure out how to switch on level versus edge-triggered.
|
||||
static void pcu_service_interrupts(void)
|
||||
@ -181,27 +188,43 @@ static void pcu_service_interrupts(void)
|
||||
// Count list of pending interrupts
|
||||
int num_servicable = dsp56k_count_pending_interrupts();
|
||||
|
||||
if (num_servicable == 0) return;
|
||||
if (num_servicable == 0)
|
||||
return;
|
||||
|
||||
// Sort list
|
||||
// Sort list according to priority
|
||||
dsp56k_sort_pending_interrupts(num_servicable);
|
||||
|
||||
// Service each interrupt in order
|
||||
// TODO: This just *can't* be right :)
|
||||
for (i = 0; i < num_servicable; i++)
|
||||
{
|
||||
const int interrupt_index = core.PCU.pending_interrupts[i];
|
||||
|
||||
// Get the priority of the interrupt - a return value of -1 means disabled!
|
||||
INT8 priority = dsp56k_get_irq_priority(core.PCU.pending_interrupts[i]);
|
||||
INT8 priority = dsp56k_get_irq_priority(interrupt_index);
|
||||
|
||||
// 1-12 Make sure you're not masked out against the Interrupt Mask Bits (disabled is handled for free here)
|
||||
if (priority >= I_bits())
|
||||
{
|
||||
// If you're acceptable to go, execute the interrupt
|
||||
|
||||
// TODO: 5-7 Remember the host command input has a floating vector. Do it up right.
|
||||
// TODO: 5-9 5-11 Gotta' Clear HI (HCP & HC) when taking this exception too!
|
||||
// Are you anything but the Host Command interrupt?
|
||||
if (interrupt_index != 22)
|
||||
{
|
||||
// Execute a normal interrupt
|
||||
PC = dsp56k_interrupt_sources[interrupt_index].irq_vector;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The host command input has a floating vector.
|
||||
const UINT16 irq_vector = HV_bits() << 1;
|
||||
PC = irq_vector;
|
||||
|
||||
// TODO: 5-9 5-11 Gotta' Clear HC (HCP gets it too) when taking this exception!
|
||||
HC_bit_set(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dsp56k_clear_pending_interrupts();
|
||||
}
|
||||
|
||||
//
|
||||
@ -218,18 +241,11 @@ static void dsp56k_add_pending_interrupt(const char* name)
|
||||
if (core.PCU.pending_interrupts[i] == -1)
|
||||
{
|
||||
core.PCU.pending_interrupts[i] = irq_index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT16 irq_vector;
|
||||
char irq_source[128];
|
||||
} dsp56k_irq_data;
|
||||
|
||||
static dsp56k_irq_data dsp56k_interrupt_sources[32];
|
||||
|
||||
static void dsp56k_set_irq_source(UINT8 irq_num, UINT16 iv, const char* source)
|
||||
{
|
||||
dsp56k_interrupt_sources[irq_num].irq_vector = iv;
|
||||
@ -263,7 +279,7 @@ static void dsp56k_irq_table_init(void)
|
||||
dsp56k_set_irq_source(19, 0x0026, "Host DMA Transmit Data");
|
||||
dsp56k_set_irq_source(20, 0x0028, "Host Receive Data");
|
||||
dsp56k_set_irq_source(21, 0x002a, "Host Transmit Data");
|
||||
dsp56k_set_irq_source(22, 0x002c, "Host Command 0 (Default)");
|
||||
dsp56k_set_irq_source(22, 0x002c, "Host Command"); /* Default vector for the host command */
|
||||
dsp56k_set_irq_source(23, 0x002e, "Codec Receive/Transmit");
|
||||
dsp56k_set_irq_source(24, 0x0030, "Host Command 1");
|
||||
dsp56k_set_irq_source(25, 0x0032, "Host Command 2");
|
||||
@ -383,7 +399,7 @@ static int dsp56k_get_irq_index_by_tag(const char* tag)
|
||||
int i;
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
if (!strcmp(tag, dsp56k_interrupt_sources[i].irq_source))
|
||||
if (strcmp(tag, dsp56k_interrupt_sources[i].irq_source) == 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user