Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ add_library(parallel-rsp STATIC
arch/simd/rsp/vcmp.h
arch/simd/rsp/vdivh.h
arch/simd/rsp/vmac.h
arch/simd/rsp/vmov.h
arch/simd/rsp/vmrg.h
arch/simd/rsp/vmudh.h
arch/simd/rsp/vmul.h
Expand Down
6 changes: 3 additions & 3 deletions CREDITS.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
Written by Themaister.

The code is heavily reliant on MarathonMan's CEN64 RSP implementation, as well as CXD4's RSP implementation.
The code is heavily reliant on MarathonMan's CEN64 RSP implementation, as well as Ares and CXD4's RSP implementations.

MIPS core: Rewritten from scratch
CP0: Near copy-pasta from CEN64
CP0: Near copy-pasta from CEN64, with some fixes from Ares brought in
CP2: Near copy-pasta from CEN64
LS pipe: Near copy-pasta from CXD4
LS pipe: Ported from Ares
Mupen64plus glue code: Reused most of CXD4.
Lightning jitter interface: Written from scratch

Expand Down
1 change: 0 additions & 1 deletion arch/simd/rsp/rsp_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include "vcr.h"
#include "vdivh.h"
#include "vmac.h"
#include "vmov.h"
#include "vmrg.h"
#include "vmul.h"
#include "vmulh.h"
Expand Down
18 changes: 0 additions & 18 deletions arch/simd/rsp/vmov.h

This file was deleted.

4 changes: 3 additions & 1 deletion parallel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ extern "C"

EXPORT unsigned int CALL parallelRSPDoRspCycles(unsigned int cycles)
{
if (*RSP::rsp.SP_STATUS_REG & (SP_STATUS_HALT | SP_STATUS_BROKE))
if (*RSP::rsp.SP_STATUS_REG & SP_STATUS_HALT)
return 0;

// We don't know if Mupen from the outside invalidated our IMEM.
Expand Down Expand Up @@ -83,6 +83,8 @@ extern "C"
return cycles;
else if (*RSP::cpu.get_state().cp0.irq & 1)
RSP::rsp.CheckInterrupts();
else if (*RSP::rsp.SP_STATUS_REG & SP_STATUS_HALT)
return cycles;
else if (*RSP::rsp.SP_SEMAPHORE_REG != 0) // Semaphore lock fixes.
{
}
Expand Down
116 changes: 49 additions & 67 deletions rsp/cp0.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,10 @@ extern "C"
if (rt)
rsp->sr[rt] = res;

// CFG_MEND_SEMAPHORE_LOCK == 0 by default,
// so don't bother implementing semaphores.
// It makes Mario Golf run terribly for some reason.

#ifdef PARALLEL_INTEGRATION
// WAIT_FOR_CPU_HOST. From CXD4.
if (rd == CP0_REGISTER_SP_STATUS)
{
// Might be waiting for the CPU to set a signal bit on the STATUS register. Increment timeout
RSP::MFC0_count[rt] += 1;
if (RSP::MFC0_count[rt] >= RSP::SP_STATUS_TIMEOUT)
{
Expand All @@ -44,81 +40,65 @@ extern "C"
}
#endif

if (rd == CP0_REGISTER_SP_SEMAPHORE)
{
if (*rsp->cp0.cr[CP0_REGISTER_SP_SEMAPHORE])
{
#ifdef PARALLEL_INTEGRATION
RSP::MFC0_count[rt] += 8; // Almost certainly waiting on the CPU. Timeout faster.
if (RSP::MFC0_count[rt] >= RSP::SP_STATUS_TIMEOUT)
{
*RSP::rsp.SP_STATUS_REG |= SP_STATUS_HALT;
return MODE_CHECK_FLAGS;
}
#endif
}
else
*rsp->cp0.cr[CP0_REGISTER_SP_SEMAPHORE] = 1;
}

//if (rd == 4) // SP_STATUS_REG
// fprintf(stderr, "READING STATUS REG!\n");

return MODE_CONTINUE;
}

#define RSP_HANDLE_STATUS_WRITE(flag) \
switch (rt & (SP_SET_##flag | SP_CLR_##flag)) \
{ \
case SP_SET_##flag: status |= SP_STATUS_##flag; break; \
case SP_CLR_##flag: status &= ~SP_STATUS_##flag; break; \
default: break; \
}

static inline int rsp_status_write(RSP::CPUState *rsp, uint32_t rt)
{
//fprintf(stderr, "Writing 0x%x to status reg!\n", rt);

uint32_t status = *rsp->cp0.cr[CP0_REGISTER_SP_STATUS];

if (rt & SP_CLR_HALT)
status &= ~SP_STATUS_HALT;
else if (rt & SP_SET_HALT)
status |= SP_STATUS_HALT;
RSP_HANDLE_STATUS_WRITE(HALT)
RSP_HANDLE_STATUS_WRITE(SSTEP)
RSP_HANDLE_STATUS_WRITE(INTR_BREAK)
RSP_HANDLE_STATUS_WRITE(SIG0)
RSP_HANDLE_STATUS_WRITE(SIG1)
RSP_HANDLE_STATUS_WRITE(SIG2)
RSP_HANDLE_STATUS_WRITE(SIG3)
RSP_HANDLE_STATUS_WRITE(SIG4)
RSP_HANDLE_STATUS_WRITE(SIG5)
RSP_HANDLE_STATUS_WRITE(SIG6)
RSP_HANDLE_STATUS_WRITE(SIG7)

switch (rt & (SP_SET_INTR | SP_CLR_INTR))
{
case SP_SET_INTR: *rsp->cp0.irq |= 1; break;
case SP_CLR_INTR: *rsp->cp0.irq &= ~1; break;
default: break;
}

if (rt & SP_CLR_BROKE)
status &= ~SP_STATUS_BROKE;

if (rt & SP_CLR_INTR)
*rsp->cp0.irq &= ~1;
else if (rt & SP_SET_INTR)
*rsp->cp0.irq |= 1;

if (rt & SP_CLR_SSTEP)
status &= ~SP_STATUS_SSTEP;
else if (rt & SP_SET_SSTEP)
status |= SP_STATUS_SSTEP;

if (rt & SP_CLR_INTR_BREAK)
status &= ~SP_STATUS_INTR_BREAK;
else if (rt & SP_SET_INTR_BREAK)
status |= SP_STATUS_INTR_BREAK;

if (rt & SP_CLR_SIG0)
status &= ~SP_STATUS_SIG0;
else if (rt & SP_SET_SIG0)
status |= SP_STATUS_SIG0;

if (rt & SP_CLR_SIG1)
status &= ~SP_STATUS_SIG1;
else if (rt & SP_SET_SIG1)
status |= SP_STATUS_SIG1;

if (rt & SP_CLR_SIG2)
status &= ~SP_STATUS_SIG2;
else if (rt & SP_SET_SIG2)
status |= SP_STATUS_SIG2;

if (rt & SP_CLR_SIG3)
status &= ~SP_STATUS_SIG3;
else if (rt & SP_SET_SIG3)
status |= SP_STATUS_SIG3;

if (rt & SP_CLR_SIG4)
status &= ~SP_STATUS_SIG4;
else if (rt & SP_SET_SIG4)
status |= SP_STATUS_SIG4;

if (rt & SP_CLR_SIG5)
status &= ~SP_STATUS_SIG5;
else if (rt & SP_SET_SIG5)
status |= SP_STATUS_SIG5;

if (rt & SP_CLR_SIG6)
status &= ~SP_STATUS_SIG6;
else if (rt & SP_SET_SIG6)
status |= SP_STATUS_SIG6;

if (rt & SP_CLR_SIG7)
status &= ~SP_STATUS_SIG7;
else if (rt & SP_SET_SIG7)
status |= SP_STATUS_SIG7;

*rsp->cp0.cr[CP0_REGISTER_SP_STATUS] = status;
return ((*rsp->cp0.irq & 1) || (status & SP_STATUS_HALT)) ? MODE_CHECK_FLAGS : MODE_CONTINUE;
}
Expand Down Expand Up @@ -178,6 +158,7 @@ extern "C"

*rsp->cp0.cr[CP0_REGISTER_DMA_DRAM] = source;
*rsp->cp0.cr[CP0_REGISTER_DMA_CACHE] = dest;
*rsp->cp0.cr[CP0_REGISTER_DMA_READ_LENGTH] = 0xff8;

#ifdef INTENSE_DEBUG
log_rsp_mem_parallel();
Expand Down Expand Up @@ -231,6 +212,7 @@ extern "C"

*rsp->cp0.cr[CP0_REGISTER_DMA_CACHE] = source;
*rsp->cp0.cr[CP0_REGISTER_DMA_DRAM] = dest;
*rsp->cp0.cr[CP0_REGISTER_DMA_WRITE_LENGTH] = 0xff8;
#ifdef INTENSE_DEBUG
log_rsp_mem_parallel();
#endif
Expand Down Expand Up @@ -269,9 +251,9 @@ extern "C"
case CP0_REGISTER_SP_STATUS:
return rsp_status_write(rsp, val);

case CP0_REGISTER_SP_RESERVED:
// CXD4 forces this to 0.
*rsp->cp0.cr[CP0_REGISTER_SP_RESERVED] = 0;
case CP0_REGISTER_SP_SEMAPHORE:
// Any write to the semaphore register, regardless of value, sets it to 0 for the next read
*rsp->cp0.cr[CP0_REGISTER_SP_SEMAPHORE] = 0;
break;

case CP0_REGISTER_CMD_START:
Expand Down
16 changes: 7 additions & 9 deletions rsp/cp2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,21 @@ extern "C"

void RSP_MTC2(RSP::CPUState *rsp, unsigned rt, unsigned rd, unsigned element)
{
uint16_t *e = rsp->cp2.regs[rd].e;

#ifdef INTENSE_DEBUG
fprintf(stderr, "MTC2, rt = %u, [rt] = 0x%x, rd = %u, e = %u\n", rt, rsp->sr[rt], rd, element);
#endif

unsigned lo = element >> 1;
rt = rsp->sr[rt];

uint16_t *e = rsp->cp2.regs[rd].e;
const uint16_t v = rsp->sr[rt];
if (element & 1)
{
unsigned hi = (element + 1) >> 1;
e[lo] = (e[lo] & 0xff00) | ((rt >> 8) & 0xff);
e[hi] = (e[lo] & 0x00ff) | ((rt & 0xff) << 8);
const auto i = element >> 1;
e[i] = (e[i] & 0xff00) | (v >> 8);
if (element != 0xf)
e[i+1] = (e[i+1] & 0xff) | (v << 8);
}
else
e[lo] = rt;
e[element >> 1] = v;
}

void RSP_MFC2(RSP::CPUState *rsp, unsigned rt, unsigned rd, unsigned element)
Expand Down
Loading