cdrom: Update status flags and implementations for PSX CD-Rom.

Added SEEKERROR and IDERROR status. Set StatP to account for SEEKS, READS and shell open.
Added speed to cdrom struct instead of cdvd. Adjustments to cdlPlay to be in line with No$ description.
Added MODE_INIT. Removed old needless hack. Added ToDo in cdlPlay
This commit is contained in:
kenshen112 2022-03-07 11:12:01 -07:00 committed by refractionpcsx2
parent 565ff86ab4
commit 02dfc5d20d
2 changed files with 30 additions and 26 deletions

View File

@ -41,7 +41,7 @@ enum cdrom_registers
CdlDemute = 12,
CdlSetfilter = 13,
CdlSetmode = 14,
CdlGetmode = 15,
CdlGetparam = 15,
CdlGetlocL = 16,
CdlGetlocP = 17,
Cdl18 = 18,
@ -54,7 +54,6 @@ enum cdrom_registers
CdlReadS = 27,
CdlReset = 28,
CdlReadToc = 30,
AUTOPAUSE = 249,
READ_ACK = 250,
READ = 251,
@ -68,7 +67,7 @@ const char* CmdName[0x100] = {
"CdlSync", "CdlNop", "CdlSetloc", "CdlPlay",
"CdlForward", "CdlBackward", "CdlReadN", "CdlStandby",
"CdlStop", "CdlPause", "CdlInit", "CdlMute",
"CdlDemute", "CdlSetfilter", "CdlSetmode", "CdlGetmode",
"CdlDemute", "CdlSetfilter", "CdlSetmode", "CdlGetparam",
"CdlGetlocL", "CdlGetlocP", "Cdl18", "CdlGetTN",
"CdlGetTD", "CdlSeekL", "CdlSeekP", NULL,
NULL, "CdlTest", "CdlID", "CdlReadS",
@ -93,6 +92,7 @@ u8 Test23[] = {0x43, 0x58, 0x44, 0x32, 0x39, 0x34, 0x30, 0x51};
#define DiskError 5
/* Modes flags */
#define MODE_INIT (0 << 0) // Init sets mode 00h or not all bits cleared
#define MODE_SPEED (1 << 7) // 0x80
#define MODE_STRSND (1 << 6) // 0x40 ADPCM on/off
#define MODE_SIZE_2340 (1 << 5) // 0x20
@ -108,8 +108,8 @@ u8 Test23[] = {0x43, 0x58, 0x44, 0x32, 0x39, 0x34, 0x30, 0x51};
#define STATUS_SEEK (1 << 6) // 0x40
#define STATUS_READ (1 << 5) // 0x20
#define STATUS_SHELLOPEN (1 << 4) // 0x10
#define STATUS_UNKNOWN3 (1 << 3) // 0x08
#define STATUS_UNKNOWN2 (1 << 2) // 0x04
#define STATUS_IDERROR (1 << 3) // 0x08
#define STATUS_SEEKERROR (1 << 2) // 0x04
#define STATUS_ROTATING (1 << 1) // 0x02
#define STATUS_ERROR (1 << 0) // 0x01
@ -134,6 +134,8 @@ static void AddIrqQueue(u8 irq, u32 ecycle);
static __fi void StartReading(u32 type)
{
cdr.Reading = type;
// Read's retry. If there's a status error clear and try, try again
cdr.StatP &~ STATUS_ERROR;
cdr.FirstSector = 1;
cdr.Readed = 0xff;
//DevCon.Warning("ReadN/ReadS delay: %d", sectorSeekReadDelay);
@ -217,6 +219,7 @@ void cdrInterrupt()
case CdlNop:
SetResultSize(1);
cdr.StatP &= ~STATUS_SHELLOPEN;
cdr.Result[0] = cdr.StatP;
cdr.Stat = Acknowledge;
break;
@ -256,7 +259,14 @@ void cdrInterrupt()
case CdlStandby:
cdr.CmdProcess = 0;
SetResultSize(1);
cdr.StatP |= STATUS_ROTATING;
if (cdr.StatP & STATUS_ROTATING)
{
cdr.StatP |= ERROR_INVALIDARG;
}
else
{
cdr.StatP |= STATUS_ROTATING;
}
cdr.Result[0] = cdr.StatP;
cdr.Stat = Complete;
break;
@ -288,6 +298,7 @@ void cdrInterrupt()
case CdlInit:
SetResultSize(1);
cdr.StatP = STATUS_ROTATING;
cdr.Mode |= MODE_INIT;
cdr.Result[0] = cdr.StatP;
cdr.Stat = Acknowledge;
AddIrqQueue(CdlInit + 0x20, 0x800);
@ -328,7 +339,7 @@ void cdrInterrupt()
cdr.Stat = Acknowledge;
break;
case CdlGetmode:
case CdlGetparam:
SetResultSize(6);
cdr.StatP |= STATUS_ROTATING;
cdr.Result[0] = cdr.StatP;
@ -555,7 +566,8 @@ void cdrReadInterrupt()
cdr.OCUP = 1;
SetResultSize(1);
cdr.StatP |= STATUS_READ | STATUS_ROTATING;
cdr.StatP &= ~STATUS_SEEK;
cdr.StatP |= STATUS_READ;
cdr.Result[0] = cdr.StatP;
if (cdr.RErr == 0)
@ -573,7 +585,8 @@ void cdrReadInterrupt()
DevCon.Warning("CD err");
memzero(cdr.Transfer);
cdr.Stat = DiskError;
cdr.Result[0] |= STATUS_ERROR;
cdr.StatP |= STATUS_ERROR;
cdr.Result[0] = cdr.StatP;
ReadTrack();
CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime);
return;
@ -730,6 +743,7 @@ void cdrWrite1(u8 rt)
//StopReading();
// Setloc is memorizing the wanted target, and marks it as unprocessed, and has no other effect
// (it doesn't start reading or seeking, and doesn't interrupt or redirect any active reads).
// But it does set the seek target. This is used to set the target then seperately start the seek after setloc
int oldSector = msf_to_lsn(cdr.SetSector);
for (i = 0; i < 3; i++)
cdr.SetSector[i] = btoi(cdr.Param[i]);
@ -752,13 +766,7 @@ void cdrWrite1(u8 rt)
AddIrqQueue(cdr.Cmd, 0x800); // the seek delay occurs on the next read / seek command (CdlReadS, CdlSeekL, etc)
}
break;
do_CdlPlay:
case CdlPlay:
// Taken from pcsxr
if (cdr.Reading)
{
StopReading();
}
if (cdr.SetlocPending)
{
memcpy(cdr.SetSectorSeek, cdr.SetSector, 4);
@ -767,6 +775,8 @@ void cdrWrite1(u8 rt)
cdr.Play = 1;
cdr.Ctrl |= 0x80;
cdr.Stat = NoIntr;
// Play is almost identical to CdlReadS, believe it or not. The main difference is that this does not trigger a completed read IRQ
StartReading(2);
AddIrqQueue(cdr.Cmd, 0x800);
break;
@ -795,8 +805,6 @@ void cdrWrite1(u8 rt)
break;
case CdlStandby:
StopCdda();
StopReading();
cdr.Ctrl |= 0x80;
cdr.Stat = NoIntr;
AddIrqQueue(cdr.Cmd, 0x800);
@ -851,22 +859,21 @@ void cdrWrite1(u8 rt)
case CdlSetmode:
CDVD_LOG("Setmode %x", cdr.Param[0]);
cdr.Mode = cdr.Param[0];
cdr.Ctrl |= 0x80;
cdr.Stat = NoIntr;
cdr.Speed = 1 + ((cdr.Mode >> 7) & 0x1);
if (cdr.Mode & MODE_CDDA)
{
StopCdda();
cdvd.Type = CDVD_TYPE_CDDA;
cdvd.Type = CDVD_TYPE_PSCDDA;
}
cdvd.Speed = 1 + ((cdr.Mode >> 7) & 0x1);
setPs1CDVDSpeed(cdvd.Speed);
AddIrqQueue(cdr.Cmd, 0x800);
break;
case CdlGetmode:
case CdlGetparam:
cdr.Ctrl |= 0x80;
cdr.Stat = NoIntr;
AddIrqQueue(cdr.Cmd, 0x800);
@ -929,8 +936,6 @@ void cdrWrite1(u8 rt)
break;
case CdlReadS:
if (cdvd.Type == CDVD_TYPE_PSCDDA) // Taken from pcsxr
goto do_CdlPlay;
cdr.Irq = 0;
StopReading();
cdr.Ctrl |= 0x80;
@ -1065,9 +1070,7 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr)
if (cdr.Readed == 0)
{
DevCon.Warning("*** DMA 3 *** NOT READY");
HW_DMA3_CHCR &= ~0x01000000; //hack
psxDmaInterrupt(3); //hack
return;
break;
}
cdsize = (bcr & 0xffff) * 4;

View File

@ -69,6 +69,7 @@ struct cdrStruct
u8 SetSectorSeek[4];
u8 Track;
int Play;
int Speed;
int CurTrack;
int Mode, File, Channel, Muted;
int Reset;