mirror of https://github.com/PCSX2/pcsx2.git
369 lines
8.9 KiB
C
369 lines
8.9 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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()
|
|
|
|
#ifndef __LINUX__
|
|
#ifdef __linux__
|
|
#define __LINUX__
|
|
#endif /* __linux__ */
|
|
#endif /* No __LINUX__ */
|
|
|
|
#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"
|
|
|
|
#include "../version.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()
|