* changed SPU receive model to a push model; updated drivers accordingly
 * added macros for setting the SPU transmit handler and sending bytes
 * cleaned up ppc.h
This commit is contained in:
Aaron Giles 2008-06-12 02:48:11 +00:00
parent 3b3f47b864
commit 20ee6bc325
6 changed files with 102 additions and 86 deletions

View File

@ -1,8 +1,13 @@
/***************************************************************************
mips3.h
Interface file for the portable MIPS III/IV emulator.
Written by Aaron Giles
Interface file for the universal machine language-based
MIPS III/IV emulator.
Copyright Aaron Giles
Released for general non-commercial use under the MAME license
Visit http://mamedev.org for licensing and usage restrictions.
***************************************************************************/

View File

@ -1,8 +1,13 @@
/***************************************************************************
ppc.h
Interface file for the portable MIPS III/IV emulator.
Written by Aaron Giles
Interface file for the universal machine language-based
PowerPC emulator.
Copyright Aaron Giles
Released for general non-commercial use under the MAME license
Visit http://mamedev.org for licensing and usage restrictions.
***************************************************************************/
@ -13,9 +18,24 @@
/***************************************************************************
REGISTER ENUMERATION
CONSTANTS
***************************************************************************/
/* general constants */
#define PPC_MAX_FASTRAM 4
#define PPC_MAX_HOTSPOTS 16
/* interrupt types */
#define PPC_IRQ 0 /* external IRQ */
#define PPC_IRQ_LINE_0 0 /* (4XX) external IRQ0 */
#define PPC_IRQ_LINE_1 1 /* (4XX) external IRQ1 */
#define PPC_IRQ_LINE_2 2 /* (4XX) external IRQ2 */
#define PPC_IRQ_LINE_3 3 /* (4XX) external IRQ3 */
#define PPC_IRQ_LINE_4 4 /* (4XX) external IRQ4 */
/* register enumeration */
enum
{
PPC_PC = 1,
@ -73,10 +93,7 @@ enum
};
#define PPC_MAX_FASTRAM 4
#define PPC_MAX_HOTSPOTS 16
/* interface extensions */
enum
{
CPUINFO_INT_PPC_DRC_OPTIONS = CPUINFO_INT_CPU_SPECIFIC,
@ -95,31 +112,30 @@ enum
CPUINFO_PTR_PPC_FASTRAM_BASE = CPUINFO_PTR_CPU_SPECIFIC,
CPUINFO_PTR_SPU_RX_HANDLER,
CPUINFO_PTR_SPU_TX_HANDLER,
CPUINFO_PTR_CONTEXT /* temporary */
};
/* compiler-specific options */
#define PPCDRC_STRICT_VERIFY 0x0001 /* verify all instructions */
#define PPCDRC_FLUSH_PC 0x0002 /* flush the PC value before each memory access */
#define PPCDRC_ACCURATE_SINGLES 0x0004 /* do excessive rounding to make single-precision results "accurate" */
/***************************************************************************
INTERRUPT CONSTANTS
***************************************************************************/
#define PPC_IRQ 0 /* external IRQ */
#define PPC_IRQ_LINE_0 0 /* (4XX) external IRQ0 */
#define PPC_IRQ_LINE_1 1 /* (4XX) external IRQ1 */
#define PPC_IRQ_LINE_2 2 /* (4XX) external IRQ2 */
#define PPC_IRQ_LINE_3 3 /* (4XX) external IRQ3 */
#define PPC_IRQ_LINE_4 4 /* (4XX) external IRQ4 */
/* common sets of options */
#define PPCDRC_COMPATIBLE_OPTIONS (PPCDRC_STRICT_VERIFY | PPCDRC_FLUSH_PC | PPCDRC_ACCURATE_SINGLES)
#define PPCDRC_FASTEST_OPTIONS (0)
/***************************************************************************
STRUCTURES
STRUCTURES AND TYPEDEFS
***************************************************************************/
typedef void (*ppc4xx_spu_tx_handler)(UINT8 data);
typedef struct _powerpc_config powerpc_config;
struct _powerpc_config
{
@ -171,14 +187,20 @@ void mpc8240_get_info(UINT32 state, cpuinfo *info);
/***************************************************************************
COMPILER-SPECIFIC OPTIONS
INLINE FUNCTIONS
***************************************************************************/
#define PPCDRC_STRICT_VERIFY 0x0001 /* verify all instructions */
#define PPCDRC_FLUSH_PC 0x0002 /* flush the PC value before each memory access */
#define PPCDRC_ACCURATE_SINGLES 0x0004 /* do excessive rounding to make single-precision results "accurate" */
INLINE void ppc4xx_spu_set_tx_handler(int cpunum, ppc4xx_spu_tx_handler handler)
{
cpunum_set_info_fct(cpunum, CPUINFO_PTR_SPU_TX_HANDLER, (genf *)handler);
}
INLINE void ppc4xx_spu_receive_byte(int cpunum, UINT8 byteval)
{
cpunum_set_info_int(cpunum, CPUINFO_INT_PPC_RX_DATA, byteval);
}
#define PPCDRC_COMPATIBLE_OPTIONS (PPCDRC_STRICT_VERIFY | PPCDRC_FLUSH_PC | PPCDRC_ACCURATE_SINGLES)
#define PPCDRC_FASTEST_OPTIONS (0)
#endif /* __PPC_H__ */

View File

@ -16,7 +16,7 @@
#define PRINTF_TLB_FILL (1)
#define PRINTF_SPU (0)
#define PRINTF_DECREMENTER (1)
#define PRINTF_DECREMENTER (0)
@ -909,18 +909,22 @@ void ppccom_execute_mfdcr(powerpc_state *ppc)
case DCR4XX_DMADA0:
case DCR4XX_DMASA0:
case DCR4XX_DMACC0:
case DCR4XX_DMACR0:
case DCR4XX_DMACT1:
case DCR4XX_DMADA1:
case DCR4XX_DMASA1:
case DCR4XX_DMACC1:
case DCR4XX_DMACR1:
case DCR4XX_DMACT2:
case DCR4XX_DMADA2:
case DCR4XX_DMASA2:
case DCR4XX_DMACC2:
case DCR4XX_DMACR2:
case DCR4XX_DMACT3:
case DCR4XX_DMADA3:
case DCR4XX_DMASA3:
case DCR4XX_DMACC3:
case DCR4XX_DMACR3:
case DCR4XX_EXIER:
case DCR4XX_EXISR:
case DCR4XX_IOCR:
@ -1634,7 +1638,16 @@ static void ppc4xx_spu_update_irq_states(powerpc_state *ppc)
static void ppc4xx_spu_rx_data(powerpc_state *ppc, UINT8 data)
{
fatalerror("ppc4xx_spu_rx_data unimplemented\n");
UINT32 new_rxin;
/* fail if we are going to overflow */
new_rxin = (ppc->spu.rxin + 1) % ARRAY_LENGTH(ppc->spu.rxbuffer);
if (new_rxin == ppc->spu.rxout)
fatalerror("ppc4xx_spu_rx_data: buffer overrun!");
/* store the data and accept the new in index */
ppc->spu.rxbuffer[ppc->spu.rxin] = data;
ppc->spu.rxin = new_rxin;
}
@ -1656,7 +1669,7 @@ static void ppc4xx_spu_timer_reset(powerpc_state *ppc)
attotime charperiod = attotime_mul(clockperiod, divisor * 16 * bpc);
timer_adjust_periodic(ppc->spu.timer, charperiod, 0, charperiod);
if (PRINTF_SPU)
mame_printf_debug("ppc4xx_spu_timer_reset: baud rate = %.0f\n", ATTOSECONDS_TO_HZ(charperiod.attoseconds) * bpc);
printf("ppc4xx_spu_timer_reset: baud rate = %.0f\n", ATTOSECONDS_TO_HZ(charperiod.attoseconds) * bpc);
}
/* otherwise, disable the timer */
@ -1673,7 +1686,6 @@ static void ppc4xx_spu_timer_reset(powerpc_state *ppc)
static TIMER_CALLBACK( ppc4xx_spu_callback )
{
powerpc_state *ppc = ptr;
UINT8 rxbyte;
/* transmit enabled? */
if (ppc->spu.regs[SPU4XX_TX_COMMAND] & 0x80)
@ -1703,9 +1715,14 @@ static TIMER_CALLBACK( ppc4xx_spu_callback )
/* receive enabled? */
if (ppc->spu.regs[SPU4XX_RX_COMMAND] & 0x80)
if (ppc->spu.rx_handler != NULL && (*ppc->spu.rx_handler)(&rxbyte))
if (ppc->spu.rxout != ppc->spu.rxin)
{
int operation = (ppc->spu.regs[SPU4XX_RX_COMMAND] >> 5) & 3;
UINT8 rxbyte;
/* consume the byte and advance the out pointer */
rxbyte = ppc->spu.rxbuffer[ppc->spu.rxout];
ppc->spu.rxout = (ppc->spu.rxout + 1) % ARRAY_LENGTH(ppc->spu.rxbuffer);
/* if we're not full, copy data to the buffer and update the line status */
if (!(ppc->spu.regs[SPU4XX_LINE_STATUS] & 0x80))
@ -1754,7 +1771,7 @@ static READ8_HANDLER( ppc4xx_spu_r )
break;
}
if (PRINTF_SPU)
mame_printf_debug("spu_r(%d) = %02X\n", offset, result);
printf("spu_r(%d) = %02X\n", offset, result);
return result;
}
@ -1769,7 +1786,7 @@ static WRITE8_HANDLER( ppc4xx_spu_w )
UINT8 oldstate, newstate;
if (PRINTF_SPU)
mame_printf_debug("spu_w(%d) = %02X\n", offset, data);
printf("spu_w(%d) = %02X\n", offset, data);
switch (offset)
{
/* clear error bits */
@ -1853,7 +1870,6 @@ void ppc4xx_set_info(powerpc_state *ppc, UINT32 state, cpuinfo *info)
case CPUINFO_INT_PPC_RX_DATA: ppc4xx_spu_rx_data(ppc, info->i); break;
/* --- the following bits of info are returned as pointers to data or functions --- */
case CPUINFO_PTR_SPU_RX_HANDLER: ppc->spu.rx_handler = (ppc4xx_spu_rx_handler)info->f; break;
case CPUINFO_PTR_SPU_TX_HANDLER: ppc->spu.tx_handler = (ppc4xx_spu_tx_handler)info->f; break;
/* --- everything else is handled generically --- */

View File

@ -491,10 +491,6 @@ enum
STRUCTURES & TYPEDEFS
***************************************************************************/
typedef int (*ppc4xx_spu_rx_handler)(UINT8 *data);
typedef void (*ppc4xx_spu_tx_handler)(UINT8 data);
/* PowerPC 4XX-specific serial port state */
typedef struct _ppc4xx_spu_state ppc4xx_spu_state;
struct _ppc4xx_spu_state
@ -503,7 +499,8 @@ struct _ppc4xx_spu_state
UINT8 txbuf;
UINT8 rxbuf;
emu_timer * timer;
ppc4xx_spu_rx_handler rx_handler;
UINT8 rxbuffer[256];
UINT32 rxin, rxout;
ppc4xx_spu_tx_handler tx_handler;
};

View File

@ -2256,7 +2256,7 @@ static void security_w(UINT8 data)
{
int r = ibutton_w(data);
if (r >= 0)
cpunum_set_info_int(0, CPUINFO_INT_PPC_RX_DATA, r & 0xff);
ppc4xx_spu_receive_byte(0, r);
}
/*****************************************************************************/
@ -2291,7 +2291,7 @@ static void init_firebeat(running_machine *machine)
cur_cab_data = cab_data;
cpunum_set_info_fct(0, CPUINFO_PTR_SPU_TX_HANDLER, (genf *)security_w);
ppc4xx_spu_set_tx_handler(0, security_w);
set_ibutton(rom);

View File

@ -1076,22 +1076,9 @@ MACHINE_DRIVER_END
static void jamma_jvs_cmd_exec(void);
static UINT8 jvs_rdata[1024];
static UINT8 jvs_sdata[1024];
static int jvs_rdata_ptr = 0;
static int jvs_sdata_ptr = 0;
static int jvs_rdata_count = 0;
static int jamma_jvs_r(UINT8 *data)
{
if (jvs_rdata_ptr < jvs_rdata_count)
{
*data = jvs_rdata[jvs_rdata_ptr++];
return TRUE;
}
return FALSE;
}
static void jamma_jvs_w(UINT8 data)
{
@ -1104,31 +1091,33 @@ static void jamma_jvs_w(UINT8 data)
jamma_jvs_cmd_exec();
}
static int jvs_encode_data(UINT8 *in, UINT8 *out, int length)
static int jvs_encode_data(UINT8 *in, int length)
{
int outptr = 0;
int inptr = 0;
int sum = 0;
while (inptr < length)
{
UINT8 b = in[inptr++];
if (b == 0xe0)
{
out[outptr++] = 0xd0;
out[outptr++] = 0xdf;
sum += 0xd0 + 0xdf;
ppc4xx_spu_receive_byte(0, 0xd0);
ppc4xx_spu_receive_byte(0, 0xdf);
}
else if (b == 0xd0)
{
out[outptr++] = 0xd0;
out[outptr++] = 0xcf;
sum += 0xd0 + 0xcf;
ppc4xx_spu_receive_byte(0, 0xd0);
ppc4xx_spu_receive_byte(0, 0xcf);
}
else
{
out[outptr++] = b;
sum += b;
ppc4xx_spu_receive_byte(0, b);
}
};
return outptr;
}
return sum;
}
static int jvs_decode_data(UINT8 *in, UINT8 *out, int length)
@ -1157,7 +1146,7 @@ static void jamma_jvs_cmd_exec(void)
{
UINT8 sync, node, byte_num;
UINT8 data[1024], rdata[1024];
int i, length;
int length;
int rdata_ptr;
int sum;
@ -1213,24 +1202,13 @@ static void jamma_jvs_cmd_exec(void)
}
// write jvs return data
jvs_rdata[0] = 0xe0; // sync
jvs_rdata[1] = 0x00; // node
jvs_rdata[2] = rdata_ptr+1; // num of bytes
sum = 0x00 + (rdata_ptr+1);
ppc4xx_spu_receive_byte(0, 0xe0); // sync
ppc4xx_spu_receive_byte(0, 0x00); // node
ppc4xx_spu_receive_byte(0, rdata_ptr+1); // num of bytes
sum += jvs_encode_data(rdata, rdata_ptr);
ppc4xx_spu_receive_byte(0, sum - 1); // checksum
length = jvs_encode_data(rdata, &jvs_rdata[3], rdata_ptr);
// calculate sum
sum = 0;
for (i=0; i < length+2; i++)
{
sum += jvs_rdata[1+i];
}
// write sum
jvs_rdata[3+length] = (UINT8)(sum-1);
jvs_rdata_count = length + 4;
jvs_rdata_ptr = 0;
jvs_sdata_ptr = 0;
}
@ -1258,8 +1236,7 @@ static void init_hornet(running_machine *machine)
timekeeper_init(0, TIMEKEEPER_M48T58, backup_ram);
cpunum_set_info_fct(0, CPUINFO_PTR_SPU_TX_HANDLER, (genf *)jamma_jvs_w);
cpunum_set_info_fct(0, CPUINFO_PTR_SPU_RX_HANDLER, (genf *)jamma_jvs_r);
ppc4xx_spu_set_tx_handler(0, jamma_jvs_w);
}
static void init_hornet_2board(running_machine *machine)
@ -1276,8 +1253,7 @@ static void init_hornet_2board(running_machine *machine)
timekeeper_init(0, TIMEKEEPER_M48T58, backup_ram);
cpunum_set_info_fct(0, CPUINFO_PTR_SPU_TX_HANDLER, (genf *)jamma_jvs_w);
cpunum_set_info_fct(0, CPUINFO_PTR_SPU_RX_HANDLER, (genf *)jamma_jvs_r);
ppc4xx_spu_set_tx_handler(0, jamma_jvs_w);
}
static DRIVER_INIT(gradius4)