summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/nubus/nubus_image.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/nubus/nubus_image.cpp')
-rw-r--r--src/devices/bus/nubus/nubus_image.cpp117
1 files changed, 62 insertions, 55 deletions
diff --git a/src/devices/bus/nubus/nubus_image.cpp b/src/devices/bus/nubus/nubus_image.cpp
index 32b1d33100a..3d17b2500a1 100644
--- a/src/devices/bus/nubus/nubus_image.cpp
+++ b/src/devices/bus/nubus/nubus_image.cpp
@@ -6,12 +6,26 @@
HFS images, including floppy images (DD and HD) and vMac/Basilisk HDD
volumes up to 256 MB in size.
+ TODO:
+ * Get get directory and get listing commands have no way to indicate
+ that the path/name is too long for the buffer.
+ * The set directory command doesn't work well with host filesystems that
+ have roots (e.g. Windows drive letters).
+ * The set directory command assumes '/' is a valid host directory
+ separator character.
+ * The get listing commands have no way to indicate whether an entry is
+ a directory.
+
***************************************************************************/
#include "emu.h"
#include "nubus_image.h"
+
#include "osdcore.h"
+#include <algorithm>
+
+
#define IMAGE_ROM_REGION "image_rom"
#define IMAGE_DISK0_TAG "nb_disk"
@@ -26,19 +40,16 @@ public:
// construction/destruction
messimg_disk_image_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- // image-level overrides
- virtual iodevice_t image_type() const noexcept override { return IO_QUICKLOAD; }
-
+ // device_image_interface implementation
virtual bool is_readable() const noexcept override { return true; }
virtual bool is_writeable() const noexcept override { return true; }
virtual bool is_creatable() const noexcept override { return false; }
- virtual bool must_be_loaded() const noexcept override { return false; }
virtual bool is_reset_on_load() const noexcept override { return false; }
virtual const char *file_extensions() const noexcept override { return "img"; }
- virtual const char *custom_instance_name() const noexcept override { return "disk"; }
- virtual const char *custom_brief_instance_name() const noexcept override { return "disk"; }
+ virtual const char *image_type_name() const noexcept override { return "disk"; }
+ virtual const char *image_brief_type_name() const noexcept override { return "disk"; }
- virtual image_init_result call_load() override;
+ virtual std::pair<std::error_condition, std::string> call_load() override;
virtual void call_unload() override;
protected:
@@ -54,7 +65,7 @@ public:
// device type definition
-DEFINE_DEVICE_TYPE_NS(MESSIMG_DISK, nubus_image_device, messimg_disk_image_device, "messimg_disk_image", "Mac image")
+DEFINE_DEVICE_TYPE(MESSIMG_DISK, nubus_image_device::messimg_disk_image_device, "messimg_disk_image", "Mac image")
nubus_image_device::messimg_disk_image_device::messimg_disk_image_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, MESSIMG_DISK, tag, owner, clock),
@@ -72,29 +83,30 @@ void nubus_image_device::messimg_disk_image_device::device_start()
{
m_data = nullptr;
- if (exists() && fseek(0, SEEK_END) == 0)
+ if (exists() && !fseek(0, SEEK_END))
{
- m_size = (uint32_t)ftell();
+ m_size = uint32_t(ftell());
}
}
-image_init_result nubus_image_device::messimg_disk_image_device::call_load()
+std::pair<std::error_condition, std::string> nubus_image_device::messimg_disk_image_device::call_load()
{
- fseek(0, SEEK_END);
- m_size = (uint32_t)ftell();
+ m_size = length();
if (m_size > (256*1024*1024))
{
- osd_printf_error("Mac image too large: must be 256MB or less!\n");
m_size = 0;
- return image_init_result::FAIL;
+ return std::make_pair(image_error::INVALIDLENGTH, "Image file is too large (must be no more than 256MB)");
}
- m_data = make_unique_clear<uint8_t[]>(m_size);
+ m_data.reset(new (std::nothrow) uint8_t [m_size]);
+ if (!m_data)
+ return std::make_pair(std::errc::not_enough_memory, "Error allocating memory for volume image");
+
fseek(0, SEEK_SET);
fread(m_data.get(), m_size);
m_ejected = false;
- return image_init_result::PASS;
+ return std::make_pair(std::error_condition(), std::string());
}
void nubus_image_device::messimg_disk_image_device::call_unload()
@@ -173,7 +185,7 @@ void nubus_image_device::device_start()
uint32_t slotspace;
uint32_t superslotspace;
- install_declaration_rom(this, IMAGE_ROM_REGION);
+ install_declaration_rom(IMAGE_ROM_REGION);
slotspace = get_slotspace();
superslotspace = get_super_slotspace();
@@ -190,10 +202,9 @@ void nubus_image_device::device_start()
m_image = subdevice<messimg_disk_image_device>(IMAGE_DISK0_TAG);
- filectx.curdir[0] = '.';
- filectx.curdir[1] = '\0';
- filectx.dirp = nullptr;
- filectx.fd = nullptr;
+ filectx.curdir = ".";
+ filectx.dirp.reset();
+ filectx.fd.reset();
}
//-------------------------------------------------
@@ -233,8 +244,8 @@ uint32_t nubus_image_device::image_r()
void nubus_image_device::image_super_w(offs_t offset, uint32_t data, uint32_t mem_mask)
{
uint32_t *image = (uint32_t*)m_image->m_data.get();
- data = ((data & 0xff) << 24) | ((data & 0xff00) << 8) | ((data & 0xff0000) >> 8) | ((data & 0xff000000) >> 24);
- mem_mask = ((mem_mask & 0xff) << 24) | ((mem_mask & 0xff00) << 8) | ((mem_mask & 0xff0000) >> 8) | ((mem_mask & 0xff000000) >> 24);
+ data = swapendian_int32(data);
+ mem_mask = swapendian_int32(mem_mask);
COMBINE_DATA(&image[offset]);
}
@@ -242,63 +253,61 @@ void nubus_image_device::image_super_w(offs_t offset, uint32_t data, uint32_t me
uint32_t nubus_image_device::image_super_r(offs_t offset, uint32_t mem_mask)
{
uint32_t *image = (uint32_t*)m_image->m_data.get();
- uint32_t data = image[offset];
- return ((data & 0xff) << 24) | ((data & 0xff00) << 8) | ((data & 0xff0000) >> 8) | ((data & 0xff000000) >> 24);
+ return swapendian_int32(image[offset]);
}
void nubus_image_device::file_cmd_w(uint32_t data)
{
-// data = ((data & 0xff) << 24) | ((data & 0xff00) << 8) | ((data & 0xff0000) >> 8) | ((data & 0xff000000) >> 24);
+// data = swapendian_int32(data);
filectx.curcmd = data;
- switch(data) {
+ switch (data) {
case kFileCmdGetDir:
- strcpy((char*)filectx.filename, (char*)filectx.curdir);
+ strncpy(filectx.filename, filectx.curdir.c_str(), std::size(filectx.filename));
break;
case kFileCmdSetDir:
if ((filectx.filename[0] == '/') || (filectx.filename[0] == '$')) {
- strcpy((char*)filectx.curdir, (char*)filectx.filename);
+ filectx.curdir.assign(std::begin(filectx.filename), std::find(std::begin(filectx.filename), std::end(filectx.filename), '\0'));
} else {
- strcat((char*)filectx.curdir, "/");
- strcat((char*)filectx.curdir, (char*)filectx.filename);
+ filectx.curdir += '/';
+ filectx.curdir.append(std::begin(filectx.filename), std::find(std::begin(filectx.filename), std::end(filectx.filename), '\0'));
}
break;
case kFileCmdGetFirstListing:
- filectx.dirp = osd::directory::open((const char *)filectx.curdir);
+ filectx.dirp = osd::directory::open(filectx.curdir);
+ [[fallthrough]];
case kFileCmdGetNextListing:
if (filectx.dirp) {
osd::directory::entry const *const dp = filectx.dirp->read();
- if(dp) {
- strncpy((char*)filectx.filename, dp->name, sizeof(filectx.filename));
+ if (dp) {
+ strncpy(filectx.filename, dp->name, std::size(filectx.filename));
} else {
- memset(filectx.filename, 0, sizeof(filectx.filename));
+ std::fill(std::begin(filectx.filename), std::end(filectx.filename), '\0');
}
}
else {
- memset(filectx.filename, 0, sizeof(filectx.filename));
+ std::fill(std::begin(filectx.filename), std::end(filectx.filename), '\0');
}
break;
case kFileCmdGetFile:
{
- std::string fullpath;
- fullpath.reserve(1024);
- fullpath.assign((const char *)filectx.curdir);
- fullpath.append(PATH_SEPARATOR);
- fullpath.append((const char*)filectx.filename);
- if(osd_file::open(fullpath, OPEN_FLAG_READ, filectx.fd, filectx.filelen) != osd_file::error::NONE)
- osd_printf_error("Error opening %s\n", fullpath);
+ std::string fullpath(filectx.curdir);
+ fullpath += PATH_SEPARATOR;
+ fullpath.append(std::begin(filectx.filename), std::find(std::begin(filectx.filename), std::end(filectx.filename), '\0'));
+ std::error_condition const filerr = osd_file::open(fullpath, OPEN_FLAG_READ, filectx.fd, filectx.filelen);
+ if (filerr)
+ osd_printf_error("%s: Error opening %s (%s:%d %s)\n", tag(), fullpath, filerr.category().name(), filerr.value(), filerr.message());
filectx.bytecount = 0;
}
break;
case kFileCmdPutFile:
{
- std::string fullpath;
- fullpath.reserve(1024);
- fullpath.assign((const char *)filectx.curdir);
- fullpath.append(PATH_SEPARATOR);
- fullpath.append((const char*)filectx.filename);
+ std::string fullpath(filectx.curdir);
+ fullpath += PATH_SEPARATOR;
+ fullpath.append(std::begin(filectx.filename), std::find(std::begin(filectx.filename), std::end(filectx.filename), '\0'));
uint64_t filesize; // unused, but it's an output from the open call
- if(osd_file::open(fullpath, OPEN_FLAG_WRITE|OPEN_FLAG_CREATE, filectx.fd, filesize) != osd_file::error::NONE)
- osd_printf_error("Error opening %s\n", fullpath);
+ std::error_condition const filerr = osd_file::open(fullpath, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, filectx.fd, filesize);
+ if (filerr)
+ osd_printf_error("%s: Error opening %s (%s:%d %s)\n", tag(), fullpath, filerr.category().name(), filerr.value(), filerr.message());
filectx.bytecount = 0;
}
break;
@@ -356,12 +365,10 @@ uint32_t nubus_image_device::file_len_r()
void nubus_image_device::file_name_w(offs_t offset, uint32_t data)
{
- ((uint32_t*)(filectx.filename))[offset] = big_endianize_int32(data);
+ reinterpret_cast<uint32_t *>(filectx.filename)[offset] = big_endianize_int32(data);
}
uint32_t nubus_image_device::file_name_r(offs_t offset)
{
- uint32_t ret;
- ret = big_endianize_int32(((uint32_t*)(filectx.filename))[offset]);
- return ret;
+ return big_endianize_int32(reinterpret_cast<uint32_t const *>(filectx.filename)[offset]);
}