mirror of
https://github.com/SourMesen/Mesen2.git
synced 2025-04-02 10:21:44 -04:00
-IRQ/SCSI status should happen after seek is done when a play command is sent (fixes audio sync in Brandish intro cutscene) -Fixed seek delay not being applied correctly when swapping from audio playback to data loading and tweaked seek delays to make them a bit slower (fixes Brandish audio glitch during introduction) -Fixed regression that causes the "transfer ready" irq flag to not be reset when a sector was done reading (this broke the intro sequence in "It came from the desert") -Improved behavior when a load operation is cancelled (to match the expected results of both scsitest and verificator tests)
79 lines
No EOL
2.4 KiB
C++
79 lines
No EOL
2.4 KiB
C++
#include "pch.h"
|
|
|
|
//Adaptation of https://github.com/pce-devel/PCECD_seek/blob/master/seektime.c by Dave Shadoff (MIT)
|
|
|
|
class PceCdSeekDelay
|
|
{
|
|
private:
|
|
struct SectorGroup
|
|
{
|
|
uint32_t SectorPerRevolution;
|
|
uint32_t FirstSector;
|
|
uint32_t LastSector;
|
|
double RotationMs;
|
|
};
|
|
|
|
static constexpr uint32_t NUM_SECTOR_GROUPS = 14;
|
|
|
|
static constexpr SectorGroup _sectorList[NUM_SECTOR_GROUPS] = {
|
|
{ 10, 0, 12572, 133.47 },
|
|
{ 11, 12573, 30244, 146.82 },
|
|
{ 12, 30245, 49523, 160.17 },
|
|
{ 13, 49524, 70408, 173.51 },
|
|
{ 14, 70409, 92900, 186.86 },
|
|
{ 15, 92901, 116998, 200.21 },
|
|
{ 16, 116999, 142703, 213.56 },
|
|
{ 17, 142704, 170014, 226.90 },
|
|
{ 18, 170015, 198932, 240.25 },
|
|
{ 19, 198933, 229456, 253.60 },
|
|
{ 20, 229457, 261587, 266.95 },
|
|
{ 21, 261588, 295324, 280.29 },
|
|
{ 22, 295325, 330668, 293.64 },
|
|
{ 23, 330669, 333012, 306.99 }
|
|
};
|
|
|
|
static uint32_t FindGroup(uint32_t lba)
|
|
{
|
|
for(uint32_t i = 0; i < NUM_SECTOR_GROUPS; i++) {
|
|
if(lba >= _sectorList[i].FirstSector && lba <= _sectorList[i].LastSector) {
|
|
return i;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
public:
|
|
static uint32_t GetSeekTimeMs(uint32_t startLba, uint32_t targetLba)
|
|
{
|
|
uint32_t src = FindGroup(startLba);
|
|
uint32_t dst = FindGroup(targetLba);
|
|
|
|
uint32_t lbaGap = std::abs((int)targetLba - (int)startLba);
|
|
double trackGap = 0;
|
|
if(dst == src) {
|
|
trackGap = (lbaGap / _sectorList[dst].SectorPerRevolution);
|
|
} else if(dst > src) {
|
|
trackGap = (_sectorList[src].LastSector - startLba) / _sectorList[src].SectorPerRevolution;
|
|
trackGap += (targetLba - _sectorList[dst].FirstSector) / _sectorList[dst].SectorPerRevolution;
|
|
trackGap += (1606.48 * (dst - src - 1));
|
|
} else {
|
|
trackGap = (startLba - _sectorList[src].FirstSector) / _sectorList[src].SectorPerRevolution;
|
|
trackGap += (_sectorList[dst].LastSector - targetLba) / _sectorList[dst].SectorPerRevolution;
|
|
trackGap += (1606.48 * (src - dst - 1));
|
|
}
|
|
|
|
if(lbaGap < 2) {
|
|
return 9 * 1000 / 60;
|
|
} else if(lbaGap < 5) {
|
|
return (9 * 1000 / 60) + (_sectorList[dst].RotationMs / 2);
|
|
} else if(trackGap <= 80) {
|
|
return (18 * 1000 / 60) + (_sectorList[dst].RotationMs / 2);
|
|
} else if(trackGap <= 160) {
|
|
return (22 * 1000 / 60) + (_sectorList[dst].RotationMs / 2);
|
|
} else if(trackGap <= 644) {
|
|
return (22 * 1000 / 60) + (_sectorList[dst].RotationMs / 2) + ((trackGap - 161) * 16.66 / 80);
|
|
} else {
|
|
return (48 * 1000 / 60) + ((trackGap - 644) * 16.66 / 195);
|
|
}
|
|
}
|
|
}; |