diff --git a/src/dos/cdrom.cpp b/src/dos/cdrom.cpp index b84f1510..a94cfd6f 100644 --- a/src/dos/cdrom.cpp +++ b/src/dos/cdrom.cpp @@ -16,741 +16,172 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// ASPI support for WIN32 CDROM -#ifdef WIN32 +// ****************************************************** +// SDL CDROM +// ****************************************************** -#include -#include +#include "sdl.h" +#include "support.h" #include "cdrom.h" -#include "scsidefs.h" // Aspi stuff -#include "dosbox.h" - -CDROM_Interface_Aspi::CDROM_Interface_Aspi(void) +CDROM_Interface_SDL::CDROM_Interface_SDL(void) { - hASPI = NULL; - hEvent = NULL; - pGetASPI32SupportInfo = NULL; - pSendASPI32Command = NULL; - memset(&oldLeadOut,0,sizeof(oldLeadOut)); + driveID = 0; + oldLeadOut = 0; + cd = 0; }; -CDROM_Interface_Aspi::~CDROM_Interface_Aspi(void) +CDROM_Interface_SDL::~CDROM_Interface_SDL(void) { - // Stop Audio StopAudio(); - - pGetASPI32SupportInfo = NULL; // clear funcs - pSendASPI32Command = NULL; - - if (hASPI) { // free aspi - FreeLibrary(hASPI); - hASPI=NULL; - } + SDL_CDClose(cd); + cd = 0; }; -bool GetRegistryValue(HKEY& hKey,char* valueName, char* buffer, ULONG bufferSize) -// hKey has to be open -{ - // Read subkey - ULONG valType; - ULONG result; - result = RegQueryValueEx(hKey,valueName,NULL,&valType,(unsigned char*)&buffer[0],&bufferSize); - return (result == ERROR_SUCCESS); -}; +bool CDROM_Interface_SDL::SetDevice (char* path, int forceCD) +{ + char buffer[512]; + strcpy(buffer,path); + upcase(buffer); -BYTE CDROM_Interface_Aspi::GetHostAdapter(char* hardwareID) -{ - SRB_HAInquiry sh; - SRB_GDEVBlock sd; - DWORD d = pGetASPI32SupportInfo(); - int cnt = LOBYTE(LOWORD(d)); - int i,j,k,max; - - for(i=0; i4)) { - if (GetDriveType(path)==DRIVE_CDROM) { - // WIN XP/NT/2000 - int iDA,iDT,iDL; - letter = path[0]; - HANDLE hF = OpenIOCTLFile(letter,FALSE); - GetIOCTLAdapter(hF,&iDA,&iDT,&iDL); - CloseHandle(hF); - // Set SCSI IDs - haId = iDA; - target = iDT; - lun = iDL; - return true; - } - } else { - // win 95/98/ME have to scan the registry... - // lets hope the layout is always the same... i dunno... - char key[2048]; - HKEY hKeyBase; - bool found = false; - strcpy(key,"ENUM\\SCSI"); - if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,key,0,KEY_READ,&hKeyBase)==ERROR_SUCCESS) { - found = ScanRegistry(hKeyBase); - }; - RegCloseKey(hKeyBase); - return found; - } - return false; -}; - -bool CDROM_Interface_Aspi::GetAudioTracks(int& stTrack, int& endTrack, TMSF& leadOut) -{ - TOC toc; - if (GetTOC((LPTOC)&toc) == SS_COMP) { - stTrack = toc.cFirstTrack; - endTrack = toc.cLastTrack; - leadOut.min = (unsigned char)(toc.tracks[endTrack].lAddr >> 8) &0xFF; - leadOut.sec = (unsigned char)(toc.tracks[endTrack].lAddr >> 16) &0xFF; - leadOut.fr = (unsigned char)(toc.tracks[endTrack].lAddr >> 24) &0xFF; + int num = SDL_CDNumDrives(); + if ((forceCD>=0) && (forceCD> 8) &0xFF; - start.sec = (unsigned char)(toc.tracks[track-1].lAddr >> 16) &0xFF; - start.fr = (unsigned char)(toc.tracks[track-1].lAddr >> 24) &0xFF; - attr = toc.tracks[track-1].cAdrCtrl; - return true; - }; - return false; -}; - -HANDLE CDROM_Interface_Aspi::OpenIOCTLFile(char cLetter,BOOL bAsync) -{ - HANDLE hF; - char szFName[16]; - OSVERSIONINFO ov; - DWORD dwFlags; - DWORD dwIOCTLAttr; -// if(bAsync) dwIOCTLAttr=FILE_FLAG_OVERLAPPED; -// else - dwIOCTLAttr=0; - - memset(&ov,0,sizeof(OSVERSIONINFO)); - ov.dwOSVersionInfoSize=sizeof(OSVERSIONINFO); - GetVersionEx(&ov); - - if ((ov.dwPlatformId==VER_PLATFORM_WIN32_NT) && (ov.dwMajorVersion>4)) - dwFlags = GENERIC_READ|GENERIC_WRITE; // add gen write on W2k/XP - else - dwFlags = GENERIC_READ; - - wsprintf(szFName, "\\\\.\\%c:",cLetter); - - hF=CreateFile(szFName,dwFlags,FILE_SHARE_READ, // open drive - NULL,OPEN_EXISTING,dwIOCTLAttr,NULL); - - if (hF==INVALID_HANDLE_VALUE) { - dwFlags^=GENERIC_WRITE; // mmm... no success - hF=CreateFile(szFName,dwFlags,FILE_SHARE_READ, // -> open drive again - NULL,OPEN_EXISTING,dwIOCTLAttr,NULL); - if (hF==INVALID_HANDLE_VALUE) return NULL; - } - return hF; -} - -void CDROM_Interface_Aspi::GetIOCTLAdapter(HANDLE hF,int * iDA,int * iDT,int * iDL) -{ - char szBuf[1024]; - PSCSI_ADDRESS pSA; - DWORD dwRet; - - *iDA=*iDT=*iDL=-1; - if(hF==NULL) return; - - memset(szBuf,0,1024); - - pSA=(PSCSI_ADDRESS)szBuf; - pSA->Length=sizeof(SCSI_ADDRESS); - - if(!DeviceIoControl(hF,IOCTL_SCSI_GET_ADDRESS,NULL, - 0,pSA,sizeof(SCSI_ADDRESS), - &dwRet,NULL)) - return; - - *iDA = pSA->PortNumber; - *iDT = pSA->TargetId; - *iDL = pSA->Lun; -} - -DWORD CDROM_Interface_Aspi::GetTOC(LPTOC toc) -{ - SRB_ExecSCSICmd s;DWORD dwStatus; - - hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); - - memset(&s,0,sizeof(s)); - - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaId = haId; - s.SRB_Target = target; - s.SRB_Lun = lun; - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_BufLen = sizeof(*toc); - s.SRB_BufPointer = (BYTE FAR *)toc; - s.SRB_SenseLen = SENSE_LEN; - s.SRB_CDBLen = 0x0A; - s.SRB_PostProc = (LPVOID)hEvent; - s.CDBByte[0] = SCSI_READ_TOC; - s.CDBByte[1] = 0x02; // 0x02 for MSF - s.CDBByte[7] = 0x03; - s.CDBByte[8] = 0x24; - - ResetEvent(hEvent); - dwStatus=pSendASPI32Command((LPSRB)&s); - - if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,30000); - - CloseHandle(hEvent); - - return (s.SRB_Status==SS_COMP); -} - -bool CDROM_Interface_Aspi::PlayAudioSector(unsigned long start,unsigned long len) -{ - SRB_ExecSCSICmd s;DWORD dwStatus; - - hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); - - memset(&s,0,sizeof(s)); - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaId = haId; - s.SRB_Target = target; - s.SRB_Lun = lun; - 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; - - s.CDBByte[0] = SCSI_PLAYAUD_12; - s.CDBByte[1] = lun << 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) WaitForSingleObject(hEvent,10000); - - CloseHandle(hEvent); - - return s.SRB_Status==SS_COMP; -} - -bool CDROM_Interface_Aspi::StopAudio(void) -{ - return PauseAudio(false); -}; - -bool CDROM_Interface_Aspi::PauseAudio(bool resume) -{ - SRB_ExecSCSICmd s;DWORD dwStatus; - - hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); - - memset(&s,0,sizeof(s)); - - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaId = haId; - s.SRB_Target = target; - s.SRB_Lun = lun; - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_BufLen = 0x00; - s.SRB_SenseLen = SENSE_LEN; - s.SRB_CDBLen = 0x0A; - s.SRB_PostProc = (LPVOID)hEvent; - s.CDBByte[0] = 0x4B; - s.CDBByte[8] = (unsigned char)resume; // Pause - - ResetEvent(hEvent); - dwStatus=pSendASPI32Command((LPSRB)&s); - - if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,30000); - - CloseHandle(hEvent); - - return (s.SRB_Status==SS_COMP); -}; - -bool CDROM_Interface_Aspi::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) -{ - SUB_Q_CURRENT_POSITION pos; - SRB_ExecSCSICmd s;DWORD dwStatus; - - hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); - - memset(&s,0,sizeof(s)); - - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaId = haId; - s.SRB_Target = target; - s.SRB_Lun = lun; - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_SenseLen = SENSE_LEN; - - s.SRB_BufLen = sizeof(pos); - s.SRB_BufPointer = (BYTE FAR *)&pos; - s.SRB_CDBLen = 10; - s.SRB_PostProc = (LPVOID)hEvent; - - s.CDBByte[0] = SCSI_SUBCHANNEL; - s.CDBByte[1] = (lun<<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] = sizeof(pos); - - ResetEvent(hEvent); - - dwStatus = pSendASPI32Command((LPSRB)&s); - - if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF); - - CloseHandle(hEvent); - - if (s.SRB_Status!=SS_COMP) return false; - - attr = (pos.ADR<<4) | pos.Control; - track = pos.TrackNumber; - index = pos.IndexNumber; - absPos.min = pos.AbsoluteAddress[1]; - absPos.sec = pos.AbsoluteAddress[2]; - absPos.fr = pos.AbsoluteAddress[3]; - relPos.min = pos.TrackRelativeAddress[1]; - relPos.sec = pos.TrackRelativeAddress[2]; - relPos.fr = pos.TrackRelativeAddress[3]; - - return true; -}; - -bool CDROM_Interface_Aspi::GetUPC(unsigned char& attr, char* upcdata) -{ - SUB_Q_MEDIA_CATALOG_NUMBER upc; - SRB_ExecSCSICmd s;DWORD dwStatus; - - hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); - - memset(&s,0,sizeof(s)); - - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaId = haId; - s.SRB_Target = target; - s.SRB_Lun = lun; - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_SenseLen = SENSE_LEN; - - s.SRB_BufLen = sizeof(upc); - s.SRB_BufPointer = (BYTE FAR *)&upc; - s.SRB_CDBLen = 10; - s.SRB_PostProc = (LPVOID)hEvent; - - s.CDBByte[0] = SCSI_SUBCHANNEL; - s.CDBByte[1] = (lun<<5)|2; // lun & msf - s.CDBByte[2] = 0x40; // subq - s.CDBByte[3] = 0x02; // get upc - s.CDBByte[6] = 0; // track number (only in isrc mode, ignored) - s.CDBByte[7] = 0; // alloc len - s.CDBByte[8] = sizeof(upc); - - ResetEvent(hEvent); - - dwStatus = pSendASPI32Command((LPSRB)&s); - - if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF); - - CloseHandle(hEvent); - - if (s.SRB_Status!=SS_COMP) return false; - -// attr = (upc.ADR<<4) | upc.Control; - attr = 0; - int pos = 0; - // Convert to mscdex format -// for (int i=0; i<6; i++) upcdata[i] = (upc.MediaCatalog[pos++]<<4)+(upc.MediaCatalog[pos++]&0x0F); -// upcdata[6] = (upc.MediaCatalog[pos++]<<4); - for (int i=0; i<7; i++) upcdata[i] = upc.MediaCatalog[i]; - - return true; -}; - -bool CDROM_Interface_Aspi::GetAudioStatus(bool& playing, bool& pause) -{ - playing = pause = false; - - SUB_Q_HEADER sub; - SRB_ExecSCSICmd s;DWORD dwStatus; - - hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); - - memset(&s,0,sizeof(s)); - - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaId = haId; - s.SRB_Target = target; - s.SRB_Lun = lun; - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_SenseLen = SENSE_LEN; - - s.SRB_BufLen = sizeof(sub); - s.SRB_BufPointer = (BYTE FAR *)⊂ - s.SRB_CDBLen = 10; - s.SRB_PostProc = (LPVOID)hEvent; - - s.CDBByte[0] = SCSI_SUBCHANNEL; - s.CDBByte[1] = (lun<<5)|2; // lun & msf - s.CDBByte[2] = 0x00; // no subq - s.CDBByte[3] = 0x00; // dont care - s.CDBByte[6] = 0; // track number (only in isrc mode, ignored) - s.CDBByte[7] = 0; // alloc len - s.CDBByte[8] = sizeof(sub); - - ResetEvent(hEvent); - - dwStatus = pSendASPI32Command((LPSRB)&s); - - if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF); - - CloseHandle(hEvent); - - if (s.SRB_Status!=SS_COMP) return false; - - playing = (sub.AudioStatus==0x11); - pause = (sub.AudioStatus==0x12); - - return true; -}; - -bool CDROM_Interface_Aspi::LoadUnloadMedia(bool unload) -{ - SRB_ExecSCSICmd s;DWORD dwStatus; - - hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); - - memset(&s,0,sizeof(s)); - - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaId = haId; - s.SRB_Target = target; - s.SRB_Lun = lun; - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_SenseLen = SENSE_LEN; - - s.SRB_BufLen = 0; - s.SRB_BufPointer = 0; - s.SRB_CDBLen = 14; - s.SRB_PostProc = (LPVOID)hEvent; - - s.CDBByte[0] = SCSI_LOAD_UN; - s.CDBByte[1] = (lun<<5)|1; // lun & immediate - s.CDBByte[4] = (unload ? 0x02:0x03); // unload/load media - - ResetEvent(hEvent); - - dwStatus = pSendASPI32Command((LPSRB)&s); - - if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF); - - CloseHandle(hEvent); - - if (s.SRB_Status!=SS_COMP) return false; - - return true; -}; - -bool CDROM_Interface_Aspi::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) -{ - // Seems not possible to get this values using ioctl... - int track1,track2; - TMSF leadOut; - // If we can read, there's a media - mediaPresent = GetAudioTracks(track1, track2, leadOut), - trayOpen = !mediaPresent; - mediaChanged = (oldLeadOut.min!=leadOut.min) || (oldLeadOut.sec!=leadOut.sec) || (oldLeadOut.fr!=leadOut.fr); - // Save old values - oldLeadOut.min = leadOut.min; - oldLeadOut.sec = leadOut.sec; - oldLeadOut.fr = leadOut.fr; - // always success - return true; -}; - -bool CDROM_Interface_Aspi::ReadSectors(void* buffer, bool raw, unsigned long sector, unsigned long num) -{ - SRB_ExecSCSICmd s;DWORD dwStatus; - - hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); - - memset(&s,0,sizeof(s)); - - // FIXME : Is there a method to get cooked sectors with aspi ??? - // all combination i tried were failing. - // so we have to allocate extra mem and copy data to buffer if in cooked mode - char* inPtr = (char*)buffer; - if (!raw) inPtr = new char[num*2352]; - if (!inPtr) return false; - - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaId = haId; - s.SRB_Target = target; - s.SRB_Lun = lun; - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_SenseLen = SENSE_LEN; - - s.SRB_BufLen = 2352*num; //num*(raw?2352:2048); - s.SRB_BufPointer = (BYTE FAR*)inPtr; - s.SRB_CDBLen = 12; - s.SRB_PostProc = (LPVOID)hEvent; - - s.CDBByte[0] = 0xBE; - s.CDBByte[2] = (unsigned char)((sector >> 24) & 0xFF); - s.CDBByte[3] = (unsigned char)((sector >> 16) & 0xFF); - s.CDBByte[4] = (unsigned char)((sector >> 8) & 0xFF); - s.CDBByte[5] = (unsigned char)((sector & 0xFF)); - s.CDBByte[6] = (unsigned char)((num >> 16) & 0xFF); - s.CDBByte[7] = (unsigned char)((num >> 8) & 0xFF); - s.CDBByte[8] = (unsigned char) (num & 0xFF); - s.CDBByte[9] = (raw?0xF0:0x10); - - ResetEvent(hEvent); - - dwStatus = pSendASPI32Command((LPSRB)&s); - - if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF); - - CloseHandle(hEvent); - - if (s.SRB_Status!=SS_COMP) { - if (!raw) delete[] inPtr; - return false; - } - - if (!raw) { - // copy user data to buffer - char* source = inPtr; - source+=16; // jump 16 bytes - char* outPtr = (char*)buffer; - for (unsigned long i=0; istatus)) { + stTrack = 1; + end = cd->numtracks; + FRAMES_TO_MSF(cd->track[cd->numtracks].offset,&leadOut.min,&leadOut.sec,&leadOut.fr); + } + return CD_INDRIVE(cd->status); +}; + +bool CDROM_Interface_SDL::GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr) +{ + SDL_CDStatus(cd); + if (CD_INDRIVE(cd->status)) { + FRAMES_TO_MSF(cd->track[track-1].offset+150,&start.min,&start.sec,&start.fr); + attr = cd->track[track-1].type; + } + return CD_INDRIVE(cd->status); +}; + +bool CDROM_Interface_SDL::GetAudioSub (unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) +{ + SDL_CDStatus(cd); + if (CD_INDRIVE(cd->status)) { + track = cd->cur_track; + index = cd->cur_track; + attr = cd->track[track].type; + FRAMES_TO_MSF(cd->cur_frame,&relPos.min,&relPos.sec,&relPos.fr); + FRAMES_TO_MSF(cd->cur_frame+cd->track[track].offset,&absPos.min,&absPos.sec,&absPos.fr); + } + return CD_INDRIVE(cd->status); +}; + +bool CDROM_Interface_SDL::GetAudioStatus (bool& playing, bool& pause) +{ + SDL_CDStatus(cd); + if (CD_INDRIVE(cd->status)) { + playing = (cd->status==CD_PLAYING); + pause = (cd->status==CD_PAUSED); + } + return CD_INDRIVE(cd->status); +}; + +bool CDROM_Interface_SDL::GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen) +{ + SDL_CDStatus(cd); + mediaPresent = (cd->status!=CD_TRAYEMPTY) && (cd->status!=CD_ERROR); + mediaChanged = (oldLeadOut!=cd->track[cd->numtracks].offset); + trayOpen = !mediaPresent; + oldLeadOut = cd->track[cd->numtracks].offset; + if (mediaChanged) SDL_CDStatus(cd); return true; }; -int CDROM_GetMountType(char* path) +bool CDROM_Interface_SDL::PlayAudioSector (unsigned long start,unsigned long len) +{ + // Has to be there, otherwise wrong cd status report (dunno why, sdl bug ?) + SDL_CDClose(cd); + cd = SDL_CDOpen(driveID); + bool success = (SDL_CDPlay(cd,start,len)==0); + return success; +}; + +bool CDROM_Interface_SDL::PauseAudio (bool resume) +{ + bool success; + if (resume) success = (SDL_CDResume(cd)==0); + else success = (SDL_CDPause (cd)==0); + return success; +}; + +bool CDROM_Interface_SDL::StopAudio (void) +{ + // Has to be there, otherwise wrong cd status report (dunno why, sdl bug ?) + SDL_CDClose(cd); + cd = SDL_CDOpen(driveID); + bool success = (SDL_CDStop(cd)==0); + return success; +}; + +bool CDROM_Interface_SDL::LoadUnloadMedia(bool unload) +{ + bool success = (SDL_CDEject(cd)==0); + return success; +}; + +int CDROM_GetMountType(char* path, int forceCD) // 0 - physical CDROM // 1 - Iso file // 2 - subdirectory { // 1. Smells like a real cdrom - if ((strlen(path)<=3) && (path[2]=='\\') && (strchr(path,'\\')==strrchr(path,'\\')) && (GetDriveType(path)==DRIVE_CDROM)) return 0; - // 2. Iso file ? - // FIXME : How to detect them ? - // return 1; - // 3. bah, ordinary directory + // if ((strlen(path)<=3) && (path[2]=='\\') && (strchr(path,'\\')==strrchr(path,'\\')) && (GetDriveType(path)==DRIVE_CDROM)) return 0; + + const char* cdName; + char buffer[512]; + strcpy(buffer,path); +#if defined (WIN32) + upcase(buffer); +#endif + + int num = SDL_CDNumDrives(); + // If cd drive is forced then check if its in range and return 0 + if ((forceCD>=0) && (forceCD +#include "sdl.h" #define RAW_SECTOR_SIZE 2352 #define COOKED_SECTOR_SIZE 2048 +enum { CDROM_USE_SDL, CDROM_USE_ASPI, CDROM_USE_IOCTL }; + typedef struct SMSF { unsigned char min; unsigned char sec; unsigned char fr; } TMSF; -extern int CDROM_GetMountType(char* path); +extern int CDROM_GetMountType(char* path, int force); class CDROM_Interface { @@ -23,7 +26,7 @@ public: // CDROM_Interface (void); virtual ~CDROM_Interface (void) {}; - virtual bool SetDevice (char* path) = 0; + virtual bool SetDevice (char* path, int forceCD) = 0; virtual bool GetUPC (unsigned char& attr, char* upc) = 0; @@ -42,10 +45,38 @@ public: virtual bool LoadUnloadMedia (bool unload) = 0; }; +class CDROM_Interface_SDL : public CDROM_Interface +{ +public: + CDROM_Interface_SDL (void); + ~CDROM_Interface_SDL (void); + + bool SetDevice (char* path, int forceCD); + bool GetUPC (unsigned char& attr, char* upc) { attr = 0; strcpy(upc,"UPC"); return true; }; + bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut); + bool GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr); + bool GetAudioSub (unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos); + bool GetAudioStatus (bool& playing, bool& pause); + bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen); + bool PlayAudioSector (unsigned long start,unsigned long len); + bool PauseAudio (bool resume); + bool StopAudio (void); + bool ReadSectors (void* buffer, bool raw, unsigned long sector, unsigned long num) { return true; }; + bool LoadUnloadMedia (bool unload); + +private: + bool Open (void); + void Close (void); + + SDL_CD* cd; + int driveID; + Uint32 oldLeadOut; +}; + class CDROM_Interface_Fake : public CDROM_Interface { public: - bool SetDevice (char* path) { return true; }; + bool SetDevice (char* path, int forceCD) { return true; }; bool GetUPC (unsigned char& attr, char* upc) { attr = 0; strcpy(upc,"UPC"); return true; }; bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut); bool GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr); @@ -59,7 +90,6 @@ public: bool LoadUnloadMedia (bool unload) { return true; }; }; - #if defined (WIN32) /* Win 32 */ #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers @@ -73,7 +103,7 @@ public: CDROM_Interface_Aspi (void); ~CDROM_Interface_Aspi (void); - bool SetDevice (char* path); + bool SetDevice (char* path, int forceCD); bool GetUPC (unsigned char& attr, char* upc); @@ -120,7 +150,7 @@ public: CDROM_Interface_Ioctl (void); ~CDROM_Interface_Ioctl (void); - bool SetDevice (char* path); + bool SetDevice (char* path, int forceCD); bool GetUPC (unsigned char& attr, char* upc); @@ -148,41 +178,6 @@ private: TMSF oldLeadOut; }; -#else /* Linux */ - -class CDROM_Interface_Linux : public CDROM_Interface -{ -public: - CDROM_Interface_Linux (void); - ~CDROM_Interface_Linux (void); - - bool SetDevice (char* path); - - bool GetUPC (unsigned char& attr, char* upc); - - bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut); - bool GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr); - bool GetAudioSub (unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos); - bool GetAudioStatus (bool& playing, bool& pause); - bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen); - - bool PlayAudioSector (unsigned long start,unsigned long len); - bool PauseAudio (bool resume); - bool StopAudio (void); - - bool ReadSectors (void* buffer, bool raw, unsigned long sector, unsigned long num); - - bool LoadUnloadMedia (bool unload); - -private: - bool Open (void); - void Close (void); - - char pathname[64]; - int dhandle; - TMSF oldLeadOut; -}; - -#endif /* linux */ +#endif /* WIN 32 */ #endif /* __CDROM_INTERFACE__ */ diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index af48208b..e4e13832 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -38,11 +38,13 @@ #define REQUEST_STATUS_DONE 0x0100 #define REQUEST_STATUS_ERROR 0x8000 +// Use cdrom Interface +int useCdromInterface = CDROM_USE_SDL; +int forceCD = -1; + static Bitu MSCDEX_Strategy_Handler(void); static Bitu MSCDEX_Interrupt_Handler(void); -bool gUseASPI = false; - class DOS_DeviceHeader:public MemStruct { public: @@ -218,8 +220,9 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) // Set return type to ok int result = 0; // Get Mounttype and init needed cdrom interface - switch (CDROM_GetMountType(physicalPath)) { - case 0x00 : { // physical drive + switch (CDROM_GetMountType(physicalPath,forceCD)) { + case 0x00 : { + LOG(LOG_MISC,"MSCDEX: Mounting physical cdrom: %s" ,physicalPath); #if defined (WIN32) // Check OS OSVERSIONINFO osi; @@ -227,25 +230,24 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) GetVersionEx(&osi); if ((osi.dwPlatformId==VER_PLATFORM_WIN32_NT) && (osi.dwMajorVersion>4)) { // WIN NT/200/XP - if (gUseASPI) { + if (useCdromInterface==CDROM_USE_ASPI) { cdrom[numDrives] = new CDROM_Interface_Aspi(); LOG(LOG_MISC,"MSCDEX: ASPI Interface."); - } else { + break; + } else if (useCdromInterface==CDROM_USE_IOCTL) { cdrom[numDrives] = new CDROM_Interface_Ioctl(); LOG(LOG_MISC,"MSCDEX: IOCTL Interface."); + break; } } else { // Win 95/98/ME - always use ASPI cdrom[numDrives] = new CDROM_Interface_Aspi(); LOG(LOG_MISC,"MSCDEX: ASPI Interface."); + break; } - #elif __linux__ - cdrom[numDrives] = new CDROM_Interface_Linux(); - #else // No support on this machine... - cdrom[numDrives] = new CDROM_Interface_Fake(); - LOG(LOG_MISC|LOG_ERROR,"MSCDEX: No MSCDEX support on this machine."); #endif - LOG(LOG_MISC,"MSCDEX: Mounting physical cdrom: %s" ,physicalPath); + cdrom[numDrives] = new CDROM_Interface_SDL(); + LOG(LOG_MISC,"MSCDEX: SDL Interface."); } break; case 0x01 : // iso cdrom interface // FIXME: Not yet supported @@ -262,7 +264,7 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit) default : // weird result return 6; }; - if (!cdrom[numDrives]->SetDevice(physicalPath)) return 3; + if (!cdrom[numDrives]->SetDevice(physicalPath,forceCD)) return 3; subUnit = numDrives; // Set drive DOS_DeviceHeader devHeader(PhysMake(rootDriverHeaderSeg,0)); @@ -816,14 +818,10 @@ bool MSCDEX_HasMediaChanged(Bit8u subUnit) return true; }; -void MSCDEX_SetUseASPI(bool use) +void MSCDEX_SetCDInterface(int intNr, int numCD) { - gUseASPI = use; -}; - -bool MSCDEX_GetUseASPI(void) -{ - return gUseASPI; + useCdromInterface = intNr; + forceCD = numCD; }; void MSCDEX_ShutDown(Section* sec)