pcsx2/plugins/CDVDlinuz/Src/Linux/CDVDlinuz.c

361 lines
8.8 KiB
C

/* CDVDlinuz.c
* Copyright (C) 2002-2005 CDVDlinuz Team
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <errno.h> // errno
#include <fcntl.h> // open()
#include <stddef.h> // NULL
#include <stdio.h> // printf()
#include <stdlib.h> // getenv(), system()
#include <string.h> // strerror(), sprintf()
#include <sys/ioctl.h> // ioctl()
#include <sys/stat.h> // stat()
#include <sys/types.h> // stat()
#include <time.h> // time_t, time(), struct timeval
#include <unistd.h> // stat()
#define CDVDdefs
#include "PS2Edefs.h"
// #include "PS2Etypes.h"
#include "CDVDlinuz.h"
#include "buffer.h"
#include "conf.h"
#include "logfile.h"
#include "CD.h" // InitCDInfo()
#include "DVD.h" // InitDVDInfo()
#include "device.h"
// Globals
time_t lasttime;
// Interface Functions
u32 CALLBACK PS2EgetLibType() {
return(PS2E_LT_CDVD); // Library Type CDVD
} // END PS2EgetLibType()
u32 CALLBACK PS2EgetLibVersion2(u32 type) {
return((version<<16)|(revision<<8)|build);
} // END PS2EgetLibVersion2()
char* CALLBACK PS2EgetLibName() {
return(libname);
} // END PS2EgetLibName()
s32 CALLBACK CDVDinit() {
errno = 0;
InitLog();
if(OpenLog() != 0) return(-1);
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDinit()");
#endif /* VERBOSE_FUNCTION */
InitConf();
devicehandle = -1;
devicecapability = 0;
lasttime = time(NULL);
// Initialize DVD.c and CD.c as well
InitDisc();
InitDVDInfo();
InitCDInfo();
return(0);
} // END CDVDinit()
void CALLBACK CDVDshutdown() {
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDshutdown()");
#endif /* VERBOSE_FUNCTION */
DeviceClose();
CloseLog();
} // END CDVDshutdown()
s32 CALLBACK CDVDopen(const char* pTitleFilename) {
s32 s32result;
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDopen()");
#endif /* VERBOSE_FUNCTION */
InitBuffer();
LoadConf();
errno = 0;
s32result = DeviceOpen();
if(s32result != 0) return(s32result);
if(errno != 0) return(-1);
return(0);
} // END CDVDopen();
void CALLBACK CDVDclose() {
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDclose()");
#endif /* VERBOSE_FUNCTION */
DeviceClose();
} // END CDVDclose()
s32 CALLBACK CDVDreadTrack(u32 lsn, int mode) {
s32 s32result;
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDreadTrack(%i)", lsn);
#endif /* VERBOSE_FUNCTION */
s32result = 0;
errno = 0;
if(DiscInserted() == -1) return(-1);
if(userbuffer < BUFFERMAX) {
if((bufferlist[userbuffer].lsn == lsn) &&
(bufferlist[userbuffer].mode == mode)) {
return(0);
} // ENDIF- And it's the right one?
} // ENDIF- Are we already pointing at the buffer?
userbuffer = FindListBuffer(lsn);
if(userbuffer < BUFFERMAX) {
if((bufferlist[userbuffer].lsn == lsn) &&
(bufferlist[userbuffer].mode == mode)) {
return(0);
} // ENDIF- And it was the right one?
} // ENDIF- Was a buffer found in the cache?
replacebuffer++;
if(replacebuffer >= BUFFERMAX) replacebuffer = 0;
userbuffer = replacebuffer;
if(bufferlist[replacebuffer].upsort != 0xffff) {
RemoveListBuffer(replacebuffer);
} // ENDIF- Reference already in place? Remove it.
s32result = DeviceReadTrack(lsn, mode, bufferlist[replacebuffer].buffer);
bufferlist[replacebuffer].lsn = lsn;
bufferlist[replacebuffer].mode = mode;
bufferlist[replacebuffer].offset = DeviceBufferOffset();
if((s32result != 0) || (errno != 0)) {
bufferlist[replacebuffer].mode = -1; // Error! flag buffer as such.
} else {
if((disctype != CDVD_TYPE_PS2DVD) && (disctype != CDVD_TYPE_DVDV)) {
if(mode == CDVD_MODE_2352) {
CDreadSubQ(lsn, &bufferlist[replacebuffer].subq);
errno = 0;
} // ENDIF- Read subq as well?
} // ENDIF- Read a DVD buffer or a CD buffer?
} // ENDIF-Read ok? Fill out rest of buffer info.
AddListBuffer(replacebuffer);
return(s32result);
} // END CDVDreadTrack()
u8* CALLBACK CDVDgetBuffer() {
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDgetBuffer()");
#endif /* VERBOSE_FUNCTION */
if(DiscInserted() == -1) return(NULL);
if(userbuffer == 0xffff) {
#ifdef VERBOSE_WARNINGS
PrintLog("CDVD interface: Not pointing to a buffer!");
#endif /* VERBOSE_WARNINGS */
return(NULL); // No buffer reference?
} // ENDIF- user buffer not pointing at anything? Abort
if(bufferlist[userbuffer].mode < 0) {
#ifdef VERBOSE_WARNINGS
PrintLog("CDVD interface: Error in buffer!");
#endif /* VERBOSE_WARNINGS */
return(NULL); // Bad Sector?
} // ENDIF- Trouble reading physical sector? Tell them.
return(bufferlist[userbuffer].buffer + bufferlist[userbuffer].offset);
} // END CDVDgetBuffer()
// Note: without the lsn, I could pull the SubQ data directly from
// the stored buffer (in buffer.h). Oh, well.
s32 CALLBACK CDVDreadSubQ(u32 lsn, cdvdSubQ *subq) {
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDreadSubQ(%i)", lsn);
#endif /* VERBOSE_FUNCTION */
if(DiscInserted() == -1) return(-1);
// DVDs don't have SubQ data
if(disctype == CDVD_TYPE_PS2DVD) return(-1);
if(disctype == CDVD_TYPE_DVDV) return(-1);
return(CDreadSubQ(lsn, subq));
} // END CDVDreadSubQ()
s32 CALLBACK CDVDgetTN(cdvdTN *cdvdtn) {
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDgetTN()");
#endif /* VERBOSE_FUNCTION */
if(DiscInserted() == -1) return(-1);
if((disctype == CDVD_TYPE_PS2DVD) || (disctype == CDVD_TYPE_DVDV)) {
return(DVDgetTN(cdvdtn));
} else {
return(CDgetTN(cdvdtn));
} // ENDIF- Are we looking at a DVD?
} // END CDVDgetTN()
s32 CALLBACK CDVDgetTD(u8 newtrack, cdvdTD *cdvdtd) {
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDgetTD()");
#endif /* VERBOSE_FUNCTION */
if(DiscInserted() == -1) return(-1);
if((disctype == CDVD_TYPE_PS2DVD) || (disctype == CDVD_TYPE_DVDV)) {
return(DVDgetTD(newtrack, cdvdtd));
} else {
return(CDgetTD(newtrack, cdvdtd));
} // ENDIF- Are we looking at a DVD?
} // END CDVDgetTD()
s32 CALLBACK CDVDgetTOC(void *toc) {
// A structure to fill in, or at least some documentation on what
// the PS2 expects from this call would be more helpful than a
// "void *".
union {
void *voidptr;
u8 *u8ptr;
} tocptr;
s32 i;
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDgetTOC()");
#endif /* VERBOSE_FUNCTION */
if(toc == NULL) return(-1);
if(DiscInserted() == -1) return(-1);
tocptr.voidptr = toc;
for(i = 0; i < 1024; i++) *(tocptr.u8ptr + i) = tocbuffer[i];
tocptr.voidptr = NULL;
return(0);
} // END CDVDgetTOC()
s32 CALLBACK CDVDgetDiskType() {
#ifdef VERBOSE_FUNCTION
// Called way too often in boot part of bios to be left in.
// PrintLog("CDVD interface: CDVDgetDiskType()");
#endif /* VERBOSE_FUNCTION */
if(lasttime != time(NULL)) {
lasttime = time(NULL);
DeviceTrayStatus();
} // ENDIF- Has enough time passed between calls?
return(disctype);
} // END CDVDgetDiskType()
s32 CALLBACK CDVDgetTrayStatus() {
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDgetTrayStatus()");
#endif /* VERBOSE_FUNCTION */
if(lasttime != time(NULL)) {
lasttime = time(NULL);
DeviceTrayStatus();
} // ENDIF- Has enough time passed between calls?
return(traystatus);
} // END CDVDgetTrayStatus()
s32 CALLBACK CDVDctrlTrayOpen() {
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDctrlTrayOpen()");
#endif /* VERBOSE_FUNCTION */
return(DeviceTrayOpen());
} // END CDVDctrlTrayOpen()
s32 CALLBACK CDVDctrlTrayClose() {
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD interface: CDVDctrlTrayClose()");
#endif /* VERBOSE_FUNCTION */
return(DeviceTrayClose());
} // END CDVDctrlTrayClose()
void CALLBACK CDVDconfigure() {
ExecCfg("configure");
} // END CDVDconfigure()
void CALLBACK CDVDabout() {
ExecCfg("about");
} // END CDVDabout()
s32 CALLBACK CDVDtest() {
s32 s32result;
errno = 0;
if(devicehandle != -1) {
#ifdef VERBOSE_WARNINGS
PrintLog("CDVD interface: Device already open");
#endif /* VERBOSE_WARNINGS */
return(0);
} // ENDIF- Is the CD/DVD already in use? That's fine.
#ifdef VERBOSE_FUNCTION
PrintLog("CDVD driver: CDVDtest()");
#endif /* VERBOSE_FUNCTION */
s32result = DeviceOpen();
DeviceClose();
return(s32result);
} // END CDVDtest()