summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author arbee <rb6502@users.noreply.github.com>2015-05-02 21:23:02 -0400
committer arbee <rb6502@users.noreply.github.com>2015-05-02 21:23:02 -0400
commitb702e6bd3e4a16ee3889e5a5fa4c3f0ea52b3c8c (patch)
tree6f84d9c81e743592083d171b97163a60e4d45573
parent4c7066c7871190ddc4cad1c263d97c8868f7ef8d (diff)
mac: NuBus "image" card now provides primitives for programs on the Mac to interact with the host's filesystem. [Rob Braun, R. Belmont]
-rw-r--r--src/emu/bus/nubus/nubus_image.c130
-rw-r--r--src/emu/bus/nubus/nubus_image.h29
2 files changed, 159 insertions, 0 deletions
diff --git a/src/emu/bus/nubus/nubus_image.c b/src/emu/bus/nubus/nubus_image.c
index 3bacfff6fe9..20a7051eaa6 100644
--- a/src/emu/bus/nubus/nubus_image.c
+++ b/src/emu/bus/nubus/nubus_image.c
@@ -8,12 +8,22 @@
#include "emu.h"
#include "nubus_image.h"
+#include "osdcore.h"
#define IMAGE_ROM_REGION "image_rom"
#define IMAGE_DISK0_TAG "nb_disk"
#define MESSIMG_DISK_SECTOR_SIZE (512)
+// on big-endian, these are NOPs. (TODO: hey, where did WORDS_BIGENDIAN go since the GENie transition?!)
+#if defined(__ppc__) || defined (__PPC__) || defined(__ppc64__) || defined(__PPC64__)
+static UINT32 ni_htonl(UINT32 x) { return x; }
+static UINT32 ni_ntohl(UINT32 x) { return x; }
+#else
+static UINT32 ni_htonl(UINT32 x) { return FLIPENDIAN_INT32(x); }
+static UINT32 ni_ntohl(UINT32 x) { return FLIPENDIAN_INT32(x); }
+#endif
+
// messimg_disk_image_device
@@ -193,9 +203,16 @@ void nubus_image_device::device_start()
m_nubus->install_device(slotspace, slotspace+3, read32_delegate(FUNC(nubus_image_device::image_r), this), write32_delegate(FUNC(nubus_image_device::image_w), this));
m_nubus->install_device(slotspace+4, slotspace+7, read32_delegate(FUNC(nubus_image_device::image_status_r), this), write32_delegate(FUNC(nubus_image_device::image_status_w), this));
+ m_nubus->install_device(slotspace+8, slotspace+11, read32_delegate(FUNC(nubus_image_device::file_cmd_r), this), write32_delegate(FUNC(nubus_image_device::file_cmd_w), this));
+ m_nubus->install_device(slotspace+12, slotspace+15, read32_delegate(FUNC(nubus_image_device::file_data_r), this), write32_delegate(FUNC(nubus_image_device::file_data_w), this));
+ m_nubus->install_device(slotspace+16, slotspace+19, read32_delegate(FUNC(nubus_image_device::file_len_r), this), write32_delegate(FUNC(nubus_image_device::file_len_w), this));
+ m_nubus->install_device(slotspace+20, slotspace+147, read32_delegate(FUNC(nubus_image_device::file_name_r), this), write32_delegate(FUNC(nubus_image_device::file_name_w), this));
m_nubus->install_device(superslotspace, superslotspace+((256*1024*1024)-1), read32_delegate(FUNC(nubus_image_device::image_super_r), this), write32_delegate(FUNC(nubus_image_device::image_super_w), this));
m_image = subdevice<messimg_disk_image_device>(IMAGE_DISK0_TAG);
+
+ filectx.curdir[0] = '.';
+ filectx.curdir[1] = '\0';
}
//-------------------------------------------------
@@ -247,3 +264,116 @@ READ32_MEMBER( nubus_image_device::image_super_r )
UINT32 data = image[offset];
return ((data & 0xff) << 24) | ((data & 0xff00) << 8) | ((data & 0xff0000) >> 8) | ((data & 0xff000000) >> 24);
}
+
+WRITE32_MEMBER( nubus_image_device::file_cmd_w )
+{
+ const osd_directory_entry *dp = NULL;
+ char fullpath[1024];
+ UINT64 filesize;
+
+// data = ((data & 0xff) << 24) | ((data & 0xff00) << 8) | ((data & 0xff0000) >> 8) | ((data & 0xff000000) >> 24);
+ filectx.curcmd = data;
+ switch(data) {
+ case kFileCmdGetDir:
+ strcpy((char*)filectx.filename, (char*)filectx.curdir);
+ break;
+ case kFileCmdSetDir:
+ if(filectx.filename[0] == '/') {
+ strcpy((char*)filectx.curdir, (char*)filectx.filename);
+ } else {
+ strcat((char*)filectx.curdir, "/");
+ strcat((char*)filectx.curdir, (char*)filectx.filename);
+ }
+ break;
+ case kFileCmdGetFirstListing:
+ if(filectx.dirp) osd_closedir(filectx.dirp);
+ filectx.dirp = osd_opendir((const char *)filectx.curdir);
+ case kFileCmdGetNextListing:
+ dp = osd_readdir(filectx.dirp);
+ if(dp) {
+ strncpy((char*)filectx.filename, dp->name, sizeof(filectx.filename));
+ } else {
+ memset(filectx.filename, 0, sizeof(filectx.filename));
+ }
+ break;
+ case kFileCmdGetFile:
+ memset(fullpath, 0, sizeof(fullpath));
+ strcpy(fullpath, (const char *)filectx.curdir);
+ strcat(fullpath, "/");
+ strcat(fullpath, (const char*)filectx.filename);
+ if(osd_open((const char*)fullpath, OPEN_FLAG_READ, &filectx.fd, &filectx.filelen) != FILERR_NONE) printf("Error opening %s\n", fullpath);
+ filectx.bytecount = 0;
+ break;
+ case kFileCmdPutFile:
+ memset(fullpath, 0, sizeof(fullpath));
+ strcpy(fullpath, (const char *)filectx.curdir);
+ strcat(fullpath, "/");
+ strcat(fullpath, (const char*)filectx.filename);
+ if(osd_open((const char*)fullpath, OPEN_FLAG_WRITE|OPEN_FLAG_CREATE, &filectx.fd, &filesize) != FILERR_NONE) printf("Error opening %s\n", fullpath);
+ filectx.bytecount = 0;
+ break;
+ }
+}
+
+READ32_MEMBER( nubus_image_device::file_cmd_r )
+{
+ return 0;
+}
+
+WRITE32_MEMBER( nubus_image_device::file_data_w )
+{
+ UINT32 count = 4;
+ UINT32 actualcount = 0;
+
+ data = ((data & 0xff) << 24) | ((data & 0xff00) << 8) | ((data & 0xff0000) >> 8) | ((data & 0xff000000) >> 24);
+ if(filectx.fd != NULL) {
+ //data = ni_ntohl(data);
+ if((filectx.bytecount + count) > filectx.filelen) count = filectx.filelen - filectx.bytecount;
+ osd_write(filectx.fd, &data, filectx.bytecount, count, &actualcount);
+ filectx.bytecount += actualcount;
+
+ if(filectx.bytecount >= filectx.filelen) {
+ osd_close(filectx.fd);
+ filectx.fd = NULL;
+ }
+ }
+}
+
+READ32_MEMBER( nubus_image_device::file_data_r )
+{
+ if(filectx.fd != NULL) {
+ UINT32 ret;
+ UINT32 actual = 0;
+ osd_read(filectx.fd, &ret, filectx.bytecount, sizeof(ret), &actual);
+ filectx.bytecount += actual;
+ if(actual < sizeof(ret)) {
+ osd_close(filectx.fd);
+ filectx.fd = NULL;
+ }
+ return ni_htonl(ret);
+ }
+ return 0;
+}
+
+WRITE32_MEMBER( nubus_image_device::file_len_w )
+{
+ data = ((data & 0xff) << 24) | ((data & 0xff00) << 8) | ((data & 0xff0000) >> 8) | ((data & 0xff000000) >> 24);
+ filectx.filelen = ni_ntohl(data);
+}
+
+READ32_MEMBER( nubus_image_device::file_len_r )
+{
+ return filectx.filelen;
+}
+
+WRITE32_MEMBER( nubus_image_device::file_name_w )
+{
+ ((UINT32*)(filectx.filename))[offset] = ni_ntohl(data);
+}
+
+READ32_MEMBER( nubus_image_device::file_name_r )
+{
+ UINT32 ret;
+ ret = ni_htonl(((UINT32*)(filectx.filename))[offset]);
+ return ret;
+}
diff --git a/src/emu/bus/nubus/nubus_image.h b/src/emu/bus/nubus/nubus_image.h
index 66e9aff46a3..9bd7c11c002 100644
--- a/src/emu/bus/nubus/nubus_image.h
+++ b/src/emu/bus/nubus/nubus_image.h
@@ -5,12 +5,23 @@
#include "emu.h"
#include "nubus.h"
+#include "osdcore.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
class messimg_disk_image_device;
+struct nbfilectx {
+ UINT32 curcmd;
+ UINT8 filename[128];
+ UINT8 curdir[1024];
+ osd_directory *dirp;
+ osd_file *fd;
+ UINT64 filelen;
+ UINT32 bytecount;
+};
+
// ======================> nubus_image_device
class nubus_image_device :
@@ -37,13 +48,31 @@ protected:
DECLARE_WRITE32_MEMBER(image_w);
DECLARE_READ32_MEMBER(image_super_r);
DECLARE_WRITE32_MEMBER(image_super_w);
+ DECLARE_READ32_MEMBER(file_cmd_r);
+ DECLARE_WRITE32_MEMBER(file_cmd_w);
+ DECLARE_READ32_MEMBER(file_data_r);
+ DECLARE_WRITE32_MEMBER(file_data_w);
+ DECLARE_READ32_MEMBER(file_len_r);
+ DECLARE_WRITE32_MEMBER(file_len_w);
+ DECLARE_READ32_MEMBER(file_name_r);
+ DECLARE_WRITE32_MEMBER(file_name_w);
public:
messimg_disk_image_device *m_image;
+ struct nbfilectx filectx;
};
// device type definition
extern const device_type NUBUS_IMAGE;
+enum {
+ kFileCmdGetDir = 1,
+ kFileCmdSetDir,
+ kFileCmdGetFirstListing,
+ kFileCmdGetNextListing,
+ kFileCmdGetFile,
+ kFileCmdPutFile
+};
+
#endif /* __NUBUS_IMAGE_H__ */