aboutsummaryrefslogtreecommitdiff
path: root/backends/ps2/asyncfio.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'backends/ps2/asyncfio.cpp')
-rw-r--r--backends/ps2/asyncfio.cpp138
1 files changed, 138 insertions, 0 deletions
diff --git a/backends/ps2/asyncfio.cpp b/backends/ps2/asyncfio.cpp
new file mode 100644
index 0000000000..e85da1e04c
--- /dev/null
+++ b/backends/ps2/asyncfio.cpp
@@ -0,0 +1,138 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2004-2005 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#include "asyncfio.h"
+#include <tamtypes.h>
+#include <kernel.h>
+#include <fileio.h>
+#include <assert.h>
+#include <string.h>
+
+extern void sioprintf(const char *zFormat, ...);
+
+AsyncFio::AsyncFio(void) {
+ _runningOp = NULL;
+ memset(_ioSlots, 0, MAX_HANDLES * sizeof(int));
+ ee_sema_t newSema;
+ newSema.init_count = 1;
+ newSema.max_count = 1;
+ _ioSema = CreateSema(&newSema);
+}
+
+AsyncFio::~AsyncFio(void) {
+ DeleteSema(_ioSema);
+}
+
+int AsyncFio::open(const char *name, int ioMode) {
+ WaitSema(_ioSema);
+ checkSync();
+ int res;
+ fioOpen(name, ioMode);
+ int fioRes = fioSync(FIO_WAIT, &res);
+ if (fioRes != FIO_COMPLETE) {
+ sioprintf("ERROR: fioOpen(%s, %X):\n", name, ioMode);
+ sioprintf(" fioSync returned %d, open res = %d\n", fioRes, res);
+ SleepThread();
+ }
+ SignalSema(_ioSema);
+ return res;
+}
+
+void AsyncFio::close(int handle) {
+ WaitSema(_ioSema);
+ checkSync();
+ fioClose(handle);
+ SignalSema(_ioSema);
+}
+
+void AsyncFio::checkSync(void) {
+ if (_runningOp) {
+ assert(fioSync(FIO_WAIT, _runningOp) == FIO_COMPLETE);
+ _runningOp = NULL;
+ }
+}
+
+void AsyncFio::read(int fd, void *dest, unsigned int len) {
+ WaitSema(_ioSema);
+ checkSync();
+ assert(fd < MAX_HANDLES);
+ _runningOp = _ioSlots + fd;
+ fioRead(fd, dest, len);
+ SignalSema(_ioSema);
+}
+
+void AsyncFio::write(int fd, const void *src, unsigned int len) {
+ WaitSema(_ioSema);
+ checkSync();
+ assert(fd < MAX_HANDLES);
+ _runningOp = _ioSlots + fd;
+ fioWrite(fd, (unsigned char*)src, len);
+ SignalSema(_ioSema);
+}
+
+int AsyncFio::seek(int fd, int offset, int whence) {
+ WaitSema(_ioSema);
+ checkSync();
+ int res = fioLseek(fd, offset, whence);
+ SignalSema(_ioSema);
+ return res;
+}
+
+int AsyncFio::sync(int fd) {
+ WaitSema(_ioSema);
+ if (_runningOp == _ioSlots + fd)
+ checkSync();
+ SignalSema(_ioSema);
+ return _ioSlots[fd];
+}
+
+bool AsyncFio::poll(int fd) {
+ bool retVal = false;
+ if (PollSema(_ioSema) > 0) {
+ if (_runningOp == _ioSlots + fd) {
+ if (fioSync(FIO_NOWAIT, _runningOp) == FIO_COMPLETE) {
+ _runningOp = NULL;
+ retVal = true;
+ } else
+ retVal = false;
+ } else
+ retVal = true;
+ SignalSema(_ioSema);
+ }
+ return retVal;
+}
+
+bool AsyncFio::fioAvail(void) {
+ bool retVal = false;
+ if (PollSema(_ioSema) > 0) {
+ if (_runningOp) {
+ if (fioSync(FIO_NOWAIT, _runningOp) == FIO_COMPLETE) {
+ _runningOp = NULL;
+ retVal = true;
+ } else
+ retVal = false;
+ } else
+ retVal = true;
+ SignalSema(_ioSema);
+ }
+ return retVal;
+}
+