Note: Removing the static qualifier on vi_width is necessary for PIN64 captures to work. I'm not submitting my changes for PIN64 yet, but leaving it as non-static means one less thing I need to manually merge to get PIN64 working in whenever I update my tree.

- Final pass on single-stepping behavior [SGINut]
- Corrected VRCP element lookup [SGINut]
- Corrected unaligned DMA behavior [Ville Linde] (Ville, do you mind that I submit this?)
This commit is contained in:
Ryan Holtz 2008-01-22 02:11:24 +00:00
parent 2c63c6e3d4
commit 0960ad9d7b
3 changed files with 47 additions and 60 deletions

View File

@ -2289,7 +2289,7 @@ static void handle_vector_ops(UINT32 op)
// Calculates reciprocal // Calculates reciprocal
int del = (VS1REG & 7); int del = (VS1REG & 7);
int sel = VEC_EL_2(EL, del); int sel = EL & 7;
INT32 rec; INT32 rec;
rec = (INT16)(R_VREG_S(VS2REG, sel)); rec = (INT16)(R_VREG_S(VS2REG, sel));
@ -2925,15 +2925,9 @@ static void rsp_set_info(UINT32 state, cpuinfo *info)
case CPUINFO_INT_REGISTER + RSP_R30: rsp.r[30] = info->i; break; case CPUINFO_INT_REGISTER + RSP_R30: rsp.r[30] = info->i; break;
case CPUINFO_INT_SP: case CPUINFO_INT_SP:
case CPUINFO_INT_REGISTER + RSP_R31: rsp.r[31] = info->i; break; case CPUINFO_INT_REGISTER + RSP_R31: rsp.r[31] = info->i; break;
case CPUINFO_INT_REGISTER + RSP_SR: case CPUINFO_INT_REGISTER + RSP_SR: rsp.sr = info->i; break;
rsp.sr = info->i; case CPUINFO_INT_REGISTER + RSP_NEXTPC: rsp.nextpc = info->i; break;
if( info->i & RSP_STATUS_SSTEP ) case CPUINFO_INT_REGISTER + RSP_STEPCNT: rsp.step_count = info->i; break;
{
// Heaven help me for putting this check here, but it's accurate to the hardware and works.
rsp.step_count = ( cpu_getactivecpu() == 0 ) ? 0 : 1;
}
break;
case CPUINFO_INT_REGISTER + RSP_NEXTPC: rsp.nextpc = info->i; break;
} }
} }
@ -3005,6 +2999,7 @@ void rsp_get_info(UINT32 state, cpuinfo *info)
case CPUINFO_INT_REGISTER + RSP_R31: info->i = rsp.r[31]; break; case CPUINFO_INT_REGISTER + RSP_R31: info->i = rsp.r[31]; break;
case CPUINFO_INT_REGISTER + RSP_SR: info->i = rsp.sr; break; case CPUINFO_INT_REGISTER + RSP_SR: info->i = rsp.sr; break;
case CPUINFO_INT_REGISTER + RSP_NEXTPC: info->i = rsp.nextpc; break; case CPUINFO_INT_REGISTER + RSP_NEXTPC: info->i = rsp.nextpc; break;
case CPUINFO_INT_REGISTER + RSP_STEPCNT: info->i = rsp.step_count; 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_PTR_GET_CONTEXT: info->getcontext = rsp_get_context; break; case CPUINFO_PTR_GET_CONTEXT: info->getcontext = rsp_get_context; break;
@ -3065,5 +3060,6 @@ void rsp_get_info(UINT32 state, cpuinfo *info)
case CPUINFO_STR_REGISTER + RSP_R31: sprintf(info->s, "R31: %08X", rsp.r[31]); break; case CPUINFO_STR_REGISTER + RSP_R31: sprintf(info->s, "R31: %08X", rsp.r[31]); break;
case CPUINFO_STR_REGISTER + RSP_SR: sprintf(info->s, "SR: %08X", rsp.sr); break; case CPUINFO_STR_REGISTER + RSP_SR: sprintf(info->s, "SR: %08X", rsp.sr); break;
case CPUINFO_STR_REGISTER + RSP_NEXTPC: sprintf(info->s, "NPC: %08X", rsp.nextpc);break; case CPUINFO_STR_REGISTER + RSP_NEXTPC: sprintf(info->s, "NPC: %08X", rsp.nextpc);break;
case CPUINFO_STR_REGISTER + RSP_STEPCNT: sprintf(info->s, "STEP: %d", rsp.step_count); break;
} }
} }

View File

@ -48,6 +48,7 @@ enum
RSP_R31, RSP_R31,
RSP_SR, RSP_SR,
RSP_NEXTPC, RSP_NEXTPC,
RSP_STEPCNT,
}; };
#define RSP_STATUS_HALT 0x0001 #define RSP_STATUS_HALT 0x0001

View File

@ -125,7 +125,7 @@ static UINT32 sp_semaphore;
static void sp_dma(int direction) static void sp_dma(int direction)
{ {
UINT8 *src, *dst; UINT8 *src, *dst;
int i; int i, c;
//int cpu = cpu_getactivecpu(); //int cpu = cpu_getactivecpu();
if (sp_dma_length == 0) if (sp_dma_length == 0)
@ -134,12 +134,11 @@ static void sp_dma(int direction)
} }
sp_dma_length++; sp_dma_length++;
if ((sp_dma_length & 3) != 0) if ((sp_dma_length & 3) != 0)
{ {
//fatalerror("sp_dma (%s): sp_dma_length unaligned %08X\n", cpu ? "RSP" : "R4300i", sp_dma_length); //fatalerror("sp_dma (%s): sp_dma_length unaligned %08X\n", cpu ? "RSP" : "R4300i", sp_dma_length);
sp_dma_length = sp_dma_length & ~3; //sp_dma_length = sp_dma_length & ~3;
//sp_dma_length = (sp_dma_length + 3) & ~3; sp_dma_length = (sp_dma_length + 3) & ~3;
//sp_dma_length &= ~3; //sp_dma_length &= ~3;
} }
@ -153,23 +152,16 @@ static void sp_dma(int direction)
} }
if (sp_dram_addr & 0x3) if (sp_dram_addr & 0x3)
{ {
//sp_dram_addr = (sp_dram_addr + 3) & ~3; sp_dram_addr = sp_dram_addr & ~7;
sp_dram_addr = sp_dram_addr & ~3;
// sp_dram_addr &= ~0x3;
// fatalerror("sp_dma (%s): sp_dram_addr unaligned: %08X\n", cpu ? "RSP" : "R4300i", sp_dram_addr);
// Diddy Kong Racing does unaligned DMA?
//sp_dram_addr &= ~0x3;
//sp_dram_addr = (sp_dram_addr + 3) & ~0x3;
} }
if (sp_dma_count > 0) if (sp_dma_count > 0)
{ {
fatalerror("sp_dma: dma_count = %d\n", sp_dma_count); // fatalerror("sp_dma: dma_count = %d\n", sp_dma_count);
} }
if (sp_dma_skip > 0) if (sp_dma_skip > 0)
{ {
fatalerror("sp_dma: dma_skip = %d\n", sp_dma_skip); // fatalerror("sp_dma: dma_skip = %d\n", sp_dma_skip);
} }
if ((sp_mem_addr & 0xfff) + (sp_dma_length) > 0x1000) if ((sp_mem_addr & 0xfff) + (sp_dma_length) > 0x1000)
@ -179,45 +171,39 @@ static void sp_dma(int direction)
if (direction == 0) // RDRAM -> I/DMEM if (direction == 0) // RDRAM -> I/DMEM
{ {
src = (UINT8*)&rdram[sp_dram_addr / 4]; for (c=0; c <= sp_dma_count; c++)
dst = (sp_mem_addr & 0x1000) ? (UINT8*)&rsp_imem[(sp_mem_addr & 0xfff) / 4] : (UINT8*)&rsp_dmem[(sp_mem_addr & 0xfff) / 4];
//mame_printf_debug("sp_dma: %08X to %08X, length %08X\n", sp_dram_addr, sp_mem_addr, sp_dma_length);
for (i=0; i < sp_dma_length; i++)
{
dst[BYTE4_XOR_BE(i)] = src[BYTE4_XOR_BE(i)];
}
/*dst = (sp_mem_addr & 0x1000) ? (UINT8*)rsp_imem : (UINT8*)rsp_dmem;
for (i=0; i <= sp_dma_length; i++)
{ {
dst[BYTE4_XOR_BE(sp_mem_addr+i) & 0xfff] = src[BYTE4_XOR_BE(i)]; src = (UINT8*)&rdram[sp_dram_addr / 4];
}*/ dst = (sp_mem_addr & 0x1000) ? (UINT8*)&rsp_imem[(sp_mem_addr & 0xfff) / 4] : (UINT8*)&rsp_dmem[(sp_mem_addr & 0xfff) / 4];
sp_mem_addr += sp_dma_length; for (i=0; i < sp_dma_length; i++)
sp_dram_addr += sp_dma_length; {
dst[BYTE4_XOR_BE(i)] = src[BYTE4_XOR_BE(i)];
}
sp_mem_addr += sp_dma_length;
sp_dram_addr += sp_dma_length;
sp_mem_addr += sp_dma_skip;
}
} }
else // I/DMEM -> RDRAM else // I/DMEM -> RDRAM
{ {
src = (sp_mem_addr & 0x1000) ? (UINT8*)&rsp_imem[(sp_mem_addr & 0xfff) / 4] : (UINT8*)&rsp_dmem[(sp_mem_addr & 0xfff) / 4]; for (c=0; c <= sp_dma_count; c++)
dst = (UINT8*)&rdram[sp_dram_addr / 4];
// mame_printf_debug("sp_dma: %08X to %08X, length %08X\n", sp_mem_addr, sp_dram_addr, sp_dma_length);
for (i=0; i < sp_dma_length; i++)
{
dst[BYTE4_XOR_BE(i)] = src[BYTE4_XOR_BE(i)];
}
/*src = (sp_mem_addr & 0x1000) ? (UINT8*)rsp_imem : (UINT8*)rsp_dmem;
for (i=0; i <= sp_dma_length; i++)
{ {
dst[BYTE4_XOR_BE(i)] = src[BYTE4_XOR_BE(sp_mem_addr+i) & 0xfff]; src = (sp_mem_addr & 0x1000) ? (UINT8*)&rsp_imem[(sp_mem_addr & 0xfff) / 4] : (UINT8*)&rsp_dmem[(sp_mem_addr & 0xfff) / 4];
}*/ dst = (UINT8*)&rdram[sp_dram_addr / 4];
sp_mem_addr += sp_dma_length; for (i=0; i < sp_dma_length; i++)
sp_dram_addr += sp_dma_length; {
dst[BYTE4_XOR_BE(i)] = src[BYTE4_XOR_BE(i)];
}
sp_mem_addr += sp_dma_length;
sp_dram_addr += sp_dma_length;
sp_dram_addr += sp_dma_skip;
}
} }
} }
@ -370,6 +356,10 @@ WRITE32_HANDLER( n64_sp_reg_w )
{ {
//printf( "Setting RSP_STATUS_SSTEP\n" ); //printf( "Setting RSP_STATUS_SSTEP\n" );
cpunum_set_info_int(1, CPUINFO_INT_REGISTER + RSP_SR, cpunum_get_info_int(1, CPUINFO_INT_REGISTER + RSP_SR) | RSP_STATUS_SSTEP ); cpunum_set_info_int(1, CPUINFO_INT_REGISTER + RSP_SR, cpunum_get_info_int(1, CPUINFO_INT_REGISTER + RSP_SR) | RSP_STATUS_SSTEP );
if( !( cpunum_get_info_int(1, CPUINFO_INT_REGISTER + RSP_SR) & ( RSP_STATUS_BROKE | RSP_STATUS_HALT ) ) )
{
cpunum_set_info_int(1, CPUINFO_INT_REGISTER + RSP_STEPCNT, 1 );
}
// RSP_STATUS |= RSP_STATUS_SSTEP; // set single step // RSP_STATUS |= RSP_STATUS_SSTEP; // set single step
} }
if (data & 0x00000080) if (data & 0x00000080)
@ -575,7 +565,7 @@ const rsp_config n64_rsp_config =
// Video Interface // Video Interface
static UINT32 vi_width; UINT32 vi_width;
UINT32 vi_origin; UINT32 vi_origin;
UINT32 vi_control; UINT32 vi_control;
static UINT32 vi_burst, vi_vsync, vi_hsync, vi_leap, vi_hstart, vi_vstart; static UINT32 vi_burst, vi_vsync, vi_hsync, vi_leap, vi_hstart, vi_vstart;
@ -708,10 +698,10 @@ WRITE32_HANDLER( n64_vi_reg_w )
/* /*
Uncomment this for convenient homebrew debugging Uncomment this for convenient homebrew debugging
*/
case 0x44/4: // TEMP DEBUG case 0x44/4: // TEMP DEBUG
printf( "E Ping: %08x\n", data ); printf( "E Ping: %08x\n", data );
break; break;
*/
default: default:
logerror("vi_reg_w: %08X, %08X, %08X at %08X\n", data, offset, mem_mask, activecpu_get_pc()); logerror("vi_reg_w: %08X, %08X, %08X at %08X\n", data, offset, mem_mask, activecpu_get_pc());
@ -974,10 +964,10 @@ WRITE32_HANDLER( n64_pi_reg_w )
int i; int i;
UINT32 dma_length = (data + 1); UINT32 dma_length = (data + 1);
/*if (dma_length & 3) if (dma_length & 3)
{ {
dma_length = (dma_length + 3) & ~3; dma_length = (dma_length + 3) & ~3;
}*/ }
//mame_printf_debug("PI DMA: %08X to %08X, length %08X\n", pi_cart_addr, pi_dram_addr, dma_length); //mame_printf_debug("PI DMA: %08X to %08X, length %08X\n", pi_cart_addr, pi_dram_addr, dma_length);