Files

161 lines
4.3 KiB
C++
Raw Permalink Normal View History

// SPDX-FileCopyrightText: 2002-2026 PCSX2 Dev Team
2024-07-30 13:42:36 +02:00
// SPDX-License-Identifier: GPL-3.0+
#include "Dma.h"
2020-09-24 23:39:21 +02:00
#include "IopDma.h"
2021-05-13 09:37:10 +02:00
#include "IopHw.h"
2024-04-24 01:17:52 +10:00
#include "SPU2/Debug.h"
#include "SPU2/defs.h"
#include "SPU2/spu2.h"
// Core 0 Input is "SPDIF mode" - Source audio is AC3 compressed.
// Core 1 Input is "CDDA mode" - Source audio data is 32 bits.
// PS2 note: Very! few PS2 games use this mode. Some PSX games used it, however no
// *known* PS2 game does since it was likely only available if the game was recorded to CD
// media (ie, not available in DVD mode, which almost all PS2 games use). Plus PS2 games
// generally prefer to use ADPCM streaming audio since they need as much storage space as
// possible for FMVs and high-def textures.
//
StereoOut32 V_Core::ReadInput_HiFi()
{
2022-12-30 15:35:16 +10:00
if (SPU2::IsRunningPSXMode() && SPU2::MsgToConsole())
SPU2::ConLog("ReadInput_HiFi!!!!!\n");
2023-05-11 21:00:51 +02:00
const u16 ReadIndex = (OutPos * 2) & 0x1FF;
2020-09-25 14:42:06 +02:00
StereoOut32 retval(
(s32&)(*GetMemPtr(0x2000 + (Index << 10) + ReadIndex)),
(s32&)(*GetMemPtr(0x2200 + (Index << 10) + ReadIndex)));
2020-09-25 14:42:06 +02:00
if (Index == 1)
{
2023-10-20 16:20:29 +02:00
retval.Left >>= 16;
retval.Right >>= 16;
2020-09-25 14:42:06 +02:00
}
2021-05-27 00:10:33 +01:00
// Simulate MADR increase, GTA VC tracks the MADR address for calculating a certain point in the buffer
if (InputDataTransferred)
{
u32 amount = std::min(InputDataTransferred, (u32)0x180);
InputDataTransferred -= amount;
MADR += amount;
// Because some games watch the MADR to see when it reaches the end we need to end the DMA here
// Tom & Jerry War of the Whiskers is one such game, the music will skip
if (!InputDataTransferred && !InputDataLeft)
{
if (Index == 0)
spu2DMA4Irq();
else
spu2DMA7Irq();
}
}
if (ReadIndex == 0x100 || ReadIndex == 0x0 || ReadIndex == 0x80 || ReadIndex == 0x180)
2020-09-25 14:42:06 +02:00
{
if (ReadIndex == 0x100)
InputPosWrite = 0;
else if (ReadIndex == 0)
InputPosWrite = 0x100;
if (InputDataLeft >= 0x100)
2020-09-25 14:42:06 +02:00
{
AutoDMAReadBuffer(0);
AdmaInProgress = 1;
if (InputDataLeft < 0x100)
2020-09-25 14:42:06 +02:00
{
if (IsDevBuild)
{
2022-12-30 15:35:16 +10:00
SPU2::FileLog("[%10d] AutoDMA%c block end.\n", Cycles, GetDmaIndexChar());
2020-09-25 14:42:06 +02:00
if (InputDataLeft > 0)
{
2022-12-30 15:35:16 +10:00
if (SPU2::MsgAutoDMA())
SPU2::ConLog("WARNING: adma buffer didn't finish with a whole block!!\n");
2020-09-25 14:42:06 +02:00
}
}
2020-09-25 14:42:06 +02:00
InputDataLeft = 0;
}
}
else if ((AutoDMACtrl & (Index + 1)))
AutoDMACtrl |= ~3;
2020-09-25 14:42:06 +02:00
}
return retval;
}
StereoOut32 V_Core::ReadInput()
{
2020-09-25 14:42:06 +02:00
StereoOut32 retval;
2022-04-15 23:13:04 +01:00
u16 ReadIndex = OutPos;
for (int i = 0; i < 2; i++)
if (Cores[i].IRQEnable && (0x2000 + (Index << 10) + ReadIndex) == (Cores[i].IRQA & 0xfffffdff))
SetIrqCall(i);
// PlayMode & 2 is Bypass Mode, so it doesn't go through the SPU
if ((Index == 1) || !(Index == 0 && (PlayMode & 2) != 0))
{
2020-09-25 14:42:06 +02:00
retval = StereoOut32(
(s32)(*GetMemPtr(0x2000 + (Index << 10) + ReadIndex)),
(s32)(*GetMemPtr(0x2200 + (Index << 10) + ReadIndex)));
2020-09-25 14:42:06 +02:00
}
#ifdef PCSX2_DEVBUILD
DebugCores[Index].admaWaveformL[OutPos % 0x100] = retval.Left;
DebugCores[Index].admaWaveformR[OutPos % 0x100] = retval.Right;
#endif
// Simulate MADR increase, GTA VC tracks the MADR address for calculating a certain point in the buffer
if (InputDataTransferred)
2020-09-25 14:42:06 +02:00
{
u32 amount = std::min(InputDataTransferred, (u32)0x180);
2021-01-30 04:55:28 +00:00
InputDataTransferred -= amount;
2021-01-30 04:55:28 +00:00
MADR += amount;
// Because some games watch the MADR to see when it reaches the end we need to end the DMA here
// Tom & Jerry War of the Whiskers is one such game, the music will skip
if (!InputDataTransferred && !InputDataLeft)
{
if (Index == 0)
2021-02-19 22:09:48 -05:00
spu2DMA4Irq();
2021-01-30 04:55:28 +00:00
else
2021-02-19 22:09:48 -05:00
spu2DMA7Irq();
2021-01-30 04:55:28 +00:00
}
}
if (PlayMode == 2 && Index == 0) //Bitstream bypass refills twice as quickly (GTA VC)
ReadIndex = (ReadIndex * 2) & 0x1FF;
if (ReadIndex == 0x100 || ReadIndex == 0x0 || ReadIndex == 0x80 || ReadIndex == 0x180)
{
if (ReadIndex == 0x100)
2021-01-24 17:56:14 +00:00
InputPosWrite = 0;
else if (ReadIndex == 0)
2021-01-24 17:56:14 +00:00
InputPosWrite = 0x100;
2021-01-23 16:53:18 +00:00
if (InputDataLeft >= 0x100)
2020-09-25 14:42:06 +02:00
{
AutoDMAReadBuffer(0);
AdmaInProgress = 1;
2021-01-23 16:53:18 +00:00
if (InputDataLeft < 0x100)
2020-09-25 14:42:06 +02:00
{
if (IsDevBuild)
{
2022-12-30 15:35:16 +10:00
SPU2::FileLog("[%10d] AutoDMA%c block end.\n", Cycles, GetDmaIndexChar());
2020-09-25 14:42:06 +02:00
if (InputDataLeft > 0)
{
2022-12-30 15:35:16 +10:00
if (SPU2::MsgAutoDMA())
SPU2::ConLog("WARNING: adma buffer didn't finish with a whole block!!\n");
2020-09-25 14:42:06 +02:00
}
}
2020-09-25 14:42:06 +02:00
InputDataLeft = 0;
}
}
else if ((AutoDMACtrl & (Index + 1)))
AutoDMACtrl |= ~3;
2020-09-25 14:42:06 +02:00
}
return retval;
}