Skip to content

Commit

Permalink
Improve the way we track command delays in CDVDFSV.
Browse files Browse the repository at this point in the history
  • Loading branch information
jpd002 committed Sep 13, 2024
1 parent 2ecf092 commit a96da74
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 7 deletions.
2 changes: 1 addition & 1 deletion Source/iop/IopBios.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1915,6 +1915,7 @@ void CIopBios::CountTicks(uint32 ticks)
CurrentTime() += ticks;
#ifdef _IOP_EMULATE_MODULES
m_cdvdman->CountTicks(ticks);
m_cdvdfsv->CountTicks(ticks, m_sifMan.get());
m_mcserv->CountTicks(ticks, m_sifMan.get());
m_usbd->CountTicks(ticks);
#endif
Expand Down Expand Up @@ -1945,7 +1946,6 @@ void CIopBios::NotifyVBlankEnd()
}
}
#ifdef _IOP_EMULATE_MODULES
m_cdvdfsv->ProcessCommands(m_sifMan.get());
m_fileIo->ProcessCommands(m_sifMan.get());
#endif
}
Expand Down
16 changes: 15 additions & 1 deletion Source/iop/Iop_Cdvdfsv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "Iop_Cdvdfsv.h"
#include "Iop_Cdvdman.h"
#include "Iop_SifManPs2.h"
#include "TimeUtils.h"

using namespace Iop;

Expand All @@ -20,6 +21,8 @@ using namespace Iop;
#define STATE_STREAMPOS ("StreamPos")
#define STATE_STREAMBUFFERSIZE ("StreamBufferSize")

constexpr uint64 COMMAND_DEFAULT_DELAY = TimeUtils::UsecsToCycles(PS2::IOP_CLOCK_OVER_FREQ, 16666);

CCdvdfsv::CCdvdfsv(CSifMan& sif, CCdvdman& cdvdman, uint8* iopRam)
: m_cdvdman(cdvdman)
, m_iopRam(iopRam)
Expand Down Expand Up @@ -58,10 +61,16 @@ std::string CCdvdfsv::GetFunctionName(unsigned int) const
return "unknown";
}

void CCdvdfsv::ProcessCommands(CSifMan* sifMan)
void CCdvdfsv::CountTicks(uint32 ticks, CSifMan* sifMan)
{
if(m_pendingCommand != COMMAND_NONE)
{
m_pendingCommandDelay -= std::min<uint32>(m_pendingCommandDelay, ticks);
if(m_pendingCommandDelay != 0)
{
return;
}

static const uint32 sectorSize = 0x800;

uint8* eeRam = nullptr;
Expand Down Expand Up @@ -400,6 +409,7 @@ void CCdvdfsv::Read(uint32* args, uint32 argsSize, uint32* ret, uint32 retSize,

assert(m_pendingCommand == COMMAND_NONE);
m_pendingCommand = COMMAND_READ;
m_pendingCommandDelay = CCdvdman::COMMAND_READ_BASE_DELAY + (count * CCdvdman::COMMAND_READ_SECTOR_DELAY);
m_pendingReadSector = sector;
m_pendingReadCount = count;
m_pendingReadAddr = dstAddr & 0x1FFFFFFF;
Expand All @@ -422,6 +432,7 @@ void CCdvdfsv::ReadIopMem(uint32* args, uint32 argsSize, uint32* ret, uint32 ret

assert(m_pendingCommand == COMMAND_NONE);
m_pendingCommand = COMMAND_READIOP;
m_pendingCommandDelay = COMMAND_DEFAULT_DELAY;
m_pendingReadSector = sector;
m_pendingReadCount = count;
m_pendingReadAddr = dstAddr & 0x1FFFFFFF;
Expand Down Expand Up @@ -454,6 +465,7 @@ bool CCdvdfsv::StreamCmd(uint32* args, uint32 argsSize, uint32* ret, uint32 retS
case 2:
//Read
m_pendingCommand = COMMAND_STREAM_READ;
m_pendingCommandDelay = COMMAND_DEFAULT_DELAY;
m_pendingReadSector = 0;
m_pendingReadCount = count;
m_pendingReadAddr = dstAddr & (PS2::EE_RAM_SIZE - 1);
Expand Down Expand Up @@ -509,6 +521,7 @@ bool CCdvdfsv::NDiskReady(uint32* args, uint32 argsSize, uint32* ret, uint32 ret
{
//Delay command (required by Downhill Domination)
m_pendingCommand = COMMAND_NDISKREADY;
m_pendingCommandDelay = COMMAND_DEFAULT_DELAY;
ret[0x00] = 2;
return false;
}
Expand Down Expand Up @@ -544,6 +557,7 @@ void CCdvdfsv::ReadChain(uint32* args, uint32 argsSize, uint32* ret, uint32 retS

//DBZ: Budokai Tenkaichi hangs in its loading screen if this command's result is not delayed.
m_pendingCommand = COMMAND_READCHAIN;
m_pendingCommandDelay = COMMAND_DEFAULT_DELAY;
}

void CCdvdfsv::SearchFile(uint32* args, uint32 argsSize, uint32* ret, uint32 retSize, uint8* ram)
Expand Down
3 changes: 2 additions & 1 deletion Source/iop/Iop_Cdvdfsv.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ namespace Iop
std::string GetFunctionName(unsigned int) const override;
void Invoke(CMIPS&, unsigned int) override;

void ProcessCommands(CSifMan*);
void CountTicks(uint32, CSifMan*);
void SetOpticalMedia(COpticalMedia*);

void LoadState(Framework::CZipArchiveReader&) override;
Expand Down Expand Up @@ -71,6 +71,7 @@ namespace Iop
COpticalMedia* m_opticalMedia = nullptr;

COMMAND m_pendingCommand = COMMAND_NONE;
int32 m_pendingCommandDelay = 0;
uint32 m_pendingReadSector = 0;
uint32 m_pendingReadCount = 0;
uint32 m_pendingReadAddr = 0;
Expand Down
8 changes: 4 additions & 4 deletions Source/iop/Iop_Cdvdman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@
#define FUNCTION_CDREADDVDDUALINFO "CdReadDvdDualInfo"
#define FUNCTION_CDLAYERSEARCHFILE "CdLayerSearchFile"

constexpr uint64 COMMAND_READ_BASE_DELAY = TimeUtils::UsecsToCycles(PS2::IOP_CLOCK_OVER_FREQ, 100);
constexpr uint64 COMMAND_READ_SECTOR_DELAY = TimeUtils::UsecsToCycles(PS2::IOP_CLOCK_OVER_FREQ, 500);
constexpr uint64 COMMAND_SEEK_DELAY = TimeUtils::UsecsToCycles(PS2::IOP_CLOCK_OVER_FREQ, 100);

using namespace Iop;

const uint64 CCdvdman::COMMAND_READ_BASE_DELAY = TimeUtils::UsecsToCycles(PS2::IOP_CLOCK_OVER_FREQ, 100);
const uint64 CCdvdman::COMMAND_READ_SECTOR_DELAY = TimeUtils::UsecsToCycles(PS2::IOP_CLOCK_OVER_FREQ, 500);
const uint64 CCdvdman::COMMAND_SEEK_DELAY = TimeUtils::UsecsToCycles(PS2::IOP_CLOCK_OVER_FREQ, 100);

CCdvdman::CCdvdman(CIopBios& bios, uint8* ram)
: m_bios(bios)
, m_ram(ram)
Expand Down
4 changes: 4 additions & 0 deletions Source/iop/Iop_Cdvdman.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ namespace Iop
uint32 CdGetDiskTypeDirect(COpticalMedia*);
uint32 CdLayerSearchFileDirect(COpticalMedia*, FILEINFO*, const char*, uint32);

static const uint64 COMMAND_READ_BASE_DELAY;
static const uint64 COMMAND_READ_SECTOR_DELAY;
static const uint64 COMMAND_SEEK_DELAY;

private:
enum COMMAND : uint32
{
Expand Down

0 comments on commit a96da74

Please sign in to comment.