diff options
Diffstat (limited to 'src/devices/bus/nubus/nubus_image.cpp')
-rw-r--r-- | src/devices/bus/nubus/nubus_image.cpp | 117 |
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]); } |