viper.c: Fixed EPIC register access

This commit is contained in:
Ville Linde 2012-09-23 13:04:36 +00:00
parent 252b05c173
commit 70954f7acb

View File

@ -292,6 +292,8 @@ An additional control PCB is used for Mocap Golf for the golf club sensor. It co
#define VIPER_DEBUG_LOG #define VIPER_DEBUG_LOG
#define VIPER_DEBUG_EPIC_INTS 1 #define VIPER_DEBUG_EPIC_INTS 1
#define VIPER_DEBUG_EPIC_TIMERS 0 #define VIPER_DEBUG_EPIC_TIMERS 0
#define VIPER_DEBUG_EPIC_REGS 0
#define VIPER_DEBUG_EPIC_I2C 0
#define SDRAM_CLOCK 166666666 // Main SDRAMs run at 166MHz #define SDRAM_CLOCK 166666666 // Main SDRAMs run at 166MHz
@ -491,6 +493,7 @@ struct MPC8240_EPIC
// TODO: move to viper_state // TODO: move to viper_state
static MPC8240_EPIC epic; static MPC8240_EPIC epic;
#if VIPER_DEBUG_EPIC_REGS
static const char* epic_get_register_name(UINT32 reg) static const char* epic_get_register_name(UINT32 reg)
{ {
switch (reg >> 16) switch (reg >> 16)
@ -604,6 +607,7 @@ static const char* epic_get_register_name(UINT32 reg)
return NULL; return NULL;
} }
#endif
static TIMER_CALLBACK(epic_global_timer_callback) static TIMER_CALLBACK(epic_global_timer_callback)
{ {
@ -682,6 +686,7 @@ READ32_MEMBER(viper_state::epic_r)
int reg; int reg;
reg = offset * 4; reg = offset * 4;
#if VIPER_DEBUG_EPIC_REGS
if (reg != 0x600a0) // IACK is spammy if (reg != 0x600a0) // IACK is spammy
{ {
const char *regname = epic_get_register_name(reg); const char *regname = epic_get_register_name(reg);
@ -694,6 +699,9 @@ READ32_MEMBER(viper_state::epic_r)
printf("EPIC: read %08X at %08X\n", reg, space.device().safe_pc()); printf("EPIC: read %08X at %08X\n", reg, space.device().safe_pc());
} }
} }
#endif
UINT32 ret = 0;
switch (reg >> 16) switch (reg >> 16)
{ {
@ -704,19 +712,23 @@ READ32_MEMBER(viper_state::epic_r)
{ {
case 0x3000: // Offset 0x3000 - I2CADR case 0x3000: // Offset 0x3000 - I2CADR
{ {
return epic.i2c_adr; ret = epic.i2c_adr;
break;
} }
case 0x3004: // Offset 0x3004 - I2CFDR case 0x3004: // Offset 0x3004 - I2CFDR
{ {
return epic.i2c_freq_div | (epic.i2c_freq_sample_rate << 8); ret = epic.i2c_freq_div | (epic.i2c_freq_sample_rate << 8);
break;
} }
case 0x3008: // Offset 0x3008 - I2CCR case 0x3008: // Offset 0x3008 - I2CCR
{ {
return epic.i2c_cr; ret = epic.i2c_cr;
break;
} }
case 0x300c: // Offset 0x300c - I2CSR case 0x300c: // Offset 0x300c - I2CSR
{ {
return epic.i2c_sr; ret = epic.i2c_sr;
break;
} }
case 0x3010: // Offset 0x3010 - I2CDR case 0x3010: // Offset 0x3010 - I2CDR
{ {
@ -778,12 +790,12 @@ READ32_MEMBER(viper_state::epic_r)
case 0x11e0: // Offset 0x411e0 - Global Timer 3 vector/priority register case 0x11e0: // Offset 0x411e0 - Global Timer 3 vector/priority register
{ {
int timer_num = ((reg & 0xffff) - 0x1120) >> 6; int timer_num = ((reg & 0xffff) - 0x1120) >> 6;
UINT32 value = 0;
value |= epic.irq[MPC8240_GTIMER0_IRQ + timer_num].mask ? 0x80000000 : 0; ret |= epic.irq[MPC8240_GTIMER0_IRQ + timer_num].mask ? 0x80000000 : 0;
value |= epic.irq[MPC8240_GTIMER0_IRQ + timer_num].priority << 16; ret |= epic.irq[MPC8240_GTIMER0_IRQ + timer_num].priority << 16;
value |= epic.irq[MPC8240_GTIMER0_IRQ + timer_num].vector; ret |= epic.irq[MPC8240_GTIMER0_IRQ + timer_num].vector;
value |= epic.irq[MPC8240_GTIMER0_IRQ + timer_num].active ? 0x40000000 : 0; ret |= epic.irq[MPC8240_GTIMER0_IRQ + timer_num].active ? 0x40000000 : 0;
return value; break;
} }
} }
break; break;
@ -812,23 +824,20 @@ READ32_MEMBER(viper_state::epic_r)
case 0x03e0: // Offset 0x503e0 - IRQ15 vector/priority register case 0x03e0: // Offset 0x503e0 - IRQ15 vector/priority register
{ {
int irq = ((reg & 0xffff) - 0x200) >> 5; int irq = ((reg & 0xffff) - 0x200) >> 5;
int value = 0;
value |= epic.irq[MPC8240_IRQ0 + irq].mask ? 0x80000000 : 0; ret |= epic.irq[MPC8240_IRQ0 + irq].mask ? 0x80000000 : 0;
value |= epic.irq[MPC8240_IRQ0 + irq].priority << 16; ret |= epic.irq[MPC8240_IRQ0 + irq].priority << 16;
value |= epic.irq[MPC8240_IRQ0 + irq].vector; ret |= epic.irq[MPC8240_IRQ0 + irq].vector;
value |= epic.irq[MPC8240_IRQ0 + irq].active ? 0x40000000 : 0; ret |= epic.irq[MPC8240_IRQ0 + irq].active ? 0x40000000 : 0;
break;
return value;
} }
case 0x1020: // Offset 0x51020 - I2C IRQ vector/priority register case 0x1020: // Offset 0x51020 - I2C IRQ vector/priority register
{ {
UINT32 value = 0; ret |= epic.irq[MPC8240_I2C_IRQ].mask ? 0x80000000 : 0;
value |= epic.irq[MPC8240_I2C_IRQ].mask ? 0x80000000 : 0; ret |= epic.irq[MPC8240_I2C_IRQ].priority << 16;
value |= epic.irq[MPC8240_I2C_IRQ].priority << 16; ret |= epic.irq[MPC8240_I2C_IRQ].vector;
value |= epic.irq[MPC8240_I2C_IRQ].vector; ret |= epic.irq[MPC8240_I2C_IRQ].active ? 0x40000000 : 0;
value |= epic.irq[MPC8240_I2C_IRQ].active ? 0x40000000 : 0; return ret;
return value;
} }
} }
break; break;
@ -845,13 +854,14 @@ READ32_MEMBER(viper_state::epic_r)
if (epic.active_irq >= 0) if (epic.active_irq >= 0)
{ {
return epic.iack; ret = epic.iack;
} }
else else
{ {
// spurious vector register is returned if no pending interrupts // spurious vector register is returned if no pending interrupts
return epic.svr; ret = epic.svr;
} }
break;
} }
} }
@ -859,7 +869,7 @@ READ32_MEMBER(viper_state::epic_r)
} }
} }
return 0; return FLIPENDIAN_INT32(ret);
} }
WRITE32_MEMBER(viper_state::epic_w) WRITE32_MEMBER(viper_state::epic_w)
@ -867,6 +877,9 @@ WRITE32_MEMBER(viper_state::epic_w)
int reg; int reg;
reg = offset * 4; reg = offset * 4;
data = FLIPENDIAN_INT32(data);
#if VIPER_DEBUG_EPIC_REGS
if (reg != 0x600b0) // interrupt clearing is spammy if (reg != 0x600b0) // interrupt clearing is spammy
{ {
const char *regname = epic_get_register_name(reg); const char *regname = epic_get_register_name(reg);
@ -879,6 +892,7 @@ WRITE32_MEMBER(viper_state::epic_w)
printf("EPIC: write %08X, %08X at %08X\n", data, reg, space.device().safe_pc()); printf("EPIC: write %08X, %08X at %08X\n", data, reg, space.device().safe_pc());
} }
} }
#endif
switch (reg >> 16) switch (reg >> 16)
{ {
@ -921,10 +935,12 @@ WRITE32_MEMBER(viper_state::epic_w)
{ {
if (epic.i2c_state == I2C_STATE_ADDRESS_CYCLE) // waiting for address cycle if (epic.i2c_state == I2C_STATE_ADDRESS_CYCLE) // waiting for address cycle
{ {
int addr = (data >> 1) & 0x7f;
//int rw = data & 1; //int rw = data & 1;
#if VIPER_DEBUG_EPIC_I2C
int addr = (data >> 1) & 0x7f;
printf("I2C address cycle, addr = %02X\n", addr); printf("I2C address cycle, addr = %02X\n", addr);
#endif
epic.i2c_state = I2C_STATE_DATA_TRANSFER; epic.i2c_state = I2C_STATE_DATA_TRANSFER;
// set transfer complete in status register // set transfer complete in status register
@ -933,7 +949,9 @@ WRITE32_MEMBER(viper_state::epic_w)
// generate interrupt if interrupt are enabled // generate interrupt if interrupt are enabled
if (epic.i2c_cr & 0x40) if (epic.i2c_cr & 0x40)
{ {
#if VIPER_DEBUG_EPIC_I2C
printf("I2C interrupt\n"); printf("I2C interrupt\n");
#endif
mpc8240_interrupt(machine(), MPC8240_I2C_IRQ); mpc8240_interrupt(machine(), MPC8240_I2C_IRQ);
// set interrupt flag in status register // set interrupt flag in status register
@ -942,7 +960,9 @@ WRITE32_MEMBER(viper_state::epic_w)
} }
else if (epic.i2c_state == I2C_STATE_DATA_TRANSFER) // waiting for data transfer else if (epic.i2c_state == I2C_STATE_DATA_TRANSFER) // waiting for data transfer
{ {
#if VIPER_DEBUG_EPIC_I2C
printf("I2C data transfer, data = %02X\n", data); printf("I2C data transfer, data = %02X\n", data);
#endif
epic.i2c_state = I2C_STATE_ADDRESS_CYCLE; epic.i2c_state = I2C_STATE_ADDRESS_CYCLE;
// set transfer complete in status register // set transfer complete in status register
@ -951,7 +971,9 @@ WRITE32_MEMBER(viper_state::epic_w)
// generate interrupt if interrupts are enabled // generate interrupt if interrupts are enabled
if (epic.i2c_cr & 0x40) if (epic.i2c_cr & 0x40)
{ {
#if VIPER_DEBUG_EPIC_I2C
printf("I2C interrupt\n"); printf("I2C interrupt\n");
#endif
mpc8240_interrupt(machine(), MPC8240_I2C_IRQ); mpc8240_interrupt(machine(), MPC8240_I2C_IRQ);
// set interrupt flag in status register // set interrupt flag in status register