fake out gcos into thinking it is using dvd drive debug commands
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3093 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
1990c79c25
commit
ae41086ec8
|
@ -74,6 +74,15 @@ enum DVDInterruptType
|
||||||
INT_CVRINT = 3,
|
INT_CVRINT = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// debug commands which may be ORd
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
STOP_DRIVE = 0,
|
||||||
|
START_DRIVE = 0x100,
|
||||||
|
ACCEPT_COPY = 0x4000,
|
||||||
|
DISC_CHECK = 0x8000,
|
||||||
|
};
|
||||||
|
|
||||||
// DI Status Register
|
// DI Status Register
|
||||||
union UDISR
|
union UDISR
|
||||||
{
|
{
|
||||||
|
@ -101,7 +110,7 @@ union UDICVR
|
||||||
{
|
{
|
||||||
unsigned CVR : 1; // 0: Cover closed 1: Cover open
|
unsigned CVR : 1; // 0: Cover closed 1: Cover open
|
||||||
unsigned CVRINTMASK : 1; // 1: Interrupt enabled;
|
unsigned CVRINTMASK : 1; // 1: Interrupt enabled;
|
||||||
unsigned CVRINT : 1; // 1: Interrupt clear
|
unsigned CVRINT : 1; // r 1: Interrupt requested w 1: Interrupt clear
|
||||||
unsigned : 29;
|
unsigned : 29;
|
||||||
};
|
};
|
||||||
UDICVR() {Hex = 0;}
|
UDICVR() {Hex = 0;}
|
||||||
|
@ -156,6 +165,14 @@ union UDIConfigRegister
|
||||||
UDIConfigRegister(u32 _hex) {Hex = _hex;}
|
UDIConfigRegister(u32 _hex) {Hex = _hex;}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// HACK to allow multi-command debug-mode transfers
|
||||||
|
struct SDIDebugTransfer
|
||||||
|
{
|
||||||
|
u32 Address;
|
||||||
|
u16 Length;
|
||||||
|
bool InProgress;
|
||||||
|
};
|
||||||
|
|
||||||
// hardware registers
|
// hardware registers
|
||||||
struct DVDMemStruct
|
struct DVDMemStruct
|
||||||
{
|
{
|
||||||
|
@ -170,12 +187,13 @@ struct DVDMemStruct
|
||||||
u32 AudioStart;
|
u32 AudioStart;
|
||||||
u32 AudioPos;
|
u32 AudioPos;
|
||||||
u32 AudioLength;
|
u32 AudioLength;
|
||||||
|
SDIDebugTransfer DebugTransfer;
|
||||||
};
|
};
|
||||||
|
|
||||||
// STATE_TO_SAVE
|
// STATE_TO_SAVE
|
||||||
DVDMemStruct dvdMem;
|
DVDMemStruct dvdMem;
|
||||||
u32 g_ErrorCode = 0x00;
|
u32 g_ErrorCode = 0x00;
|
||||||
bool g_bDiscInside = true;
|
bool g_bDiscInside = false;
|
||||||
|
|
||||||
Common::CriticalSection dvdread_section;
|
Common::CriticalSection dvdread_section;
|
||||||
|
|
||||||
|
@ -221,24 +239,12 @@ void SetDiscInside(bool _DiscInside)
|
||||||
|
|
||||||
void SetLidOpen(bool _bOpen)
|
void SetLidOpen(bool _bOpen)
|
||||||
{
|
{
|
||||||
if (_bOpen)
|
|
||||||
dvdMem.CoverReg.Hex = 0x7;
|
|
||||||
else
|
|
||||||
dvdMem.CoverReg.Hex = 0x0;
|
|
||||||
|
|
||||||
GenerateDVDInterrupt(INT_CVRINT);
|
|
||||||
|
|
||||||
|
|
||||||
//Todo: Make this work perhaps?
|
|
||||||
/*
|
|
||||||
if (_bOpen)
|
if (_bOpen)
|
||||||
dvdMem.CoverReg.CVR = 1;
|
dvdMem.CoverReg.CVR = 1;
|
||||||
else
|
else
|
||||||
dvdMem.CoverReg.CVR = 0;
|
dvdMem.CoverReg.CVR = 0;
|
||||||
*/
|
|
||||||
|
|
||||||
UpdateInterrupts();
|
|
||||||
|
|
||||||
|
GenerateDVDInterrupt(INT_CVRINT);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsLidOpen()
|
bool IsLidOpen()
|
||||||
|
@ -345,20 +351,13 @@ void Write32(const u32 _iValue, const u32 _iAddress)
|
||||||
|
|
||||||
case DI_COVER_REGISTER:
|
case DI_COVER_REGISTER:
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
// Todo: fix this, it doesn't work properly
|
|
||||||
|
|
||||||
UDICVR tmpCoverReg(_iValue);
|
UDICVR tmpCoverReg(_iValue);
|
||||||
|
|
||||||
dvdMem.CoverReg.CVR = 0;
|
|
||||||
dvdMem.CoverReg.CVRINTMASK = tmpCoverReg.CVRINTMASK;
|
dvdMem.CoverReg.CVRINTMASK = tmpCoverReg.CVRINTMASK;
|
||||||
if (tmpCoverReg.CVRINT) dvdMem.CoverReg.CVRINT = 0;
|
|
||||||
|
if (tmpCoverReg.CVRINT) dvdMem.CoverReg.CVRINT = 0;
|
||||||
|
|
||||||
UpdateInterrupts();
|
UpdateInterrupts();
|
||||||
|
|
||||||
_dbg_assert_(DVDINTERFACE, (tmpCoverReg.CVR == 0));
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -430,8 +429,19 @@ bool m_bStream = false;
|
||||||
|
|
||||||
void ExecuteCommand(UDIDMAControlRegister& _DMAControlReg)
|
void ExecuteCommand(UDIDMAControlRegister& _DMAControlReg)
|
||||||
{
|
{
|
||||||
_dbg_assert_(DVDINTERFACE, _DMAControlReg.RW == 0); // only DVD to Memory
|
_dbg_assert_(DVDINTERFACE, _DMAControlReg.RW == 0); // only DVD to Memory
|
||||||
|
|
||||||
|
// Catch multi-command transfers here
|
||||||
|
if (dvdMem.DebugTransfer.InProgress)
|
||||||
|
{
|
||||||
|
dvdMem.DebugTransfer.InProgress = false;
|
||||||
|
// If we ever need to actually read/write the drive ram/cache, here would be the place
|
||||||
|
// Up to 12bytes can be written at once (dvdMem.Command[0] through dvdMem.Command[2])
|
||||||
|
INFO_LOG(DVDINTERFACE, "\t queued cmd: 0x%08x @ 0x%08x NOT IMPLEMENTED",
|
||||||
|
dvdMem.Command[0], dvdMem.DebugTransfer.Address);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // The huge switch is in this else!
|
||||||
switch ((dvdMem.Command[0] & 0xFF000000) >> 24)
|
switch ((dvdMem.Command[0] & 0xFF000000) >> 24)
|
||||||
{
|
{
|
||||||
//=========================================================================================================
|
//=========================================================================================================
|
||||||
|
@ -449,24 +459,33 @@ void ExecuteCommand(UDIDMAControlRegister& _DMAControlReg)
|
||||||
//=========================================================================================================
|
//=========================================================================================================
|
||||||
case 0x12:
|
case 0x12:
|
||||||
{
|
{
|
||||||
#if MAX_LOGLEVEL >= INFO_LEVEL
|
// small safety check, dunno if it's needed
|
||||||
u32 offset = dvdMem.Command[1];
|
if ((dvdMem.Command[1] == 0) && (dvdMem.DMALength.Length == 0x20))
|
||||||
// u32 sourcelength = dvdMem.Command[2];
|
|
||||||
#endif
|
|
||||||
u32 destbuffer = dvdMem.DMAAddress.Address;
|
|
||||||
u32 destlength = dvdMem.DMALength.Length;
|
|
||||||
dvdMem.DMALength.Length = 0;
|
|
||||||
|
|
||||||
INFO_LOG(DVDINTERFACE, "[WARNING] DVD: Get drive info offset=%08x, destbuffer=%08x, destlength=%08x", offset * 4, destbuffer, destlength);
|
|
||||||
|
|
||||||
// metroid uses this...
|
|
||||||
for (unsigned int i = 0; i < destlength / 4; i++)
|
|
||||||
{
|
{
|
||||||
Memory::Write_U32(0, destbuffer + i * 4);
|
u8* driveInfo = Memory::GetPointer(dvdMem.DMAAddress.Address);
|
||||||
|
// gives the correct output in GCOS - 06 2001/08 (61)
|
||||||
|
// there may be other stuff missing ?
|
||||||
|
driveInfo[4] = 0x20;
|
||||||
|
driveInfo[5] = 0x01;
|
||||||
|
driveInfo[6] = 0x06;
|
||||||
|
driveInfo[7] = 0x08;
|
||||||
|
driveInfo[8] = 0x61;
|
||||||
|
|
||||||
|
// Just for fun
|
||||||
|
INFO_LOG(DVDINTERFACE, "Drive Info: %02x %02x%02x/%02x (%02x)",
|
||||||
|
driveInfo[6], driveInfo[4], driveInfo[5], driveInfo[7], driveInfo[8]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
//=========================================================================================================
|
||||||
|
// SET EXTENSION
|
||||||
|
// Apparently the drive needs certain flags set explicitly?
|
||||||
|
//=========================================================================================================
|
||||||
|
case 0x55:
|
||||||
|
INFO_LOG(DVDINTERFACE, "SetExtension %x", _DMAControlReg);
|
||||||
|
break;
|
||||||
|
|
||||||
//=========================================================================================================
|
//=========================================================================================================
|
||||||
// READ (DMA)
|
// READ (DMA)
|
||||||
// Command/Subcommand/Padding <- A8000000
|
// Command/Subcommand/Padding <- A8000000
|
||||||
|
@ -480,11 +499,12 @@ void ExecuteCommand(UDIDMAControlRegister& _DMAControlReg)
|
||||||
{
|
{
|
||||||
u32 iDVDOffset = dvdMem.Command[1] << 2;
|
u32 iDVDOffset = dvdMem.Command[1] << 2;
|
||||||
u32 iSrcLength = dvdMem.Command[2];
|
u32 iSrcLength = dvdMem.Command[2];
|
||||||
if (false) { iSrcLength++; } // avoid warning << wtf is this?
|
|
||||||
INFO_LOG(DVDINTERFACE, "DVD: Read ISO: DVDOffset=%08x, DMABuffer=%08x, SrcLength=%08x, DMALength=%08x",iDVDOffset,dvdMem.DMAAddress.Address,iSrcLength,dvdMem.DMALength.Length);
|
INFO_LOG(DVDINTERFACE, "Read ISO: DVDOffset=%08x, DMABuffer=%08x, SrcLength=%08x, DMALength=%08x",
|
||||||
|
iDVDOffset, dvdMem.DMAAddress.Address, iSrcLength, dvdMem.DMALength.Length);
|
||||||
_dbg_assert_(DVDINTERFACE, iSrcLength == dvdMem.DMALength.Length);
|
_dbg_assert_(DVDINTERFACE, iSrcLength == dvdMem.DMALength.Length);
|
||||||
|
|
||||||
if (DVDRead(iDVDOffset, dvdMem.DMAAddress.Address, dvdMem.DMALength.Length) != true)
|
if (!DVDRead(iDVDOffset, dvdMem.DMAAddress.Address, dvdMem.DMALength.Length))
|
||||||
{
|
{
|
||||||
PanicAlert("Cant read from DVD_Plugin - DVD-Interface: Fatal Error");
|
PanicAlert("Cant read from DVD_Plugin - DVD-Interface: Fatal Error");
|
||||||
}
|
}
|
||||||
|
@ -492,6 +512,8 @@ void ExecuteCommand(UDIDMAControlRegister& _DMAControlReg)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// there is no disc to read
|
// there is no disc to read
|
||||||
|
_DMAControlReg.TSTART = 0;
|
||||||
|
dvdMem.DMALength.Length = 0;
|
||||||
GenerateDVDInterrupt(INT_DEINT);
|
GenerateDVDInterrupt(INT_DEINT);
|
||||||
g_ErrorCode = 0x03023A00;
|
g_ErrorCode = 0x03023A00;
|
||||||
return;
|
return;
|
||||||
|
@ -509,7 +531,7 @@ void ExecuteCommand(UDIDMAControlRegister& _DMAControlReg)
|
||||||
#if MAX_LOGLEVEL >= DEBUG_LEVEL
|
#if MAX_LOGLEVEL >= DEBUG_LEVEL
|
||||||
u32 offset = dvdMem.Command[1] << 2;
|
u32 offset = dvdMem.Command[1] << 2;
|
||||||
#endif
|
#endif
|
||||||
DEBUG_LOG(DVDINTERFACE, "DVD: Seek: offset=%08x (ignoring)", offset);
|
DEBUG_LOG(DVDINTERFACE, "Seek: offset=%08x (ignoring)", offset);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -518,7 +540,7 @@ void ExecuteCommand(UDIDMAControlRegister& _DMAControlReg)
|
||||||
// Command/Subcommand/Padding <- E0000000
|
// Command/Subcommand/Padding <- E0000000
|
||||||
//=========================================================================================================
|
//=========================================================================================================
|
||||||
case 0xE0:
|
case 0xE0:
|
||||||
ERROR_LOG(DVDINTERFACE, "DVD: Requesting error");
|
ERROR_LOG(DVDINTERFACE, "Requesting error");
|
||||||
dvdMem.Immediate = g_ErrorCode;
|
dvdMem.Immediate = g_ErrorCode;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -550,7 +572,8 @@ void ExecuteCommand(UDIDMAControlRegister& _DMAControlReg)
|
||||||
|
|
||||||
m_bStream = true;
|
m_bStream = true;
|
||||||
|
|
||||||
DEBUG_LOG(DVDINTERFACE, "DVD(Audio) Stream subcmd = %02x offset = %08x length=%08x", subCommand, dvdMem.AudioPos, dvdMem.AudioLength);
|
DEBUG_LOG(DVDINTERFACE, "DVD(Audio) Stream subcmd = %02x offset = %08x length=%08x",
|
||||||
|
subCommand, dvdMem.AudioPos, dvdMem.AudioLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -574,7 +597,7 @@ void ExecuteCommand(UDIDMAControlRegister& _DMAControlReg)
|
||||||
// Command/Subcommand/Padding <- E3000000
|
// Command/Subcommand/Padding <- E3000000
|
||||||
//=========================================================================================================
|
//=========================================================================================================
|
||||||
case 0xE3:
|
case 0xE3:
|
||||||
DEBUG_LOG(DVDINTERFACE, "DVD: Stop motor");
|
DEBUG_LOG(DVDINTERFACE, "Stop motor");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//=========================================================================================================
|
//=========================================================================================================
|
||||||
|
@ -595,14 +618,93 @@ void ExecuteCommand(UDIDMAControlRegister& _DMAControlReg)
|
||||||
}*/
|
}*/
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
//=========================================================================================================
|
||||||
|
// SET STATUS
|
||||||
|
//=========================================================================================================
|
||||||
|
case 0xEE:
|
||||||
|
INFO_LOG(DVDINTERFACE, "SetStatus %x", _DMAControlReg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
//=========================================================================================================
|
||||||
|
// DEBUG COMMANDS
|
||||||
|
// Subcommands:
|
||||||
|
// 0x00: ?
|
||||||
|
// 0x01: read/write memory/cache
|
||||||
|
// 0x10: ?
|
||||||
|
// 0x11: stop/start/accept copy/disk check CAN BE OR'd!
|
||||||
|
// 0x12: jump (jsr) to address
|
||||||
|
//=========================================================================================================
|
||||||
|
case 0xFE:
|
||||||
|
{
|
||||||
|
u8 subCommand = (dvdMem.Command[0] & 0x00FF0000) >> 16;
|
||||||
|
u16 argument = (u16)(dvdMem.Command[0] & 0x0000FFFF);
|
||||||
|
|
||||||
|
switch (subCommand)
|
||||||
|
{
|
||||||
|
case 0x01:
|
||||||
|
{
|
||||||
|
dvdMem.DebugTransfer.Address = dvdMem.Command[1];
|
||||||
|
dvdMem.DebugTransfer.Length = dvdMem.Command[2] >> 16; // can be up to 12 bytes
|
||||||
|
|
||||||
|
INFO_LOG(DVDINTERFACE, "Next cmd will %s %i bytes to drive %s @ 0x%08x",
|
||||||
|
(argument & 0x100) ? "write" : "read", dvdMem.DebugTransfer.Length,
|
||||||
|
(argument & 0x8000) ? "cache" : "mem", dvdMem.DebugTransfer.Address);
|
||||||
|
|
||||||
|
dvdMem.DebugTransfer.InProgress = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x11:
|
||||||
|
char flags[256];
|
||||||
|
sprintf(flags, "%s%s%s%s",
|
||||||
|
(argument & STOP_DRIVE) ? "StopDrive " : "",
|
||||||
|
(argument & START_DRIVE) ? "StartDrive " : "",
|
||||||
|
(argument & ACCEPT_COPY) ? "AcceptCopy " : "",
|
||||||
|
(argument & DISC_CHECK) ? "DiscCheck" : "");
|
||||||
|
INFO_LOG(DVDINTERFACE, "Debug cmd(s): %s", flags);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
WARN_LOG(DVDINTERFACE, "Unsupported DVD Drive debug command 0x%08x", dvdMem.Command[0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
//=========================================================================================================
|
||||||
|
// UNLOCK COMMANDS 1: "MATSHITA" 2: "DVD-GAME"
|
||||||
|
// LOL
|
||||||
|
//=========================================================================================================
|
||||||
|
case 0xFF:
|
||||||
|
{
|
||||||
|
if (dvdMem.Command[0] == 0xFF014D41
|
||||||
|
&& dvdMem.Command[1] == 0x54534849
|
||||||
|
&& dvdMem.Command[2] == 0x54410200)
|
||||||
|
{
|
||||||
|
INFO_LOG(DVDINTERFACE, "Unlock test 1 passed");
|
||||||
|
}
|
||||||
|
else if (dvdMem.Command[0] == 0xFF004456
|
||||||
|
&& dvdMem.Command[1] == 0x442D4741
|
||||||
|
&& dvdMem.Command[2] == 0x4D450300)
|
||||||
|
{
|
||||||
|
INFO_LOG(DVDINTERFACE, "Unlock test 2 passed");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
INFO_LOG(DVDINTERFACE, "Unlock test failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
//=========================================================================================================
|
//=========================================================================================================
|
||||||
// UNKNOWN DVD COMMAND
|
// UNKNOWN DVD COMMAND
|
||||||
//=========================================================================================================
|
//=========================================================================================================
|
||||||
default:
|
default:
|
||||||
PanicAlert("DVD - Unknown DVD command %08x - fatal error", dvdMem.Command[0]);
|
PanicAlert("Unknown DVD command %08x - fatal error", dvdMem.Command[0]);
|
||||||
_dbg_assert_(DVDINTERFACE, 0);
|
_dbg_assert_(DVDINTERFACE, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} // end of if(dvdMem.DebugTransfer.InProgress)
|
||||||
|
|
||||||
// transfer is done
|
// transfer is done
|
||||||
_DMAControlReg.TSTART = 0;
|
_DMAControlReg.TSTART = 0;
|
||||||
|
|
|
@ -320,11 +320,12 @@ void Write16(const u16 _iValue, const u32 _iAddress)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VI_VERTICAL_BEAM_POSITION:
|
case VI_VERTICAL_BEAM_POSITION:
|
||||||
_dbg_assert_(VIDEOINTERFACE,0);
|
// writing the beam position goes against yagcd, let's cross our fingers
|
||||||
|
VerticalBeamPos = _iValue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VI_HORIZONTAL_BEAM_POSITION:
|
case VI_HORIZONTAL_BEAM_POSITION:
|
||||||
_dbg_assert_(VIDEOINTERFACE,0);
|
HorizontalBeamPos = _iValue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// RETRACE STUFF ...
|
// RETRACE STUFF ...
|
||||||
|
|
Loading…
Reference in New Issue