aboutsummaryrefslogtreecommitdiff
path: root/backends/platform/ps2/iop
diff options
context:
space:
mode:
authorMax Horn2006-07-06 21:44:48 +0000
committerMax Horn2006-07-06 21:44:48 +0000
commit1d8d9f5510dc5f574e926bd6fadb9d20337daede (patch)
tree5cdcf6c8a233159776be9d90f3f39885222f65eb /backends/platform/ps2/iop
parent9269ebe9f5a281f452594f1e8108e31c88a398fb (diff)
downloadscummvm-rg350-1d8d9f5510dc5f574e926bd6fadb9d20337daede.tar.gz
scummvm-rg350-1d8d9f5510dc5f574e926bd6fadb9d20337daede.tar.bz2
scummvm-rg350-1d8d9f5510dc5f574e926bd6fadb9d20337daede.zip
Moving remaining platform/backends code, as previously threatened
svn-id: r23380
Diffstat (limited to 'backends/platform/ps2/iop')
-rw-r--r--backends/platform/ps2/iop/CoDyVDfs/Makefile30
-rw-r--r--backends/platform/ps2/iop/CoDyVDfs/common/codyvdirx.h38
-rw-r--r--backends/platform/ps2/iop/CoDyVDfs/iop/cdtypes.h134
-rw-r--r--backends/platform/ps2/iop/CoDyVDfs/iop/codyvdfs.c347
-rw-r--r--backends/platform/ps2/iop/CoDyVDfs/iop/codyvdfs.h84
-rw-r--r--backends/platform/ps2/iop/CoDyVDfs/iop/fiofs.c262
-rw-r--r--backends/platform/ps2/iop/CoDyVDfs/iop/fiofs.h37
-rw-r--r--backends/platform/ps2/iop/CoDyVDfs/iop/imports.lst65
-rw-r--r--backends/platform/ps2/iop/CoDyVDfs/iop/irx_imports.h30
-rw-r--r--backends/platform/ps2/iop/CoDyVDfs/iop/rpcfs.c115
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;
+}
+
+