diff options
Diffstat (limited to 'backends/platform/ps2/iop')
-rw-r--r-- | backends/platform/ps2/iop/CoDyVDfs/Makefile | 30 | ||||
-rw-r--r-- | backends/platform/ps2/iop/CoDyVDfs/common/codyvdirx.h | 38 | ||||
-rw-r--r-- | backends/platform/ps2/iop/CoDyVDfs/iop/cdtypes.h | 134 | ||||
-rw-r--r-- | backends/platform/ps2/iop/CoDyVDfs/iop/codyvdfs.c | 347 | ||||
-rw-r--r-- | backends/platform/ps2/iop/CoDyVDfs/iop/codyvdfs.h | 84 | ||||
-rw-r--r-- | backends/platform/ps2/iop/CoDyVDfs/iop/fiofs.c | 262 | ||||
-rw-r--r-- | backends/platform/ps2/iop/CoDyVDfs/iop/fiofs.h | 37 | ||||
-rw-r--r-- | backends/platform/ps2/iop/CoDyVDfs/iop/imports.lst | 65 | ||||
-rw-r--r-- | backends/platform/ps2/iop/CoDyVDfs/iop/irx_imports.h | 30 | ||||
-rw-r--r-- | backends/platform/ps2/iop/CoDyVDfs/iop/rpcfs.c | 115 |
10 files changed, 1142 insertions, 0 deletions
diff --git a/backends/platform/ps2/iop/CoDyVDfs/Makefile b/backends/platform/ps2/iop/CoDyVDfs/Makefile new file mode 100644 index 0000000000..4493e77154 --- /dev/null +++ b/backends/platform/ps2/iop/CoDyVDfs/Makefile @@ -0,0 +1,30 @@ +# _____ ___ ____ ___ ____ +# ____| | ____| | | |____| +# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. +#----------------------------------------------------------------------- +# Copyright 2001-2004, ps2dev - http://www.ps2dev.org +# Licenced under Academic Free License version 2.0 +# Review ps2sdk README & LICENSE files for further details. +# +# $Id$ + + +IOP_OBJS_DIR = obj/ +IOP_BIN_DIR = bin/ +IOP_SRC_DIR = iop/ +IOP_INC_DIR = include/ + +IOP_BIN = iop/CoDyVDfs.irx +IOP_OBJS = obj/codyvdfs.o obj/fiofs.o obj/rpcfs.o obj/imports.o + +IOP_CFLAGS += -Wall -fno-builtin +IOP_LDFLAGS += -s + +all: $(IOP_OBJS_DIR) $(IOP_BIN_DIR) $(IOP_BIN) + +clean: + rm -f -r $(IOP_OBJS_DIR) $(IOP_BIN_DIR) + +include $(PS2SDKSRC)/Defs.make +include $(PS2SDKSRC)/iop/Rules.make +include $(PS2SDKSRC)/iop/Rules.release diff --git a/backends/platform/ps2/iop/CoDyVDfs/common/codyvdirx.h b/backends/platform/ps2/iop/CoDyVDfs/common/codyvdirx.h new file mode 100644 index 0000000000..6b81d000ae --- /dev/null +++ b/backends/platform/ps2/iop/CoDyVDfs/common/codyvdirx.h @@ -0,0 +1,38 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2005-2006 The ScummVM project + * + * 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. + * + * $URL$ + * $Id$ + * + */ + +#ifndef CDVDFS_COMMON_H +#define CDVDFS_COMMON_H + +#define CDVDFS_IRX_ID 0xD004352 + +// commands: +#define READ_RTC 0 +#define SET_READ_SPEED 1 +#define DRIVE_STOP 2 +#define DRIVE_STANDBY 3 + +#define CdTrayOpen 0 +#define CdTrayClose 1 +#define CdTrayCheck 2 + +#endif // CDVDFS_COMMON_H diff --git a/backends/platform/ps2/iop/CoDyVDfs/iop/cdtypes.h b/backends/platform/ps2/iop/CoDyVDfs/iop/cdtypes.h new file mode 100644 index 0000000000..9f7a9762be --- /dev/null +++ b/backends/platform/ps2/iop/CoDyVDfs/iop/cdtypes.h @@ -0,0 +1,134 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2005-2006 The ScummVM project + * + * 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. + * + * $URL$ + * $Id$ + * + */ + +#ifndef __CDTYPES_H__ +#define __CDTYPES_H__ + +typedef unsigned int uint32; +typedef unsigned short uint16; +typedef unsigned char uint8; +typedef signed int int32; +typedef signed short int16; +typedef signed char int8; + +typedef struct { + uint8 len_di; + uint8 attributeLength; + uint8 lba[4]; + uint16 parent; + char name[256]; // arbitrary number +} ISOPathTableRecord __attribute__ ((packed)); + +typedef struct { + uint8 year; // Number of years since 1900 + uint8 month; // Month of the year from 1 to 12 + uint8 day; // Day of the Month from 1 to 31 + uint8 hour; // Hour of the day from 0 to 23 + uint8 min; // Minute of the hour from 0 to 59 + uint8 sec; // second of the minute from 0 to 59 + uint8 gmtOff; // Offset from Greenwich Mean Time in number of 15 minute intervals from -48(West) to +52(East) + uint8 padding[10]; +} ISOTime __attribute__ ((packed)); + +typedef struct { + uint8 year; // Number of years since 1900 + uint8 month; // Month of the year from 1 to 12 + uint8 day; // Day of the Month from 1 to 31 + uint8 hour; // Hour of the day from 0 to 23 + uint8 min; // Minute of the hour from 0 to 59 + uint8 sec; // second of the minute from 0 to 59 + uint8 gmtOff; // Offset from Greenwich Mean Time in number of 15 minute intervals from -48(West) to +52(East) + //uint8 padding[10]; +} ISOFileTime __attribute__ ((packed)); + +typedef struct { + uint8 len_dr; + uint8 attributeLength; + uint8 lba[4]; + uint8 lba_BE[4]; + uint8 size[4]; + uint8 size_BE[4]; + ISOFileTime time; + uint8 flags; + uint8 fieldSize; + uint8 gapSize; + uint8 sequenceNumber[4]; + uint8 len_fi; + char name[256]; // arbitrary number +} ISODirectoryRecord __attribute__ ((packed)); + +typedef struct { + char volumeSetId[128]; + char publisherId[128]; + char preparerId[128]; + char applicationId[128]; + char copyrightId[37]; + char abstractId[37]; + char bibliographicId[37]; +} ISOIds __attribute__ ((packed)); + +typedef struct { + uint16 length; + uint32 tocLBA; + uint32 tocLBA_bigend; + uint32 tocSize; + uint32 tocSize_bigend; + uint8 dateStamp[8]; + uint8 reserved[6]; + uint8 reserved2; + uint8 reserved3; +} ISORoot __attribute__((packed)); // 0x22 + +typedef struct { + uint8 type; // 0x00 + char identifier[5]; // 0x01 + uint8 version; // 0x06 + uint8 reserved1; // 0x07 + char systemIdentifier[32]; // 0x08 + char volumeIdentifier[32]; // 0x28 + uint8 reserved2[8]; // 0x48 + uint32 volumeSpaceSize; // 0x50 + uint32 volumeSpaceSizeBE; // 0x54 + char reserved3[32]; // 0x58 + uint32 volumeSetSize; // 0x78 + uint32 volumeSequenceNumber; // 0x7C + uint32 logicalBlockSize; // 0x80 + uint32 pathTableSize; // 0x84 + uint32 pathTableSizeBE; // 0x88 + uint32 pathTablePos; // 0x8C + uint32 pathTable2Pos; // 0x90 + uint32 pathTablePosBE; // 0x94 + uint32 pathTable2PosBE; // 0x98 + ISORoot rootDir; // 0x9C + ISOIds ids; // 0xBE + ISOTime creation; // 0x32D + ISOTime modification; // 0x33E + ISOTime expiration; // 0x34F + ISOTime effective; // 0x360 + uint8 fileStructureVersion; // 0x371 + uint8 reserved4; // 0x372 + uint8 applicationUse[512]; // 0x373 + uint8 reserved5[653]; // 0x573 +} ISOPvd __attribute__ ((packed)); // 0x800 + +#endif // __CDTYPES_H__ + diff --git a/backends/platform/ps2/iop/CoDyVDfs/iop/codyvdfs.c b/backends/platform/ps2/iop/CoDyVDfs/iop/codyvdfs.c new file mode 100644 index 0000000000..627054e6fd --- /dev/null +++ b/backends/platform/ps2/iop/CoDyVDfs/iop/codyvdfs.c @@ -0,0 +1,347 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2005-2006 The ScummVM project + * + * 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. + * + * $URL$ + * $Id$ + * + */ + +#include <types.h> +#include <defs.h> +#include <irx.h> +#include <sys/stat.h> + +#include <stdio.h> +#include <sysclib.h> +#include <sysmem.h> +#include <thbase.h> +#include <iomanX.h> + +#include <io_common.h> +#include <errno.h> + +#include "fiofs.h" +#include "codyvdfs.h" +#include "../common/codyvdirx.h" + +#define DBG_PRINTF printf + +char cachedDir[256]; +int cachedDirLba, cachedDirOfs, cachedDirSize; +static uint8 cacheBuf[2340]; + +int mediaType, fsRootLba, fsRootSize; + +int verifyDriveReady(void) { + int res; + u32 trayStat; + res = CdTrayReq(CdTrayCheck, &trayStat); + if ((mediaType == DISC_UNKNOWN) || (res == 0) || (trayStat == 1)) { + // media was exchanged + if (checkDiscReady(100) == 0) // wait up to 1 second + return initDisc(); + else { + mediaType = DISC_UNKNOWN; + return -1; // drive still not ready + } + } + if (mediaType == DISC_NONE) + return -1; + return 0; +} + +int cacheEnterDir(ISODirectoryRecord *dir) { + CdRMode rmode = { 16, 0, CdSect2048, 0 }; + char *cacheName; + cachedDirLba = READ_ARRAY32(dir->lba); + cachedDirSize = READ_ARRAY32(dir->size); + cachedDirOfs = 0; + cacheName = cachedDir + strlen(cachedDir); + memcpy(cacheName, dir->name, dir->len_fi); + cacheName[dir->len_fi] = '/'; + cacheName[dir->len_fi + 1] = '\0'; + return cdReadSectors(cachedDirLba, 1, cacheBuf, &rmode); +} + +int initRootCache(void) { + CdRMode rmode = { 16, 0, CdSect2048, 0 }; + ISODirectoryRecord *root = (ISODirectoryRecord*)cacheBuf; + + if (cdReadSectors(fsRootLba, 1, cacheBuf, &rmode) == 0) { + cachedDir[0] = '\0'; + fsRootSize = READ_ARRAY32(root->size); + cachedDirLba = fsRootLba; + cachedDirOfs = 0; + cachedDirSize = fsRootSize; + if (READ_ARRAY32(root->lba) == fsRootLba) + return 0; + } + DBG_PRINTF("Can't read root directory table in sector %d\n", fsRootLba); + mediaType = DISC_NONE; + return -1; +} + +ISODirectoryRecord *findEntryInCache(const char *name, int nameLen) { + int i; + CdRMode rmode = { 16, 0, CdSect2048, 0 }; + ISODirectoryRecord *entry; + for (i = 0; i < NUM_SECTORS(cachedDirSize); i++) { + entry = (ISODirectoryRecord *)cacheBuf; + if (i != cachedDirOfs) { + if (cdReadSectors(cachedDirLba + i, 1, cacheBuf, &rmode) < 0) + return NULL; + cachedDirOfs = i; + } + + while (entry->len_dr && ((uint8*)entry < cacheBuf + SECTOR_SIZE)) { + if ((entry->len_fi > 2) && (entry->name[entry->len_fi - 2] == ';') && (entry->name[entry->len_fi - 1] == '1')) { + if ((nameLen == entry->len_fi - 2) && (strnicmp(name, entry->name, entry->len_fi - 2) == 0)) + return entry; + } else { + if ((nameLen == entry->len_fi) && (strnicmp(name, entry->name, entry->len_fi) == 0)) + return entry; + } + entry = (ISODirectoryRecord *)( (uint8*)entry + entry->len_dr ); + } + } + return NULL; +} + +ISODirectoryRecord *findPath(const char *path) { + ISODirectoryRecord *pathPos; + const char *tok; + + if (path[0] == '/') + path++; + + if (strnicmp(cachedDir, path, strlen(cachedDir)) == 0) + path += strlen(cachedDir); // requested path is somewhere in our cache + else + initRootCache(); // not cached, we start again at the cd root + + if (path[0] == '/') + path++; + + if (!path[0]) { // open root dir + if (cachedDirOfs) + initRootCache(); + return (ISODirectoryRecord *)cacheBuf; + } + + do { + tok = strchr(path, '/'); + if (tok) + pathPos = findEntryInCache(path, tok - path); + else + pathPos = findEntryInCache(path, strlen(path)); + + if (pathPos && tok && tok[1] && IS_DIR(pathPos)) + if (cacheEnterDir(pathPos) < 0) + return NULL; + + path = tok + 1; + } while (pathPos && tok && tok[1]); + return pathPos; +} + +int checkDiscReady(int retries) { + if (retries == -1) { + if (CdDiskReady(0) == 2) // block until drive ready, should always return 2 + return 0; + } else { + do { + if (CdDiskReady(1) == 2) + return 0; + DelayThread(10 * 1000); + } while (--retries >= 0); + } + return -1; +} + + +int initDisc(void) { + int type, sector, discType; + ISOPvd *pvd; + CdRMode rmode = { 16, 0, CdSect2048, 0 }; + ISOPathTableRecord *rootRec; + + if (checkDiscReady(0) < 0) { + printf("disc not ready\n"); + mediaType = DISC_UNKNOWN; // retry later + return -1; + } + + do { // wait until drive detected disc type + type = CdGetDiskType(); + if (DISC_NOT_READY(type)) + DelayThread(10 * 1000); + } while (DISC_NOT_READY(type)); + + if (type == CdDiskIllegal) { + printf("Illegal disc type\n"); + mediaType = DISC_NONE; + return -1; + } + if (type == CdDiskNone) { + printf("Tray empty\n"); + mediaType = DISC_NONE; + return -1; + } + + discType = DISC_DVD; + switch (type) { + case CdDiskCDPS1: + case CdDiskCDDAPS1: + case CdDiskCDPS2: + case CdDiskCDDAPS2: + case CdDiskCDDA: + discType = DISC_MODE2; + rmode.datapattern = CdSect2340; + default: + break; + } + + for (sector = 16; sector < 32; sector++) { + printf("sec %d\n", sector); + if (cdReadSectors(sector, 1, cacheBuf, &rmode) == 0) { + if (discType == DISC_DVD) + pvd = (ISOPvd *)cacheBuf; + else { + switch (cacheBuf[3]) { + case 1: + discType = DISC_MODE1; + printf("Disc: Mode1\n"); + pvd = (ISOPvd*)(cacheBuf + 4); + break; + case 2: + discType = DISC_MODE2; + printf("Disc: Mode2\n"); + pvd = (ISOPvd*)(cacheBuf + 12); + break; + default: + DBG_PRINTF("Unknown Sector Type %02X\n", cacheBuf[3]); + return -1; + } + } + rmode.datapattern = CdSect2048; + if ((pvd->type == 1) && (memcmp(pvd->identifier, "CD001", 5) == 0)) { // found ISO9660 PVD + DBG_PRINTF("Found ISO9660 PVD in sector %d\n", sector); + + DBG_PRINTF("reading path table from sector %d\n", pvd->pathTablePos); + if (cdReadSectors(pvd->pathTablePos, 1, cacheBuf, &rmode) < 0) { + DBG_PRINTF("Can't read path table\n"); + return -1; + } + + rootRec = (ISOPathTableRecord *)cacheBuf; + if ((rootRec->len_di != 1) || (rootRec->name[0] != 0)) { + DBG_PRINTF("Root entry missing: %02X - %02X\n", rootRec->len_di, rootRec->name[0]); + return -1; + } + + fsRootLba = READ_ARRAY32(rootRec->lba); // this points to the root record + + mediaType = discType; + DBG_PRINTF("Root directory in sector %d\n", fsRootLba); + return initRootCache(); + } + } + } + mediaType = DISC_NONE; + // PVD not found + return -1; +} + +int cdReadSectors(int lba, int num, void *dest, CdRMode *rmode) { + int err; + if (CdRead(lba, num, dest, rmode) == 1) { + CdSync(0); + err = CdGetError(); + return (err > 0) ? -err : err; + } + return -0xFF; +} + +int cd_dummy(void) { + printf("cd_dummy called!\n"); + return -1; +} + +int cd_init(iop_device_t *dev) { + printf("FS init\n"); + memset(cachedDir, 0, 256); + cachedDirLba = cachedDirOfs = 0; + mediaType = DISC_UNKNOWN; + return 0; +} + +iop_device_ops_t FS_ops = { + (void *) cd_init, + (void *) cd_dummy, + (void *) cd_dummy, + (void *) cd_open, + (void *) cd_close, + (void *) cd_read, + (void *) cd_dummy, + (void *) cd_lseek, + (void *) cd_dummy, + (void *) cd_dummy, + (void *) cd_dummy, + (void *) cd_dummy, + (void *) cd_dopen, + (void *) cd_dclose, + (void *) cd_dread, + (void *) cd_dummy, + (void *) cd_dummy, +}; + +#define FS_NAME "cdfs" +#define FS_DESC "CD-ROM" + +iop_device_t fsdriver = { + FS_NAME, + IOP_DT_FS | IOP_DT_FSEXT, + 1, + FS_DESC, + &FS_ops +}; + +int _start(void) { + printf("CoDyVDfs v0.01\n"); + + CdInit(1); + DelDrv(FS_NAME); + AddDrv(&fsdriver); + + initRpc(); + initFio(); + return(0); +} + +int strnicmp(const char *s1, const char *s2, int n) { + if (n) { + do { + if (tolower(*s1) != tolower(*s2)) + return tolower(*s1) - tolower(*s2); + if (*s1++ == '\0') + break; + s2++; + } while (--n); + } + return 0; +} + diff --git a/backends/platform/ps2/iop/CoDyVDfs/iop/codyvdfs.h b/backends/platform/ps2/iop/CoDyVDfs/iop/codyvdfs.h new file mode 100644 index 0000000000..5e6295993c --- /dev/null +++ b/backends/platform/ps2/iop/CoDyVDfs/iop/codyvdfs.h @@ -0,0 +1,84 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2005-2006 The ScummVM project + * + * 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. + * + * $URL$ + * $Id$ + * + */ + +#ifndef __CoDyVDfs_H__ +#define __CoDyVDfs_H__ + +#include <cdvdman.h> +#include "cdtypes.h" + +typedef cd_read_mode_t CdRMode; + +// for reading misaligned ints +#define READ_ARRAY32(a) \ + (a[0] | (a[1] << 8) | (a[2] << 16) | (a[3] << 24)) + +#define SECTOR_SIZE 0x800 +#define SECTOR_MASK 0x7FF +#define NUM_SECTORS(a) ((a + 2047) >> 11) + +#define IS_DIR(a) ((a)->flags & 2) + +#define DISC_UNKNOWN 0xFE +#define DISC_NONE 0xFF +#define DISC_DVD 0 +#define DISC_MODE1 1 +#define DISC_MODE2 2 + +enum ReadModes { + CdSect2048 = 0, + CdSect2328, // 1 + CdSect2340 // 2 +}; + +enum { + CdDiskNone = 0x00, + CdDiskDetect, // 0x01 + CdDiskDetectCD, // 0x02 + CdDiskDetectDVD, // 0x03 + CdDiskDetectUnk = 0x05, + CdDiskCDPS1 = 0x10, + CdDiskCDDAPS1 = 0x11, + CdDiskCDPS2 = 0x12, + CdDiskCDDAPS2 = 0x13, + CdDiskDVDPS2 = 0x14, + CdDiskDVDV2 = 0xFC, + CdDiskCDDA = 0xFD, + CdDiskDVDV = 0xFE, + CdDiskIllegal = 0xFF +}; + +#define DISC_NOT_READY(type) ((type > CdDiskNone) && (type < CdDiskCDPS1) && (type != CdDiskDetectUnk)) + +int initRpc(void); + +int verifyDriveReady(void); +int cdReadSectors(int lba, int num, void *dest, CdRMode *rmode); +int initRootCache(void); +ISODirectoryRecord *findPath(const char *path); +int cacheEnterDir(ISODirectoryRecord *dir); +int initDisc(void); +int checkDiscReady(int retries); +int strnicmp(const char *s1, const char *s2, int n); + +#endif // __MYCDVDFS_H__ + diff --git a/backends/platform/ps2/iop/CoDyVDfs/iop/fiofs.c b/backends/platform/ps2/iop/CoDyVDfs/iop/fiofs.c new file mode 100644 index 0000000000..701ece1525 --- /dev/null +++ b/backends/platform/ps2/iop/CoDyVDfs/iop/fiofs.c @@ -0,0 +1,262 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2005-2006 The ScummVM project + * + * 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. + * + * $URL$ + * $Id$ + * + */ + +#include "cdtypes.h" +#include "codyvdfs.h" +#include <iomanX.h> +#include <io_common.h> +#include <errno.h> +#include <sysmem.h> +#include <sysclib.h> +#include <sys/stat.h> + +#define MAX_DIO_HANDLES 8 +#define MAX_FIO_HANDLES 32 + +typedef struct { + int lba, size, lbaOfs; + uint32 curOfs; + uint8 *buf; +} DioHandle; + +typedef struct { + int lba, size; + int pos; + uint8 *buf; + int cachedLba; +} FioHandle; + +static DioHandle dioHandles[MAX_DIO_HANDLES]; +static FioHandle fioHandles[MAX_FIO_HANDLES]; + +int initFio(void) { + int i; + + for (i = 0; i < MAX_DIO_HANDLES; i++) + dioHandles[i].lba = 0; + for (i = 0; i < MAX_FIO_HANDLES; i++) + fioHandles[i].lba = 0; + return 0; +} + +int allocDioHandle(void) { + int i; + for (i = 0; i < MAX_DIO_HANDLES; i++) + if (!dioHandles[i].lba) + return i; + return -1; +} + +int allocFioHandle(void) { + int i; + for (i = 0; i < MAX_FIO_HANDLES; i++) + if (!fioHandles[i].lba) + return i; + return -1; +} + +int cd_open(iop_file_t *handle, const char *name, int mode) { + int fdSlot; + FioHandle *fd; + ISODirectoryRecord *rec; + + if (verifyDriveReady() < 0) + return -EIO; + + rec = findPath(name); + if (!rec || IS_DIR(rec)) + return -ENOENT; + + fdSlot = allocFioHandle(); + if (fdSlot < 0) + return -ENFILE; + + fd = fioHandles + fdSlot; + + fd->buf = AllocSysMemory(ALLOC_FIRST, 0x800, NULL); + if (!fd->buf) + return -ENOMEM; + + fd->lba = READ_ARRAY32(rec->lba); + fd->size = READ_ARRAY32(rec->size); + fd->pos = 0; + fd->cachedLba = 0; + + handle->privdata = (void*)fdSlot; + return 0; +} + +int cd_lseek(iop_file_t *handle, int ofs, int whence) { + FioHandle *fd = fioHandles + (int)handle->privdata; + int newOfs; + switch(whence) { + case SEEK_SET: + newOfs = ofs; + break; + case SEEK_CUR: + newOfs = fd->pos + ofs; + break; + case SEEK_END: + newOfs = fd->size + ofs; + break; + default: + newOfs = -1; + } + if ((newOfs >= 0) && (newOfs <= fd->size)) { + fd->pos = newOfs; + return newOfs; + } else + return -1; +} + +int cd_read(iop_file_t *handle, void *dest, int length) { + FioHandle *fd = fioHandles + (int)handle->privdata; + CdRMode rmode = { 16, 0, CdSect2048, 0 }; + int readLba, readPos, bytesLeft; + uint8 *destPos = (uint8*)dest; + int doCopy; + int numLba; + readLba = fd->lba + (fd->pos >> 11); + readPos = fd->pos & 0x7FF; + + if (fd->pos + length > fd->size) + length = fd->size - fd->pos; + + if (length < 0) + return 0; + + bytesLeft = length; + while (bytesLeft > 0) { + if (readPos || (bytesLeft < 0x800) || (readLba == fd->cachedLba)) { + if (fd->cachedLba != readLba) { + if (cdReadSectors(readLba, 1, fd->buf, &rmode) == 0) + fd->cachedLba = readLba; + else + break; // read error + } + doCopy = 0x800 - readPos; + if (doCopy > bytesLeft) + doCopy = bytesLeft; + + memcpy(destPos, fd->buf + readPos, doCopy); + readPos += doCopy; + readLba += readPos >> 11; + readPos &= 0x7FF; + bytesLeft -= doCopy; + fd->pos += doCopy; + destPos += doCopy; + } else { + numLba = bytesLeft >> 11; + if (cdReadSectors(readLba, numLba, destPos, &rmode) != 0) + break; + readLba += numLba; + fd->pos += numLba << 11; + destPos += numLba << 11; + bytesLeft &= 0x7FF; + } + } + return destPos - (uint8*)dest; +} + +int cd_close(iop_file_t *handle) { + FioHandle *hd = fioHandles + (int)handle->privdata; + FreeSysMemory(hd->buf); + hd->lba = hd->pos = hd->size = 0; + hd->buf = 0; + return 0; +} + +int cd_dopen(iop_file_t *handle, const char *path) { + CdRMode rmode = { 16, 0, CdSect2048, 0 }; + int fdSlot; + ISODirectoryRecord *rec; + + if (verifyDriveReady() < 0) + return -EIO; + + rec = findPath(path); + if (!rec || !IS_DIR(rec)) + return -ENOENT; + + fdSlot = allocDioHandle(); + + if (fdSlot < 0) + return -ENFILE; + + dioHandles[fdSlot].buf = AllocSysMemory(ALLOC_FIRST, 0x800, NULL); + if (!dioHandles[fdSlot].buf) + return -ENOMEM; + + dioHandles[fdSlot].lba = READ_ARRAY32(rec->lba); + dioHandles[fdSlot].size = READ_ARRAY32(rec->size); + if (cdReadSectors(dioHandles[fdSlot].lba, 1, dioHandles[fdSlot].buf, &rmode) != 0) { + dioHandles[fdSlot].lba = dioHandles[fdSlot].size = 0; + FreeSysMemory(dioHandles[fdSlot].buf); + dioHandles[fdSlot].buf = NULL; + return -EIO; + } + dioHandles[fdSlot].curOfs = 0; + dioHandles[fdSlot].lbaOfs = 0; + handle->privdata = (void*)fdSlot; + return fdSlot; +} + +int cd_dread(iop_file_t *handle, iox_dirent_t *buf) { + CdRMode rmode = { 16, 0, CdSect2048, 0 }; + ISODirectoryRecord *rec; + DioHandle *hd = dioHandles + (int)handle->privdata; + int i; + for (i = hd->lbaOfs; i < NUM_SECTORS(hd->size); i++) { + if (i != hd->lbaOfs) { + cdReadSectors(hd->lba + i, 1, hd->buf, &rmode); + hd->lbaOfs = i; + hd->curOfs = 0; + } + while ((hd->curOfs < SECTOR_SIZE) && ((ISODirectoryRecord *)(hd->buf + hd->curOfs))->len_dr) { + rec = (ISODirectoryRecord *)(hd->buf + hd->curOfs); + hd->curOfs += rec->len_dr; + if ((rec->len_fi != 1) || ((rec->name[0] != 0) && (rec->name[0] != 1))) { // skip '.' / '..' + memcpy(buf->name, rec->name, rec->len_fi); + if ((buf->name[rec->len_fi - 2] == ';') && (buf->name[rec->len_fi - 1] == '1')) + buf->name[rec->len_fi - 2] = '\0'; + else + buf->name[rec->len_fi] = '\0'; + buf->stat.mode = FIO_S_IRUSR | FIO_S_IXUSR | FIO_S_IRGRP | FIO_S_IXGRP | FIO_S_IROTH | FIO_S_IXOTH; + buf->stat.mode |= IS_DIR(rec) ? FIO_S_IFDIR : FIO_S_IFREG; + buf->stat.attr = 0; + buf->stat.size = READ_ARRAY32(rec->size); + buf->stat.hisize = 0; + return 1; + } + } + } + return 0; +} + +int cd_dclose(iop_file_t *handle) { + DioHandle *hd; + hd = dioHandles + (int)handle->privdata; + FreeSysMemory(hd->buf); + hd->size = hd->lba = 0; + return 0; +} + diff --git a/backends/platform/ps2/iop/CoDyVDfs/iop/fiofs.h b/backends/platform/ps2/iop/CoDyVDfs/iop/fiofs.h new file mode 100644 index 0000000000..21d7dff218 --- /dev/null +++ b/backends/platform/ps2/iop/CoDyVDfs/iop/fiofs.h @@ -0,0 +1,37 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2005-2006 The ScummVM project + * + * 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. + * + * $URL$ + * $Id$ + * + */ + +#ifndef __FIOFS_H__ +#define __FIOFS_H__ + +int initFio(void); + +int cd_open(iop_file_t *handle, const char *name, int mode); +int cd_lseek(iop_file_t *handle, int ofs, int whence); +int cd_read(iop_file_t *handle, void *dest, int length); +int cd_close(iop_file_t *handle); +int cd_dopen(iop_file_t *handle, const char *path); +int cd_dread(iop_file_t *handle, fio_dirent_t *buf); +int cd_dclose(iop_file_t *handle); + +#endif // __FIOFS_H__ + diff --git a/backends/platform/ps2/iop/CoDyVDfs/iop/imports.lst b/backends/platform/ps2/iop/CoDyVDfs/iop/imports.lst new file mode 100644 index 0000000000..d3ed3b0442 --- /dev/null +++ b/backends/platform/ps2/iop/CoDyVDfs/iop/imports.lst @@ -0,0 +1,65 @@ + +cdvdman_IMPORTS_start +I_sceCdInit +I_sceCdStandby +I_sceCdRead +I_sceCdSeek +I_sceCdGetError +I_sceCdSync +I_sceCdGetDiskType +I_sceCdDiskReady +I_sceCdTrayReq +I_sceCdStop +I_sceCdReadClock +cdvdman_IMPORTS_end + +intrman_IMPORTS_start +I_CpuSuspendIntr +I_CpuResumeIntr +intrman_IMPORTS_end + +iomanX_IMPORTS_start +I_AddDrv +I_DelDrv +iomanX_IMPORTS_end + +sifcmd_IMPORTS_start +I_sceSifInitRpc +I_sceSifSetRpcQueue +I_sceSifRegisterRpc +I_sceSifRpcLoop +sifcmd_IMPORTS_end + +stdio_IMPORTS_start +I_printf +stdio_IMPORTS_end + +sysclib_IMPORTS_start +I_memcmp +I_memcpy +I_memset +I_strlen +I_strncmp +I_strtoul +I_strcpy +I_strcat +I_strchr +I_strncpy +I_strtok +I_strrchr +I_tolower +sysclib_IMPORTS_end + +sysmem_IMPORTS_start +I_AllocSysMemory +I_FreeSysMemory +sysmem_IMPORTS_end + +thbase_IMPORTS_start +I_CreateThread +I_StartThread +I_GetThreadId +I_DelayThread +thbase_IMPORTS_end + + diff --git a/backends/platform/ps2/iop/CoDyVDfs/iop/irx_imports.h b/backends/platform/ps2/iop/CoDyVDfs/iop/irx_imports.h new file mode 100644 index 0000000000..1f974cf834 --- /dev/null +++ b/backends/platform/ps2/iop/CoDyVDfs/iop/irx_imports.h @@ -0,0 +1,30 @@ +/* +# _____ ___ ____ ___ ____ +# ____| | ____| | | |____| +# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. +#----------------------------------------------------------------------- +# Copyright (c) 2003 Marcus R. Brown <mrbrown@0xd6.org> +# Licenced under Academic Free License version 2.0 +# Review ps2sdk README & LICENSE files for further details. +# +# $Id$ +# Defines all IRX imports. +*/ + +#ifndef IOP_IRX_IMPORTS_H +#define IOP_IRX_IMPORTS_H + +#include "irx.h" + +/* Please keep these in alphabetical order! */ +#include "cdvdman.h" +#include "intrman.h" +#include "iomanX.h" +#include "loadcore.h" +#include "sifcmd.h" +#include "stdio.h" +#include "sysclib.h" +#include "sysmem.h" +#include "thbase.h" + +#endif /* IOP_IRX_IMPORTS_H */ diff --git a/backends/platform/ps2/iop/CoDyVDfs/iop/rpcfs.c b/backends/platform/ps2/iop/CoDyVDfs/iop/rpcfs.c new file mode 100644 index 0000000000..16f70e9ed4 --- /dev/null +++ b/backends/platform/ps2/iop/CoDyVDfs/iop/rpcfs.c @@ -0,0 +1,115 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2005-2006 The ScummVM project + * + * 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. + * + * $URL$ + * $Id$ + * + */ + +#include <sifman.h> +#include <sifrpc.h> +#include <thbase.h> +#include <stdio.h> +#include "codyvdfs.h" +#include "../common/codyvdirx.h" + +struct t_SifRpcDataQueue qd; +struct t_SifRpcServerData sd0; +static uint8 rpcBuffer[64]; + +void *rpcServer(int func, void *data, int size); +void rpcThread(void *param); + +int initRpc(void) { + iop_thread_t thread; + int tid; + + thread.attr = TH_C; + thread.thread = rpcThread; + thread.priority = 40; + thread.stacksize = 0x1000; + thread.attr = 0; + + tid = CreateThread(&thread); + if (tid >= 0) + StartThread(tid, 0); + else { + printf("Unable to start RPC Thread!\n"); + return -1; + } + return 0; +} + +void rpcThread(void *param) { + SifInitRpc(0); + SifSetRpcQueue(&qd, GetThreadId()); + SifRegisterRpc(&sd0, CDVDFS_IRX_ID, rpcServer, (void *)rpcBuffer, 0, 0, &qd); + SifRpcLoop(&qd); +} + +void *rpcReadClock(void *data) { + CdReadClock((cd_clock_t *)data); + return data; +} + +void *driveStop(void *data) { + if (CdStop() == 1) { + if (CdSync(0) == 0) { + *(int*)data = CdGetError(); + } else + *(int*)data = -0x100; + } else + *(int*)data = -0x101; + return data; +} + +void *driveStandby(void *data) { + int type; + if (CdStandby() == 1) { + if (CdSync(0) == 0) { + *(int*)data = CdGetError(); + } else + *(int*)data = -0x100; + } else + *(int*)data = -0x101; + + do { // wait until drive detected disc type + type = CdGetDiskType(); + if (DISC_NOT_READY(type)) + DelayThread(10 * 1000); + } while (DISC_NOT_READY(type)); + printf("Standby: Disc type: %02X\n", type); + + return data; +} + +void *rpcServer(int func, void *data, int size) { + switch (func) { + case READ_RTC: + return rpcReadClock(data); + case DRIVE_STOP: + return driveStop(data); + case DRIVE_STANDBY: + return driveStandby(data); + default: + printf("Unknown RPC command %d\n", func); + return NULL; + } + return NULL; +} + + |