mirror of
https://github.com/libretro/pcsx2.git
synced 2024-11-28 20:00:44 +00:00
4457fe40fc
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2897 96395faa-99c1-11dd-bbfe-3dabce05a288
1135 lines
30 KiB
C
1135 lines
30 KiB
C
/***************************************************************************
|
|
scsi.c - description
|
|
-------------------
|
|
begin : Sun Nov 16 2003
|
|
copyright : (C) 2003 by Pete Bernert
|
|
email : BlackDove@addcom.de
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. See also the license.txt file for *
|
|
* additional informations. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
//*************************************************************************//
|
|
// History of changes:
|
|
//
|
|
// 2003/11/16 - Pete
|
|
// - generic cleanup for the Peops release
|
|
//
|
|
//*************************************************************************//
|
|
|
|
/////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#define _IN_SCSI
|
|
#include "externals.h"
|
|
|
|
/////////////////////////////////////////////////////////
|
|
|
|
SRB_ExecSCSICmd sx; // used with all (non-waiting) read funcs
|
|
BOOL bDoWaiting=FALSE; // flag for async reads
|
|
|
|
/////////////////////////////////////////////////////////
|
|
// returns device type
|
|
|
|
int GetSCSIDevice(int iA,int iT,int iL)
|
|
{
|
|
SRB_GDEVBlock s;DWORD dwStatus;
|
|
|
|
memset(&s,0,sizeof(SRB_GDEVBlock));
|
|
s.SRB_Cmd = SC_GET_DEV_TYPE;
|
|
s.SRB_HaID = iA;
|
|
s.SRB_Target = iT;
|
|
s.SRB_Lun = iL;
|
|
|
|
ResetEvent(hEvent);
|
|
|
|
dwStatus=pSendASPI32Command((LPSRB)&s);
|
|
|
|
if(dwStatus==SS_PENDING)
|
|
{WaitGenEvent(30000);dwStatus=s.SRB_Status;}
|
|
|
|
if(dwStatus==SS_COMP) return s.SRB_DeviceType;
|
|
|
|
return -1;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////
|
|
|
|
int GetSCSIStatus(int iA,int iT,int iL)
|
|
{
|
|
SRB_ExecSCSICmd s;DWORD dwStatus;
|
|
char ret[0x324];
|
|
|
|
memset(&s,0,sizeof(s));
|
|
|
|
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
s.SRB_HaId = iCD_AD;
|
|
s.SRB_Target = iCD_TA;
|
|
s.SRB_Lun = iCD_LU;
|
|
s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
|
s.SRB_BufLen = 0x324;
|
|
s.SRB_BufPointer = (BYTE FAR *)ret;
|
|
s.SRB_SenseLen = 0x0E;
|
|
s.SRB_CDBLen = 0x0A;
|
|
s.SRB_PostProc = (LPVOID)hEvent;
|
|
s.CDBByte[0] = 0x00;
|
|
|
|
ResetEvent(hEvent);
|
|
dwStatus=pSendASPI32Command((LPSRB)&s);
|
|
|
|
if(dwStatus==SS_PENDING) WaitGenEvent(30000);
|
|
|
|
return s.SRB_Status;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////
|
|
// fills toc infos
|
|
|
|
DWORD GetSCSITOC(LPTOC toc)
|
|
{
|
|
SRB_ExecSCSICmd s;DWORD dwStatus;
|
|
|
|
memset(&s,0,sizeof(s));
|
|
|
|
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
s.SRB_HaId = iCD_AD;
|
|
s.SRB_Target = iCD_TA;
|
|
s.SRB_Lun = iCD_LU;
|
|
s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
|
s.SRB_BufLen = 0x324;
|
|
s.SRB_BufPointer = (BYTE FAR *)toc;
|
|
s.SRB_SenseLen = 0x0E;
|
|
s.SRB_CDBLen = 0x0A;
|
|
s.SRB_PostProc = (LPVOID)hEvent;
|
|
s.CDBByte[0] = 0x43;
|
|
s.CDBByte[1] = 0x00; // 0x02 for MSF
|
|
s.CDBByte[7] = 0x03;
|
|
s.CDBByte[8] = 0x24;
|
|
|
|
ResetEvent(hEvent);
|
|
dwStatus=pSendASPI32Command((LPSRB)&s);
|
|
|
|
if(dwStatus==SS_PENDING) WaitGenEvent(30000);
|
|
|
|
if(s.SRB_Status!=SS_COMP) return SS_ERR;
|
|
|
|
return SS_COMP;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////
|
|
// enum all cd drives into 32k buffer, return num of drives
|
|
|
|
int GetSCSICDDrives(char * pDList)
|
|
{
|
|
int iCnt=0,iA,iT,iL;char * p=pDList;
|
|
SRB_HAInquiry si;SRB_GDEVBlock sd;
|
|
SRB_ExecSCSICmd s;int iNumA;char szBuf[100];
|
|
DWORD dw,dwStatus;
|
|
|
|
if(!pGetASPI32SupportInfo) return 0;
|
|
|
|
dw=pGetASPI32SupportInfo();
|
|
|
|
if(HIBYTE(LOWORD(dw))!=SS_COMP) return 0;
|
|
iNumA=(int)LOBYTE(LOWORD(dw));
|
|
|
|
for(iA=0;iA<iNumA;iA++)
|
|
{
|
|
memset(&si,0,sizeof(SRB_HAInquiry));
|
|
si.SRB_Cmd = SC_HA_INQUIRY;
|
|
si.SRB_HaId = iA;
|
|
pSendASPI32Command((LPSRB)&si);
|
|
if(si.SRB_Status!=SS_COMP) continue;
|
|
if(!si.HA_Unique[3]) si.HA_Unique[3]=8;
|
|
for(iT=0;iT<si.HA_Unique[3];iT++)
|
|
{
|
|
for(iL=0;iL<8;iL++)
|
|
{
|
|
memset(&sd,0,sizeof(SRB_GDEVBlock));
|
|
sd.SRB_Cmd = SC_GET_DEV_TYPE;
|
|
sd.SRB_HaID = iA;
|
|
sd.SRB_Target = iT;
|
|
sd.SRB_Lun = iL;
|
|
|
|
pSendASPI32Command((LPSRB)&sd);
|
|
if(sd.SRB_Status==SS_COMP &&
|
|
sd.SRB_DeviceType==DTYPE_CDROM)
|
|
{
|
|
memset(&s,0,sizeof(s));
|
|
|
|
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
s.SRB_HaId = iA;
|
|
s.SRB_Target = iT;
|
|
s.SRB_Lun = iL;
|
|
s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
|
s.SRB_BufLen = 100;
|
|
s.SRB_BufPointer = szBuf;
|
|
s.SRB_SenseLen = SENSE_LEN;
|
|
s.SRB_CDBLen = 6;
|
|
s.SRB_PostProc = (LPVOID)hEvent;
|
|
s.CDBByte[0] = SCSI_INQUIRY;
|
|
s.CDBByte[4] = 100;
|
|
ResetEvent(hEvent);
|
|
dwStatus=pSendASPI32Command((LPSRB)&s);
|
|
if(dwStatus==SS_PENDING)
|
|
WaitGenEvent(WAITFOREVER);
|
|
if(s.SRB_Status==SS_COMP)
|
|
{
|
|
int i;
|
|
for(i=8 ;i<15;i++) if(szBuf[i]==' ') {szBuf[i]=0;break;}
|
|
szBuf[15]=0;
|
|
for(i=16;i<32;i++) if(szBuf[i]==' ') {szBuf[i]=0;break;}
|
|
szBuf[31]=0;
|
|
for(i=32;i<37;i++) if(szBuf[i]==' ') {szBuf[i]=0;break;}
|
|
szBuf[36]=0;
|
|
wsprintf(p,"[%d:%d:%d] %s %s V%s",
|
|
iA,iT,iL,&szBuf[8],&szBuf[16],&szBuf[32]);
|
|
iCnt++;
|
|
p+=strlen(p)+1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return iCnt;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////
|
|
// play audio
|
|
|
|
DWORD PlaySCSIAudio(unsigned long start,unsigned long len)
|
|
{
|
|
SRB_ExecSCSICmd s;DWORD dwStatus;
|
|
|
|
memset(&s,0,sizeof(s));
|
|
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
s.SRB_HaId = iCD_AD;
|
|
s.SRB_Target = iCD_TA;
|
|
s.SRB_Lun = iCD_LU;
|
|
s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
|
s.SRB_BufLen = 0;
|
|
s.SRB_BufPointer = 0;
|
|
s.SRB_SenseLen = SENSE_LEN;
|
|
s.SRB_CDBLen = 12;
|
|
s.SRB_PostProc = (LPVOID)hEvent;
|
|
|
|
if(start==0) // mmm... that stop doesn't seem to work on all drives... pfff
|
|
{
|
|
s.CDBByte[0] = 0x4b;
|
|
s.CDBByte[1] = (iCD_LU << 5) | 01;
|
|
s.CDBByte[2] = 0;
|
|
s.CDBByte[3] = 0;
|
|
s.CDBByte[4] = 0;
|
|
s.CDBByte[5] = 0;
|
|
s.CDBByte[6] = 0;
|
|
s.CDBByte[7] = 0;
|
|
s.CDBByte[8] = 0;
|
|
s.CDBByte[9] = 0;
|
|
}
|
|
else // start playing
|
|
{
|
|
s.CDBByte[0] = 0xa5;
|
|
s.CDBByte[1] = iCD_LU << 5;
|
|
s.CDBByte[2] = (unsigned char)((start >> 24) & 0xFF);
|
|
s.CDBByte[3] = (unsigned char)((start >> 16) & 0xFF);
|
|
s.CDBByte[4] = (unsigned char)((start >> 8) & 0xFF);
|
|
s.CDBByte[5] = (unsigned char)((start & 0xFF));
|
|
s.CDBByte[6] = (unsigned char)((len >> 24) & 0xFF);
|
|
s.CDBByte[7] = (unsigned char)((len >> 16) & 0xFF);
|
|
s.CDBByte[8] = (unsigned char)((len >> 8) & 0xFF);
|
|
s.CDBByte[9] = (unsigned char)(len & 0xFF);
|
|
}
|
|
|
|
ResetEvent(hEvent);
|
|
|
|
dwStatus = pSendASPI32Command((LPSRB)&s);
|
|
|
|
if(dwStatus==SS_PENDING) WaitGenEvent(10000);
|
|
|
|
return s.SRB_Status;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////
|
|
// do (unprecise) sub channel read on audio play
|
|
|
|
unsigned char * GetSCSIAudioSub(void)
|
|
{
|
|
SRB_ExecSCSICmd s;DWORD dwStatus;
|
|
unsigned char cB[20];
|
|
|
|
memset(cB,0,20);
|
|
memset(&s,0,sizeof(s));
|
|
|
|
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
s.SRB_HaId = iCD_AD;
|
|
s.SRB_Target = iCD_TA;
|
|
s.SRB_Lun = iCD_LU;
|
|
s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
|
s.SRB_SenseLen = SENSE_LEN;
|
|
|
|
s.SRB_BufLen = 20;//44;
|
|
s.SRB_BufPointer = cB;
|
|
s.SRB_CDBLen = 10;
|
|
|
|
s.CDBByte[0] = 0x42;
|
|
s.CDBByte[1] = (iCD_LU<<5)|2; // lun & msf
|
|
s.CDBByte[2] = 0x40; // subq
|
|
s.CDBByte[3] = 0x01; // curr pos info
|
|
s.CDBByte[6] = 0; // track number (only in isrc mode, ignored)
|
|
s.CDBByte[7] = 0; // alloc len
|
|
s.CDBByte[8] = 20;//44;
|
|
|
|
ResetEvent(hEvent);
|
|
|
|
dwStatus = pSendASPI32Command((LPSRB)&s);
|
|
|
|
if(dwStatus==SS_PENDING) WaitGenEvent(WAITFOREVER);
|
|
|
|
if(s.SRB_Status!=SS_COMP) return NULL;
|
|
|
|
SubAData[12]=(cB[5]<<4)|(cB[5]>>4);
|
|
SubAData[13]=cB[6];
|
|
SubAData[14]=cB[7];
|
|
SubAData[15]=itob(cB[13]);
|
|
SubAData[16]=itob(cB[14]);
|
|
SubAData[17]=itob(cB[15]);
|
|
SubAData[18]=0;
|
|
SubAData[19]=itob(cB[9]);
|
|
SubAData[20]=itob(cB[10]);
|
|
SubAData[21]=itob(cB[11]);
|
|
|
|
return SubAData;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////
|
|
// test, if drive is ready (doesn't work on all drives)
|
|
|
|
BOOL TestSCSIUnitReady(void)
|
|
{
|
|
SRB_ExecSCSICmd s;DWORD dwStatus;
|
|
|
|
memset(&s,0,sizeof(s));
|
|
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
s.SRB_HaId = iCD_AD;
|
|
s.SRB_Target = iCD_TA;
|
|
s.SRB_Lun = iCD_LU;
|
|
s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
|
s.SRB_BufLen = 0;
|
|
s.SRB_BufPointer = 0;
|
|
s.SRB_SenseLen = SENSE_LEN;
|
|
s.SRB_CDBLen = 6;
|
|
s.SRB_PostProc = (LPVOID)hEvent;
|
|
s.CDBByte[0] = 0x00;
|
|
s.CDBByte[1] = iCD_LU << 5;
|
|
|
|
ResetEvent(hEvent);
|
|
dwStatus = pSendASPI32Command((LPSRB)&s);
|
|
|
|
if(dwStatus==SS_PENDING)
|
|
WaitGenEvent(1000);
|
|
|
|
if(s.SRB_Status!=SS_COMP)
|
|
return FALSE;
|
|
|
|
if(s.SRB_TargStat==STATUS_GOOD) return TRUE; // will always be GOOD with ioctl, so no problem here
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////
|
|
// change the read speed (not supported on all drives)
|
|
|
|
DWORD SetSCSISpeed(DWORD dwSpeed)
|
|
{
|
|
SRB_ExecSCSICmd s;DWORD dwStatus;
|
|
|
|
memset(&s,0,sizeof(s));
|
|
|
|
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
s.SRB_HaId = iCD_AD;
|
|
s.SRB_Target = iCD_TA;
|
|
s.SRB_Lun = iCD_LU;
|
|
s.SRB_Flags = SRB_DIR_OUT | SRB_EVENT_NOTIFY;
|
|
s.SRB_SenseLen = SENSE_LEN;
|
|
s.SRB_CDBLen = 12;
|
|
s.SRB_PostProc = (LPVOID)hEvent;
|
|
s.CDBByte[0] = 0xBB;
|
|
s.CDBByte[2] = (BYTE)(dwSpeed >> 8);
|
|
s.CDBByte[3] = (BYTE)dwSpeed;
|
|
|
|
ResetEvent(hEvent);
|
|
dwStatus=pSendASPI32Command((LPSRB)&s);
|
|
|
|
if(dwStatus==SS_PENDING)
|
|
WaitGenEvent(WAITFOREVER);
|
|
|
|
if(s.SRB_Status!=SS_COMP) return SS_ERR;
|
|
|
|
return SS_COMP;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////
|
|
// all the different SCSI read commands can be found here
|
|
// 'bWait' is a flag, if the command should wait until
|
|
// completed, or if the func can return as soon as possible
|
|
// (async reading). Attention: 'bWait' is not really used
|
|
// in the Sub-channel commands yet (sub is done always
|
|
// blocking, and just 'one sector' reads are done, caching=0)
|
|
/////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////
|
|
// BE: used by most ATAPI drives
|
|
/////////////////////////////////////////////////////////
|
|
|
|
DWORD ReadSCSI_BE(BOOL bWait,FRAMEBUF * f)
|
|
{
|
|
DWORD dwStatus;
|
|
|
|
memset(&sx,0,sizeof(sx));
|
|
|
|
sx.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
sx.SRB_HaId = iCD_AD;
|
|
sx.SRB_Target = iCD_TA;
|
|
sx.SRB_Lun = iCD_LU;
|
|
sx.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
|
sx.SRB_BufLen = f->dwBufLen;
|
|
sx.SRB_BufPointer = &(f->BufData[0]);
|
|
sx.SRB_SenseLen = SENSE_LEN;
|
|
sx.SRB_CDBLen = 12;
|
|
sx.SRB_PostProc = (LPVOID)hEvent;
|
|
sx.CDBByte[0] = 0xBE;
|
|
//s.CDBByte[1] = 0x04;
|
|
sx.CDBByte[2] = (unsigned char)((f->dwFrame >> 24) & 0xFF);
|
|
sx.CDBByte[3] = (unsigned char)((f->dwFrame >> 16) & 0xFF);
|
|
sx.CDBByte[4] = (unsigned char)((f->dwFrame >> 8) & 0xFF);
|
|
sx.CDBByte[5] = (unsigned char)(f->dwFrame & 0xFF);
|
|
sx.CDBByte[8] = (unsigned char)(f->dwFrameCnt & 0xFF);
|
|
sx.CDBByte[9] = (iRType==MODE_BE_1)?0x10:0xF8;//F0!!!!!!!!!!!
|
|
|
|
ResetEvent(hEvent);
|
|
dwStatus=pSendASPI32Command((LPSRB)&sx);
|
|
|
|
if(dwStatus==SS_PENDING)
|
|
{
|
|
if(bWait) WaitGenEvent(WAITFOREVER);
|
|
else
|
|
{
|
|
bDoWaiting=TRUE;
|
|
return SS_COMP;
|
|
}
|
|
}
|
|
|
|
if(sx.SRB_Status!=SS_COMP)
|
|
return SS_ERR;
|
|
|
|
return SS_COMP;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////
|
|
|
|
DWORD ReadSCSI_BE_Sub(BOOL bWait,FRAMEBUF * f)
|
|
{
|
|
DWORD dwStatus;
|
|
|
|
memset(&sx,0,sizeof(sx));
|
|
sx.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
sx.SRB_HaId = iCD_AD;
|
|
sx.SRB_Target = iCD_TA;
|
|
sx.SRB_Lun = iCD_LU;
|
|
sx.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
|
sx.SRB_BufLen = f->dwBufLen + 16;
|
|
sx.SRB_BufPointer = &(f->BufData[0]);
|
|
sx.SRB_SenseLen = SENSE_LEN;
|
|
sx.SRB_CDBLen = 12;
|
|
sx.SRB_PostProc = (LPVOID)hEvent;
|
|
sx.CDBByte[0] = 0xBE;
|
|
//s.CDBByte[1] = 0x04;
|
|
sx.CDBByte[2] = (unsigned char)((f->dwFrame >> 24) & 0xFF);
|
|
sx.CDBByte[3] = (unsigned char)((f->dwFrame >> 16) & 0xFF);
|
|
sx.CDBByte[4] = (unsigned char)((f->dwFrame >> 8) & 0xFF);
|
|
sx.CDBByte[5] = (unsigned char)(f->dwFrame & 0xFF);
|
|
sx.CDBByte[8] = (unsigned char)(f->dwFrameCnt & 0xFF);
|
|
sx.CDBByte[9] = (iRType==MODE_BE_1)?0x10:0xF8;//F0!!!!!!!!!!!
|
|
sx.CDBByte[10] = 0x2;
|
|
|
|
ResetEvent(hEvent );
|
|
dwStatus=pSendASPI32Command((LPSRB)&sx);
|
|
|
|
if(dwStatus==SS_PENDING)
|
|
WaitGenEvent(WAITSUB);
|
|
|
|
if(sx.SRB_Status!=SS_COMP)
|
|
return SS_ERR;
|
|
|
|
memcpy(&SubCData[12],&f->BufData[2352],16);
|
|
|
|
SubCData[15]=itob(SubCData[15]);
|
|
SubCData[16]=itob(SubCData[16]);
|
|
SubCData[17]=itob(SubCData[17]);
|
|
|
|
SubCData[19]=itob(SubCData[19]);
|
|
SubCData[20]=itob(SubCData[20]);
|
|
SubCData[21]=itob(SubCData[21]);
|
|
|
|
return SS_COMP;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////
|
|
// different sub reading for lite-on ltd163d...
|
|
// 16 bytes subc data is encoded in 96 bytes...
|
|
|
|
DWORD ReadSCSI_BE_Sub_1(BOOL bWait,FRAMEBUF * f)
|
|
{
|
|
DWORD dwStatus;
|
|
|
|
memset(&sx,0,sizeof(sx));
|
|
|
|
sx.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
sx.SRB_HaId = iCD_AD;
|
|
sx.SRB_Target = iCD_TA;
|
|
sx.SRB_Lun = iCD_LU;
|
|
sx.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
|
sx.SRB_BufLen = f->dwBufLen + 96;
|
|
sx.SRB_BufPointer = &(f->BufData[0]);
|
|
sx.SRB_SenseLen = SENSE_LEN;
|
|
sx.SRB_CDBLen = 12;
|
|
sx.SRB_PostProc = (LPVOID)hEvent;
|
|
sx.CDBByte[0] = 0xBE;
|
|
sx.CDBByte[2] = (unsigned char)((f->dwFrame >> 24) & 0xFF);
|
|
sx.CDBByte[3] = (unsigned char)((f->dwFrame >> 16) & 0xFF);
|
|
sx.CDBByte[4] = (unsigned char)((f->dwFrame >> 8) & 0xFF);
|
|
sx.CDBByte[5] = (unsigned char)(f->dwFrame & 0xFF);
|
|
sx.CDBByte[8] = (unsigned char)(f->dwFrameCnt & 0xFF);
|
|
sx.CDBByte[9] = 0xF8;
|
|
sx.CDBByte[10] = 0x1;
|
|
|
|
ResetEvent(hEvent);
|
|
dwStatus=pSendASPI32Command((LPSRB)&sx);
|
|
|
|
if(dwStatus==SS_PENDING)
|
|
WaitGenEvent(WAITSUB);
|
|
|
|
if(sx.SRB_Status!=SS_COMP)
|
|
return SS_ERR;
|
|
|
|
DecodeSub_BE_2_1(&f->BufData[2352]);
|
|
|
|
memcpy(&SubCData[12],&f->BufData[2352],16);
|
|
|
|
return SS_COMP;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////
|
|
// 28: used by most SCSI drives
|
|
/////////////////////////////////////////////////////////
|
|
|
|
DWORD InitSCSI_28_2(void)
|
|
{
|
|
SRB_ExecSCSICmd s;DWORD dwStatus;
|
|
int i;
|
|
BYTE init1[] = { 0, 0, 0, 0x08, 0, 0, 0, 0, 0, 0, 0x09, 0x30, 0x23, 6, 0, 0, 0, 0, 0, 0x80 };
|
|
BYTE init2[] = { 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 9, 48, 1, 6, 32, 7, 0, 0, 0, 0 };
|
|
|
|
for(i=0;i<2;i++)
|
|
{
|
|
memset( &s, 0, sizeof( s ) );
|
|
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
s.SRB_HaId = iCD_AD;
|
|
s.SRB_Target = iCD_TA;
|
|
s.SRB_Lun = iCD_LU;
|
|
s.SRB_Flags = SRB_EVENT_NOTIFY;
|
|
s.SRB_BufLen = 0x14;
|
|
s.SRB_BufPointer = (i==0)?init1:init2;
|
|
s.SRB_SenseLen = SENSE_LEN;
|
|
s.SRB_CDBLen = 6;
|
|
s.SRB_PostProc = (LPVOID)hEvent;
|
|
s.CDBByte[0] = 0x15;
|
|
s.CDBByte[1] = 0x10;
|
|
s.CDBByte[4] = 0x14;
|
|
|
|
ResetEvent(hEvent);
|
|
|
|
dwStatus=pSendASPI32Command((LPSRB)&s);
|
|
if (dwStatus == SS_PENDING)
|
|
WaitGenEvent(WAITFOREVER);
|
|
|
|
if(s.SRB_Status!=SS_COMP)
|
|
return SS_ERR;
|
|
}
|
|
|
|
pDeInitFunc = DeInitSCSI_28;
|
|
|
|
return s.SRB_Status;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////
|
|
|
|
DWORD InitSCSI_28_1(void)
|
|
{
|
|
SRB_ExecSCSICmd s;DWORD dwStatus;
|
|
BYTE init1[] = { 0, 0, 0, 0x08, 0, 0, 0, 0, 0, 0, 0x09, 0x30 };
|
|
|
|
memset(&s,0,sizeof(s));
|
|
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
s.SRB_HaId = iCD_AD;
|
|
s.SRB_Target = iCD_TA;
|
|
s.SRB_Lun = iCD_LU;
|
|
s.SRB_Flags = SRB_EVENT_NOTIFY;
|
|
s.SRB_BufLen = 0x0C;
|
|
s.SRB_BufPointer = init1;
|
|
s.SRB_SenseLen = SENSE_LEN;
|
|
s.SRB_CDBLen = 6;
|
|
s.SRB_PostProc = (LPVOID)hEvent;
|
|
s.CDBByte[0] = 0x15;
|
|
s.CDBByte[4] = 0x0C;
|
|
|
|
ResetEvent(hEvent);
|
|
dwStatus=pSendASPI32Command((LPSRB)&s);
|
|
if(dwStatus==SS_PENDING)
|
|
WaitGenEvent(WAITFOREVER);
|
|
|
|
if(s.SRB_Status!=SS_COMP)
|
|
return SS_ERR;
|
|
|
|
pDeInitFunc = DeInitSCSI_28;
|
|
|
|
return s.SRB_Status;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////
|
|
|
|
DWORD InitSCSI_28_2048(void)
|
|
{
|
|
SRB_ExecSCSICmd s;DWORD dwStatus;
|
|
BYTE init1[] = { 0, 0, 0, 0x08, 0, 0, 0, 0, 0, 0, 0x08, 0x0 };
|
|
|
|
pDeInitFunc = DeInitSCSI_28;
|
|
|
|
memset(&s,0,sizeof(s));
|
|
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
s.SRB_HaId = iCD_AD;
|
|
s.SRB_Target = iCD_TA;
|
|
s.SRB_Lun = iCD_LU;
|
|
s.SRB_Flags = SRB_EVENT_NOTIFY;
|
|
s.SRB_BufLen = 0x0C;
|
|
s.SRB_BufPointer = init1;
|
|
s.SRB_SenseLen = SENSE_LEN;
|
|
s.SRB_CDBLen = 6;
|
|
s.SRB_PostProc = (LPVOID)hEvent;
|
|
s.CDBByte[0] = 0x15;
|
|
s.CDBByte[4] = 0x0C;
|
|
|
|
ResetEvent(hEvent);
|
|
dwStatus=pSendASPI32Command((LPSRB)&s);
|
|
if(dwStatus==SS_PENDING)
|
|
WaitGenEvent(WAITFOREVER);
|
|
|
|
if(s.SRB_Status!=SS_COMP)
|
|
return SS_ERR;
|
|
|
|
return s.SRB_Status;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////
|
|
|
|
DWORD DeInitSCSI_28(void)
|
|
{
|
|
SRB_ExecSCSICmd s;DWORD dwStatus;
|
|
BYTE init1[] = { 0, 0, 0, 8, 83, 0, 0, 0, 0, 0, 8, 0 };
|
|
|
|
memset(&s,0,sizeof(s));
|
|
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
s.SRB_HaId = iCD_AD;
|
|
s.SRB_Target = iCD_TA;
|
|
s.SRB_Lun = iCD_LU;
|
|
s.SRB_Flags = SRB_EVENT_NOTIFY | SRB_ENABLE_RESIDUAL_COUNT;
|
|
s.SRB_BufLen = 0x0C;
|
|
s.SRB_BufPointer = init1;
|
|
s.SRB_SenseLen = SENSE_LEN;
|
|
s.SRB_CDBLen = 6;
|
|
s.SRB_PostProc = (LPVOID)hEvent;
|
|
s.CDBByte[0] = 0x15;
|
|
s.CDBByte[4] = 0x0C;
|
|
|
|
ResetEvent(hEvent);
|
|
dwStatus=pSendASPI32Command((LPSRB)&s);
|
|
if(dwStatus==SS_PENDING)
|
|
WaitGenEvent(WAITFOREVER);
|
|
|
|
if(s.SRB_Status!=SS_COMP)
|
|
return SS_ERR;
|
|
|
|
return s.SRB_Status;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////
|
|
|
|
DWORD ReadSCSI_28(BOOL bWait,FRAMEBUF * f)
|
|
{
|
|
DWORD dwStatus;
|
|
|
|
if(!pDeInitFunc)
|
|
{
|
|
if(iRType==MODE_28_2)
|
|
{
|
|
if(InitSCSI_28_2()!=SS_COMP) return SS_ERR;
|
|
}
|
|
else
|
|
{
|
|
if(InitSCSI_28_1()!=SS_COMP) return SS_ERR;
|
|
}
|
|
}
|
|
|
|
memset(&sx,0,sizeof(sx));
|
|
sx.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
sx.SRB_HaId = iCD_AD;
|
|
sx.SRB_Target = iCD_TA;
|
|
sx.SRB_Lun = iCD_LU;
|
|
sx.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
|
sx.SRB_BufLen = f->dwBufLen;
|
|
sx.SRB_BufPointer = &(f->BufData[0]);
|
|
sx.SRB_SenseLen = SENSE_LEN;
|
|
sx.SRB_CDBLen = 10;
|
|
sx.SRB_PostProc = (LPVOID)hEvent;
|
|
sx.CDBByte[0] = 0x28; // read10 command
|
|
sx.CDBByte[1] = iCD_LU << 5;
|
|
sx.CDBByte[2] = (unsigned char)((f->dwFrame >> 24) & 0xFF);
|
|
sx.CDBByte[3] = (unsigned char)((f->dwFrame >> 16) & 0xFF);
|
|
sx.CDBByte[4] = (unsigned char)((f->dwFrame >> 8) & 0xFF);
|
|
sx.CDBByte[5] = (unsigned char)(f->dwFrame & 0xFF);
|
|
sx.CDBByte[8] = (unsigned char)(f->dwFrameCnt & 0xFF);
|
|
|
|
ResetEvent(hEvent);
|
|
dwStatus=pSendASPI32Command((LPSRB)&sx);
|
|
if(dwStatus==SS_PENDING)
|
|
{
|
|
if(bWait) WaitGenEvent(WAITFOREVER);
|
|
else
|
|
{
|
|
bDoWaiting=TRUE;
|
|
return SS_COMP;
|
|
}
|
|
}
|
|
|
|
if(sx.SRB_Status!=SS_COMP)
|
|
return SS_ERR;
|
|
|
|
return SS_COMP;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////
|
|
// DVD MODE
|
|
|
|
DWORD ReadSCSI_28_2048(BOOL bWait,FRAMEBUF * f)
|
|
{
|
|
DWORD dwStatus;
|
|
|
|
if(!pDeInitFunc)
|
|
{
|
|
InitSCSI_28_2048();
|
|
|
|
//if(InitSCSI_28_2048()!=SS_COMP) return SS_ERR;
|
|
}
|
|
|
|
memset(&sx,0,sizeof(sx));
|
|
sx.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
sx.SRB_HaId = iCD_AD;
|
|
sx.SRB_Target = iCD_TA;
|
|
sx.SRB_Lun = iCD_LU;
|
|
sx.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
|
sx.SRB_BufLen = f->dwBufLen;
|
|
sx.SRB_BufPointer = &(f->BufData[0]);
|
|
sx.SRB_SenseLen = SENSE_LEN;
|
|
sx.SRB_CDBLen = 10;
|
|
sx.SRB_PostProc = (LPVOID)hEvent;
|
|
sx.CDBByte[0] = 0x28; // read10 command
|
|
sx.CDBByte[1] = iCD_LU << 5;
|
|
sx.CDBByte[2] = (unsigned char)((f->dwFrame >> 24) & 0xFF);
|
|
sx.CDBByte[3] = (unsigned char)((f->dwFrame >> 16) & 0xFF);
|
|
sx.CDBByte[4] = (unsigned char)((f->dwFrame >> 8) & 0xFF);
|
|
sx.CDBByte[5] = (unsigned char)(f->dwFrame & 0xFF);
|
|
sx.CDBByte[8] = (unsigned char)(f->dwFrameCnt & 0xFF);
|
|
sx.CDBByte[9] = 0xF8;
|
|
|
|
ResetEvent(hEvent);
|
|
dwStatus=pSendASPI32Command((LPSRB)&sx);
|
|
if(dwStatus==SS_PENDING)
|
|
{
|
|
if(bWait) WaitGenEvent(WAITFOREVER);
|
|
else
|
|
{
|
|
bDoWaiting=TRUE;
|
|
return SS_COMP;
|
|
}
|
|
}
|
|
|
|
if(sx.SRB_Status!=SS_COMP)
|
|
return SS_ERR;
|
|
|
|
return SS_COMP;
|
|
}
|
|
|
|
DWORD ReadSCSI_28_2048_Ex(BOOL bWait,FRAMEBUF * f)
|
|
{
|
|
DWORD dwStatus;
|
|
|
|
if(!pDeInitFunc)
|
|
{
|
|
InitSCSI_28_2048();
|
|
|
|
//if(InitSCSI_28_2048()!=SS_COMP) return SS_ERR;
|
|
}
|
|
|
|
memset(&sx,0,sizeof(sx));
|
|
sx.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
sx.SRB_HaId = iCD_AD;
|
|
sx.SRB_Target = iCD_TA;
|
|
sx.SRB_Lun = iCD_LU;
|
|
sx.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
|
sx.SRB_BufLen = f->dwBufLen;
|
|
sx.SRB_BufPointer = &(f->BufData[0]);
|
|
sx.SRB_SenseLen = SENSE_LEN;
|
|
sx.SRB_CDBLen = 10;
|
|
sx.SRB_PostProc = (LPVOID)hEvent;
|
|
sx.CDBByte[0] = 0x28; // read10 command
|
|
sx.CDBByte[1] = iCD_LU << 5;
|
|
sx.CDBByte[2] = (unsigned char)((f->dwFrame >> 24) & 0xFF);
|
|
sx.CDBByte[3] = (unsigned char)((f->dwFrame >> 16) & 0xFF);
|
|
sx.CDBByte[4] = (unsigned char)((f->dwFrame >> 8) & 0xFF);
|
|
sx.CDBByte[5] = (unsigned char)(f->dwFrame & 0xFF);
|
|
sx.CDBByte[8] = (unsigned char)(f->dwFrameCnt & 0xFF);
|
|
// NO F8
|
|
//sx.CDBByte[9] = 0xF8;
|
|
|
|
ResetEvent(hEvent);
|
|
dwStatus=pSendASPI32Command((LPSRB)&sx);
|
|
if(dwStatus==SS_PENDING)
|
|
{
|
|
if(bWait) WaitGenEvent(WAITFOREVER);
|
|
else
|
|
{
|
|
bDoWaiting=TRUE;
|
|
return SS_COMP;
|
|
}
|
|
}
|
|
|
|
if(sx.SRB_Status!=SS_COMP)
|
|
return SS_ERR;
|
|
|
|
return SS_COMP;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////
|
|
// stupid subc reading on Teac 532S
|
|
|
|
char tbuf[2368];
|
|
|
|
DWORD ReadSCSI_28_Sub(BOOL bWait,FRAMEBUF * f)
|
|
{
|
|
DWORD dwStatus;
|
|
|
|
if(!pDeInitFunc)
|
|
{
|
|
if(iRType==MODE_28_2)
|
|
{
|
|
if(InitSCSI_28_2()!=SS_COMP) return SS_ERR;
|
|
}
|
|
else
|
|
{
|
|
if(InitSCSI_28_1()!=SS_COMP) return SS_ERR;
|
|
}
|
|
}
|
|
|
|
memset(&sx,0,sizeof(sx));
|
|
sx.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
sx.SRB_HaId = iCD_AD;
|
|
sx.SRB_Target = iCD_TA;
|
|
sx.SRB_Lun = iCD_LU;
|
|
sx.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
|
sx.SRB_BufLen = f->dwBufLen;
|
|
sx.SRB_BufPointer = &(f->BufData[0]);
|
|
sx.SRB_SenseLen = SENSE_LEN;
|
|
sx.SRB_CDBLen = 10;
|
|
sx.SRB_PostProc = (LPVOID)hEvent;
|
|
sx.CDBByte[0] = 0x28; // read10
|
|
sx.CDBByte[1] = iCD_LU << 5;
|
|
sx.CDBByte[2] = (unsigned char)((f->dwFrame >> 24) & 0xFF);
|
|
sx.CDBByte[3] = (unsigned char)((f->dwFrame >> 16) & 0xFF);
|
|
sx.CDBByte[4] = (unsigned char)((f->dwFrame >> 8) & 0xFF);
|
|
sx.CDBByte[5] = (unsigned char)(f->dwFrame & 0xFF);
|
|
sx.CDBByte[8] = (unsigned char)(f->dwFrameCnt & 0xFF);
|
|
|
|
ResetEvent(hEvent);
|
|
dwStatus=pSendASPI32Command((LPSRB)&sx);
|
|
if(dwStatus==SS_PENDING)
|
|
WaitGenEvent(WAITFOREVER);
|
|
|
|
if(sx.SRB_Status!=SS_COMP)
|
|
return SS_ERR;
|
|
|
|
memset(&sx,0,sizeof(sx));
|
|
sx.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
sx.SRB_HaId = iCD_AD;
|
|
sx.SRB_Target = iCD_TA;
|
|
sx.SRB_Lun = iCD_LU;
|
|
sx.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
|
sx.SRB_BufLen = 2368;
|
|
sx.SRB_BufPointer = tbuf;
|
|
sx.SRB_SenseLen = SENSE_LEN;
|
|
sx.SRB_CDBLen = 12;
|
|
sx.SRB_PostProc = (LPVOID)hEvent;
|
|
sx.CDBByte[0] = 0xD8;
|
|
sx.CDBByte[2] = (unsigned char)((f->dwFrame >> 24) & 0xFF);
|
|
sx.CDBByte[3] = (unsigned char)((f->dwFrame >> 16) & 0xFF);
|
|
sx.CDBByte[4] = (unsigned char)((f->dwFrame >> 8) & 0xFF);
|
|
sx.CDBByte[5] = (unsigned char)(f->dwFrame & 0xFF);
|
|
sx.CDBByte[9] = (unsigned char)(f->dwFrameCnt & 0xFF);
|
|
sx.CDBByte[10] = 1;
|
|
|
|
ResetEvent(hEvent);
|
|
dwStatus=pSendASPI32Command((LPSRB)&sx);
|
|
if(dwStatus==SS_PENDING)
|
|
WaitGenEvent(WAITFOREVER);
|
|
|
|
if(sx.SRB_Status!=SS_COMP)
|
|
return SS_ERR;
|
|
|
|
memcpy(&SubCData[12],&tbuf[2352],16);
|
|
|
|
return SS_COMP;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////
|
|
// various simple scsi sub data read funcs... used for
|
|
// ripping and subread checking... first 2352 bytes can
|
|
// be trash after read, only the bytes after are important
|
|
/////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////
|
|
|
|
int ReadSub_BE_2(unsigned long addr,unsigned char * pBuf,int iNum)
|
|
{
|
|
DWORD dwStatus;
|
|
|
|
memset(&sx,0,sizeof(sx));
|
|
sx.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
sx.SRB_HaId = iCD_AD;
|
|
sx.SRB_Target = iCD_TA;
|
|
sx.SRB_Lun = iCD_LU;
|
|
sx.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
|
sx.SRB_BufLen = 2368*iNum;
|
|
sx.SRB_BufPointer = pBuf;
|
|
sx.SRB_SenseLen = SENSE_LEN;
|
|
sx.SRB_CDBLen = 12;
|
|
sx.SRB_PostProc = (LPVOID)hEvent;
|
|
sx.CDBByte[0] = 0xBE;
|
|
sx.CDBByte[2] = (unsigned char)((addr >> 24) & 0xFF);
|
|
sx.CDBByte[3] = (unsigned char)((addr >> 16) & 0xFF);
|
|
sx.CDBByte[4] = (unsigned char)((addr >> 8) & 0xFF);
|
|
sx.CDBByte[5] = (unsigned char)(addr & 0xFF);
|
|
sx.CDBByte[8] = iNum;
|
|
sx.CDBByte[9] = 0xF8;
|
|
sx.CDBByte[10] = 0x2;
|
|
|
|
ResetEvent(hEvent);
|
|
dwStatus=pSendASPI32Command( (LPSRB)&sx );
|
|
if(dwStatus==SS_PENDING)
|
|
WaitGenEvent(WAITSUB);
|
|
|
|
if(sx.SRB_Status!=SS_COMP)
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////
|
|
|
|
int ReadSub_BE_2_1(unsigned long addr,unsigned char * pBuf,int iNum)
|
|
{
|
|
DWORD dwStatus;
|
|
|
|
memset(&sx,0,sizeof(sx));
|
|
sx.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
sx.SRB_HaId = iCD_AD;
|
|
sx.SRB_Target = iCD_TA;
|
|
sx.SRB_Lun = iCD_LU;
|
|
sx.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
|
sx.SRB_BufLen = 2448*iNum; // special! 96 bytes instead of 16
|
|
sx.SRB_BufPointer = pBuf;
|
|
sx.SRB_SenseLen = SENSE_LEN;
|
|
sx.SRB_CDBLen = 12;
|
|
sx.SRB_PostProc = (LPVOID)hEvent;
|
|
sx.CDBByte[0] = 0xBE;
|
|
sx.CDBByte[2] = (unsigned char)((addr >> 24) & 0xFF);
|
|
sx.CDBByte[3] = (unsigned char)((addr >> 16) & 0xFF);
|
|
sx.CDBByte[4] = (unsigned char)((addr >> 8) & 0xFF);
|
|
sx.CDBByte[5] = (unsigned char)(addr & 0xFF);
|
|
sx.CDBByte[8] = iNum;
|
|
sx.CDBByte[9] = 0xF8;
|
|
sx.CDBByte[10] = 0x1;
|
|
|
|
ResetEvent(hEvent);
|
|
dwStatus=pSendASPI32Command((LPSRB)&sx);
|
|
if(dwStatus==SS_PENDING)
|
|
WaitGenEvent(WAITSUB);
|
|
|
|
if(sx.SRB_Status!=SS_COMP)
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////
|
|
|
|
int ReadSub_D8(unsigned long addr,unsigned char * pBuf,int iNum)
|
|
{
|
|
DWORD dwStatus;
|
|
|
|
memset(&sx,0,sizeof(sx));
|
|
sx.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
sx.SRB_HaId = iCD_AD;
|
|
sx.SRB_Target = iCD_TA;
|
|
sx.SRB_Lun = iCD_LU;
|
|
sx.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
|
sx.SRB_BufLen = 2368*iNum;
|
|
sx.SRB_BufPointer = pBuf;
|
|
sx.SRB_SenseLen = SENSE_LEN;
|
|
sx.SRB_CDBLen = 12;
|
|
sx.SRB_PostProc = (LPVOID)hEvent;
|
|
sx.CDBByte[0] = 0xD8;
|
|
sx.CDBByte[2] = (unsigned char)((addr >> 24) & 0xFF);
|
|
sx.CDBByte[3] = (unsigned char)((addr >> 16) & 0xFF);
|
|
sx.CDBByte[4] = (unsigned char)((addr >> 8) & 0xFF);
|
|
sx.CDBByte[5] = (unsigned char)(addr & 0xFF);
|
|
sx.CDBByte[9] = iNum;
|
|
sx.CDBByte[10] = 1;
|
|
|
|
ResetEvent(hEvent);
|
|
dwStatus=pSendASPI32Command((LPSRB)&sx);
|
|
if(dwStatus==SS_PENDING)
|
|
WaitGenEvent(WAITFOREVER);
|
|
|
|
if(sx.SRB_Status!=SS_COMP)
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////
|
|
// liteon subdata decoding
|
|
|
|
void DecodeSub_BE_2_1(unsigned char * pBuf)
|
|
{
|
|
int i,j;
|
|
unsigned char * pS=pBuf;
|
|
unsigned char c;
|
|
|
|
for(i=0;i<12;i++)
|
|
{
|
|
c=0;
|
|
for(j=7;j>=0;j--,pS++)
|
|
{
|
|
if(*pS & 0x40) c|=(1<<j);
|
|
}
|
|
*(pBuf+i)=c;
|
|
}
|
|
|
|
for(i=12;i<16;i++) *(pBuf+i)=0;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////
|
|
// auto-detection of read mode (without subc), called
|
|
// on plugin startup
|
|
|
|
#define MAXMODES 6
|
|
|
|
DWORD CheckSCSIReadMode(void)
|
|
{
|
|
DWORD dwStatus;int i,j,k,iCnt;char * p;
|
|
int iModes[MAXMODES]={MODE_BE_2,MODE_BE_1,MODE_28_1,MODE_28_2,MODE_28_2048,MODE_28_2048_Ex};
|
|
int iBlock[MAXMODES]={2352, 2352, 2352, 2352, 2048, 2048};
|
|
unsigned char cdb[3000];
|
|
FRAMEBUF * f=(FRAMEBUF *)cdb;
|
|
|
|
for(i=0;i<MAXMODES;i++) // loop avail read modes
|
|
{
|
|
f->dwFrame = 16; // we check on addr 16 (should be available on all ps2 cds/dvds)
|
|
f->dwFrameCnt = 1;
|
|
f->dwBufLen = iBlock[i];
|
|
|
|
pDeInitFunc = NULL;
|
|
iRType=iModes[i]; // set global read mode
|
|
GetGenReadFunc(iRType); // get read func pointer
|
|
|
|
for(j=0;j<3;j++) // try it 3 times
|
|
{
|
|
memset(f->BufData,0xAA,f->dwBufLen); // fill buf with AA
|
|
dwStatus=pReadFunc(TRUE,f); // do the read
|
|
|
|
#ifdef DBGOUT
|
|
auxprintf("status %d\n",dwStatus);
|
|
#endif
|
|
|
|
if(dwStatus!=SS_COMP) continue; // error? try again
|
|
|
|
p=&(f->BufData[0]);
|
|
|
|
#ifdef DBGOUT
|
|
auxprintf("check mode %d\n",i);
|
|
#endif
|
|
|
|
for(k=0,iCnt=0;k<(int)f->dwBufLen;k+=4,p+=4) // now check the returned data
|
|
{
|
|
#ifdef DBGOUT
|
|
// auxprintf("%08x ",*((DWORD *)p));
|
|
#endif
|
|
|
|
if(*((DWORD *)p)==0xAAAAAAAA) // -> still AA? bad
|
|
iCnt++;
|
|
else iCnt=0;
|
|
|
|
if(iCnt>=8) {dwStatus=SS_ERR;break;} // -> if we have found many AA's, the reading was bad
|
|
}
|
|
|
|
if(dwStatus==SS_COMP) // reading was a success, no AA's?
|
|
{
|
|
iRType = iModes[i]; // -> set found mode
|
|
iUsedBlockSize = iBlock[i];
|
|
if(iUsedBlockSize==2352)
|
|
iUsedMode=CDVD_MODE_2352;
|
|
else iUsedMode=CDVD_MODE_2048;
|
|
|
|
#ifdef DBGOUT
|
|
auxprintf("mode found %d\n",i);
|
|
#endif
|
|
|
|
return dwStatus; // -> bye
|
|
}
|
|
}
|
|
if(pDeInitFunc) pDeInitFunc(); // deinit, try next mode
|
|
}
|
|
|
|
return dwStatus;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////
|
|
// dummy read dunc
|
|
|
|
DWORD ReadSCSI_Dummy(BOOL bWait,FRAMEBUF * f)
|
|
{
|
|
return SS_ERR;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////
|