diff options
author | 2021-08-22 09:06:15 +1000 | |
---|---|---|
committer | 2021-08-22 09:06:15 +1000 | |
commit | e8bbea1fc6e94e14768509d322f6c624403ffb36 (patch) | |
tree | 74dd1606a900d83de8aecff17a6737af4113308d | |
parent | e319bde5fc3696d7f48f62b15b6366c4377fe5d1 (diff) |
formats, osd, util: Started refactoring file I/O stuff. (#8456)
Added more modern generic I/O interfaces with implementation backed by stdio, osd_file and core_file, replacing io_generic. Also replaced core_file's build-in zlib compression with a filter.
unzip.cpp, un7z.cpp: Added option to supply abstract I/O interface rather than filename.
Converted osd_file, core_file, archive_file, chd_file and device_image_interface to use std::error_condition rather than their own error enums.
Allow mounting TI-99 RPK from inside archives.
390 files changed, 9006 insertions, 6553 deletions
diff --git a/scripts/src/formats.lua b/scripts/src/formats.lua index 5afef69d522..d2c7ceda4a5 100644 --- a/scripts/src/formats.lua +++ b/scripts/src/formats.lua @@ -33,8 +33,6 @@ project "formats" MAME_DIR .. "src/lib/formats/all.cpp", MAME_DIR .. "src/lib/formats/all.h", - MAME_DIR .. "src/lib/formats/ioprocs.cpp", - MAME_DIR .. "src/lib/formats/ioprocs.h", MAME_DIR .. "src/lib/formats/imageutl.cpp", MAME_DIR .. "src/lib/formats/imageutl.h", diff --git a/scripts/src/lib.lua b/scripts/src/lib.lua index c943656ca14..c24bb015cd4 100644 --- a/scripts/src/lib.lua +++ b/scripts/src/lib.lua @@ -71,6 +71,12 @@ project "utils" MAME_DIR .. "src/lib/util/hashing.h", MAME_DIR .. "src/lib/util/huffman.cpp", MAME_DIR .. "src/lib/util/huffman.h", + MAME_DIR .. "src/lib/util/ioprocs.cpp", + MAME_DIR .. "src/lib/util/ioprocs.h", + MAME_DIR .. "src/lib/util/ioprocsfill.h", + MAME_DIR .. "src/lib/util/ioprocsfilter.cpp", + MAME_DIR .. "src/lib/util/ioprocsfilter.h", + MAME_DIR .. "src/lib/util/ioprocsvec.h", MAME_DIR .. "src/lib/util/jedparse.cpp", MAME_DIR .. "src/lib/util/jedparse.h", MAME_DIR .. "src/lib/util/md5.cpp", @@ -85,6 +91,8 @@ project "utils" MAME_DIR .. "src/lib/util/options.h", MAME_DIR .. "src/lib/util/palette.cpp", MAME_DIR .. "src/lib/util/palette.h", + MAME_DIR .. "src/lib/util/path.cpp", + MAME_DIR .. "src/lib/util/path.h", MAME_DIR .. "src/lib/util/path_to_regex.cpp", MAME_DIR .. "src/lib/util/path_to_regex.hpp", MAME_DIR .. "src/lib/util/plaparse.cpp", @@ -104,6 +112,7 @@ project "utils" MAME_DIR .. "src/lib/util/unzip.cpp", MAME_DIR .. "src/lib/util/unzip.h", MAME_DIR .. "src/lib/util/un7z.cpp", + MAME_DIR .. "src/lib/util/utilfwd.h", MAME_DIR .. "src/lib/util/vbiparse.cpp", MAME_DIR .. "src/lib/util/vbiparse.h", MAME_DIR .. "src/lib/util/vecstream.cpp", diff --git a/scripts/src/osd/mac.lua b/scripts/src/osd/mac.lua index 2cc3e53c926..8a57b4ab4a3 100644 --- a/scripts/src/osd/mac.lua +++ b/scripts/src/osd/mac.lua @@ -166,7 +166,6 @@ project ("ocore_" .. _OPTIONS["osd"]) MAME_DIR .. "src/osd/modules/lib/osdlib_macosx.cpp", MAME_DIR .. "src/osd/modules/lib/osdlib.h", MAME_DIR .. "src/osd/modules/file/posixdir.cpp", - MAME_DIR .. "src/osd/modules/file/posixdomain.cpp", MAME_DIR .. "src/osd/modules/file/posixfile.cpp", MAME_DIR .. "src/osd/modules/file/posixfile.h", MAME_DIR .. "src/osd/modules/file/posixptty.cpp", diff --git a/scripts/src/osd/sdl.lua b/scripts/src/osd/sdl.lua index 37dfb221067..31dafbbeb20 100644 --- a/scripts/src/osd/sdl.lua +++ b/scripts/src/osd/sdl.lua @@ -482,7 +482,6 @@ project ("ocore_" .. _OPTIONS["osd"]) if BASE_TARGETOS=="unix" then files { MAME_DIR .. "src/osd/modules/file/posixdir.cpp", - MAME_DIR .. "src/osd/modules/file/posixdomain.cpp", MAME_DIR .. "src/osd/modules/file/posixfile.cpp", MAME_DIR .. "src/osd/modules/file/posixfile.h", MAME_DIR .. "src/osd/modules/file/posixptty.cpp", diff --git a/src/devices/bus/a7800/a78_slot.cpp b/src/devices/bus/a7800/a78_slot.cpp index 4a7392fc3f6..d55412058d1 100644 --- a/src/devices/bus/a7800/a78_slot.cpp +++ b/src/devices/bus/a7800/a78_slot.cpp @@ -491,7 +491,7 @@ image_verify_result a78_cart_slot_device::verify_header(char *header) if (strncmp(magic, header + 1, 9)) { logerror("Not a valid A7800 image\n"); - seterror(IMAGE_ERROR_UNSPECIFIED, "File is not a valid A7800 image"); + seterror(image_error::INVALIDIMAGE, "File is not a valid A7800 image"); return image_verify_result::FAIL; } diff --git a/src/devices/bus/acorn/system/8k.cpp b/src/devices/bus/acorn/system/8k.cpp index ecbd69c930f..b2e1c7bb3d2 100644 --- a/src/devices/bus/acorn/system/8k.cpp +++ b/src/devices/bus/acorn/system/8k.cpp @@ -144,7 +144,7 @@ image_init_result acorn_8k_device::load_rom(device_image_interface &image, gener // socket accepts 2K and 4K ROM only if (size != 0x0800 && size != 0x1000) { - image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size: Only 2K/4K is supported"); + image.seterror(image_error::INVALIDIMAGE, "Invalid size: Only 2K/4K is supported"); return image_init_result::FAIL; } diff --git a/src/devices/bus/apf/slot.cpp b/src/devices/bus/apf/slot.cpp index 0d44530a8b6..c43738fae2a 100644 --- a/src/devices/bus/apf/slot.cpp +++ b/src/devices/bus/apf/slot.cpp @@ -152,7 +152,7 @@ image_init_result apf_cart_slot_device::call_load() if (size > 0x3800) { - seterror(IMAGE_ERROR_UNSPECIFIED, "Image extends beyond the expected size for an APF cart"); + seterror(image_error::INVALIDIMAGE, "Image extends beyond the expected size for an APF cart"); return image_init_result::FAIL; } diff --git a/src/devices/bus/aquarius/slot.cpp b/src/devices/bus/aquarius/slot.cpp index 825e03f39d5..88be36900f4 100644 --- a/src/devices/bus/aquarius/slot.cpp +++ b/src/devices/bus/aquarius/slot.cpp @@ -91,7 +91,7 @@ image_init_result aquarius_cartridge_slot_device::call_load() if (size % 0x1000) { - seterror(IMAGE_ERROR_INVALIDIMAGE, "Invalid ROM size"); + seterror(image_error::INVALIDIMAGE, "Invalid ROM size"); return image_init_result::FAIL; } diff --git a/src/devices/bus/ata/idehd.cpp b/src/devices/bus/ata/idehd.cpp index 15a079963de..dd1a8f932ec 100644 --- a/src/devices/bus/ata/idehd.cpp +++ b/src/devices/bus/ata/idehd.cpp @@ -838,7 +838,7 @@ void ide_hdd_device::device_reset() // build the features page uint32_t metalength; - if (m_handle && m_handle->read_metadata (HARD_DISK_IDENT_METADATA_TAG, 0, &m_buffer[0], 512, metalength) == CHDERR_NONE) + if (m_handle && !m_handle->read_metadata(HARD_DISK_IDENT_METADATA_TAG, 0, &m_buffer[0], 512, metalength)) { for( int w = 0; w < 256; w++ ) { diff --git a/src/devices/bus/bbc/1mhzbus/datacentre.cpp b/src/devices/bus/bbc/1mhzbus/datacentre.cpp index 05ba11a3bab..f21d5af1d54 100644 --- a/src/devices/bus/bbc/1mhzbus/datacentre.cpp +++ b/src/devices/bus/bbc/1mhzbus/datacentre.cpp @@ -328,7 +328,7 @@ QUICKLOAD_LOAD_MEMBER(bbc_datacentre_device::quickload_cb) } else { - image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Invalid filetype, must be SSD, DSD, or IMG"); + image.seterror(image_error::INVALIDIMAGE, "Invalid filetype, must be SSD, DSD, or IMG"); return image_init_result::FAIL; } diff --git a/src/devices/bus/bbc/rom/slot.cpp b/src/devices/bus/bbc/rom/slot.cpp index 8a315e12234..65acb920bca 100644 --- a/src/devices/bus/bbc/rom/slot.cpp +++ b/src/devices/bus/bbc/rom/slot.cpp @@ -122,7 +122,7 @@ image_init_result bbc_romslot_device::call_load() if (size % 0x2000) { - seterror(IMAGE_ERROR_INVALIDIMAGE, "Invalid ROM size"); + seterror(image_error::INVALIDIMAGE, "Invalid ROM size"); return image_init_result::FAIL; } diff --git a/src/devices/bus/c64/exp.cpp b/src/devices/bus/c64/exp.cpp index e4cc42f61d8..cf20f18fe45 100644 --- a/src/devices/bus/c64/exp.cpp +++ b/src/devices/bus/c64/exp.cpp @@ -191,7 +191,7 @@ image_init_result c64_expansion_slot_device::call_load() if ((m_card->m_roml_size & (m_card->m_roml_size - 1)) || (m_card->m_romh_size & (m_card->m_romh_size - 1))) { - seterror(IMAGE_ERROR_UNSPECIFIED, "ROM size must be power of 2"); + seterror(image_error::INVALIDIMAGE, "ROM size must be power of 2"); return image_init_result::FAIL; } } diff --git a/src/devices/bus/cgenie/expansion/floppy.cpp b/src/devices/bus/cgenie/expansion/floppy.cpp index b6f0a9c30ac..ee914179d10 100644 --- a/src/devices/bus/cgenie/expansion/floppy.cpp +++ b/src/devices/bus/cgenie/expansion/floppy.cpp @@ -181,7 +181,7 @@ DEVICE_IMAGE_LOAD_MEMBER( cgenie_fdc_device::socket_load ) if (size > 0x1000) { - image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported ROM size"); + image.seterror(image_error::INVALIDIMAGE, "Unsupported ROM size"); return image_init_result::FAIL; } diff --git a/src/devices/bus/coco/coco_dwsock.cpp b/src/devices/bus/coco/coco_dwsock.cpp index b970458c91c..a69ac57b4c4 100644 --- a/src/devices/bus/coco/coco_dwsock.cpp +++ b/src/devices/bus/coco/coco_dwsock.cpp @@ -82,18 +82,14 @@ beckerport_device::~beckerport_device() void beckerport_device::device_start() { - char chAddress[64]; - - /* format address string for opening the port */ - snprintf(chAddress, sizeof(chAddress), "socket.%s:%d", m_hostname, m_dwtcpport); - - osd_printf_verbose("Connecting to Drivewire server on %s:%d... ", m_hostname, m_dwtcpport); + osd_printf_verbose("%s: Connecting to Drivewire server on %s:%d... ", tag(), m_hostname, m_dwtcpport); u64 filesize; // unused - osd_file::error filerr = osd_file::open(chAddress, 0, m_pSocket, filesize); - if (filerr != osd_file::error::NONE) + /* format address string for opening the port */ + std::error_condition filerr = osd_file::open(util::string_format("socket.%s:%d", m_hostname, m_dwtcpport), 0, m_pSocket, filesize); + if (filerr) { - osd_printf_verbose("Error: osd_open returned error %i!\n", (int) filerr); + osd_printf_verbose("Error: osd_open returned error %s:%d %s!\n", filerr.category().name(), filerr.value(), filerr.message()); return; } @@ -108,7 +104,7 @@ void beckerport_device::device_stop() { if (m_pSocket) { - printf("Closing connection to Drivewire server\n"); + printf("%s: Closing connection to Drivewire server\n", tag()); m_pSocket.reset(); } } @@ -140,23 +136,24 @@ u8 beckerport_device::read(offs_t offset) if (!m_rx_pending) { /* Try to read from dws */ - osd_file::error filerr = m_pSocket->read(m_buf, 0, sizeof(m_buf), m_rx_pending); - if (filerr != osd_file::error::NONE && filerr != osd_file::error::FAILURE) // osd_file::error::FAILURE means no data available, so don't throw error message - fprintf(stderr, "coco_dwsock.c: beckerport_device::read() socket read operation failed with osd_file::error %i\n", int(filerr)); + std::error_condition filerr = m_pSocket->read(m_buf, 0, sizeof(m_buf), m_rx_pending); + if (filerr) + osd_printf_error("%s: coco_dwsock.c: beckerport_device::read() socket read operation failed with error %s:%d %s\n", tag(), filerr.category().name(), filerr.value(), filerr.message()); else m_head = 0; } - //printf("beckerport_device: status read. %i bytes remaining.\n", m_rx_pending); + //logerror("beckerport_device: status read. %i bytes remaining.\n", m_rx_pending); data = (m_rx_pending > 0) ? 2 : 0; break; case DWS_DATA: - if (!m_rx_pending) { - fprintf(stderr, "coco_dwsock.c: beckerport_device::read() buffer underrun\n"); + if (!m_rx_pending) + { + osd_printf_error("%s: coco_dwsock.c: beckerport_device::read() buffer underrun\n", tag()); break; } data = m_buf[m_head++]; m_rx_pending--; - //printf("beckerport_device: data read 1 byte (0x%02x). %i bytes remaining.\n", data&0xff, m_rx_pending); + //logerror("beckerport_device: data read 1 byte (0x%02x). %i bytes remaining.\n", data&0xff, m_rx_pending); break; default: fprintf(stderr, "%s: read from bad offset %d\n", __FILE__, offset); @@ -172,7 +169,7 @@ u8 beckerport_device::read(offs_t offset) void beckerport_device::write(offs_t offset, u8 data) { char d = char(data); - osd_file::error filerr; + std::error_condition filerr; u32 written; if (!m_pSocket) @@ -181,13 +178,13 @@ void beckerport_device::write(offs_t offset, u8 data) switch (offset) { case DWS_STATUS: - //printf("beckerport_write: error: write (0x%02x) to status register\n", d); + //logerror("beckerport_write: error: write (0x%02x) to status register\n", d); break; case DWS_DATA: filerr = m_pSocket->write(&d, 0, 1, written); - if (filerr != osd_file::error::NONE) - fprintf(stderr, "coco_dwsock.c: beckerport_device::write() socket write operation failed with osd_file::error %i\n", int(filerr)); - //printf("beckerport_write: data write one byte (0x%02x)\n", d & 0xff); + if (filerr) + osd_printf_error("%s: coco_dwsock.c: beckerport_device::write() socket write operation failed with error %s:%d %s\n", tag(), filerr.category().name(), filerr.value(), filerr.message()); + //logerror("beckerport_write: data write one byte (0x%02x)\n", d & 0xff); break; default: fprintf(stderr, "%s: write to bad offset %d\n", __FILE__, offset); diff --git a/src/devices/bus/crvision/slot.cpp b/src/devices/bus/crvision/slot.cpp index ecab87796e4..ce1e2a5ea1e 100644 --- a/src/devices/bus/crvision/slot.cpp +++ b/src/devices/bus/crvision/slot.cpp @@ -145,7 +145,7 @@ image_init_result crvision_cart_slot_device::call_load() if (size > 0x4800) { - seterror(IMAGE_ERROR_UNSPECIFIED, "Image extends beyond the expected size for an APF cart"); + seterror(image_error::INVALIDIMAGE, "Image extends beyond the expected size for an APF cart"); return image_init_result::FAIL; } diff --git a/src/devices/bus/electron/cart/ap5.cpp b/src/devices/bus/electron/cart/ap5.cpp index cc4c951a154..90c4188d7b1 100644 --- a/src/devices/bus/electron/cart/ap5.cpp +++ b/src/devices/bus/electron/cart/ap5.cpp @@ -161,7 +161,7 @@ image_init_result electron_ap5_device::load_rom(device_image_interface &image, g // socket accepts 8K and 16K ROM only if (size != 0x2000 && size != 0x4000) { - image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size: Only 8K/16K is supported"); + image.seterror(image_error::INVALIDIMAGE, "Invalid size: Only 8K/16K is supported"); return image_init_result::FAIL; } diff --git a/src/devices/bus/electron/cart/romp144.cpp b/src/devices/bus/electron/cart/romp144.cpp index de947454fd8..8bdeab7cc34 100644 --- a/src/devices/bus/electron/cart/romp144.cpp +++ b/src/devices/bus/electron/cart/romp144.cpp @@ -147,7 +147,7 @@ image_init_result electron_romp144_device::load_rom(device_image_interface &imag // socket accepts 8K and 16K ROM only if (size != 0x2000 && size != 0x4000) { - image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size: Only 8K/16K is supported"); + image.seterror(image_error::INVALIDIMAGE, "Invalid size: Only 8K/16K is supported"); return image_init_result::FAIL; } diff --git a/src/devices/bus/electron/cart/slot.cpp b/src/devices/bus/electron/cart/slot.cpp index 489cb567c4d..342cd3ae4f8 100644 --- a/src/devices/bus/electron/cart/slot.cpp +++ b/src/devices/bus/electron/cart/slot.cpp @@ -132,7 +132,7 @@ image_init_result electron_cartslot_device::call_load() if (size % 0x2000) { - seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size"); + seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size"); return image_init_result::FAIL; } @@ -152,7 +152,7 @@ image_init_result electron_cartslot_device::call_load() if ((upsize % 0x2000 && upsize != 0) || (losize % 0x2000 && losize != 0) || (romsize % 0x2000 && romsize != 0)) { - seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size"); + seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size"); return image_init_result::FAIL; } diff --git a/src/devices/bus/electron/plus1.cpp b/src/devices/bus/electron/plus1.cpp index 5bf61578b2b..4b2c3ba9dad 100644 --- a/src/devices/bus/electron/plus1.cpp +++ b/src/devices/bus/electron/plus1.cpp @@ -522,7 +522,7 @@ image_init_result electron_ap6_device::load_rom(device_image_interface &image, g // socket accepts 8K and 16K ROM only if (size != 0x2000 && size != 0x4000) { - image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size: Only 8K/16K is supported"); + image.seterror(image_error::INVALIDIMAGE, "Invalid size: Only 8K/16K is supported"); return image_init_result::FAIL; } diff --git a/src/devices/bus/electron/plus2.cpp b/src/devices/bus/electron/plus2.cpp index d379f053047..82e75bd6030 100644 --- a/src/devices/bus/electron/plus2.cpp +++ b/src/devices/bus/electron/plus2.cpp @@ -231,7 +231,7 @@ image_init_result electron_plus2_device::load_rom(device_image_interface &image, // socket accepts 8K and 16K ROM only if (size != 0x2000 && size != 0x4000) { - image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size: Only 8K/16K is supported"); + image.seterror(image_error::INVALIDIMAGE, "Invalid size: Only 8K/16K is supported"); return image_init_result::FAIL; } diff --git a/src/devices/bus/electron/rombox.cpp b/src/devices/bus/electron/rombox.cpp index 920419c2d66..47040271e7f 100644 --- a/src/devices/bus/electron/rombox.cpp +++ b/src/devices/bus/electron/rombox.cpp @@ -185,7 +185,7 @@ image_init_result electron_rombox_device::load_rom(device_image_interface &image // socket accepts 8K and 16K ROM only if (size != 0x2000 && size != 0x4000) { - image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size: Only 8K/16K is supported"); + image.seterror(image_error::INVALIDIMAGE, "Invalid size: Only 8K/16K is supported"); return image_init_result::FAIL; } diff --git a/src/devices/bus/electron/romboxp.cpp b/src/devices/bus/electron/romboxp.cpp index e6cfd472989..59d83bc4121 100644 --- a/src/devices/bus/electron/romboxp.cpp +++ b/src/devices/bus/electron/romboxp.cpp @@ -328,7 +328,7 @@ image_init_result electron_romboxp_device::load_rom(device_image_interface &imag // socket accepts 8K and 16K ROM only if (size != 0x2000 && size != 0x4000) { - image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size: Only 8K/16K is supported"); + image.seterror(image_error::INVALIDIMAGE, "Invalid size: Only 8K/16K is supported"); return image_init_result::FAIL; } diff --git a/src/devices/bus/electron/sidewndr.cpp b/src/devices/bus/electron/sidewndr.cpp index e66ac800f3c..a2ab8011b09 100644 --- a/src/devices/bus/electron/sidewndr.cpp +++ b/src/devices/bus/electron/sidewndr.cpp @@ -174,7 +174,7 @@ image_init_result electron_sidewndr_device::load_rom(device_image_interface &ima // socket accepts 8K and 16K ROM only if (size != 0x2000 && size != 0x4000) { - image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size: Only 8K/16K is supported"); + image.seterror(image_error::INVALIDIMAGE, "Invalid size: Only 8K/16K is supported"); return image_init_result::FAIL; } diff --git a/src/devices/bus/gamate/slot.cpp b/src/devices/bus/gamate/slot.cpp index 625e4103482..3f98a30927d 100644 --- a/src/devices/bus/gamate/slot.cpp +++ b/src/devices/bus/gamate/slot.cpp @@ -134,7 +134,7 @@ image_init_result gamate_cart_slot_device::call_load() if (len > 0x80000) { - seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size"); + seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size"); return image_init_result::FAIL; } diff --git a/src/devices/bus/gameboy/gb_slot.cpp b/src/devices/bus/gameboy/gb_slot.cpp index a408b9d15ff..79708f95314 100644 --- a/src/devices/bus/gameboy/gb_slot.cpp +++ b/src/devices/bus/gameboy/gb_slot.cpp @@ -267,7 +267,7 @@ image_init_result gb_cart_slot_device_base::call_load() /* Verify that the file contains 16kb blocks */ if ((len == 0) || ((len % 0x4000) != 0)) { - seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid rom file size\n"); + seterror(image_error::INVALIDIMAGE, "Invalid ROM file size\n"); return image_init_result::FAIL; } } diff --git a/src/devices/bus/gba/gba_slot.cpp b/src/devices/bus/gba/gba_slot.cpp index 06ec379cf77..ac036718e2d 100644 --- a/src/devices/bus/gba/gba_slot.cpp +++ b/src/devices/bus/gba/gba_slot.cpp @@ -625,7 +625,7 @@ image_init_result gba_cart_slot_device::call_load() uint32_t size = loaded_through_softlist() ? get_software_region_length("rom") : length(); if (size > 0x4000000) { - seterror(IMAGE_ERROR_UNSPECIFIED, "Attempted loading a cart larger than 64MB"); + seterror(image_error::INVALIDIMAGE, "Attempted loading a cart larger than 64MB"); return image_init_result::FAIL; } diff --git a/src/devices/bus/isa/sc499.cpp b/src/devices/bus/isa/sc499.cpp index c313dd84148..bc942ede9e8 100644 --- a/src/devices/bus/isa/sc499.cpp +++ b/src/devices/bus/isa/sc499.cpp @@ -16,7 +16,7 @@ #include "emu.h" #include "sc499.h" -#include "formats/ioprocs.h" + #define VERBOSE 0 @@ -1310,18 +1310,17 @@ void sc499_ctape_image_device::write_block(int block_num, uint8_t *ptr) image_init_result sc499_ctape_image_device::call_load() { - uint32_t size; - io_generic io; - io.file = (device_image_interface *)this; - io.procs = &image_ioprocs; - io.filler = 0xff; - - size = io_generic_size(&io); - m_ctape_data.resize(size); - - io_generic_read(&io, &m_ctape_data[0], 0, size); - - return image_init_result::PASS; + try + { + auto const size = length(); + m_ctape_data.resize(size); + if (!fseek(0, SEEK_SET) && (fread(m_ctape_data.data(), size) == size)) + return image_init_result::PASS; + } + catch (...) + { + } + return image_init_result::FAIL; } void sc499_ctape_image_device::call_unload() diff --git a/src/devices/bus/m5/slot.cpp b/src/devices/bus/m5/slot.cpp index a1b9d551b23..a75599bb807 100644 --- a/src/devices/bus/m5/slot.cpp +++ b/src/devices/bus/m5/slot.cpp @@ -166,7 +166,7 @@ image_init_result m5_cart_slot_device::call_load() if (size > 0x5000 && m_type == M5_STD) { - seterror(IMAGE_ERROR_UNSPECIFIED, "Image extends beyond the expected size for an M5 cart"); + seterror(image_error::INVALIDIMAGE, "Image extends beyond the expected size for an M5 cart"); return image_init_result::FAIL; } diff --git a/src/devices/bus/mc10/mc10_cart.cpp b/src/devices/bus/mc10/mc10_cart.cpp index e8addd9939a..088b3ca8c81 100644 --- a/src/devices/bus/mc10/mc10_cart.cpp +++ b/src/devices/bus/mc10/mc10_cart.cpp @@ -96,14 +96,14 @@ image_init_result mc10cart_slot_device::call_load() memory_region *romregion(loaded_through_softlist() ? memregion("rom") : nullptr); if (loaded_through_softlist() && !romregion) { - seterror(IMAGE_ERROR_INVALIDIMAGE, "Software list item has no 'rom' data area"); + seterror(image_error::INVALIDIMAGE, "Software list item has no 'rom' data area"); return image_init_result::FAIL; } u32 const len(loaded_through_softlist() ? romregion->bytes() : length()); if (len > m_cart->max_rom_length()) { - seterror(IMAGE_ERROR_UNSUPPORTED, "Unsupported cartridge size"); + seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size"); return image_init_result::FAIL; } @@ -114,7 +114,7 @@ image_init_result mc10cart_slot_device::call_load() u32 const cnt(fread(romregion->base(), len)); if (cnt != len) { - seterror(IMAGE_ERROR_UNSPECIFIED, "Error reading cartridge file"); + seterror(image_error::UNSPECIFIED, "Error reading cartridge file"); return image_init_result::FAIL; } } diff --git a/src/devices/bus/msx_slot/cartridge.cpp b/src/devices/bus/msx_slot/cartridge.cpp index 87b89f93c78..30c9f0a2b00 100644 --- a/src/devices/bus/msx_slot/cartridge.cpp +++ b/src/devices/bus/msx_slot/cartridge.cpp @@ -165,7 +165,7 @@ image_init_result msx_slot_cartridge_device::call_load() if (fread(m_cartridge->get_rom_base(), length) != length) { - seterror(IMAGE_ERROR_UNSPECIFIED, "Unable to fully read file"); + seterror(image_error::UNSPECIFIED, "Unable to fully read file"); return image_init_result::FAIL; } diff --git a/src/devices/bus/nes/nes_slot.cpp b/src/devices/bus/nes/nes_slot.cpp index 812aa738399..f75694bd041 100644 --- a/src/devices/bus/nes/nes_slot.cpp +++ b/src/devices/bus/nes/nes_slot.cpp @@ -887,7 +887,7 @@ image_init_result nes_cart_slot_device::call_load() else { logerror("%s is NOT a file in either iNES or UNIF format.\n", filename()); - seterror(IMAGE_ERROR_UNSPECIFIED, "File is neither iNES or UNIF format"); + seterror(image_error::INVALIDIMAGE, "File is neither iNES or UNIF format"); return image_init_result::FAIL; } } diff --git a/src/devices/bus/nubus/nubus_image.cpp b/src/devices/bus/nubus/nubus_image.cpp index 8c94882cd4f..80875c6bd41 100644 --- a/src/devices/bus/nubus/nubus_image.cpp +++ b/src/devices/bus/nubus/nubus_image.cpp @@ -295,8 +295,9 @@ void nubus_image_device::file_cmd_w(uint32_t data) 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')); - 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::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; @@ -306,8 +307,9 @@ void nubus_image_device::file_cmd_w(uint32_t data) 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; diff --git a/src/devices/bus/plus4/exp.cpp b/src/devices/bus/plus4/exp.cpp index fb0387908ef..487de7ea3c2 100644 --- a/src/devices/bus/plus4/exp.cpp +++ b/src/devices/bus/plus4/exp.cpp @@ -118,7 +118,7 @@ image_init_result plus4_expansion_slot_device::call_load() if ((m_card->m_c1l_size & (m_card->m_c1l_size - 1)) || (m_card->m_c1h_size & (m_card->m_c1h_size - 1)) || (m_card->m_c2l_size & (m_card->m_c2l_size - 1)) || (m_card->m_c2h_size & (m_card->m_c2h_size - 1))) { - seterror(IMAGE_ERROR_UNSPECIFIED, "ROM size must be power of 2"); + seterror(image_error::INVALIDIMAGE, "ROM size must be power of 2"); return image_init_result::FAIL; } } diff --git a/src/devices/bus/scv/slot.cpp b/src/devices/bus/scv/slot.cpp index 65081801f30..86dc2d810c1 100644 --- a/src/devices/bus/scv/slot.cpp +++ b/src/devices/bus/scv/slot.cpp @@ -157,7 +157,7 @@ image_init_result scv_cart_slot_device::call_load() if (len > 0x20000) { - seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size"); + seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size"); return image_init_result::FAIL; } diff --git a/src/devices/bus/sega8/sega8_slot.cpp b/src/devices/bus/sega8/sega8_slot.cpp index 8330fc68915..8a998e71bf0 100644 --- a/src/devices/bus/sega8/sega8_slot.cpp +++ b/src/devices/bus/sega8/sega8_slot.cpp @@ -397,7 +397,7 @@ image_init_result sega8_cart_slot_device::call_load() if (m_is_card && len > 0x8000) { - seterror(IMAGE_ERROR_UNSPECIFIED, "Attempted loading a card larger than 32KB"); + seterror(image_error::INVALIDIMAGE, "Attempted loading a card larger than 32KB"); return image_init_result::FAIL; } diff --git a/src/devices/bus/spectrum/intf2.cpp b/src/devices/bus/spectrum/intf2.cpp index 7442dfe49a9..afce2005a99 100644 --- a/src/devices/bus/spectrum/intf2.cpp +++ b/src/devices/bus/spectrum/intf2.cpp @@ -99,7 +99,7 @@ DEVICE_IMAGE_LOAD_MEMBER(spectrum_intf2_device::cart_load) if (size != 0x4000) { - image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size"); + image.seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size"); return image_init_result::FAIL; } diff --git a/src/devices/bus/ti99/gromport/cartridges.cpp b/src/devices/bus/ti99/gromport/cartridges.cpp index 20831395a0c..2f5a558d29b 100644 --- a/src/devices/bus/ti99/gromport/cartridges.cpp +++ b/src/devices/bus/ti99/gromport/cartridges.cpp @@ -16,6 +16,10 @@ #include "cartridges.h" #include "corestr.h" +#include "ioprocs.h" +#include "unzip.h" +#include "xmlfile.h" + #define LOG_WARN (1U<<1) // Warnings #define LOG_CONFIG (1U<<2) // Configuration @@ -260,14 +264,14 @@ image_init_result ti99_cartridge_device::call_load() auto reader = std::make_unique<rpk_reader>(pcbdefs); try { - m_rpk = reader->open(machine().options(), filename(), machine().system().name); + m_rpk = reader->open(machine().options(), image_core_file(), machine().system().name); m_pcbtype = m_rpk->get_type(); } catch (rpk_exception& err) { LOGMASKED(LOG_WARN, "Failed to load cartridge '%s': %s\n", basename(), err.to_string().c_str()); m_rpk = nullptr; - m_err = IMAGE_ERROR_INVALIDIMAGE; + m_err = image_error::INVALIDIMAGE; return image_init_result::FAIL; } } @@ -1553,8 +1557,8 @@ void ti99_cartridge_device::rpk::close() throw emu_fatalerror("ti99_cartridge_device::rpk::close: Buffer is null or length is 0"); emu_file file(m_options.nvram_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - osd_file::error filerr = file.open(socket.second->get_pathname()); - if (filerr == osd_file::error::NONE) + std::error_condition const filerr = file.open(socket.second->get_pathname()); + if (!filerr) file.write(socket.second->get_contents(), socket.second->get_content_length()); } @@ -1641,8 +1645,8 @@ std::unique_ptr<ti99_cartridge_device::rpk_socket> ti99_cartridge_device::rpk_re catch (std::bad_alloc const &) { throw rpk_exception(RPK_OUT_OF_MEMORY); } // and unzip file from the zip file - util::archive_file::error ziperr = zip.decompress(contents.get(), length); - if (ziperr != util::archive_file::error::NONE) + std::error_condition const ziperr = zip.decompress(contents.get(), length); + if (ziperr) { if (ziperr == util::archive_file::error::UNSUPPORTED) throw rpk_exception(RPK_ZIP_UNSUPPORTED); else throw rpk_exception(RPK_ZIP_ERROR); @@ -1727,9 +1731,9 @@ std::unique_ptr<ti99_cartridge_device::rpk_socket> ti99_cartridge_device::rpk_re // try to open the battery file and read it if possible emu_file file(options.nvram_directory(), OPEN_FLAG_READ); - osd_file::error filerr = file.open(ram_pname); + std::error_condition const filerr = file.open(ram_pname); int bytes_read = 0; - if (filerr == osd_file::error::NONE) + if (!filerr) bytes_read = file.read(contents.get(), length); // fill remaining bytes (if necessary) @@ -1747,33 +1751,30 @@ std::unique_ptr<ti99_cartridge_device::rpk_socket> ti99_cartridge_device::rpk_re system_name - name of the driver (also just for NVRAM handling) -------------------------------------------------*/ -ti99_cartridge_device::rpk* ti99_cartridge_device::rpk_reader::open(emu_options &options, const char *filename, const char *system_name) +ti99_cartridge_device::rpk* ti99_cartridge_device::rpk_reader::open(emu_options &options, util::core_file &file, const char *system_name) { - util::archive_file::error ziperr; - - util::archive_file::ptr zipfile; - - std::vector<char> layout_text; - - int i; - auto newrpk = new rpk(options, system_name); try { - /* open the ZIP file */ - ziperr = util::archive_file::open_zip(filename, zipfile); - if (ziperr != util::archive_file::error::NONE) throw rpk_exception(RPK_NOT_ZIP_FORMAT); + // open the ZIP file + auto reader = util::core_file_read(file); + if (!reader) throw rpk_exception(RPK_OUT_OF_MEMORY); + + std::error_condition ziperr; + util::archive_file::ptr zipfile; + ziperr = util::archive_file::open_zip(std::move(reader), zipfile); + if (ziperr) throw rpk_exception(RPK_NOT_ZIP_FORMAT); - /* find the layout.xml file */ + // find the layout.xml file if (find_file(*zipfile, "layout.xml", 0) < 0) throw rpk_exception(RPK_MISSING_LAYOUT); - /* reserve space for the layout file contents (+1 for the termination) */ - layout_text.resize(zipfile->current_uncompressed_length() + 1); + // reserve space for the layout file contents (+1 for the termination) + std::vector<char> layout_text(zipfile->current_uncompressed_length() + 1); - /* uncompress the layout text */ + // uncompress the layout text ziperr = zipfile->decompress(&layout_text[0], zipfile->current_uncompressed_length()); - if (ziperr != util::archive_file::error::NONE) + if (ziperr) { if (ziperr == util::archive_file::error::UNSUPPORTED) throw rpk_exception(RPK_ZIP_UNSUPPORTED); else throw rpk_exception(RPK_ZIP_ERROR); @@ -1781,7 +1782,7 @@ ti99_cartridge_device::rpk* ti99_cartridge_device::rpk_reader::open(emu_options layout_text[zipfile->current_uncompressed_length()] = '\0'; // Null-terminate - /* parse the layout text */ + // parse the layout text util::xml::file::ptr const layout_xml = util::xml::file::string_read(&layout_text[0], nullptr); if (!layout_xml) throw rpk_exception(RPK_XML_ERROR); @@ -1808,7 +1809,7 @@ ti99_cartridge_device::rpk* ti99_cartridge_device::rpk_reader::open(emu_options if (!pcb_type) throw rpk_exception(RPK_INVALID_LAYOUT, "<pcb> must have a 'type' attribute"); LOGMASKED(LOG_RPK, "[RPK handler] Cartridge says it has PCB type '%s'\n", *pcb_type); - i=0; + int i=0; do { if (*pcb_type == m_types[i].name) diff --git a/src/devices/bus/ti99/gromport/cartridges.h b/src/devices/bus/ti99/gromport/cartridges.h index db2de6b2672..df94321a5f9 100644 --- a/src/devices/bus/ti99/gromport/cartridges.h +++ b/src/devices/bus/ti99/gromport/cartridges.h @@ -8,12 +8,15 @@ #pragma once -#include "emuopts.h" +#include "gromport.h" + #include "machine/tmc0430.h" + +#include "emuopts.h" #include "softlist_dev.h" -#include "gromport.h" -#include "unzip.h" -#include "xmlfile.h" + +#include "utilfwd.h" + namespace bus::ti99::gromport { @@ -137,7 +140,7 @@ private: public: rpk_reader(const pcb_type *types) : m_types(types) { } - rpk *open(emu_options &options, const char *filename, const char *system_name); + rpk *open(emu_options &options, util::core_file &file, const char *system_name); private: int find_file(util::archive_file &zip, const char *filename, uint32_t crc); diff --git a/src/devices/bus/vboy/slot.cpp b/src/devices/bus/vboy/slot.cpp index 083c0db745b..70dd9e05063 100644 --- a/src/devices/bus/vboy/slot.cpp +++ b/src/devices/bus/vboy/slot.cpp @@ -54,14 +54,14 @@ image_init_result vboy_cart_slot_device::call_load() memory_region *romregion(loaded_through_softlist() ? memregion("rom") : nullptr); if (loaded_through_softlist() && !romregion) { - seterror(IMAGE_ERROR_INVALIDIMAGE, "Software list item has no 'rom' data area"); + seterror(image_error::INVALIDIMAGE, "Software list item has no 'rom' data area"); return image_init_result::FAIL; } u32 const len(loaded_through_softlist() ? romregion->bytes() : length()); if ((0x0000'0003 & len) || (0x0100'0000 < len)) { - seterror(IMAGE_ERROR_UNSUPPORTED, "Unsupported cartridge size (must be a multiple of 4 bytes no larger than 16 MiB)"); + seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size (must be a multiple of 4 bytes no larger than 16 MiB)"); return image_init_result::FAIL; } @@ -72,7 +72,7 @@ image_init_result vboy_cart_slot_device::call_load() u32 const cnt(fread(romregion->base(), len)); if (cnt != len) { - seterror(IMAGE_ERROR_UNSPECIFIED, "Error reading cartridge file"); + seterror(image_error::UNSPECIFIED, "Error reading cartridge file"); return image_init_result::FAIL; } } diff --git a/src/devices/bus/vc4000/slot.cpp b/src/devices/bus/vc4000/slot.cpp index f33e5623639..8de01177448 100644 --- a/src/devices/bus/vc4000/slot.cpp +++ b/src/devices/bus/vc4000/slot.cpp @@ -176,7 +176,7 @@ image_init_result vc4000_cart_slot_device::call_load() if (size > 0x1800) { - seterror(IMAGE_ERROR_UNSPECIFIED, "Image extends beyond the expected size for a VC4000 cart"); + seterror(image_error::INVALIDIMAGE, "Image extends beyond the expected size for a VC4000 cart"); return image_init_result::FAIL; } diff --git a/src/devices/bus/vcs/vcs_slot.cpp b/src/devices/bus/vcs/vcs_slot.cpp index 28d402322d5..5efcc4ba32d 100644 --- a/src/devices/bus/vcs/vcs_slot.cpp +++ b/src/devices/bus/vcs/vcs_slot.cpp @@ -200,7 +200,7 @@ image_init_result vcs_cart_slot_device::call_load() break; default: - seterror(IMAGE_ERROR_UNSUPPORTED, "Invalid rom file size" ); + seterror(image_error::INVALIDIMAGE, "Invalid ROM file size" ); return image_init_result::FAIL; } diff --git a/src/devices/bus/vectrex/slot.cpp b/src/devices/bus/vectrex/slot.cpp index 014b6c9516c..9e3ebd14fa6 100644 --- a/src/devices/bus/vectrex/slot.cpp +++ b/src/devices/bus/vectrex/slot.cpp @@ -145,7 +145,7 @@ image_init_result vectrex_cart_slot_device::call_load() if (size > 0x10000) { - seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size"); + seterror(image_error::INVALIDIMAGE, "Unsupported cartridge size"); return image_init_result::FAIL; } @@ -160,7 +160,7 @@ image_init_result vectrex_cart_slot_device::call_load() // Verify the file is accepted by the Vectrex bios if (memcmp(ROM, "g GCE", 5)) { - seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid image"); + seterror(image_error::INVALIDIMAGE, "Invalid image"); return image_init_result::FAIL; } diff --git a/src/devices/bus/vsmile/vsmile_slot.cpp b/src/devices/bus/vsmile/vsmile_slot.cpp index 59f039c685d..9c2906826c9 100644 --- a/src/devices/bus/vsmile/vsmile_slot.cpp +++ b/src/devices/bus/vsmile/vsmile_slot.cpp @@ -139,7 +139,7 @@ image_init_result vsmile_cart_slot_device::call_load() uint32_t size = loaded_through_softlist() ? get_software_region_length("rom") : length(); if (size > 0x1000000) { - seterror(IMAGE_ERROR_UNSPECIFIED, "Attempted loading a cart larger than 16MB"); + seterror(image_error::INVALIDIMAGE, "Attempted loading a cart larger than 16MB"); return image_init_result::FAIL; } diff --git a/src/devices/imagedev/cassette.cpp b/src/devices/imagedev/cassette.cpp index 778b296d63d..52103cb1e7d 100644 --- a/src/devices/imagedev/cassette.cpp +++ b/src/devices/imagedev/cassette.cpp @@ -9,9 +9,12 @@ *********************************************************************/ #include "emu.h" -#include "formats/imageutl.h" #include "cassette.h" +#include "formats/imageutl.h" + +#include "util/ioprocs.h" + #define LOG_WARN (1U<<1) // Warnings #define LOG_DETAIL (1U<<2) // Details @@ -19,6 +22,7 @@ #include "logmacro.h" + // device type definition DEFINE_DEVICE_TYPE(CASSETTE, cassette_image_device, "cassette_image", "Cassette") @@ -253,12 +257,24 @@ image_init_result cassette_image_device::internal_load(bool is_create) device_image_interface *image = nullptr; interface(image); + check_for_file(); if (is_create || (length()==0)) // empty existing images are fine to write over. { - // creating an image - err = cassette_image::create((void *)image, &image_ioprocs, &cassette_image::wavfile_format, m_create_opts, cassette_image::FLAG_READWRITE|cassette_image::FLAG_SAVEONEXIT, m_cassette); - if (err != cassette_image::error::SUCCESS) - goto error; + auto io = util::core_file_read_write(image_core_file(), 0x00); + if (io) + { + // creating an image + err = cassette_image::create( + std::move(io), + &cassette_image::wavfile_format, + m_create_opts, + cassette_image::FLAG_READWRITE|cassette_image::FLAG_SAVEONEXIT, + m_cassette); + } + else + { + err = cassette_image::error::OUT_OF_MEMORY; + } } else { @@ -269,11 +285,24 @@ image_init_result cassette_image_device::internal_load(bool is_create) // we probably don't want to retry... retry = false; - // try opening the cassette - int cassette_flags = is_readonly() - ? cassette_image::FLAG_READONLY - : (cassette_image::FLAG_READWRITE | cassette_image::FLAG_SAVEONEXIT); - err = cassette_image::open_choices((void *)image, &image_ioprocs, filetype(), m_formats, cassette_flags, m_cassette); + auto io = util::core_file_read_write(image_core_file(), 0x00); + if (io) + { + // try opening the cassette + int const cassette_flags = is_readonly() + ? cassette_image::FLAG_READONLY + : (cassette_image::FLAG_READWRITE | cassette_image::FLAG_SAVEONEXIT); + err = cassette_image::open_choices( + std::move(io), + filetype(), + m_formats, + cassette_flags, + m_cassette); + } + else + { + err = cassette_image::error::OUT_OF_MEMORY; + } // special case - if we failed due to readwrite not being supported, make the image be read only and retry if (err == cassette_image::error::READ_WRITE_UNSUPPORTED) @@ -283,47 +312,48 @@ image_init_result cassette_image_device::internal_load(bool is_create) } } while(retry); - - if (err != cassette_image::error::SUCCESS) - goto error; } - /* set to default state, but only change the UI state */ - change_state(m_default_state, CASSETTE_MASK_UISTATE); - - /* reset the position */ - m_position = 0.0; - m_position_time = machine().time().as_double(); + if (err == cassette_image::error::SUCCESS) + { + /* set to default state, but only change the UI state */ + change_state(m_default_state, CASSETTE_MASK_UISTATE); - /* default channel to 0, speed multiplier to 1 */ - m_channel = 0; - m_speed = 1; - m_direction = 1; + /* reset the position */ + m_position = 0.0; + m_position_time = machine().time().as_double(); - return image_init_result::PASS; + /* default channel to 0, speed multiplier to 1 */ + m_channel = 0; + m_speed = 1; + m_direction = 1; -error: - image_error_t imgerr = IMAGE_ERROR_UNSPECIFIED; - switch(err) + return image_init_result::PASS; + } + else { - case cassette_image::error::INTERNAL: - imgerr = IMAGE_ERROR_INTERNAL; - break; - case cassette_image::error::UNSUPPORTED: - imgerr = IMAGE_ERROR_UNSUPPORTED; - break; - case cassette_image::error::OUT_OF_MEMORY: - imgerr = IMAGE_ERROR_OUTOFMEMORY; - break; - case cassette_image::error::INVALID_IMAGE: - imgerr = IMAGE_ERROR_INVALIDIMAGE; - break; - default: - imgerr = IMAGE_ERROR_UNSPECIFIED; - break; + std::error_condition imgerr = image_error::UNSPECIFIED; + switch(err) + { + case cassette_image::error::INTERNAL: + imgerr = image_error::INTERNAL; + break; + case cassette_image::error::UNSUPPORTED: + imgerr = image_error::UNSUPPORTED; + break; + case cassette_image::error::OUT_OF_MEMORY: + imgerr = std::errc::not_enough_memory; + break; + case cassette_image::error::INVALID_IMAGE: + imgerr = image_error::INVALIDIMAGE; + break; + default: + imgerr = image_error::UNSPECIFIED; + break; + } + image->seterror(imgerr, nullptr); + return image_init_result::FAIL; } - image->seterror(imgerr, "" ); - return image_init_result::FAIL; } diff --git a/src/devices/imagedev/chd_cd.cpp b/src/devices/imagedev/chd_cd.cpp index 5daaba2ed45..4eacb3d3b58 100644 --- a/src/devices/imagedev/chd_cd.cpp +++ b/src/devices/imagedev/chd_cd.cpp @@ -83,17 +83,16 @@ void cdrom_image_device::device_stop() image_init_result cdrom_image_device::call_load() { - chd_error err = (chd_error)0; - chd_file *chd = nullptr; + std::error_condition err; + chd_file *chd = nullptr; if (m_cdrom_handle) cdrom_close(m_cdrom_handle); - if (!loaded_through_softlist()) - { + if (!loaded_through_softlist()) { if (is_filetype("chd") && is_loaded()) { - err = m_self_chd.open( image_core_file() ); /* CDs are never writeable */ - if ( err ) + err = m_self_chd.open(util::core_file_read_write(image_core_file())); // CDs are never writeable + if (err) goto error; chd = &m_self_chd; } @@ -103,20 +102,20 @@ image_init_result cdrom_image_device::call_load() /* open the CHD file */ if (chd) { - m_cdrom_handle = cdrom_open( chd ); + m_cdrom_handle = cdrom_open(chd); } else { m_cdrom_handle = cdrom_open(filename()); } - if ( ! m_cdrom_handle ) + if (!m_cdrom_handle) goto error; return image_init_result::PASS; error: - if ( chd && chd == &m_self_chd ) - m_self_chd.close( ); - if ( err ) - seterror( IMAGE_ERROR_UNSPECIFIED, chd_file::error_string( err ) ); + if (chd && chd == &m_self_chd) + m_self_chd.close(); + if (err) + seterror(err, nullptr); return image_init_result::FAIL; } diff --git a/src/devices/imagedev/diablo.cpp b/src/devices/imagedev/diablo.cpp index 58a34a664f6..be09c263719 100644 --- a/src/devices/imagedev/diablo.cpp +++ b/src/devices/imagedev/diablo.cpp @@ -112,8 +112,6 @@ image_init_result diablo_image_device::call_load() image_init_result diablo_image_device::call_create(int create_format, util::option_resolution *create_args) { - int err; - if (!create_args) throw emu_fatalerror("diablo_image_device::call_create: Expected create_args to not be nullptr"); @@ -127,15 +125,15 @@ image_init_result diablo_image_device::call_create(int create_format, util::opti /* create the CHD file */ chd_codec_type compression[4] = { CHD_CODEC_NONE }; - err = m_origchd.create(image_core_file(), (uint64_t)totalsectors * (uint64_t)sectorsize, hunksize, sectorsize, compression); - if (err != CHDERR_NONE) + std::error_condition err = m_origchd.create(util::core_file_read_write(image_core_file()), uint64_t(totalsectors) * uint64_t(sectorsize), hunksize, sectorsize, compression); + if (err) return image_init_result::FAIL; /* if we created the image and hence, have metadata to set, set the metadata */ err = m_origchd.write_metadata(HARD_DISK_METADATA_TAG, 0, string_format(HARD_DISK_METADATA_FORMAT, cylinders, heads, sectors, sectorsize)); m_origchd.close(); - if (err != CHDERR_NONE) + if (err) return image_init_result::FAIL; return internal_load_dsk(); @@ -164,28 +162,28 @@ void diablo_image_device::call_unload() open_disk_diff - open a DISK diff file -------------------------------------------------*/ -static chd_error open_disk_diff(emu_options &options, const char *name, chd_file &source, chd_file &diff_chd) +static std::error_condition open_disk_diff(emu_options &options, const char *name, chd_file &source, chd_file &diff_chd) { std::string fname = std::string(name).append(".dif"); /* try to open the diff */ //printf("Opening differencing image file: %s\n", fname.c_str()); emu_file diff_file(options.diff_directory(), OPEN_FLAG_READ | OPEN_FLAG_WRITE); - osd_file::error filerr = diff_file.open(fname.c_str()); - if (filerr == osd_file::error::NONE) + std::error_condition filerr = diff_file.open(fname); + if (!filerr) { std::string fullpath(diff_file.fullpath()); diff_file.close(); //printf("Opening differencing image file: %s\n", fullpath.c_str()); - return diff_chd.open(fullpath.c_str(), true, &source); + return diff_chd.open(fullpath, true, &source); } /* didn't work; try creating it instead */ //printf("Creating differencing image: %s\n", fname.c_str()); diff_file.set_openflags(OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - filerr = diff_file.open(fname.c_str()); - if (filerr == osd_file::error::NONE) + filerr = diff_file.open(fname); + if (!filerr) { std::string fullpath(diff_file.fullpath()); diff_file.close(); @@ -193,19 +191,19 @@ static chd_error open_disk_diff(emu_options &options, const char *name, chd_file /* create the CHD */ //printf("Creating differencing image file: %s\n", fullpath.c_str()); chd_codec_type compression[4] = { CHD_CODEC_NONE }; - chd_error err = diff_chd.create(fullpath.c_str(), source.logical_bytes(), source.hunk_bytes(), compression, source); - if (err != CHDERR_NONE) + std::error_condition err = diff_chd.create(fullpath, source.logical_bytes(), source.hunk_bytes(), compression, source); + if (err) return err; return diff_chd.clone_all_metadata(source); } - return CHDERR_FILE_NOT_FOUND; + return std::errc::no_such_file_or_directory; } image_init_result diablo_image_device::internal_load_dsk() { - chd_error err = CHDERR_NONE; + std::error_condition err; m_chd = nullptr; @@ -219,18 +217,18 @@ image_init_result diablo_image_device::internal_load_dsk() } else { - err = m_origchd.open(image_core_file(), true); - if (err == CHDERR_NONE) + err = m_origchd.open(util::core_file_read_write(image_core_file()), true); + if (!err) { m_chd = &m_origchd; } - else if (err == CHDERR_FILE_NOT_WRITEABLE) + else if (err == chd_file::error::FILE_NOT_WRITEABLE) { - err = m_origchd.open(image_core_file(), false); - if (err == CHDERR_NONE) + err = m_origchd.open(util::core_file_read_write(image_core_file()), false); + if (!err) { err = open_disk_diff(device().machine().options(), basename_noext(), m_origchd, m_diffchd); - if (err == CHDERR_NONE) + if (!err) { m_chd = &m_diffchd; } @@ -250,7 +248,7 @@ image_init_result diablo_image_device::internal_load_dsk() m_origchd.close(); m_diffchd.close(); m_chd = nullptr; - seterror(IMAGE_ERROR_UNSPECIFIED, chd_file::error_string(err)); + seterror(err, nullptr); return image_init_result::FAIL; } diff --git a/src/devices/imagedev/flopdrv.cpp b/src/devices/imagedev/flopdrv.cpp index 6ab5028f2d8..316b66ef713 100644 --- a/src/devices/imagedev/flopdrv.cpp +++ b/src/devices/imagedev/flopdrv.cpp @@ -14,9 +14,13 @@ */ #include "emu.h" -#include "formats/imageutl.h" #include "flopdrv.h" +#include "formats/imageutl.h" + +#include "util/ioprocs.h" + + #define VERBOSE 0 #define LOG(x) do { if (VERBOSE) logerror x; } while (0) @@ -33,7 +37,7 @@ struct floppy_error_map { floperr_t ferr; - image_error_t ierr; + std::error_condition ierr; const char *message; }; @@ -45,11 +49,11 @@ struct floppy_error_map static const floppy_error_map errmap[] = { - { FLOPPY_ERROR_SUCCESS, IMAGE_ERROR_SUCCESS }, - { FLOPPY_ERROR_INTERNAL, IMAGE_ERROR_INTERNAL }, - { FLOPPY_ERROR_UNSUPPORTED, IMAGE_ERROR_UNSUPPORTED }, - { FLOPPY_ERROR_OUTOFMEMORY, IMAGE_ERROR_OUTOFMEMORY }, - { FLOPPY_ERROR_INVALIDIMAGE, IMAGE_ERROR_INVALIDIMAGE } + { FLOPPY_ERROR_SUCCESS, { } }, + { FLOPPY_ERROR_INTERNAL, { image_error::INTERNAL } }, + { FLOPPY_ERROR_UNSUPPORTED, { image_error::UNSUPPORTED } }, + { FLOPPY_ERROR_OUTOFMEMORY, { std::errc::not_enough_memory } }, + { FLOPPY_ERROR_INVALIDIMAGE, { image_error::INVALIDIMAGE } } }; /*************************************************************************** @@ -418,50 +422,52 @@ void legacy_floppy_image_device::floppy_drive_set_controller(device_t *controlle image_init_result legacy_floppy_image_device::internal_floppy_device_load(bool is_create, int create_format, util::option_resolution *create_args) { - floperr_t err; - const struct FloppyFormat *floppy_options; - int floppy_flags, i; + const struct FloppyFormat *floppy_options = m_config->formats; - device_image_interface *image = nullptr; - interface(image); /* figure out the floppy options */ - floppy_options = m_config->formats; - - if (is_create) + floperr_t err; + check_for_file(); + auto io = util::core_file_read_write(image_core_file(), 0xff); + if (!io) + { + err = FLOPPY_ERROR_OUTOFMEMORY; + } + else if (is_create) { /* creating an image */ assert(create_format >= 0); - err = floppy_create((void *) image, &image_ioprocs, &floppy_options[create_format], create_args, &m_floppy); - if (err) - goto error; + err = floppy_create(std::move(io), &floppy_options[create_format], create_args, &m_floppy); } else { /* opening an image */ - floppy_flags = !is_readonly() ? FLOPPY_FLAGS_READWRITE : FLOPPY_FLAGS_READONLY; - err = floppy_open_choices((void *) image, &image_ioprocs, filetype(), floppy_options, floppy_flags, &m_floppy); - if (err) - goto error; + int const floppy_flags = !is_readonly() ? FLOPPY_FLAGS_READWRITE : FLOPPY_FLAGS_READONLY; + err = floppy_open_choices(std::move(io), filetype(), floppy_options, floppy_flags, &m_floppy); } - if (floppy_callbacks(m_floppy)->get_heads_per_disk && floppy_callbacks(m_floppy)->get_tracks_per_disk) - { - floppy_drive_set_geometry_absolute(floppy_get_tracks_per_disk(m_floppy),floppy_get_heads_per_disk(m_floppy)); - } - /* disk changed */ - m_dskchg = CLEAR_LINE; - // If we have one of our hacky load procs, call it - if (m_load_proc) - m_load_proc(*this, is_create); + if (!err) + { + if (floppy_callbacks(m_floppy)->get_heads_per_disk && floppy_callbacks(m_floppy)->get_tracks_per_disk) + { + floppy_drive_set_geometry_absolute(floppy_get_tracks_per_disk(m_floppy),floppy_get_heads_per_disk(m_floppy)); + } + /* disk changed */ + m_dskchg = CLEAR_LINE; - return image_init_result::PASS; + // If we have one of our hacky load procs, call it + if (m_load_proc) + m_load_proc(*this, is_create); -error: - for (i = 0; i < std::size(errmap); i++) + return image_init_result::PASS; + } + else { - if (err == errmap[i].ferr) - seterror(errmap[i].ierr, errmap[i].message); + for (int i = 0; i < std::size(errmap); i++) + { + if (err == errmap[i].ferr) + seterror(errmap[i].ierr, errmap[i].message); + } + return image_init_result::FAIL; } - return image_init_result::FAIL; } TIMER_CALLBACK_MEMBER( legacy_floppy_image_device::set_wpt ) diff --git a/src/devices/imagedev/floppy.cpp b/src/devices/imagedev/floppy.cpp index 452fde35035..5d3956e2cab 100644 --- a/src/devices/imagedev/floppy.cpp +++ b/src/devices/imagedev/floppy.cpp @@ -26,8 +26,11 @@ #include "screen.h" #include "speaker.h" + #include "formats/imageutl.h" -#include "zippath.h" + +#include "util/ioprocs.h" +#include "util/zippath.h" /* Debugging flags. Set to 0 or 1. @@ -273,7 +276,7 @@ floppy_image_device::floppy_image_device(const machine_config &mconfig, device_t m_flux_screen(*this, "flux") { extension_list[0] = '\0'; - m_err = IMAGE_ERROR_INVALIDIMAGE; + m_err = image_error::INVALIDIMAGE; } //------------------------------------------------- @@ -398,17 +401,19 @@ void floppy_image_device::commit_image() image_dirty = false; if(!output_format || !output_format->supports_save()) return; - io_generic io; - // Do _not_ remove this cast otherwise the pointer will be incorrect when used by the ioprocs. - io.file = (device_image_interface *)this; - io.procs = &image_ioprocs; - io.filler = 0xff; - osd_file::error err = image_core_file().truncate(0); - if (err != osd_file::error::NONE) - popmessage("Error, unable to truncate image: %d", int(err)); + check_for_file(); + auto io = util::core_file_read_write(image_core_file(), 0xff); + if(!io) { + popmessage("Error, out of memory"); + return; + } + + std::error_condition const err = image_core_file().truncate(0); + if (err) + popmessage("Error, unable to truncate image: %s", err.message()); - output_format->save(&io, variants, image.get()); + output_format->save(*io, variants, image.get()); } void floppy_image_device::device_config_complete() @@ -532,28 +537,28 @@ floppy_image_format_t *floppy_image_device::identify(std::string filename) { util::core_file::ptr fd; std::string revised_path; + std::error_condition err = util::zippath_fopen(filename, OPEN_FLAG_READ, fd, revised_path); + if(err) { + seterror(err, nullptr); + return nullptr; + } - osd_file::error err = util::zippath_fopen(filename, OPEN_FLAG_READ, fd, revised_path); - if(err != osd_file::error::NONE) { - seterror(IMAGE_ERROR_INVALIDIMAGE, "Unable to open the image file"); + auto io = util::core_file_read(std::move(fd), 0xff); + if(!io) { + seterror(std::errc::not_enough_memory, nullptr); return nullptr; } - io_generic io; - io.file = fd.get(); - io.procs = &corefile_ioprocs_noclose; - io.filler = 0xff; int best = 0; floppy_image_format_t *best_format = nullptr; - for (floppy_image_format_t *format : fif_list) - { - int score = format->identify(&io, form_factor, variants); + for(floppy_image_format_t *format : fif_list) { + int score = format->identify(*io, form_factor, variants); if(score > best) { best = score; best_format = format; } } - fd.reset(); + return best_format; } @@ -585,16 +590,17 @@ void floppy_image_device::init_floppy_load(bool write_supported) image_init_result floppy_image_device::call_load() { - io_generic io; + check_for_file(); + auto io = util::core_file_read(image_core_file(), 0xff); + if(!io) { + seterror(std::errc::not_enough_memory, nullptr); + return image_init_result::FAIL; + } - // Do _not_ remove this cast otherwise the pointer will be incorrect when used by the ioprocs. - io.file = (device_image_interface *)this; - io.procs = &image_ioprocs; - io.filler = 0xff; int best = 0; floppy_image_format_t *best_format = nullptr; for (floppy_image_format_t *format : fif_list) { - int score = format->identify(&io, form_factor, variants); + int score = format->identify(*io, form_factor, variants); if(score > best) { best = score; best_format = format; @@ -602,13 +608,13 @@ image_init_result floppy_image_device::call_load() } if (!best_format) { - seterror(IMAGE_ERROR_INVALIDIMAGE, "Unable to identify the image format"); + seterror(image_error::INVALIDIMAGE, "Unable to identify the image format"); return image_init_result::FAIL; } image = std::make_unique<floppy_image>(tracks, sides, form_factor); - if (!best_format->load(&io, form_factor, variants, image.get())) { - seterror(IMAGE_ERROR_UNSUPPORTED, "Incompatible image format or corrupted data"); + if (!best_format->load(*io, form_factor, variants, image.get())) { + seterror(image_error::UNSUPPORTED, "Incompatible image format or corrupted data"); image.reset(); return image_init_result::FAIL; } @@ -822,88 +828,22 @@ image_init_result floppy_image_device::call_create(int format_type, util::option return image_init_result::PASS; } -// Should that go into ioprocs? Should ioprocs be turned into something C++? - -struct iofile_ram { - std::vector<u8> *data; - int64_t pos; -}; - -static void ram_closeproc(void *file) -{ - auto f = (iofile_ram *)file; - delete f; -} - -static int ram_seekproc(void *file, int64_t offset, int whence) -{ - auto f = (iofile_ram *)file; - switch(whence) { - case SEEK_SET: f->pos = offset; break; - case SEEK_CUR: f->pos += offset; break; - case SEEK_END: f->pos = f->data->size() + offset; break; - } - - f->pos = std::clamp(f->pos, int64_t(0), int64_t(f->data->size())); - return 0; -} - -static size_t ram_readproc(void *file, void *buffer, size_t length) -{ - auto f = (iofile_ram *)file; - size_t l = std::min(length, size_t(f->data->size() - f->pos)); - memcpy(buffer, f->data->data() + f->pos, l); - return l; -} - -static size_t ram_writeproc(void *file, const void *buffer, size_t length) -{ - auto f = (iofile_ram *)file; - size_t l = std::min(length, size_t(f->data->size() - f->pos)); - memcpy(f->data->data() + f->pos, buffer, l); - return l; -} - -static uint64_t ram_filesizeproc(void *file) -{ - auto f = (iofile_ram *)file; - return f->data->size(); -} - - -static const io_procs iop_ram = { - ram_closeproc, - ram_seekproc, - ram_readproc, - ram_writeproc, - ram_filesizeproc -}; - -static io_generic *ram_open(std::vector<u8> &data) -{ - iofile_ram *f = new iofile_ram; - f->data = &data; - f->pos = 0; - return new io_generic({ &iop_ram, f }); -} - void floppy_image_device::init_fs(const fs_info *fs, const fs_meta_data &meta) { assert(image); - if (fs->m_type) - { + if (fs->m_type) { std::vector<u8> img(fs->m_image_size); fsblk_vec_t blockdev(img); auto cfs = fs->m_manager->mount(blockdev); cfs->format(meta); - auto iog = ram_open(img); auto source_format = fs->m_type(); - source_format->load(iog, floppy_image::FF_UNKNOWN, variants, image.get()); + auto io = util::ram_read(img.data(), img.size(), 0xff); + source_format->load(*io, floppy_image::FF_UNKNOWN, variants, image.get()); delete source_format; - delete iog; - } else + } else { fs_unformatted::format(fs->m_key, image.get()); + } } /* write protect, active high diff --git a/src/devices/imagedev/harddriv.cpp b/src/devices/imagedev/harddriv.cpp index e6e0c56f896..5a7b9fe8109 100644 --- a/src/devices/imagedev/harddriv.cpp +++ b/src/devices/imagedev/harddriv.cpp @@ -133,8 +133,6 @@ image_init_result harddisk_image_device::call_load() image_init_result harddisk_image_device::call_create(int create_format, util::option_resolution *create_args) { - int err; - if (!create_args) throw emu_fatalerror("harddisk_image_device::call_create: Expected create_args to not be nullptr"); @@ -148,15 +146,15 @@ image_init_result harddisk_image_device::call_create(int create_format, util::op /* create the CHD file */ chd_codec_type compression[4] = { CHD_CODEC_NONE }; - err = m_origchd.create(image_core_file(), (uint64_t)totalsectors * (uint64_t)sectorsize, hunksize, sectorsize, compression); - if (err != CHDERR_NONE) + std::error_condition err = m_origchd.create(util::core_file_read_write(image_core_file()), (uint64_t)totalsectors * (uint64_t)sectorsize, hunksize, sectorsize, compression); + if (err) return image_init_result::FAIL; /* if we created the image and hence, have metadata to set, set the metadata */ err = m_origchd.write_metadata(HARD_DISK_METADATA_TAG, 0, string_format(HARD_DISK_METADATA_FORMAT, cylinders, heads, sectors, sectorsize)); m_origchd.close(); - if (err != CHDERR_NONE) + if (err) return image_init_result::FAIL; return internal_load_hd(); @@ -168,7 +166,7 @@ void harddisk_image_device::call_unload() if (!m_device_image_unload.isnull()) m_device_image_unload(*this); - if (m_hard_disk_handle != nullptr) + if (m_hard_disk_handle) { hard_disk_close(m_hard_disk_handle); m_hard_disk_handle = nullptr; @@ -186,28 +184,28 @@ void harddisk_image_device::call_unload() open_disk_diff - open a DISK diff file -------------------------------------------------*/ -static chd_error open_disk_diff(emu_options &options, const char *name, chd_file &source, chd_file &diff_chd) +static std::error_condition open_disk_diff(emu_options &options, const char *name, chd_file &source, chd_file &diff_chd) { std::string fname = std::string(name).append(".dif"); /* try to open the diff */ //printf("Opening differencing image file: %s\n", fname.c_str()); emu_file diff_file(options.diff_directory(), OPEN_FLAG_READ | OPEN_FLAG_WRITE); - osd_file::error filerr = diff_file.open(fname.c_str()); - if (filerr == osd_file::error::NONE) + std::error_condition filerr = diff_file.open(fname); + if (!filerr) { std::string fullpath(diff_file.fullpath()); diff_file.close(); //printf("Opening differencing image file: %s\n", fullpath.c_str()); - return diff_chd.open(fullpath.c_str(), true, &source); + return diff_chd.open(fullpath, true, &source); } /* didn't work; try creating it instead */ //printf("Creating differencing image: %s\n", fname.c_str()); diff_file.set_openflags(OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - filerr = diff_file.open(fname.c_str()); - if (filerr == osd_file::error::NONE) + filerr = diff_file.open(fname); + if (!filerr) { std::string fullpath(diff_file.fullpath()); diff_file.close(); @@ -215,23 +213,23 @@ static chd_error open_disk_diff(emu_options &options, const char *name, chd_file /* create the CHD */ //printf("Creating differencing image file: %s\n", fupointllpath.c_str()); chd_codec_type compression[4] = { CHD_CODEC_NONE }; - chd_error err = diff_chd.create(fullpath.c_str(), source.logical_bytes(), source.hunk_bytes(), compression, source); - if (err != CHDERR_NONE) + std::error_condition err = diff_chd.create(fullpath, source.logical_bytes(), source.hunk_bytes(), compression, source); + if (err) return err; return diff_chd.clone_all_metadata(source); } - return CHDERR_FILE_NOT_FOUND; + return std::errc::no_such_file_or_directory; } image_init_result harddisk_image_device::internal_load_hd() { - chd_error err = CHDERR_NONE; + std::error_condition err; m_chd = nullptr; uint8_t header[64]; - if (m_hard_disk_handle != nullptr) + if (m_hard_disk_handle) { hard_disk_close(m_hard_disk_handle); m_hard_disk_handle = nullptr; @@ -250,19 +248,19 @@ image_init_result harddisk_image_device::internal_load_hd() if (!memcmp("MComprHD", header, 8)) { - err = m_origchd.open(image_core_file(), true); + err = m_origchd.open(util::core_file_read_write(image_core_file()), true); - if (err == CHDERR_NONE) + if (!err) { m_chd = &m_origchd; } - else if (err == CHDERR_FILE_NOT_WRITEABLE) + else if (err == chd_file::error::FILE_NOT_WRITEABLE) { - err = m_origchd.open(image_core_file(), false); - if (err == CHDERR_NONE) + err = m_origchd.open(util::core_file_read_write(image_core_file()), false); + if (!err) { err = open_disk_diff(device().machine().options(), basename_noext(), m_origchd, m_diffchd); - if (err == CHDERR_NONE) + if (!err) { m_chd = &m_diffchd; } @@ -271,11 +269,11 @@ image_init_result harddisk_image_device::internal_load_hd() } } - if (m_chd != nullptr) + if (m_chd) { /* open the hard disk file */ m_hard_disk_handle = hard_disk_open(m_chd); - if (m_hard_disk_handle != nullptr) + if (m_hard_disk_handle) return image_init_result::PASS; } else @@ -306,7 +304,7 @@ image_init_result harddisk_image_device::internal_load_hd() } m_hard_disk_handle = hard_disk_open(image_core_file(), skip); - if (m_hard_disk_handle != nullptr) + if (m_hard_disk_handle) return image_init_result::PASS; } @@ -317,7 +315,7 @@ image_init_result harddisk_image_device::internal_load_hd() m_origchd.close(); m_diffchd.close(); m_chd = nullptr; - seterror(IMAGE_ERROR_UNSPECIFIED, chd_file::error_string(err)); + seterror(err, nullptr); return image_init_result::FAIL; } diff --git a/src/devices/imagedev/mfmhd.cpp b/src/devices/imagedev/mfmhd.cpp index 61eabb12217..f309b8f0d0f 100644 --- a/src/devices/imagedev/mfmhd.cpp +++ b/src/devices/imagedev/mfmhd.cpp @@ -440,8 +440,8 @@ image_init_result mfm_harddisk_device::call_load() } // Read the hard disk metadata - chd_error state = chdfile->read_metadata(HARD_DISK_METADATA_TAG, 0, metadata); - if (state != CHDERR_NONE) + std::error_condition state = chdfile->read_metadata(HARD_DISK_METADATA_TAG, 0, metadata); + if (state) { LOG("Failed to read CHD metadata\n"); return image_init_result::FAIL; @@ -475,7 +475,7 @@ image_init_result mfm_harddisk_device::call_load() param.reduced_wcurr_cylinder = -1; state = chdfile->read_metadata(MFM_HARD_DISK_METADATA_TAG, 0, metadata); - if (state != CHDERR_NONE) + if (state) { LOGMASKED(LOG_WARN, "Failed to read CHD sector arrangement/recording specs, applying defaults\n"); } @@ -494,7 +494,7 @@ image_init_result mfm_harddisk_device::call_load() param.interleave, param.cylskew, param.headskew, param.write_precomp_cylinder, param.reduced_wcurr_cylinder); state = chdfile->read_metadata(MFM_HARD_DISK_METADATA_TAG, 1, metadata); - if (state != CHDERR_NONE) + if (state) { LOGMASKED(LOG_WARN, "Failed to read CHD track gap specs, applying defaults\n"); } @@ -561,8 +561,8 @@ void mfm_harddisk_device::call_unload() LOGMASKED(LOG_WARN, "MFM HD sector arrangement and recording specs have changed; updating CHD metadata\n"); chd_file* chdfile = get_chd_file(); - chd_error err = chdfile->write_metadata(MFM_HARD_DISK_METADATA_TAG, 0, string_format(MFMHD_REC_METADATA_FORMAT, params->interleave, params->cylskew, params->headskew, params->write_precomp_cylinder, params->reduced_wcurr_cylinder), 0); - if (err != CHDERR_NONE) + std::error_condition err = chdfile->write_metadata(MFM_HARD_DISK_METADATA_TAG, 0, string_format(MFMHD_REC_METADATA_FORMAT, params->interleave, params->cylskew, params->headskew, params->write_precomp_cylinder, params->reduced_wcurr_cylinder), 0); + if (err) { LOGMASKED(LOG_WARN, "Failed to save MFM HD sector arrangement/recording specs to CHD\n"); } @@ -573,8 +573,8 @@ void mfm_harddisk_device::call_unload() LOGMASKED(LOG_WARN, "MFM HD track gap specs have changed; updating CHD metadata\n"); chd_file* chdfile = get_chd_file(); - chd_error err = chdfile->write_metadata(MFM_HARD_DISK_METADATA_TAG, 1, string_format(MFMHD_GAP_METADATA_FORMAT, params->gap1, params->gap2, params->gap3, params->sync, params->headerlen, params->ecctype), 0); - if (err != CHDERR_NONE) + std::error_condition err = chdfile->write_metadata(MFM_HARD_DISK_METADATA_TAG, 1, string_format(MFMHD_GAP_METADATA_FORMAT, params->gap1, params->gap2, params->gap3, params->sync, params->headerlen, params->ecctype), 0); + if (err) { LOGMASKED(LOG_WARN, "Failed to save MFM HD track gap specs to CHD\n"); } @@ -919,10 +919,9 @@ bool mfm_harddisk_device::write(attotime &from_when, const attotime &limit, uint return false; } -chd_error mfm_harddisk_device::load_track(uint16_t* data, int cylinder, int head) +std::error_condition mfm_harddisk_device::load_track(uint16_t* data, int cylinder, int head) { - chd_error state = m_format->load(m_chd, data, m_trackimage_size, cylinder, head); - return state; + return m_format->load(m_chd, data, m_trackimage_size, cylinder, head); } void mfm_harddisk_device::write_track(uint16_t* data, int cylinder, int head) @@ -1070,7 +1069,7 @@ void mfmhd_trackimage_cache::init(mfm_harddisk_device* mfmhd, int tracksize, int { if (TRACE_CACHE) m_machine.logerror("[%s:cache] MFM HD cache init; cache size is %d tracks\n", mfmhd->tag(), trackslots); - chd_error state; + std::error_condition state; mfmhd_trackimage* previous; mfmhd_trackimage* current = nullptr; @@ -1091,7 +1090,8 @@ void mfmhd_trackimage_cache::init(mfm_harddisk_device* mfmhd, int tracksize, int // Load the first tracks into the slots state = m_mfmhd->load_track(current->encdata.get(), cylinder, head); - if (state != CHDERR_NONE) throw emu_fatalerror("Cannot load (c=%d,h=%d) from hard disk", cylinder, head); + if (state) + throw emu_fatalerror("Cannot load (c=%d,h=%d) from hard disk", cylinder, head); current->dirty = false; current->cylinder = cylinder; @@ -1128,11 +1128,11 @@ uint16_t* mfmhd_trackimage_cache::get_trackimage(int cylinder, int head) mfmhd_trackimage* current = m_tracks; mfmhd_trackimage* previous = nullptr; - chd_error state = CHDERR_NONE; + std::error_condition state; // Repeat the search. This loop should run at most twice; once for a direct hit, // and twice on miss, then the second iteration will be a hit. - while (state == CHDERR_NONE) + while (!state) { // A simple linear search while (current != nullptr) diff --git a/src/devices/imagedev/mfmhd.h b/src/devices/imagedev/mfmhd.h index 007be4be420..bb5d8493f97 100644 --- a/src/devices/imagedev/mfmhd.h +++ b/src/devices/imagedev/mfmhd.h @@ -17,8 +17,12 @@ #pragma once #include "imagedev/harddriv.h" + #include "formats/mfm_hd.h" +#include <system_error> + + class mfm_harddisk_device; class mfmhd_trackimage @@ -94,7 +98,7 @@ public: attotime track_end_time(); // Access the tracks on the image. Used as a callback from the cache. - chd_error load_track(uint16_t* data, int cylinder, int head); + std::error_condition load_track(uint16_t* data, int cylinder, int head); void write_track(uint16_t* data, int cylinder, int head); // Delivers the number of heads according to the loaded image diff --git a/src/devices/imagedev/midiin.cpp b/src/devices/imagedev/midiin.cpp index 54a9f1c2297..e2386afb532 100644 --- a/src/devices/imagedev/midiin.cpp +++ b/src/devices/imagedev/midiin.cpp @@ -129,7 +129,7 @@ image_init_result midiin_device::call_load() { // attempt to load if it's a real file m_err = load_image_by_path(OPEN_FLAG_READ, filename()); - if (m_err == IMAGE_ERROR_SUCCESS) + if (!m_err) { // if the parsing succeeds, schedule the start to happen at least // 10 seconds after starting to allow the keyboards to initialize diff --git a/src/devices/machine/ataflash.cpp b/src/devices/machine/ataflash.cpp index 464bd074cdf..155ec34bcd3 100644 --- a/src/devices/machine/ataflash.cpp +++ b/src/devices/machine/ataflash.cpp @@ -140,7 +140,7 @@ void taito_pccard1_device::device_reset() uint32_t metalength; memset(m_key, 0, sizeof(m_key)); - if (m_handle != nullptr && m_handle->read_metadata(HARD_DISK_KEY_METADATA_TAG, 0, m_key, 5, metalength) == CHDERR_NONE) + if (m_handle && !m_handle->read_metadata(HARD_DISK_KEY_METADATA_TAG, 0, m_key, 5, metalength)) { m_locked = 0x1ff; } @@ -231,7 +231,7 @@ void taito_pccard2_device::device_reset() uint32_t metalength; memset(m_key, 0, sizeof(m_key)); - if (m_handle != nullptr && m_handle->read_metadata(HARD_DISK_KEY_METADATA_TAG, 0, m_key, 5, metalength) == CHDERR_NONE) + if (m_handle && !m_handle->read_metadata(HARD_DISK_KEY_METADATA_TAG, 0, m_key, 5, metalength)) { m_locked = true; } @@ -330,7 +330,7 @@ void taito_compact_flash_device::device_reset() uint32_t metalength; memset(m_key, 0, sizeof(m_key)); - if (m_handle != nullptr && m_handle->read_metadata(HARD_DISK_KEY_METADATA_TAG, 0, m_key, 5, metalength) == CHDERR_NONE) + if (m_handle && !m_handle->read_metadata(HARD_DISK_KEY_METADATA_TAG, 0, m_key, 5, metalength)) { m_locked = true; } diff --git a/src/devices/machine/ch376.cpp b/src/devices/machine/ch376.cpp index 8c13833292e..eeca140ec0a 100644 --- a/src/devices/machine/ch376.cpp +++ b/src/devices/machine/ch376.cpp @@ -255,7 +255,7 @@ void ch376_device::write(offs_t offset, u8 data) tmpPath.append(m_file_name); } - if (osd_file::open(tmpPath, OPEN_FLAG_READ|OPEN_FLAG_WRITE, m_file, size) == osd_file::error::NONE) + if (!osd_file::open(tmpPath, OPEN_FLAG_READ|OPEN_FLAG_WRITE, m_file, size)) { m_int_status = STATUS_USB_INT_SUCCESS; m_cur_file_size = size & 0xffffffff; diff --git a/src/devices/machine/hp_dc100_tape.cpp b/src/devices/machine/hp_dc100_tape.cpp index 2c4b55e0156..7d068af39d6 100644 --- a/src/devices/machine/hp_dc100_tape.cpp +++ b/src/devices/machine/hp_dc100_tape.cpp @@ -30,6 +30,8 @@ #include "emu.h" #include "hp_dc100_tape.h" +#include "util/ioprocs.h" + // Debugging #include "logmacro.h" #define LOG_TMR_MASK (LOG_GENERAL << 1) @@ -107,12 +109,12 @@ void hp_dc100_tape_device::call_unload() device_reset(); if (m_image_dirty) { - io_generic io; - io.file = (device_image_interface *)this; - io.procs = &image_ioprocs; - io.filler = 0; - m_image.save_tape(&io); - m_image_dirty = false; + check_for_file(); + auto io = util::core_file_read_write(image_core_file(), 0); + if (io) { + m_image.save_tape(*io); + m_image_dirty = false; + } } m_image.clear_tape(); @@ -602,18 +604,31 @@ image_init_result hp_dc100_tape_device::internal_load(bool is_create) device_reset(); - io_generic io; - io.file = (device_image_interface *)this; - io.procs = &image_ioprocs; - io.filler = 0; + check_for_file(); if (is_create) { + auto io = util::core_file_read_write(image_core_file(), 0); + if (!io) { + LOG("out of memory\n"); + seterror(std::errc::not_enough_memory, nullptr); + set_tape_present(false); + return image_init_result::FAIL; + } m_image.clear_tape(); - m_image.save_tape(&io); - } else if (!m_image.load_tape(&io)) { - LOG("load failed\n"); - seterror(IMAGE_ERROR_INVALIDIMAGE , "Wrong format"); - set_tape_present(false); - return image_init_result::FAIL; + m_image.save_tape(*io); + } else { + auto io = util::core_file_read(image_core_file(), 0); + if (!io) { + LOG("out of memory\n"); + seterror(std::errc::not_enough_memory, nullptr); + set_tape_present(false); + return image_init_result::FAIL; + } + if (!m_image.load_tape(*io)) { + LOG("load failed\n"); + seterror(image_error::INVALIDIMAGE , "Wrong format"); + set_tape_present(false); + return image_init_result::FAIL; + } } LOG("load OK\n"); diff --git a/src/devices/machine/laserdsc.cpp b/src/devices/machine/laserdsc.cpp index 92fad4019fd..6d1ef156bf9 100644 --- a/src/devices/machine/laserdsc.cpp +++ b/src/devices/machine/laserdsc.cpp @@ -10,11 +10,11 @@ #include "emu.h" #include "laserdsc.h" -#include "avhuff.h" -#include "vbiparse.h" + #include "config.h" #include "render.h" #include "romload.h" + #include "chd.h" @@ -73,7 +73,7 @@ laserdisc_device::laserdisc_device(const machine_config &mconfig, device_type ty m_height(0), m_fps_times_1million(0), m_samplerate(0), - m_readresult(CHDERR_NONE), + m_readresult(), m_chdtracks(0), m_work_queue(osd_work_queue_alloc(WORK_QUEUE_FLAG_IO)), m_audiosquelch(0), @@ -661,8 +661,9 @@ void laserdisc_device::init_disc() // read the metadata std::string metadata; - chd_error err = m_disc->read_metadata(AV_METADATA_TAG, 0, metadata); - if (err != CHDERR_NONE) + std::error_condition err; + err = m_disc->read_metadata(AV_METADATA_TAG, 0, metadata); + if (err) throw emu_fatalerror("Non-A/V CHD file specified"); // extract the metadata @@ -682,7 +683,7 @@ void laserdisc_device::init_disc() // allocate memory for the precomputed per-frame metadata err = m_disc->read_metadata(AV_LD_METADATA_TAG, 0, m_vbidata); - if (err != CHDERR_NONE || m_vbidata.size() != totalhunks * VBI_PACKED_BYTES) + if (err || (m_vbidata.size() != totalhunks * VBI_PACKED_BYTES)) throw emu_fatalerror("Precomputed VBI metadata missing or incorrect size"); } m_maxtrack = std::max(m_maxtrack, VIRTUAL_LEAD_IN_TRACKS + VIRTUAL_LEAD_OUT_TRACKS + m_chdtracks); @@ -959,14 +960,14 @@ void laserdisc_device::read_track_data() } // configure the codec and then read - m_readresult = CHDERR_FILE_NOT_FOUND; - if (m_disc != nullptr && !m_videosquelch) + m_readresult = std::errc::no_such_file_or_directory; + if (m_disc && !m_videosquelch) { m_readresult = m_disc->codec_configure(CHD_CODEC_AVHUFF, AVHUFF_CODEC_DECOMPRESS_CONFIG, &m_avhuff_config); - if (m_readresult == CHDERR_NONE) + if (!m_readresult) { m_queued_hunknum = readhunk; - m_readresult = CHDERR_OPERATION_PENDING; + m_readresult = chd_file::error::OPERATION_PENDING; osd_work_item_queue(m_work_queue, read_async_static, this, WORK_ITEM_FLAG_AUTO_RELEASE); } } @@ -994,12 +995,12 @@ void *laserdisc_device::read_async_static(void *param, int threadid) void laserdisc_device::process_track_data() { // wait for the async operation to complete - if (m_readresult == CHDERR_OPERATION_PENDING) + if (m_readresult == chd_file::error::OPERATION_PENDING) osd_work_queue_wait(m_work_queue, osd_ticks_per_second() * 10); - assert(m_readresult != CHDERR_OPERATION_PENDING); + assert(m_readresult != chd_file::error::OPERATION_PENDING); // remove the video if we had an error - if (m_readresult != CHDERR_NONE) + if (m_readresult) m_avhuff_video.reset(); // count the field as read if we are successful diff --git a/src/devices/machine/laserdsc.h b/src/devices/machine/laserdsc.h index 5fcc317a761..5eb06f105ea 100644 --- a/src/devices/machine/laserdsc.h +++ b/src/devices/machine/laserdsc.h @@ -18,8 +18,10 @@ #include "vbiparse.h" #include "avhuff.h" -#include <type_traits> +#include <algorithm> +#include <system_error> #include <utility> +#include <vector> //************************************************************************** @@ -244,8 +246,8 @@ private: { bitmap_yuy16 m_bitmap; // cached bitmap bitmap_yuy16 m_visbitmap; // wrapper around bitmap with only visible lines - uint8_t m_numfields; // number of fields in this frame - int32_t m_lastfield; // last absolute field number + uint8_t m_numfields; // number of fields in this frame + int32_t m_lastfield; // last absolute field number }; // internal helpers @@ -267,19 +269,19 @@ private: get_disc_delegate m_getdisc_callback; audio_delegate m_audio_callback; // audio streaming callback laserdisc_overlay_config m_orig_config; // original overlay configuration - uint32_t m_overwidth; // overlay screen width - uint32_t m_overheight; // overlay screen height + uint32_t m_overwidth; // overlay screen width + uint32_t m_overheight; // overlay screen height rectangle m_overclip; // overlay visarea screen_update_rgb32_delegate m_overupdate_rgb32; // overlay update delegate // disc parameters chd_file * m_disc; // handle to the disc itself - std::vector<uint8_t> m_vbidata; // pointer to precomputed VBI data + std::vector<uint8_t> m_vbidata; // pointer to precomputed VBI data int m_width; // width of video int m_height; // height of video uint32_t m_fps_times_1million; // frame rate of video int m_samplerate; // audio samplerate - int m_readresult; // result of the most recent read + std::error_condition m_readresult; // result of the most recent read uint32_t m_chdtracks; // number of tracks in the CHD bitmap_yuy16 m_avhuff_video; // decompresed frame buffer avhuff_decoder::config m_avhuff_config; // decompression configuration @@ -305,11 +307,11 @@ private: // audio data sound_stream * m_stream; std::vector<int16_t> m_audiobuffer[2]; // buffer for audio samples - uint32_t m_audiobufsize; // size of buffer - uint32_t m_audiobufin; // input index - uint32_t m_audiobufout; // output index - uint32_t m_audiocursamples; // current samples this track - uint32_t m_audiomaxsamples; // maximum samples per track + uint32_t m_audiobufsize; // size of buffer + uint32_t m_audiobufin; // input index + uint32_t m_audiobufout; // output index + uint32_t m_audiocursamples; // current samples this track + uint32_t m_audiomaxsamples; // maximum samples per track // metadata vbi_metadata m_metadata[2]; // metadata parsed from the stream, for each field diff --git a/src/devices/sound/samples.cpp b/src/devices/sound/samples.cpp index 5c8d129b799..7663d921475 100644 --- a/src/devices/sound/samples.cpp +++ b/src/devices/sound/samples.cpp @@ -605,26 +605,28 @@ bool samples_device::load_samples() // load the samples int index = 0; - for (const char *samplename = iter.first(); samplename != nullptr; index++, samplename = iter.next()) + for (const char *samplename = iter.first(); samplename; index++, samplename = iter.next()) { // attempt to open as FLAC first emu_file file(machine().options().sample_path(), OPEN_FLAG_READ); - osd_file::error filerr = file.open(util::string_format("%s" PATH_SEPARATOR "%s.flac", basename, samplename)); - if (filerr != osd_file::error::NONE && altbasename != nullptr) + std::error_condition filerr = file.open(util::string_format("%s" PATH_SEPARATOR "%s.flac", basename, samplename)); + if (filerr && altbasename) filerr = file.open(util::string_format("%s" PATH_SEPARATOR "%s.flac", altbasename, samplename)); // if not, try as WAV - if (filerr != osd_file::error::NONE) + if (filerr) filerr = file.open(util::string_format("%s" PATH_SEPARATOR "%s.wav", basename, samplename)); - if (filerr != osd_file::error::NONE && altbasename != nullptr) + if (filerr && altbasename) filerr = file.open(util::string_format("%s" PATH_SEPARATOR "%s.wav", altbasename, samplename)); // if opened, read it - if (filerr == osd_file::error::NONE) + if (!filerr) + { read_sample(file, m_sample[index]); - else if (filerr == osd_file::error::NOT_FOUND) + } + else { - logerror("%s: Sample '%s' NOT FOUND\n", tag(), samplename); + logerror("Error opening sample '%s' (%s:%d %s)\n", samplename, filerr.category().name(), filerr.value(), filerr.message()); ok = false; } } diff --git a/src/emu/addrmap.h b/src/emu/addrmap.h index c5a6c17d128..76cdc6aef54 100644 --- a/src/emu/addrmap.h +++ b/src/emu/addrmap.h @@ -72,7 +72,7 @@ class address_map_entry friend class address_map; template <typename T, typename Ret, typename... Params> - struct is_addrmap_method { static constexpr bool value = std::is_constructible<address_map_constructor, Ret (T::*)(Params...), const char *, T*>::value; }; + using is_addrmap_method = std::bool_constant<std::is_constructible_v<address_map_constructor, Ret (T::*)(Params...), const char *, T *> >; template <typename T, typename Ret, typename... Params> static std::enable_if_t<is_addrmap_method<T, Ret, Params...>::value, address_map_constructor> make_delegate(Ret (T::*func)(Params...), const char *name, T *obj) diff --git a/src/emu/config.cpp b/src/emu/config.cpp index 46bec43c1dd..792da6f255d 100644 --- a/src/emu/config.cpp +++ b/src/emu/config.cpp @@ -64,16 +64,16 @@ bool configuration_manager::load_settings() type.load(config_type::INIT, config_level::DEFAULT, nullptr); // now load the controller file - const char *controller = machine().options().ctrlr(); + char const *const controller = machine().options().ctrlr(); if (controller && *controller) { // open the config file emu_file file(machine().options().ctrlr_path(), OPEN_FLAG_READ); osd_printf_verbose("Attempting to parse: %s.cfg\n", controller); - osd_file::error filerr = file.open(std::string(controller) + ".cfg"); + std::error_condition const filerr = file.open(std::string(controller) + ".cfg"); - if (filerr != osd_file::error::NONE) - throw emu_fatalerror("Could not open controller file %s.cfg", controller); + if (filerr) + throw emu_fatalerror("Could not open controller file %s.cfg (%s:%d %s)", controller, filerr.category().name(), filerr.value(), filerr.message()); // load the XML if (!load_xml(file, config_type::CONTROLLER)) @@ -82,15 +82,15 @@ bool configuration_manager::load_settings() // next load the defaults file emu_file file(machine().options().cfg_directory(), OPEN_FLAG_READ); - osd_file::error filerr = file.open("default.cfg"); + std::error_condition filerr = file.open("default.cfg"); osd_printf_verbose("Attempting to parse: default.cfg\n"); - if (filerr == osd_file::error::NONE) + if (!filerr) load_xml(file, config_type::DEFAULT); // finally, load the game-specific file filerr = file.open(machine().basename() + ".cfg"); osd_printf_verbose("Attempting to parse: %s.cfg\n",machine().basename()); - const bool loaded = (osd_file::error::NONE == filerr) && load_xml(file, config_type::SYSTEM); + const bool loaded = !filerr && load_xml(file, config_type::SYSTEM); // loop over all registrants and call their final function for (const auto &type : m_typelist) @@ -110,13 +110,13 @@ void configuration_manager::save_settings() // save the defaults file emu_file file(machine().options().cfg_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - osd_file::error filerr = file.open("default.cfg"); - if (filerr == osd_file::error::NONE) + std::error_condition filerr = file.open("default.cfg"); + if (!filerr) save_xml(file, config_type::DEFAULT); // finally, save the system-specific file filerr = file.open(machine().basename() + ".cfg"); - if (filerr == osd_file::error::NONE) + if (!filerr) save_xml(file, config_type::SYSTEM); // loop over all registrants and call their final function diff --git a/src/emu/crsshair.cpp b/src/emu/crsshair.cpp index 43eac50587b..3c6a6b807f0 100644 --- a/src/emu/crsshair.cpp +++ b/src/emu/crsshair.cpp @@ -189,7 +189,7 @@ void render_crosshair::create_bitmap() if (!m_name.empty()) { // look for user specified file - if (crossfile.open(m_name + ".png") == osd_file::error::NONE) + if (!crossfile.open(m_name + ".png")) { render_load_png(*m_bitmap, crossfile); crossfile.close(); @@ -199,14 +199,14 @@ void render_crosshair::create_bitmap() { // look for default cross?.png in crsshair/game dir std::string const filename = string_format("cross%d.png", m_player + 1); - if (crossfile.open(m_machine.system().name + (PATH_SEPARATOR + filename)) == osd_file::error::NONE) + if (!crossfile.open(m_machine.system().name + (PATH_SEPARATOR + filename))) { render_load_png(*m_bitmap, crossfile); crossfile.close(); } // look for default cross?.png in crsshair dir - if (!m_bitmap->valid() && (crossfile.open(filename) == osd_file::error::NONE)) + if (!m_bitmap->valid() && !crossfile.open(filename)) { render_load_png(*m_bitmap, crossfile); crossfile.close(); diff --git a/src/emu/debug/debugcmd.cpp b/src/emu/debug/debugcmd.cpp index bd537935851..58cc85f7a86 100644 --- a/src/emu/debug/debugcmd.cpp +++ b/src/emu/debug/debugcmd.cpp @@ -3671,11 +3671,11 @@ void debugger_commands::execute_snap(int ref, const std::vector<std::string> &pa if (fname.find(".png") == -1) fname.append(".png"); emu_file file(m_machine.options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - osd_file::error filerr = file.open(std::move(fname)); + std::error_condition filerr = file.open(std::move(fname)); - if (filerr != osd_file::error::NONE) + if (filerr) { - m_console.printf("Error creating file '%s'\n", filename); + m_console.printf("Error creating file '%s' (%s:%d %s)\n", filename, filerr.category().name(), filerr.value(), filerr.message()); return; } diff --git a/src/emu/debug/debugcpu.cpp b/src/emu/debug/debugcpu.cpp index 1399a6b8ec2..233e369433e 100644 --- a/src/emu/debug/debugcpu.cpp +++ b/src/emu/debug/debugcpu.cpp @@ -168,8 +168,8 @@ bool debugger_cpu::comment_save() if (found_comments) { emu_file file(m_machine.options().comment_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - osd_file::error filerr = file.open(m_machine.basename() + ".cmt"); - if (filerr == osd_file::error::NONE) + std::error_condition const filerr = file.open(m_machine.basename() + ".cmt"); + if (!filerr) { root->write(file); comments_saved = true; @@ -194,10 +194,10 @@ bool debugger_cpu::comment_load(bool is_inline) { // open the file emu_file file(m_machine.options().comment_directory(), OPEN_FLAG_READ); - osd_file::error filerr = file.open(m_machine.basename() + ".cmt"); + std::error_condition const filerr = file.open(m_machine.basename() + ".cmt"); // if an error, just return false - if (filerr != osd_file::error::NONE) + if (filerr) return false; // wrap in a try/catch to handle errors diff --git a/src/emu/devcb.h b/src/emu/devcb.h index ec543aa48d6..d27d3beb74d 100644 --- a/src/emu/devcb.h +++ b/src/emu/devcb.h @@ -82,16 +82,16 @@ protected: template <typename T, typename U> using mask_t = std::make_unsigned_t<intermediate_t<T, U> >; // Detecting candidates for transform functions - template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form1 { static constexpr bool value = false; }; - template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form2 { static constexpr bool value = false; }; - template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form3 { static constexpr bool value = false; }; - template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form4 { static constexpr bool value = false; }; - template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form5 { static constexpr bool value = false; }; - template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form6 { static constexpr bool value = false; }; - template <typename Input, typename Result, typename Func> struct is_transform_form3<Input, Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func, offs_t &, Input, std::make_unsigned_t<Input> &>, Result>::value> > { static constexpr bool value = true; }; - template <typename Input, typename Result, typename Func> struct is_transform_form4<Input, Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func, offs_t &, Input>, Result>::value> > { static constexpr bool value = true; }; - template <typename Input, typename Result, typename Func> struct is_transform_form6<Input, Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func, Input>, Result>::value> > { static constexpr bool value = true; }; - template <typename Input, typename Result, typename Func> struct is_transform { static constexpr bool value = is_transform_form1<Input, Result, Func>::value || is_transform_form2<Input, Result, Func>::value || is_transform_form3<Input, Result, Func>::value || is_transform_form4<Input, Result, Func>::value || is_transform_form5<Input, Result, Func>::value || is_transform_form6<Input, Result, Func>::value; }; + template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form1 : public std::false_type { }; + template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form2 : public std::false_type { }; + template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form3 : public std::false_type { }; + template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form4 : public std::false_type { }; + template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form5 : public std::false_type { }; + template <typename Input, typename Result, typename Func, typename Enable = void> struct is_transform_form6 : public std::false_type { }; + template <typename Input, typename Result, typename Func> struct is_transform_form3<Input, Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func, offs_t &, Input, std::make_unsigned_t<Input> &>, Result>::value> > : public std::true_type { }; + template <typename Input, typename Result, typename Func> struct is_transform_form4<Input, Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func, offs_t &, Input>, Result>::value> > : public std::true_type { }; + template <typename Input, typename Result, typename Func> struct is_transform_form6<Input, Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func, Input>, Result>::value> > : public std::true_type { }; + template <typename Input, typename Result, typename Func> struct is_transform : public std::bool_constant<is_transform_form1<Input, Result, Func>::value || is_transform_form2<Input, Result, Func>::value || is_transform_form3<Input, Result, Func>::value || is_transform_form4<Input, Result, Func>::value || is_transform_form5<Input, Result, Func>::value || is_transform_form6<Input, Result, Func>::value> { }; // Determining the result type of a transform function template <typename Input, typename Result, typename Func, typename Enable = void> struct transform_result; @@ -211,13 +211,13 @@ class devcb_read_base : public devcb_base { protected: // Detecting candidates for read functions - template <typename Result, typename Func, typename Enable = void> struct is_read_form1 { static constexpr bool value = false; }; - template <typename Result, typename Func, typename Enable = void> struct is_read_form2 { static constexpr bool value = false; }; - template <typename Result, typename Func, typename Enable = void> struct is_read_form3 { static constexpr bool value = false; }; - template <typename Result, typename Func> struct is_read_form1<Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func, offs_t, Result>, Result>::value> > { static constexpr bool value = true; }; - template <typename Result, typename Func> struct is_read_form2<Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func, offs_t>, Result>::value> > { static constexpr bool value = true; }; - template <typename Result, typename Func> struct is_read_form3<Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func>, Result>::value> > { static constexpr bool value = true; }; - template <typename Result, typename Func> struct is_read { static constexpr bool value = is_read_form1<Result, Func>::value || is_read_form2<Result, Func>::value || is_read_form3<Result, Func>::value; }; + template <typename Result, typename Func, typename Enable = void> struct is_read_form1 : public std::false_type { }; + template <typename Result, typename Func, typename Enable = void> struct is_read_form2 : public std::false_type { }; + template <typename Result, typename Func, typename Enable = void> struct is_read_form3 : public std::false_type { }; + template <typename Result, typename Func> struct is_read_form1<Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func, offs_t, Result>, Result>::value> > : public std::true_type { }; + template <typename Result, typename Func> struct is_read_form2<Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func, offs_t>, Result>::value> > : public std::true_type { }; + template <typename Result, typename Func> struct is_read_form3<Result, Func, std::enable_if_t<std::is_convertible<std::invoke_result_t<Func>, Result>::value> > : public std::true_type { }; + template <typename Result, typename Func> struct is_read : public std::bool_constant<is_read_form1<Result, Func>::value || is_read_form2<Result, Func>::value || is_read_form3<Result, Func>::value> { }; // Determining the result type of a read function template <typename Result, typename Func, typename Enable = void> struct read_result; @@ -227,20 +227,20 @@ protected: template <typename Result, typename Func> using read_result_t = typename read_result<Result, Func>::type; // Detecting candidates for read delegates - template <typename T, typename Enable = void> struct is_read_method { static constexpr bool value = false; }; - template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read8s_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; }; - template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read16s_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; }; - template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read32s_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; }; - template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read64s_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; }; - template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read8sm_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; }; - template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read16sm_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; }; - template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read32sm_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; }; - template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read64sm_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; }; - template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read8smo_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; }; - template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read16smo_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; }; - template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read32smo_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; }; - template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read64smo_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; }; - template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read_line_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; }; + template <typename T, typename Enable = void> struct is_read_method : public std::false_type { }; + template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read8s_delegate, std::remove_reference_t<T> > > > : public std::true_type { }; + template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read16s_delegate, std::remove_reference_t<T> > > > : public std::true_type { }; + template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read32s_delegate, std::remove_reference_t<T> > > > : public std::true_type { }; + template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read64s_delegate, std::remove_reference_t<T> > > > : public std::true_type { }; + template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read8sm_delegate, std::remove_reference_t<T> > > > : public std::true_type { }; + template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read16sm_delegate, std::remove_reference_t<T> > > > : public std::true_type { }; + template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read32sm_delegate, std::remove_reference_t<T> > > > : public std::true_type { }; + template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read64sm_delegate, std::remove_reference_t<T> > > > : public std::true_type { }; + template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read8smo_delegate, std::remove_reference_t<T> > > > : public std::true_type { }; + template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read16smo_delegate, std::remove_reference_t<T> > > > : public std::true_type { }; + template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read32smo_delegate, std::remove_reference_t<T> > > > : public std::true_type { }; + template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read64smo_delegate, std::remove_reference_t<T> > > > : public std::true_type { }; + template <typename T> struct is_read_method<T, void_t<emu::detail::rw_device_class_t<read_line_delegate, std::remove_reference_t<T> > > > : public std::true_type { }; // Invoking read callbacks template <typename Result, typename T> static std::enable_if_t<is_read_form1<Result, T>::value, mask_t<read_result_t<Result, T>, Result> > invoke_read(T const &cb, offs_t offset, std::make_unsigned_t<Result> mem_mask) { return std::make_unsigned_t<read_result_t<Result, T> >(cb(offset, mem_mask)); } @@ -275,29 +275,29 @@ class devcb_write_base : public devcb_base { protected: // Detecting candidates for write functions - template <typename Input, typename Func, typename Enable = void> struct is_write_form1 { static constexpr bool value = false; }; - template <typename Input, typename Func, typename Enable = void> struct is_write_form2 { static constexpr bool value = false; }; - template <typename Input, typename Func, typename Enable = void> struct is_write_form3 { static constexpr bool value = false; }; - template <typename Input, typename Func> struct is_write_form1<Input, Func, void_t<std::invoke_result_t<Func, offs_t, Input, std::make_unsigned_t<Input>> > > { static constexpr bool value = true; }; - template <typename Input, typename Func> struct is_write_form2<Input, Func, void_t<std::invoke_result_t<Func, offs_t, Input> > > { static constexpr bool value = true; }; - template <typename Input, typename Func> struct is_write_form3<Input, Func, void_t<std::invoke_result_t<Func, Input> > > { static constexpr bool value = true; }; - template <typename Input, typename Func> struct is_write { static constexpr bool value = is_write_form1<Input, Func>::value || is_write_form2<Input, Func>::value || is_write_form3<Input, Func>::value; }; + template <typename Input, typename Func, typename Enable = void> struct is_write_form1 : public std::false_type { }; + template <typename Input, typename Func, typename Enable = void> struct is_write_form2 : public std::false_type { }; + template <typename Input, typename Func, typename Enable = void> struct is_write_form3 : public std::false_type { }; + template <typename Input, typename Func> struct is_write_form1<Input, Func, void_t<std::invoke_result_t<Func, offs_t, Input, std::make_unsigned_t<Input>> > > : public std::true_type { }; + template <typename Input, typename Func> struct is_write_form2<Input, Func, void_t<std::invoke_result_t<Func, offs_t, Input> > > : public std::true_type { }; + template <typename Input, typename Func> struct is_write_form3<Input, Func, void_t<std::invoke_result_t<Func, Input> > > : public std::true_type { }; + template <typename Input, typename Func> struct is_write : public std::bool_constant<is_write_form1<Input, Func>::value || is_write_form2<Input, Func>::value || is_write_form3<Input, Func>::value> { }; // Detecting candidates for write delegates - template <typename T, typename Enable = void> struct is_write_method { static constexpr bool value = false; }; - template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write8s_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; }; - template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write16s_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; }; - template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write32s_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; }; - template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write64s_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; }; - template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write8sm_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; }; - template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write16sm_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; }; - template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write32sm_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; }; - template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write64sm_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; }; - template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write8smo_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; }; - template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write16smo_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; }; - template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write32smo_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; }; - template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write64smo_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; }; - template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write_line_delegate, std::remove_reference_t<T> > > > { static constexpr bool value = true; }; + template <typename T, typename Enable = void> struct is_write_method : public std::false_type { }; + template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write8s_delegate, std::remove_reference_t<T> > > > : public std::true_type { }; + template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write16s_delegate, std::remove_reference_t<T> > > > : public std::true_type { }; + template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write32s_delegate, std::remove_reference_t<T> > > > : public std::true_type { }; + template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write64s_delegate, std::remove_reference_t<T> > > > : public std::true_type { }; + template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write8sm_delegate, std::remove_reference_t<T> > > > : public std::true_type { }; + template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write16sm_delegate, std::remove_reference_t<T> > > > : public std::true_type { }; + template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write32sm_delegate, std::remove_reference_t<T> > > > : public std::true_type { }; + template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write64sm_delegate, std::remove_reference_t<T> > > > : public std::true_type { }; + template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write8smo_delegate, std::remove_reference_t<T> > > > : public std::true_type { }; + template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write16smo_delegate, std::remove_reference_t<T> > > > : public std::true_type { }; + template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write32smo_delegate, std::remove_reference_t<T> > > > : public std::true_type { }; + template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write64smo_delegate, std::remove_reference_t<T> > > > : public std::true_type { }; + template <typename T> struct is_write_method<T, void_t<emu::detail::rw_device_class_t<write_line_delegate, std::remove_reference_t<T> > > > : public std::true_type { }; // Invoking write callbacks template <typename Input, typename T> static std::enable_if_t<is_write_form1<Input, T>::value> invoke_write(T const &cb, offs_t &offset, Input data, std::make_unsigned_t<Input> mem_mask) { return cb(offset, data, mem_mask); } diff --git a/src/emu/devdelegate.h b/src/emu/devdelegate.h index 1ba303d3ef3..906e1da9274 100644 --- a/src/emu/devdelegate.h +++ b/src/emu/devdelegate.h @@ -111,12 +111,12 @@ class device_delegate<ReturnType (Params...)> : protected named_delegate<ReturnT private: using basetype = named_delegate<ReturnType (Params...)>; - template <class T, class U> struct is_related_device_implementation - { static constexpr bool value = std::is_base_of<T, U>::value && std::is_base_of<device_t, U>::value; }; - template <class T, class U> struct is_related_device_interface - { static constexpr bool value = std::is_base_of<T, U>::value && std::is_base_of<device_interface, U>::value && !std::is_base_of<device_t, U>::value; }; - template <class T, class U> struct is_related_device - { static constexpr bool value = is_related_device_implementation<T, U>::value || is_related_device_interface<T, U>::value; }; + template <class T, class U> + using is_related_device_implementation = std::bool_constant<std::is_base_of_v<T, U> && std::is_base_of_v<device_t, U> >; + template <class T, class U> + using is_related_device_interface = std::bool_constant<std::is_base_of_v<T, U> && std::is_base_of_v<device_interface, U> && !std::is_base_of_v<device_t, U> >; + template <class T, class U> + using is_related_device = std::bool_constant<is_related_device_implementation<T, U>::value || is_related_device_interface<T, U>::value>; template <class T> static std::enable_if_t<is_related_device_implementation<T, T>::value, device_t &> get_device(T &object) { return object; } template <class T> static std::enable_if_t<is_related_device_interface<T, T>::value, device_t &> get_device(T &object) { return object.device(); } @@ -124,8 +124,8 @@ private: public: template <unsigned Count> using array = device_delegate_array<ReturnType (Params...), Count>; - template <typename T> struct supports_callback - { static constexpr bool value = std::is_constructible<device_delegate, device_t &, char const *, T, char const *>::value; }; + template <typename T> + using supports_callback = std::bool_constant<std::is_constructible_v<device_delegate, device_t &, char const *, T, char const *> >; // construct/assign explicit device_delegate(device_t &owner) : basetype(), detail::device_delegate_helper(owner) { } diff --git a/src/emu/devfind.h b/src/emu/devfind.h index c5f7a04929a..8253fb123f6 100644 --- a/src/emu/devfind.h +++ b/src/emu/devfind.h @@ -308,7 +308,7 @@ public: } /// \brief Dummy tag always treated as not found - constexpr static char DUMMY_TAG[17] = "finder_dummy_tag"; + static constexpr char DUMMY_TAG[17] = "finder_dummy_tag"; protected: /// \brief Designated constructor diff --git a/src/emu/device.h b/src/emu/device.h index 21ac3bcba6e..d5fe81dd305 100644 --- a/src/emu/device.h +++ b/src/emu/device.h @@ -69,15 +69,11 @@ namespace emu::detail { class device_type_impl_base; -template <typename T> struct is_device_implementation -{ - static constexpr bool value = std::is_base_of<device_t, T>::value; -}; +template <typename T> +using is_device_implementation = std::bool_constant<std::is_base_of_v<device_t, T> >; -template <typename T> struct is_device_interface -{ - static constexpr bool value = std::is_base_of<device_interface, T>::value && !is_device_implementation<T>::value; -}; +template <typename T> +using is_device_interface = std::bool_constant<std::is_base_of_v<device_interface, T> && !is_device_implementation<T>::value>; struct device_feature diff --git a/src/emu/diimage.cpp b/src/emu/diimage.cpp index 55a9193f3f1..e38b4939a2b 100644 --- a/src/emu/diimage.cpp +++ b/src/emu/diimage.cpp @@ -10,14 +10,15 @@ #include "emu.h" -#include "corestr.h" #include "emuopts.h" #include "romload.h" -#include "ui/uimain.h" -#include "zippath.h" #include "softlist.h" #include "softlist_dev.h" -#include "formats/ioprocs.h" + +#include "ui/uimain.h" + +#include "corestr.h" +#include "zippath.h" #include <algorithm> #include <cctype> @@ -270,11 +271,8 @@ void device_image_interface::add_format(std::string &&name, std::string &&descri void device_image_interface::clear_error() { - m_err = IMAGE_ERROR_SUCCESS; - if (!m_err_message.empty()) - { - m_err_message.clear(); - } + m_err.clear(); + m_err_message.clear(); } @@ -284,21 +282,38 @@ void device_image_interface::clear_error() // error //------------------------------------------------- -static std::string_view messages[] = +std::error_category const &image_category() noexcept { - "", - "Internal error", - "Unsupported operation", - "Out of memory", - "File not found", - "Invalid image", - "File already open", - "Unspecified error" -}; + class image_category_impl : public std::error_category + { + public: + virtual char const *name() const noexcept override { return "image"; } + + virtual std::string message(int condition) const override + { + using namespace std::literals; + static std::string_view const s_messages[] = { + "No error"sv, + "Internal error"sv, + "Unsupported operation"sv, + "Invalid image"sv, + "File already open"sv, + "Unspecified error"sv }; + if ((0 <= condition) && (std::size(s_messages) > condition)) + return std::string(s_messages[condition]); + else + return "Unknown error"s; + } + }; + static image_category_impl const s_image_category_instance; + return s_image_category_instance; +} std::string_view device_image_interface::error() { - return (!m_err_message.empty()) ? m_err_message : messages[m_err]; + if (m_err && m_err_message.empty()) + m_err_message = m_err.message(); + return m_err_message; } @@ -307,14 +322,12 @@ std::string_view device_image_interface::error() // seterror - specifies an error on an image //------------------------------------------------- -void device_image_interface::seterror(image_error_t err, const char *message) +void device_image_interface::seterror(std::error_condition err, const char *message) { clear_error(); m_err = err; - if (message != nullptr) - { + if (message) m_err_message = message; - } } @@ -544,14 +557,13 @@ void device_image_interface::battery_load(void *buffer, int length, int fill) if (!buffer || (length <= 0)) throw emu_fatalerror("device_image_interface::battery_load: Must specify sensical buffer/length"); - osd_file::error filerr; - int bytes_read = 0; - std::string fname = std::string(device().machine().system().name).append(PATH_SEPARATOR).append(m_basename_noext).append(".nv"); + std::string const fname = std::string(device().machine().system().name).append(PATH_SEPARATOR).append(m_basename_noext).append(".nv"); /* try to open the battery file and read it in, if possible */ emu_file file(device().machine().options().nvram_directory(), OPEN_FLAG_READ); - filerr = file.open(fname); - if (filerr == osd_file::error::NONE) + std::error_condition const filerr = file.open(fname); + int bytes_read = 0; + if (!filerr) bytes_read = file.read(buffer, length); // fill remaining bytes (if necessary) @@ -563,14 +575,13 @@ void device_image_interface::battery_load(void *buffer, int length, const void * if (!buffer || (length <= 0)) throw emu_fatalerror("device_image_interface::battery_load: Must specify sensical buffer/length"); - osd_file::error filerr; - int bytes_read = 0; - std::string fname = std::string(device().machine().system().name).append(PATH_SEPARATOR).append(m_basename_noext).append(".nv"); + std::string const fname = std::string(device().machine().system().name).append(PATH_SEPARATOR).append(m_basename_noext).append(".nv"); // try to open the battery file and read it in, if possible emu_file file(device().machine().options().nvram_directory(), OPEN_FLAG_READ); - filerr = file.open(fname); - if (filerr == osd_file::error::NONE) + std::error_condition const filerr = file.open(fname); + int bytes_read = 0; + if (!filerr) bytes_read = file.read(buffer, length); // if no file was present, copy the default contents @@ -598,8 +609,8 @@ void device_image_interface::battery_save(const void *buffer, int length) // try to open the battery file and write it out, if possible emu_file file(device().machine().options().nvram_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - osd_file::error filerr = file.open(fname); - if (filerr == osd_file::error::NONE) + std::error_condition const filerr = file.open(fname); + if (!filerr) file.write(buffer, length); } @@ -637,58 +648,30 @@ bool device_image_interface::uses_file_extension(const char *file_extension) con // *************************************************************************** //------------------------------------------------- -// image_error_from_file_error - converts an image -// error to a file error -//------------------------------------------------- - -image_error_t device_image_interface::image_error_from_file_error(osd_file::error filerr) -{ - switch (filerr) - { - case osd_file::error::NONE: - return IMAGE_ERROR_SUCCESS; - - case osd_file::error::NOT_FOUND: - case osd_file::error::ACCESS_DENIED: - // file not found (or otherwise cannot open) - return IMAGE_ERROR_FILENOTFOUND; - - case osd_file::error::OUT_OF_MEMORY: - // out of memory - return IMAGE_ERROR_OUTOFMEMORY; - - case osd_file::error::ALREADY_OPEN: - // this shouldn't happen - return IMAGE_ERROR_ALREADYOPEN; - - case osd_file::error::FAILURE: - case osd_file::error::TOO_MANY_FILES: - case osd_file::error::INVALID_DATA: - default: - // other errors - return IMAGE_ERROR_INTERNAL; - } -} - - -//------------------------------------------------- // load_image_by_path - loads an image with a // specific path //------------------------------------------------- -image_error_t device_image_interface::load_image_by_path(u32 open_flags, std::string_view path) +std::error_condition device_image_interface::load_image_by_path(u32 open_flags, std::string_view path) { std::string revised_path; // attempt to read the file - auto const filerr = util::zippath_fopen(path, open_flags, m_file, revised_path); - if (filerr != osd_file::error::NONE) - return image_error_from_file_error(filerr); + auto filerr = util::zippath_fopen(path, open_flags, m_file, revised_path); + if (filerr) + { + osd_printf_verbose("%s: error opening image file %s with flags=%08X (%s:%d %s)\n", device().tag(), path, open_flags, filerr.category().name(), filerr.value(), filerr.message()); + return filerr; + } + else + { + osd_printf_verbose("%s: opened image file %s with flags=%08X\n", device().tag(), path, open_flags); + } m_readonly = (open_flags & OPEN_FLAG_WRITE) ? 0 : 1; m_created = (open_flags & OPEN_FLAG_CREATE) ? 1 : 0; set_image_filename(revised_path); - return IMAGE_ERROR_SUCCESS; + return std::error_condition(); } @@ -696,7 +679,7 @@ image_error_t device_image_interface::load_image_by_path(u32 open_flags, std::st // reopen_for_write //------------------------------------------------- -int device_image_interface::reopen_for_write(std::string_view path) +std::error_condition device_image_interface::reopen_for_write(std::string_view path) { m_file.reset(); @@ -704,15 +687,15 @@ int device_image_interface::reopen_for_write(std::string_view path) // attempt to open the file for writing auto const filerr = util::zippath_fopen(path, OPEN_FLAG_READ|OPEN_FLAG_WRITE|OPEN_FLAG_CREATE, m_file, revised_path); - if (filerr != osd_file::error::NONE) - return image_error_from_file_error(filerr); + if (filerr) + return filerr; // success! m_readonly = 0; m_created = 1; set_image_filename(revised_path); - return IMAGE_ERROR_SUCCESS; + return std::error_condition(); } @@ -823,19 +806,19 @@ bool device_image_interface::load_software(software_list_device &swlist, std::st // try to load the file m_mame_file.reset(new emu_file(device().machine().options().media_path(), searchpath, OPEN_FLAG_READ)); m_mame_file->set_restrict_to_mediapath(1); - osd_file::error filerr; + std::error_condition filerr; if (has_crc) filerr = m_mame_file->open(romp->name(), crc); else filerr = m_mame_file->open(romp->name()); - if (filerr != osd_file::error::NONE) + if (filerr) m_mame_file.reset(); warningcount += verify_length_and_hash(m_mame_file.get(), romp->name(), romp->get_length(), util::hash_collection(romp->hashdata())); - if (filerr == osd_file::error::NONE) + if (!filerr) filerr = util::core_file::open_proxy(*m_mame_file, m_file); - if (filerr == osd_file::error::NONE) + if (!filerr) retval = true; break; // load first item for start @@ -878,14 +861,14 @@ image_init_result device_image_interface::load_internal(std::string_view path, b { // open the file m_err = load_image_by_path(*iter, path); - if (m_err && (m_err != IMAGE_ERROR_FILENOTFOUND)) + if (m_err && (m_err != std::errc::no_such_file_or_directory) && (m_err != std::errc::permission_denied)) goto done; } // did we fail to find the file? if (!m_file) { - m_err = IMAGE_ERROR_FILENOTFOUND; + m_err = std::errc::no_such_file_or_directory; goto done; } } @@ -894,15 +877,17 @@ image_init_result device_image_interface::load_internal(std::string_view path, b m_create_format = create_format; m_create_args = create_args; - if (init_phase()==false) { - m_err = (finish_load() == image_init_result::PASS) ? IMAGE_ERROR_SUCCESS : IMAGE_ERROR_INTERNAL; + if (!init_phase()) + { + m_err = (finish_load() == image_init_result::PASS) ? std::error_condition() : image_error::INTERNAL; if (m_err) goto done; } // success! done: - if (m_err!=0) { + if (m_err) + { if (!init_phase()) { if (device().machine().phase() == machine_phase::RUNNING) @@ -1004,7 +989,7 @@ image_init_result device_image_interface::finish_load() { if (!image_checkhash()) { - m_err = IMAGE_ERROR_INVALIDIMAGE; + m_err = image_error::INVALIDIMAGE; err = image_init_result::FAIL; } @@ -1016,7 +1001,7 @@ image_init_result device_image_interface::finish_load() if (err != image_init_result::PASS) { if (!m_err) - m_err = IMAGE_ERROR_UNSPECIFIED; + m_err = image_error::UNSPECIFIED; } } else @@ -1026,7 +1011,7 @@ image_init_result device_image_interface::finish_load() if (err != image_init_result::PASS) { if (!m_err) - m_err = IMAGE_ERROR_UNSPECIFIED; + m_err = image_error::UNSPECIFIED; } } } @@ -1354,41 +1339,3 @@ bool device_image_interface::init_phase() const return !device().has_running_machine() || device().machine().phase() == machine_phase::INIT; } - - -//---------------------------------------------------------------------------- - -static int image_fseek_thunk(void *file, s64 offset, int whence) -{ - device_image_interface *image = (device_image_interface *) file; - return image->fseek(offset, whence); -} - -static size_t image_fread_thunk(void *file, void *buffer, size_t length) -{ - device_image_interface *image = (device_image_interface *) file; - return image->fread(buffer, length); -} - -static size_t image_fwrite_thunk(void *file, const void *buffer, size_t length) -{ - device_image_interface *image = (device_image_interface *) file; - return image->fwrite(buffer, length); -} - -static u64 image_fsize_thunk(void *file) -{ - device_image_interface *image = (device_image_interface *) file; - return image->length(); -} - -//---------------------------------------------------------------------------- - -struct io_procs image_ioprocs = -{ - nullptr, - image_fseek_thunk, - image_fread_thunk, - image_fwrite_thunk, - image_fsize_thunk -}; diff --git a/src/emu/diimage.h b/src/emu/diimage.h index 507fd34e1d3..05f714f2647 100644 --- a/src/emu/diimage.h +++ b/src/emu/diimage.h @@ -19,6 +19,7 @@ #include <memory> #include <string> +#include <system_error> #include <vector> @@ -26,8 +27,6 @@ // TYPE DEFINITIONS //************************************************************************** -extern struct io_procs image_ioprocs; - enum iodevice_t { /* List of all supported devices. Refer to the device by these names only */ @@ -55,18 +54,19 @@ enum iodevice_t IO_COUNT /* 21 - Total Number of IO_devices for searching */ }; -enum image_error_t +enum class image_error : int { - IMAGE_ERROR_SUCCESS, - IMAGE_ERROR_INTERNAL, - IMAGE_ERROR_UNSUPPORTED, - IMAGE_ERROR_OUTOFMEMORY, - IMAGE_ERROR_FILENOTFOUND, - IMAGE_ERROR_INVALIDIMAGE, - IMAGE_ERROR_ALREADYOPEN, - IMAGE_ERROR_UNSPECIFIED + INTERNAL = 1, + UNSUPPORTED, + INVALIDIMAGE, + ALREADYOPEN, + UNSPECIFIED }; +const std::error_category &image_category() noexcept; +inline std::error_condition make_error_condition(image_error e) noexcept { return std::error_condition(int(e), image_category()); } +namespace std { template <> struct is_error_condition_enum<image_error> : public std::true_type { }; } + struct image_device_type_info { iodevice_t m_type; @@ -150,7 +150,7 @@ public: const util::option_guide &device_get_creation_option_guide() const { return create_option_guide(); } std::string_view error(); - void seterror(image_error_t err, const char *message); + void seterror(std::error_condition err, const char *message); void message(const char *format, ...) ATTR_PRINTF(2,3); bool exists() const noexcept { return !m_image_name.empty(); } @@ -172,7 +172,7 @@ public: int fgetc() { char ch; if (fread(&ch, 1) != 1) ch = '\0'; return ch; } char *fgets(char *buffer, u32 length) { check_for_file(); return m_file->gets(buffer, length); } int image_feof() { check_for_file(); return m_file->eof(); } - void *ptr() {check_for_file(); return const_cast<void *>(m_file->buffer()); } + void *ptr() { check_for_file(); return const_cast<void *>(m_file->buffer()); } // configuration access const software_info *software_entry() const noexcept; @@ -217,7 +217,7 @@ public: image_init_result create(std::string_view path, const image_device_format *create_format, util::option_resolution *create_args); image_init_result create(std::string_view path); bool load_software(software_list_device &swlist, std::string_view swname, const rom_entry *entry); - int reopen_for_write(std::string_view path); + std::error_condition reopen_for_write(std::string_view path); void set_user_loadable(bool user_loadable) { m_user_loadable = user_loadable; } @@ -233,7 +233,7 @@ protected: virtual const bool use_software_list_file_extension_for_filetype() const { return false; } image_init_result load_internal(std::string_view path, bool is_create, int create_format, util::option_resolution *create_args); - image_error_t load_image_by_path(u32 open_flags, std::string_view path); + std::error_condition load_image_by_path(u32 open_flags, std::string_view path); void clear(); bool is_loaded() const { return m_file != nullptr; } @@ -260,7 +260,7 @@ protected: static const image_device_type_info m_device_info_array[]; // error related info - image_error_t m_err; + std::error_condition m_err; std::string m_err_message; private: @@ -277,7 +277,6 @@ private: const software_part *m_software_part_ptr; std::string m_software_list_name; - static image_error_t image_error_from_file_error(osd_file::error filerr); std::vector<u32> determine_open_plan(bool is_create); void update_names(); bool load_software_part(std::string_view identifier); diff --git a/src/emu/dimemory.h b/src/emu/dimemory.h index f15a04166f4..119ec9bc6f9 100644 --- a/src/emu/dimemory.h +++ b/src/emu/dimemory.h @@ -50,11 +50,11 @@ constexpr int TRANSLATE_FETCH_DEBUG = (TRANSLATE_FETCH | TRANSLATE_DEBUG_MAS class device_memory_interface : public device_interface { friend class device_scheduler; - template <typename T, typename U> struct is_related_class { static constexpr bool value = std::is_convertible<std::add_pointer_t<T>, std::add_pointer_t<U> >::value; }; - template <typename T, typename U> struct is_related_device { static constexpr bool value = emu::detail::is_device_implementation<T>::value && is_related_class<T, U>::value; }; - template <typename T, typename U> struct is_related_interface { static constexpr bool value = emu::detail::is_device_interface<T>::value && is_related_class<T, U>::value; }; - template <typename T, typename U> struct is_unrelated_device { static constexpr bool value = emu::detail::is_device_implementation<T>::value && !is_related_class<T, U>::value; }; - template <typename T, typename U> struct is_unrelated_interface { static constexpr bool value = emu::detail::is_device_interface<T>::value && !is_related_class<T, U>::value; }; + template <typename T, typename U> using is_related_class = std::bool_constant<std::is_convertible_v<std::add_pointer_t<T>, std::add_pointer_t<U> > >; + template <typename T, typename U> using is_related_device = std::bool_constant<emu::detail::is_device_implementation<T>::value && is_related_class<T, U>::value >; + template <typename T, typename U> using is_related_interface = std::bool_constant<emu::detail::is_device_interface<T>::value && is_related_class<T, U>::value >; + template <typename T, typename U> using is_unrelated_device = std::bool_constant<emu::detail::is_device_implementation<T>::value && !is_related_class<T, U>::value >; + template <typename T, typename U> using is_unrelated_interface = std::bool_constant<emu::detail::is_device_interface<T>::value && !is_related_class<T, U>::value >; public: // construction/destruction diff --git a/src/emu/dipty.cpp b/src/emu/dipty.cpp index 925113edd08..6a323d84e7f 100644 --- a/src/emu/dipty.cpp +++ b/src/emu/dipty.cpp @@ -27,7 +27,7 @@ bool device_pty_interface::open() { if (!m_opened) { - if (osd_file::openpty(m_pty_master, m_slave_name) == osd_file::error::NONE) + if (!osd_file::openpty(m_pty_master, m_slave_name)) { m_opened = true; } @@ -54,7 +54,7 @@ bool device_pty_interface::is_open() const ssize_t device_pty_interface::read(u8 *rx_chars , size_t count) const { u32 actual_bytes; - if (m_opened && m_pty_master->read(rx_chars, 0, count, actual_bytes) == osd_file::error::NONE) + if (m_opened && !m_pty_master->read(rx_chars, 0, count, actual_bytes)) return actual_bytes; else return -1; @@ -72,8 +72,3 @@ bool device_pty_interface::is_slave_connected() const // TODO: really check for slave status return m_opened; } - -const char *device_pty_interface::slave_name() const -{ - return m_slave_name.c_str(); -} diff --git a/src/emu/dipty.h b/src/emu/dipty.h index 790d4ec39b0..9fc1ddbc7e1 100644 --- a/src/emu/dipty.h +++ b/src/emu/dipty.h @@ -7,10 +7,14 @@ Device PTY interface ***************************************************************************/ - #ifndef MAME_EMU_DIPTY_H #define MAME_EMU_DIPTY_H +#pragma once + +#include <string> + + class device_pty_interface : public device_interface { public: @@ -28,7 +32,7 @@ public: bool is_slave_connected() const; - const char *slave_name() const; + const std::string &slave_name() const { return m_slave_name; } protected: osd_file::ptr m_pty_master; diff --git a/src/emu/fileio.cpp b/src/emu/fileio.cpp index 293c23045b4..0fa41d3cd11 100644 --- a/src/emu/fileio.cpp +++ b/src/emu/fileio.cpp @@ -11,7 +11,8 @@ #include "emu.h" #include "fileio.h" -#include "unzip.h" +#include "util/path.h" +#include "util/unzip.h" //#define VERBOSE 1 #define LOG_OUTPUT_FUNC osd_printf_verbose @@ -121,12 +122,7 @@ bool path_iterator::next(std::string &buffer, const char *name) // append the name if we have one if (name) - { - // compute the full pathname - if (!buffer.empty() && !util::is_directory_separator(buffer.back())) - buffer.append(PATH_SEPARATOR); - buffer.append(name); - } + util::path_append(buffer, name); // bump the index and return true m_is_first = false; @@ -298,7 +294,7 @@ util::hash_collection &emu_file::hashes(std::string_view types) // open - open a file by searching paths //------------------------------------------------- -osd_file::error emu_file::open(std::string &&name) +std::error_condition emu_file::open(std::string &&name) { // remember the filename and CRC info m_filename = std::move(name); @@ -310,7 +306,7 @@ osd_file::error emu_file::open(std::string &&name) return open_next(); } -osd_file::error emu_file::open(std::string &&name, u32 crc) +std::error_condition emu_file::open(std::string &&name, u32 crc) { // remember the filename and CRC info m_filename = std::move(name); @@ -328,7 +324,7 @@ osd_file::error emu_file::open(std::string &&name, u32 crc) // the filename by iterating over paths //------------------------------------------------- -osd_file::error emu_file::open_next() +std::error_condition emu_file::open_next() { // if we're open from a previous attempt, close up now if (m_file) @@ -336,8 +332,8 @@ osd_file::error emu_file::open_next() // loop over paths LOG("emu_file: open next '%s'\n", m_filename); - osd_file::error filerr = osd_file::error::NOT_FOUND; - while (osd_file::error::NONE != filerr) + std::error_condition filerr = std::errc::no_such_file_or_directory; + while (filerr) { if (m_first) { @@ -385,7 +381,7 @@ osd_file::error emu_file::open_next() filerr = util::core_file::open(m_fullpath, m_openflags, m_file); // if we're opening for read-only we have other options - if ((osd_file::error::NONE != filerr) && ((m_openflags & (OPEN_FLAG_READ | OPEN_FLAG_WRITE)) == OPEN_FLAG_READ)) + if (filerr && ((m_openflags & (OPEN_FLAG_READ | OPEN_FLAG_WRITE)) == OPEN_FLAG_READ)) { LOG("emu_file: attempting to open '%s' from archives\n", m_fullpath); filerr = attempt_zipped(); @@ -400,7 +396,7 @@ osd_file::error emu_file::open_next() // just an array of data in RAM //------------------------------------------------- -osd_file::error emu_file::open_ram(const void *data, u32 length) +std::error_condition emu_file::open_ram(const void *data, u32 length) { // set a fake filename and CRC m_filename = "RAM"; @@ -435,29 +431,14 @@ void emu_file::close() //------------------------------------------------- -// compress - enable/disable streaming file -// compression via zlib; level is 0 to disable -// compression, or up to 9 for max compression -//------------------------------------------------- - -osd_file::error emu_file::compress(int level) -{ - return m_file->compress(level); -} - - -//------------------------------------------------- // compressed_file_ready - ensure our zip is ready // loading if needed //------------------------------------------------- -bool emu_file::compressed_file_ready() +std::error_condition emu_file::compressed_file_ready() { // load the ZIP file now if we haven't yet - if (m_zipfile && (load_zipped_file() != osd_file::error::NONE)) - return true; - - return false; + return m_zipfile ? load_zipped_file() : std::error_condition(); } //------------------------------------------------- @@ -715,9 +696,9 @@ bool emu_file::part_of_mediapath(const std::string &path) // attempt_zipped - attempt to open a ZIPped file //------------------------------------------------- -osd_file::error emu_file::attempt_zipped() +std::error_condition emu_file::attempt_zipped() { - typedef util::archive_file::error (*open_func)(const std::string &filename, util::archive_file::ptr &result); + typedef std::error_condition (*open_func)(std::string_view filename, util::archive_file::ptr &result); char const *const suffixes[] = { ".zip", ".7z" }; open_func const open_funcs[std::size(suffixes)] = { &util::archive_file::open_zip, &util::archive_file::open_7z }; @@ -750,13 +731,13 @@ osd_file::error emu_file::attempt_zipped() // attempt to open the archive file util::archive_file::ptr zip; - util::archive_file::error ziperr = open_funcs[i](m_fullpath, zip); + std::error_condition ziperr = open_funcs[i](m_fullpath, zip); // chop the archive suffix back off the filename before continuing m_fullpath = m_fullpath.substr(0, dirsep); // if we failed to open this file, continue scanning - if (ziperr != util::archive_file::error::NONE) + if (ziperr) continue; int header = -1; @@ -788,14 +769,14 @@ osd_file::error emu_file::attempt_zipped() m_hashes.reset(); m_hashes.add_crc(m_zipfile->current_crc()); m_fullpath = savepath; - return (m_openflags & OPEN_FLAG_NO_PRELOAD) ? osd_file::error::NONE : load_zipped_file(); + return (m_openflags & OPEN_FLAG_NO_PRELOAD) ? std::error_condition() : load_zipped_file(); } // close up the archive file and try the next level zip.reset(); } } - return osd_file::error::NOT_FOUND; + return std::errc::no_such_file_or_directory; } @@ -803,7 +784,7 @@ osd_file::error emu_file::attempt_zipped() // load_zipped_file - load a ZIPped file //------------------------------------------------- -osd_file::error emu_file::load_zipped_file() +std::error_condition emu_file::load_zipped_file() { assert(m_file == nullptr); assert(m_zipdata.empty()); @@ -814,21 +795,21 @@ osd_file::error emu_file::load_zipped_file() // read the data into our buffer and return auto const ziperr = m_zipfile->decompress(&m_zipdata[0], m_zipdata.size()); - if (ziperr != util::archive_file::error::NONE) + if (ziperr) { m_zipdata.clear(); - return osd_file::error::FAILURE; + return ziperr; } // convert to RAM file - osd_file::error filerr = util::core_file::open_ram(&m_zipdata[0], m_zipdata.size(), m_openflags, m_file); - if (filerr != osd_file::error::NONE) + std::error_condition const filerr = util::core_file::open_ram(&m_zipdata[0], m_zipdata.size(), m_openflags, m_file); + if (filerr) { m_zipdata.clear(); - return osd_file::error::FAILURE; + return filerr; } // close out the ZIP file m_zipfile.reset(); - return osd_file::error::NONE; + return std::error_condition(); } diff --git a/src/emu/fileio.h b/src/emu/fileio.h index d05905efa83..f05706dffed 100644 --- a/src/emu/fileio.h +++ b/src/emu/fileio.h @@ -18,6 +18,7 @@ #include <iterator> #include <string> +#include <system_error> #include <type_traits> #include <utility> #include <vector> @@ -156,19 +157,16 @@ public: void set_restrict_to_mediapath(int rtmp) { m_restrict_to_mediapath = rtmp; } // open/close - osd_file::error open(std::string &&name); - osd_file::error open(std::string &&name, u32 crc); - osd_file::error open(std::string_view name) { return open(std::string(name)); } - osd_file::error open(std::string_view name, u32 crc) { return open(std::string(name), crc); } - osd_file::error open(const char *name) { return open(std::string(name)); } - osd_file::error open(const char *name, u32 crc) { return open(std::string(name), crc); } - osd_file::error open_next(); - osd_file::error open_ram(const void *data, u32 length); + std::error_condition open(std::string &&name); + std::error_condition open(std::string &&name, u32 crc); + std::error_condition open(std::string_view name) { return open(std::string(name)); } + std::error_condition open(std::string_view name, u32 crc) { return open(std::string(name), crc); } + std::error_condition open(const char *name) { return open(std::string(name)); } + std::error_condition open(const char *name, u32 crc) { return open(std::string(name), crc); } + std::error_condition open_next(); + std::error_condition open_ram(const void *data, u32 length); void close(); - // control - osd_file::error compress(int compress); - // position int seek(s64 offset, int whence); u64 tell(); @@ -213,11 +211,11 @@ private: } bool part_of_mediapath(const std::string &path); - bool compressed_file_ready(); + std::error_condition compressed_file_ready(); // internal helpers - osd_file::error attempt_zipped(); - osd_file::error load_zipped_file(); + std::error_condition attempt_zipped(); + std::error_condition load_zipped_file(); // internal state std::string m_filename; // original filename provided diff --git a/src/emu/hashfile.cpp b/src/emu/hashfile.cpp index 50a32a60b29..a6107e5e630 100644 --- a/src/emu/hashfile.cpp +++ b/src/emu/hashfile.cpp @@ -27,10 +27,8 @@ static bool read_hash_config(const char *hash_path, const util::hash_collection { /* open a file */ emu_file file(hash_path, OPEN_FLAG_READ); - if (file.open(std::string(sysname) + ".hsi") != osd_file::error::NONE) - { + if (file.open(std::string(sysname) + ".hsi")) return false; - } pugi::xml_document doc; diff --git a/src/emu/http.cpp b/src/emu/http.cpp index b384049a37f..42d8120d32e 100644 --- a/src/emu/http.cpp +++ b/src/emu/http.cpp @@ -422,8 +422,8 @@ bool http_manager::read_file(std::ostream &os, const std::string &path) { std::ostringstream full_path; full_path << m_root << path; util::core_file::ptr f; - osd_file::error e = util::core_file::open(full_path.str(), OPEN_FLAG_READ, f); - if (e == osd_file::error::NONE) + std::error_condition const e = util::core_file::open(full_path.str(), OPEN_FLAG_READ, f); + if (!e) { int c; while ((c = f->getc()) >= 0) @@ -431,7 +431,7 @@ bool http_manager::read_file(std::ostream &os, const std::string &path) { os.put(c); } } - return e == osd_file::error::NONE; + return !e; } void http_manager::serve_document(http_request_ptr request, http_response_ptr response, const std::string &filename) { diff --git a/src/emu/image.cpp b/src/emu/image.cpp index c80d9bafde7..02cc25ce80b 100644 --- a/src/emu/image.cpp +++ b/src/emu/image.cpp @@ -173,8 +173,8 @@ int image_manager::write_config(emu_options &options, const char *filename, cons } emu_file file(options.ini_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE); - osd_file::error filerr = file.open(filename); - if (filerr == osd_file::error::NONE) + std::error_condition const filerr = file.open(filename); + if (!filerr) { std::string inistring = options.output_ini(); file.puts(inistring); diff --git a/src/emu/ioport.cpp b/src/emu/ioport.cpp index 2e9d115e46e..cae37f28c17 100644 --- a/src/emu/ioport.cpp +++ b/src/emu/ioport.cpp @@ -99,9 +99,11 @@ #include "inputdev.h" #include "natkeyboard.h" -#include "corestr.h" +#include "util/corestr.h" +#include "util/ioprocsfilter.h" +#include "util/unicode.h" + #include "osdepend.h" -#include "unicode.h" #include <cctype> #include <ctime> @@ -2652,23 +2654,26 @@ template<typename Type> Type ioport_manager::playback_read(Type &result) { // protect against nullptr handles if previous reads fail - if (!m_playback_file.is_open()) - result = 0; + if (!m_playback_stream) + return result = Type(0); // read the value; if we fail, end playback - else if (m_playback_file.read(&result, sizeof(result)) != sizeof(result)) + size_t read; + m_playback_stream->read(&result, sizeof(result), read); + if (sizeof(result) != read) { playback_end("End of file"); - result = 0; + return result = Type(0); } - // return the appropriate value - else if (sizeof(result) == 8) + // normalize byte order + if (sizeof(result) == 8) result = little_endianize_int64(result); else if (sizeof(result) == 4) result = little_endianize_int32(result); else if (sizeof(result) == 2) result = little_endianize_int16(result); + return result; } @@ -2693,15 +2698,15 @@ time_t ioport_manager::playback_init() return 0; // open the playback file - osd_file::error filerr = m_playback_file.open(filename); + std::error_condition const filerr = m_playback_file.open(filename); // return an explicit error if file isn't found in given path - if(filerr == osd_file::error::NOT_FOUND) + if (filerr == std::errc::no_such_file_or_directory) fatalerror("Input file %s not found\n",filename); // TODO: bail out any other error laconically for now - if(filerr != osd_file::error::NONE) - fatalerror("Failed to open file %s for playback (code error=%d)\n",filename,int(filerr)); + if (filerr) + fatalerror("Failed to open file %s for playback (%s:%d %s)\n", filename, filerr.category().name(), filerr.value(), filerr.message()); // read the header and verify that it is a modern version; if not, print an error inp_header header; @@ -2725,7 +2730,7 @@ time_t ioport_manager::playback_init() osd_printf_info("Input file is for machine '%s', not for current machine '%s'\n", sysname, machine().system().name); // enable compression - m_playback_file.compress(FCOMPRESS_MEDIUM); + m_playback_stream = util::zlib_read(util::core_file_read(m_playback_file), 16386); return basetime; } @@ -2737,9 +2742,10 @@ time_t ioport_manager::playback_init() void ioport_manager::playback_end(const char *message) { // only applies if we have a live file - if (m_playback_file.is_open()) + if (m_playback_stream) { // close the file + m_playback_stream.reset(); m_playback_file.close(); // pop a message @@ -2753,7 +2759,8 @@ void ioport_manager::playback_end(const char *message) osd_printf_info("Average recorded speed: %d%%\n", u32((m_playback_accumulated_speed * 200 + 1) >> 21)); // close the program at the end of inp file playback - if (machine().options().exit_after_playback()) { + if (machine().options().exit_after_playback()) + { osd_printf_info("Exiting MAME now...\n"); machine().schedule_exit(); } @@ -2769,7 +2776,7 @@ void ioport_manager::playback_end(const char *message) void ioport_manager::playback_frame(const attotime &curtime) { // if playing back, fetch the information and verify - if (m_playback_file.is_open()) + if (m_playback_stream) { // first the absolute time seconds_t seconds_temp; @@ -2795,7 +2802,7 @@ void ioport_manager::playback_frame(const attotime &curtime) void ioport_manager::playback_port(ioport_port &port) { // if playing back, fetch information about this port - if (m_playback_file.is_open()) + if (m_playback_stream) { // read the default value and the digital state playback_read(port.live().defvalue); @@ -2824,11 +2831,20 @@ template<typename Type> void ioport_manager::record_write(Type value) { // protect against nullptr handles if previous reads fail - if (!m_record_file.is_open()) + if (!m_record_stream) return; - // read the value; if we fail, end playback - if (m_record_file.write(&value, sizeof(value)) != sizeof(value)) + // normalize byte order + if (sizeof(value) == 8) + value = little_endianize_int64(value); + else if (sizeof(value) == 4) + value = little_endianize_int32(value); + else if (sizeof(value) == 2) + value = little_endianize_int16(value); + + // write the value; if we fail, end recording + size_t written; + if (m_record_stream->write(&value, sizeof(value), written) || (sizeof(value) != written)) record_end("Out of space"); } @@ -2875,9 +2891,9 @@ void ioport_manager::record_init() return; // open the record file - osd_file::error filerr = m_record_file.open(filename); - if (filerr != osd_file::error::NONE) - throw emu_fatalerror("ioport_manager::record_init: Failed to open file for recording"); + std::error_condition const filerr = m_record_file.open(filename); + if (filerr) + throw emu_fatalerror("ioport_manager::record_init: Failed to open file for recording (%s:%d %s)", filerr.category().name(), filerr.value(), filerr.message()); // get the base time system_time systime; @@ -2895,7 +2911,7 @@ void ioport_manager::record_init() header.write(m_record_file); // enable compression - m_record_file.compress(FCOMPRESS_MEDIUM); + m_record_stream = util::zlib_write(util::core_file_read_write(m_record_file), 6, 16384); } @@ -2922,9 +2938,9 @@ void ioport_manager::timecode_init() filename.append(record_filename).append(".timecode"); osd_printf_info("Record input timecode file: %s\n", record_filename); - osd_file::error filerr = m_timecode_file.open(filename); - if (filerr != osd_file::error::NONE) - throw emu_fatalerror("ioport_manager::timecode_init: Failed to open file for input timecode recording"); + std::error_condition const filerr = m_timecode_file.open(filename); + if (filerr) + throw emu_fatalerror("ioport_manager::timecode_init: Failed to open file for input timecode recording (%s:%d %s)", filerr.category().name(), filerr.value(), filerr.message()); m_timecode_file.puts("# ==========================================\n"); m_timecode_file.puts("# TIMECODE FILE FOR VIDEO PREVIEW GENERATION\n"); @@ -2948,9 +2964,10 @@ void ioport_manager::timecode_init() void ioport_manager::record_end(const char *message) { // only applies if we have a live file - if (m_record_file.is_open()) + if (m_record_stream) { // close the file + m_record_stream.reset(); // TODO: check for errors flushing the last compressed block before doing this m_record_file.close(); // pop a message @@ -2981,7 +2998,7 @@ void ioport_manager::timecode_end(const char *message) void ioport_manager::record_frame(const attotime &curtime) { // if recording, record information about the current frame - if (m_record_file.is_open()) + if (m_record_stream) { // first the absolute time record_write(curtime.seconds()); @@ -3091,7 +3108,7 @@ void ioport_manager::record_frame(const attotime &curtime) void ioport_manager::record_port(ioport_port &port) { // if recording, store information about this port - if (m_record_file.is_open()) + if (m_record_stream) { // store the default value and digital state record_write(port.live().defvalue); diff --git a/src/emu/ioport.h b/src/emu/ioport.h index 11dcf006be9..fdf859b9afd 100644 --- a/src/emu/ioport.h +++ b/src/emu/ioport.h @@ -17,11 +17,14 @@ #ifndef MAME_EMU_IOPORT_H #define MAME_EMU_IOPORT_H +#include "ioprocs.h" + #include <array> #include <cstdint> #include <cstring> #include <ctime> #include <list> +#include <memory> #include <vector> @@ -1447,8 +1450,10 @@ private: attoseconds_t m_last_delta_nsec; // nanoseconds that passed since the previous callback // playback/record information - emu_file m_record_file; // recording file (nullptr if not recording) - emu_file m_playback_file; // playback file (nullptr if not recording) + emu_file m_record_file; // recording file (closed if not recording) + emu_file m_playback_file; // playback file (closed if not recording) + util::write_stream::ptr m_record_stream; // recording stream (nullptr if not recording) + util::read_stream::ptr m_playback_stream; // playback stream (nullptr if not recording) u64 m_playback_accumulated_speed; // accumulated speed during playback u32 m_playback_accumulated_frames; // accumulated frames during playback emu_file m_timecode_file; // timecode/frames playback file (nullptr if not recording) diff --git a/src/emu/machine.cpp b/src/emu/machine.cpp index 5568bb48e85..3721ba9bec8 100644 --- a/src/emu/machine.cpp +++ b/src/emu/machine.cpp @@ -313,8 +313,8 @@ int running_machine::run(bool quiet) if (options().log() && !quiet) { m_logfile = std::make_unique<emu_file>(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - osd_file::error filerr = m_logfile->open("error.log"); - if (filerr != osd_file::error::NONE) + std::error_condition const filerr = m_logfile->open("error.log"); + if (filerr) throw emu_fatalerror("running_machine::run: unable to open error.log file"); using namespace std::placeholders; @@ -324,8 +324,8 @@ int running_machine::run(bool quiet) if (options().debug() && options().debuglog()) { m_debuglogfile = std::make_unique<emu_file>(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - osd_file::error filerr = m_debuglogfile->open("debug.log"); - if (filerr != osd_file::error::NONE) + std::error_condition const filerr = m_debuglogfile->open("debug.log"); + if (filerr) throw emu_fatalerror("running_machine::run: unable to open debug.log file"); } @@ -931,7 +931,7 @@ void running_machine::handle_saveload() // open the file emu_file file(m_saveload_searchpath ? m_saveload_searchpath : "", openflags); auto const filerr = file.open(m_saveload_pending_file); - if (filerr == osd_file::error::NONE) + if (!filerr) { const char *const opnamed = (m_saveload_schedule == saveload_schedule::LOAD) ? "loaded" : "saved"; @@ -973,7 +973,7 @@ void running_machine::handle_saveload() if (saverr != STATERR_NONE && m_saveload_schedule == saveload_schedule::SAVE) file.remove_on_close(); } - else if (openflags == OPEN_FLAG_READ && filerr == osd_file::error::NOT_FOUND) + else if ((openflags == OPEN_FLAG_READ) && (std::errc::no_such_file_or_directory == filerr)) { // attempt to load a non-existent savestate, report empty slot popmessage("Error: No savestate file to load.", opname); @@ -1174,7 +1174,7 @@ void running_machine::nvram_load() for (device_nvram_interface &nvram : nvram_interface_enumerator(root_device())) { emu_file file(options().nvram_directory(), OPEN_FLAG_READ); - if (file.open(nvram_filename(nvram.device())) == osd_file::error::NONE) + if (!file.open(nvram_filename(nvram.device()))) { nvram.nvram_load(file); file.close(); @@ -1196,7 +1196,7 @@ void running_machine::nvram_save() if (nvram.nvram_can_save()) { emu_file file(options().nvram_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - if (file.open(nvram_filename(nvram.device())) == osd_file::error::NONE) + if (!file.open(nvram_filename(nvram.device()))) { nvram.nvram_save(file); file.close(); diff --git a/src/emu/render.cpp b/src/emu/render.cpp index 1c176929aad..2c4541cb6b9 100644 --- a/src/emu/render.cpp +++ b/src/emu/render.cpp @@ -50,7 +50,8 @@ #include "ui/uimain.h" -#include "xmlfile.h" +#include "util/path.h" +#include "util/xmlfile.h" #include <zlib.h> @@ -2186,7 +2187,7 @@ bool render_target::load_layout_file(const char *dirname, const char *filename) emu_file layoutfile(m_manager.machine().options().art_path(), OPEN_FLAG_READ); layoutfile.set_restrict_to_mediapath(1); bool result(false); - for (osd_file::error filerr = layoutfile.open(fname); osd_file::error::NONE == filerr; filerr = layoutfile.open_next()) + for (std::error_condition filerr = layoutfile.open(fname); !filerr; filerr = layoutfile.open_next()) { // read the file and parse as XML util::xml::file::ptr const rootnode(util::xml::file::read(layoutfile, &parseopt)); diff --git a/src/emu/rendfont.cpp b/src/emu/rendfont.cpp index c20a7979bbc..ae295e39e2d 100644 --- a/src/emu/rendfont.cpp +++ b/src/emu/rendfont.cpp @@ -594,8 +594,8 @@ render_font::render_font(render_manager &manager, const char *filename) // load the compiled in data instead emu_file ramfile(OPEN_FLAG_READ); - osd_file::error const filerr(ramfile.open_ram(font_uismall, sizeof(font_uismall))); - if (osd_file::error::NONE == filerr) + std::error_condition const filerr(ramfile.open_ram(font_uismall, sizeof(font_uismall))); + if (!filerr) load_cached(ramfile, 0, 0); render_font_command_glyph(); } @@ -908,14 +908,14 @@ float render_font::utf8string_width(float height, float aspect, std::string_view bool render_font::load_cached_bdf(const char *filename) { - osd_file::error filerr; + std::error_condition filerr; u32 chunk; u64 bytes; // first try to open the BDF itself emu_file file(m_manager.machine().options().font_path(), OPEN_FLAG_READ); filerr = file.open(filename); - if (filerr != osd_file::error::NONE) + if (filerr) return false; // determine the file size and allocate memory @@ -952,7 +952,7 @@ bool render_font::load_cached_bdf(const char *filename) { emu_file cachefile(m_manager.machine().options().font_path(), OPEN_FLAG_READ); filerr = cachefile.open(cachedname); - if (filerr == osd_file::error::NONE) + if (!filerr) { // if we have a cached version, load it bool const result = load_cached(cachefile, m_rawsize, hash); @@ -1456,8 +1456,8 @@ bool render_font::save_cached(const char *filename, u64 length, u32 hash) // attempt to open the file emu_file file(m_manager.machine().options().font_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE); - osd_file::error const filerr = file.open(filename); - if (osd_file::error::NONE != filerr) + std::error_condition const filerr = file.open(filename); + if (filerr) return false; // count glyphs @@ -1596,7 +1596,7 @@ void render_font::render_font_command_glyph() { // FIXME: this is copy/pasta from the BDC loading, and it shouldn't be injected into every font emu_file file(OPEN_FLAG_READ); - if (file.open_ram(font_uicmd14, sizeof(font_uicmd14)) == osd_file::error::NONE) + if (!file.open_ram(font_uicmd14, sizeof(font_uicmd14))) { // get the file size, read the header, and check that it looks good u64 const filesize(file.size()); diff --git a/src/emu/rendlay.cpp b/src/emu/rendlay.cpp index 13b2d6e16c1..c3f7a70a2e8 100644 --- a/src/emu/rendlay.cpp +++ b/src/emu/rendlay.cpp @@ -17,10 +17,11 @@ #include "rendutil.h" #include "video/rgbutil.h" -#include "nanosvg.h" -#include "unicode.h" -#include "vecstream.h" -#include "xmlfile.h" +#include "util/nanosvg.h" +#include "util/path.h" +#include "util/unicode.h" +#include "util/vecstream.h" +#include "util/xmlfile.h" #include <cctype> #include <algorithm> @@ -1713,12 +1714,10 @@ private: std::string filename; if (!m_searchpath.empty()) filename = m_dirname; - if (!filename.empty() && !util::is_directory_separator(filename[filename.size() - 1])) - filename.append(PATH_SEPARATOR); - filename.append(m_imagefile); + util::path_append(filename, m_imagefile); LOGMASKED(LOG_IMAGE_LOAD, "Image component attempt to load image file '%s'\n", filename); - osd_file::error const imgerr = file.open(filename); - if (osd_file::error::NONE == imgerr) + std::error_condition const imgerr = file.open(filename); + if (!imgerr) { if (!load_bitmap(file)) { @@ -1729,7 +1728,8 @@ private: } else { - LOGMASKED(LOG_IMAGE_LOAD, "Image component unable to open image file '%s'\n", filename); + LOGMASKED(LOG_IMAGE_LOAD, "Image component unable to open image file '%s' (%s:%d %s)\n", + filename, imgerr.category().name(), imgerr.value(), imgerr.message()); } } else if (!m_data.empty()) @@ -1745,12 +1745,10 @@ private: std::string filename; if (!m_searchpath.empty()) filename = m_dirname; - if (!filename.empty() && !util::is_directory_separator(filename[filename.size() - 1])) - filename.append(PATH_SEPARATOR); - filename.append(m_alphafile); + util::path_append(filename, m_alphafile); LOGMASKED(LOG_IMAGE_LOAD, "Image component attempt to load alpha channel from file '%s'\n", filename); - osd_file::error const alferr = file.open(filename); - if (osd_file::error::NONE == alferr) + std::error_condition const alferr = file.open(filename); + if (!alferr) { // TODO: no way to detect corner case where we had alpha from the image but the alpha PNG makes it entirely opaque if (render_load_png(m_bitmap, file, true)) @@ -1759,7 +1757,8 @@ private: } else { - LOGMASKED(LOG_IMAGE_LOAD, "Image component unable to open alpha channel file '%s'\n", filename); + LOGMASKED(LOG_IMAGE_LOAD, "Image component unable to open alpha channel file '%s' (%s:%d %s)\n", + filename, alferr.category().name(), alferr.value(), alferr.message()); } } else if (m_svg) @@ -1841,8 +1840,8 @@ private: // make a file wrapper for the data and see if it looks like a bitmap util::core_file::ptr file; - osd_file::error const filerr(util::core_file::open_ram(m_data.c_str(), m_data.size(), OPEN_FLAG_READ, file)); - bool const bitmapdata((osd_file::error::NONE == filerr) && file && load_bitmap(*file)); + std::error_condition const filerr(util::core_file::open_ram(m_data.c_str(), m_data.size(), OPEN_FLAG_READ, file)); + bool const bitmapdata(!filerr && file && load_bitmap(*file)); file.reset(); // if it didn't look like a bitmap, see if it looks like it might be XML and hence SVG @@ -3398,12 +3397,10 @@ private: std::string filename; if (!m_searchpath.empty()) filename = m_dirname; - if (!filename.empty() && !util::is_directory_separator(filename[filename.size() - 1])) - filename.append(PATH_SEPARATOR); - filename.append(m_imagefile[number]); + util::path_append(filename, m_imagefile[number]); // load the basic bitmap - if (file.open(filename) == osd_file::error::NONE) + if (!file.open(filename)) render_load_png(m_bitmap[number], file); // if we can't load the bitmap just use text rendering diff --git a/src/emu/romload.cpp b/src/emu/romload.cpp index 36d7896e467..c4c3101bc89 100644 --- a/src/emu/romload.cpp +++ b/src/emu/romload.cpp @@ -101,15 +101,15 @@ std::vector<std::string> make_software_searchpath(software_list_device &swlist, } -chd_error do_open_disk(const emu_options &options, std::initializer_list<std::reference_wrapper<const std::vector<std::string> > > searchpath, const rom_entry *romp, chd_file &chd, std::function<const rom_entry * ()> next_parent) +std::error_condition do_open_disk(const emu_options &options, std::initializer_list<std::reference_wrapper<const std::vector<std::string> > > searchpath, const rom_entry *romp, chd_file &chd, std::function<const rom_entry * ()> next_parent) { // hashes are fixed, but we might need to try multiple filenames std::set<std::string> tried; const util::hash_collection hashes(romp->hashdata()); std::string filename, fullpath; const rom_entry *parent(nullptr); - chd_error result(CHDERR_FILE_NOT_FOUND); - while (romp && (CHDERR_NONE != result)) + std::error_condition result(std::errc::no_such_file_or_directory); + while (romp && result) { filename = romp->name() + ".chd"; if (tried.insert(filename).second) @@ -120,8 +120,8 @@ chd_error do_open_disk(const emu_options &options, std::initializer_list<std::re { imgfile.reset(new emu_file(options.media_path(), paths, OPEN_FLAG_READ)); imgfile->set_restrict_to_mediapath(1); - const osd_file::error filerr(imgfile->open(filename, OPEN_FLAG_READ)); - if (osd_file::error::NONE == filerr) + const std::error_condition filerr(imgfile->open(filename, OPEN_FLAG_READ)); + if (!filerr) break; else imgfile.reset(); @@ -132,12 +132,12 @@ chd_error do_open_disk(const emu_options &options, std::initializer_list<std::re { fullpath = imgfile->fullpath(); imgfile.reset(); - result = chd.open(fullpath.c_str()); + result = chd.open(fullpath); } } // walk the parents looking for a CHD with the same hashes but a different name - if (CHDERR_NONE != result) + if (result) { while (romp) { @@ -345,11 +345,11 @@ chd_file *rom_load_manager::get_disk_handle(std::string_view region) file associated with the given region -------------------------------------------------*/ -int rom_load_manager::set_disk_handle(std::string_view region, const char *fullpath) +std::error_condition rom_load_manager::set_disk_handle(std::string_view region, const char *fullpath) { auto chd = std::make_unique<open_chd>(region); auto err = chd->orig_chd().open(fullpath); - if (err == CHDERR_NONE) + if (!err) m_chd_list.push_back(std::move(chd)); return err; } @@ -439,7 +439,7 @@ void rom_load_manager::fill_random(u8 *base, u32 length) for missing files -------------------------------------------------*/ -void rom_load_manager::handle_missing_file(const rom_entry *romp, const std::vector<std::string> &tried_file_names, chd_error chderr) +void rom_load_manager::handle_missing_file(const rom_entry *romp, const std::vector<std::string> &tried_file_names, std::error_condition chderr) { std::string tried; if (!tried_file_names.empty()) @@ -453,12 +453,12 @@ void rom_load_manager::handle_missing_file(const rom_entry *romp, const std::vec tried += ')'; } - const bool is_chd(chderr != CHDERR_NONE); + const bool is_chd(chderr); const std::string name(is_chd ? romp->name() + ".chd" : romp->name()); - const bool is_chd_error(is_chd && chderr != CHDERR_FILE_NOT_FOUND); + const bool is_chd_error(is_chd && chderr != std::errc::no_such_file_or_directory); if (is_chd_error) - m_errorstring.append(string_format("%s CHD ERROR: %s\n", name, chd_file::error_string(chderr))); + m_errorstring.append(string_format("%s CHD ERROR: %s\n", name, chderr.message())); if (ROM_ISOPTIONAL(romp)) { @@ -638,7 +638,7 @@ void rom_load_manager::region_post_process(memory_region *region, bool invert) std::unique_ptr<emu_file> rom_load_manager::open_rom_file(std::initializer_list<std::reference_wrapper<const std::vector<std::string> > > searchpath, const rom_entry *romp, std::vector<std::string> &tried_file_names, bool from_list) { - osd_file::error filerr = osd_file::error::NOT_FOUND; + std::error_condition filerr = std::errc::no_such_file_or_directory; u32 const romsize = rom_file_size(romp); tried_file_names.clear(); @@ -664,14 +664,14 @@ std::unique_ptr<emu_file> rom_load_manager::open_rom_file(std::initializer_list< m_romsloadedsize += romsize; // return the result - if (osd_file::error::NONE != filerr) + if (filerr) return nullptr; else return result; } -std::unique_ptr<emu_file> rom_load_manager::open_rom_file(const std::vector<std::string> &paths, std::vector<std::string> &tried, bool has_crc, u32 crc, std::string_view name, osd_file::error &filerr) +std::unique_ptr<emu_file> rom_load_manager::open_rom_file(const std::vector<std::string> &paths, std::vector<std::string> &tried, bool has_crc, u32 crc, std::string_view name, std::error_condition &filerr) { // record the set names we search tried.insert(tried.end(), paths.begin(), paths.end()); @@ -685,7 +685,7 @@ std::unique_ptr<emu_file> rom_load_manager::open_rom_file(const std::vector<std: filerr = result->open(name); // don't return anything if unsuccessful - if (osd_file::error::NONE != filerr) + if (filerr) return nullptr; else return result; @@ -939,7 +939,7 @@ void rom_load_manager::process_rom_entries(std::initializer_list<std::reference_ { file = open_rom_file(searchpath, romp, tried_file_names, from_list); if (!file) - handle_missing_file(romp, tried_file_names, CHDERR_NONE); + handle_missing_file(romp, tried_file_names, std::error_condition()); } // loop until we run out of reloads @@ -1000,44 +1000,44 @@ void rom_load_manager::process_rom_entries(std::initializer_list<std::reference_ open_disk_diff - open a DISK diff file -------------------------------------------------*/ -chd_error rom_load_manager::open_disk_diff(emu_options &options, const rom_entry *romp, chd_file &source, chd_file &diff_chd) +std::error_condition rom_load_manager::open_disk_diff(emu_options &options, const rom_entry *romp, chd_file &source, chd_file &diff_chd) { // TODO: use system name and/or software list name in the path - the current setup doesn't scale std::string fname = romp->name() + ".dif"; - /* try to open the diff */ + // try to open the diff LOG("Opening differencing image file: %s\n", fname.c_str()); emu_file diff_file(options.diff_directory(), OPEN_FLAG_READ | OPEN_FLAG_WRITE); - osd_file::error filerr = diff_file.open(fname); - if (filerr == osd_file::error::NONE) + std::error_condition filerr = diff_file.open(fname); + if (!filerr) { std::string fullpath(diff_file.fullpath()); diff_file.close(); LOG("Opening differencing image file: %s\n", fullpath.c_str()); - return diff_chd.open(fullpath.c_str(), true, &source); + return diff_chd.open(fullpath, true, &source); } - /* didn't work; try creating it instead */ + // didn't work; try creating it instead LOG("Creating differencing image: %s\n", fname.c_str()); diff_file.set_openflags(OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); filerr = diff_file.open(fname); - if (filerr == osd_file::error::NONE) + if (!filerr) { std::string fullpath(diff_file.fullpath()); diff_file.close(); - /* create the CHD */ + // create the CHD LOG("Creating differencing image file: %s\n", fullpath.c_str()); chd_codec_type compression[4] = { CHD_CODEC_NONE }; - chd_error err = diff_chd.create(fullpath.c_str(), source.logical_bytes(), source.hunk_bytes(), compression, source); - if (err != CHDERR_NONE) + std::error_condition err = diff_chd.create(fullpath, source.logical_bytes(), source.hunk_bytes(), compression, source); + if (err) return err; return diff_chd.clone_all_metadata(source); } - return CHDERR_FILE_NOT_FOUND; + return std::errc::no_such_file_or_directory; } @@ -1059,7 +1059,7 @@ void rom_load_manager::process_disk_entries(std::initializer_list<std::reference if (ROMENTRY_ISFILE(romp)) { auto chd = std::make_unique<open_chd>(regiontag); - chd_error err; + std::error_condition err; /* make the filename of the source */ const std::string filename = romp->name() + ".chd"; @@ -1068,7 +1068,7 @@ void rom_load_manager::process_disk_entries(std::initializer_list<std::reference // FIXME: we've lost the ability to search parents here LOG("Opening disk image: %s\n", filename.c_str()); err = do_open_disk(machine().options(), searchpath, romp, chd->orig_chd(), next_parent); - if (err != CHDERR_NONE) + if (err) { handle_missing_file(romp, std::vector<std::string>(), err); chd = nullptr; @@ -1098,9 +1098,9 @@ void rom_load_manager::process_disk_entries(std::initializer_list<std::reference { /* try to open or create the diff */ err = open_disk_diff(machine().options(), romp, chd->orig_chd(), chd->diff_chd()); - if (err != CHDERR_NONE) + if (err) { - m_errorstring.append(string_format("%s DIFF CHD ERROR: %s\n", filename, chd_file::error_string(err))); + m_errorstring.append(string_format("%s DIFF CHD ERROR: %s\n", filename, err.message())); m_errors++; chd = nullptr; continue; @@ -1132,7 +1132,7 @@ std::vector<std::string> rom_load_manager::get_software_searchpath(software_list device -------------------------------------------------*/ -chd_error rom_load_manager::open_disk_image(const emu_options &options, const device_t &device, const rom_entry *romp, chd_file &image_chd) +std::error_condition rom_load_manager::open_disk_image(const emu_options &options, const device_t &device, const rom_entry *romp, chd_file &image_chd) { const std::vector<std::string> searchpath(device.searchpath()); @@ -1151,7 +1151,7 @@ chd_error rom_load_manager::open_disk_image(const emu_options &options, const de software item -------------------------------------------------*/ -chd_error rom_load_manager::open_disk_image(const emu_options &options, software_list_device &swlist, const software_info &swinfo, const rom_entry *romp, chd_file &image_chd) +std::error_condition rom_load_manager::open_disk_image(const emu_options &options, software_list_device &swlist, const software_info &swinfo, const rom_entry *romp, chd_file &image_chd) { std::vector<software_info const *> parents; std::vector<std::string> searchpath = make_software_searchpath(swlist, swinfo, parents); diff --git a/src/emu/romload.h b/src/emu/romload.h index 29caaf8e124..76fdb111cc6 100644 --- a/src/emu/romload.h +++ b/src/emu/romload.h @@ -18,6 +18,7 @@ #include <functional> #include <initializer_list> #include <string> +#include <system_error> #include <type_traits> #include <vector> @@ -419,7 +420,7 @@ public: chd_file *get_disk_handle(std::string_view region); /* set a pointer to the CHD file associated with the given region */ - int set_disk_handle(std::string_view region, const char *fullpath); + std::error_condition set_disk_handle(std::string_view region, const char *fullpath); void load_software_part_region(device_t &device, software_list_device &swlist, std::string_view swname, const rom_entry *start_region); @@ -427,27 +428,27 @@ public: static std::vector<std::string> get_software_searchpath(software_list_device &swlist, const software_info &swinfo); /* open a disk image, searching up the parent and loading by checksum */ - static chd_error open_disk_image(const emu_options &options, const device_t &device, const rom_entry *romp, chd_file &image_chd); - static chd_error open_disk_image(const emu_options &options, software_list_device &swlist, const software_info &swinfo, const rom_entry *romp, chd_file &image_chd); + static std::error_condition open_disk_image(const emu_options &options, const device_t &device, const rom_entry *romp, chd_file &image_chd); + static std::error_condition open_disk_image(const emu_options &options, software_list_device &swlist, const software_info &swinfo, const rom_entry *romp, chd_file &image_chd); private: void determine_bios_rom(device_t &device, const char *specbios); void count_roms(); void fill_random(u8 *base, u32 length); - void handle_missing_file(const rom_entry *romp, const std::vector<std::string> &tried_file_names, chd_error chderr); + void handle_missing_file(const rom_entry *romp, const std::vector<std::string> &tried_file_names, std::error_condition chderr); void dump_wrong_and_correct_checksums(const util::hash_collection &hashes, const util::hash_collection &acthashes); void verify_length_and_hash(emu_file *file, std::string_view name, u32 explength, const util::hash_collection &hashes); void display_loading_rom_message(const char *name, bool from_list); void display_rom_load_results(bool from_list); void region_post_process(memory_region *region, bool invert); std::unique_ptr<emu_file> open_rom_file(std::initializer_list<std::reference_wrapper<const std::vector<std::string> > > searchpath, const rom_entry *romp, std::vector<std::string> &tried_file_names, bool from_list); - std::unique_ptr<emu_file> open_rom_file(const std::vector<std::string> &paths, std::vector<std::string> &tried, bool has_crc, u32 crc, std::string_view name, osd_file::error &filerr); + std::unique_ptr<emu_file> open_rom_file(const std::vector<std::string> &paths, std::vector<std::string> &tried, bool has_crc, u32 crc, std::string_view name, std::error_condition &filerr); int rom_fread(emu_file *file, u8 *buffer, int length, const rom_entry *parent_region); int read_rom_data(emu_file *file, const rom_entry *parent_region, const rom_entry *romp); void fill_rom_data(const rom_entry *romp); void copy_rom_data(const rom_entry *romp); void process_rom_entries(std::initializer_list<std::reference_wrapper<const std::vector<std::string> > > searchpath, u8 bios, const rom_entry *parent_region, const rom_entry *romp, bool from_list); - chd_error open_disk_diff(emu_options &options, const rom_entry *romp, chd_file &source, chd_file &diff_chd); + std::error_condition open_disk_diff(emu_options &options, const rom_entry *romp, chd_file &source, chd_file &diff_chd); void process_disk_entries(std::initializer_list<std::reference_wrapper<const std::vector<std::string> > > searchpath, std::string_view regiontag, const rom_entry *romp, std::function<const rom_entry * ()> next_parent); void normalize_flags_for_device(std::string_view rgntag, u8 &width, endianness_t &endian); void process_region_list(); diff --git a/src/emu/save.cpp b/src/emu/save.cpp index 96fb3429a1c..120fa883655 100644 --- a/src/emu/save.cpp +++ b/src/emu/save.cpp @@ -24,7 +24,10 @@ #include "emu.h" #include "emuopts.h" -#include "coreutil.h" + +#include "util/coreutil.h" +#include "util/ioprocs.h" +#include "util/ioprocsfilter.h" //************************************************************************** @@ -212,7 +215,6 @@ save_error save_manager::check_file(running_machine &machine, emu_file &file, co sig = machine.save().signature(); // seek to the beginning and read the header - file.compress(FCOMPRESS_NONE); file.seek(0, SEEK_SET); u8 header[HEADER_SIZE]; if (file.read(header, sizeof(header)) != sizeof(header)) @@ -257,20 +259,28 @@ void save_manager::dispatch_presave() save_error save_manager::write_file(emu_file &file) { - return do_write( + util::write_stream::ptr writer; + save_error err = do_write( [] (size_t total_size) { return true; }, - [&file] (const void *data, size_t size) { return file.write(data, size) == size; }, - [&file] () + [&writer] (const void *data, size_t size) { - file.compress(FCOMPRESS_NONE); - file.seek(0, SEEK_SET); - return true; + size_t written; + std::error_condition filerr = writer->write(data, size, written); + return !filerr && (size == written); }, - [&file] () + [&file, &writer] () { - file.compress(FCOMPRESS_MEDIUM); - return true; + if (file.seek(0, SEEK_SET)) + return false; + writer = util::core_file_read_write(file); + return bool(writer); + }, + [&file, &writer] () + { + writer = util::zlib_write(util::core_file_read_write(file), 6, 16384); + return bool(writer); }); + return (STATERR_NONE != err) ? err : writer->finalize() ? STATERR_WRITE_ERROR : STATERR_NONE; } @@ -280,19 +290,26 @@ save_error save_manager::write_file(emu_file &file) save_error save_manager::read_file(emu_file &file) { + util::read_stream::ptr reader; return do_read( [] (size_t total_size) { return true; }, - [&file] (void *data, size_t size) { return file.read(data, size) == size; }, - [&file] () + [&reader] (void *data, size_t size) { - file.compress(FCOMPRESS_NONE); - file.seek(0, SEEK_SET); - return true; + std::size_t read; + std::error_condition filerr = reader->read(data, size, read); + return !filerr && (read == size); }, - [&file] () + [&file, &reader] () { - file.compress(FCOMPRESS_MEDIUM); - return true; + if (file.seek(0, SEEK_SET)) + return false; + reader = util::core_file_read(file); + return bool(reader); + }, + [&file, &reader] () + { + reader = util::zlib_read(util::core_file_read(file), 16384); + return bool(reader); }); } diff --git a/src/emu/save.h b/src/emu/save.h index 32ba0526486..cfd674e738e 100644 --- a/src/emu/save.h +++ b/src/emu/save.h @@ -55,12 +55,12 @@ typedef named_delegate<void ()> save_prepost_delegate; // saved; in general, this is intended only to be used for specific enum types // defined by your device #define ALLOW_SAVE_TYPE(TYPE) \ - template <> struct save_manager::is_atom<TYPE> { static constexpr bool value = true; }; + template <> struct save_manager::is_atom<TYPE> : public std::true_type { }; // use this as above, but also to declare that std::vector<TYPE> is safe as well #define ALLOW_SAVE_TYPE_AND_VECTOR(TYPE) \ ALLOW_SAVE_TYPE(TYPE) \ - template <> struct save_manager::is_vector_safe<TYPE> { static constexpr bool value = true; }; + template <> struct save_manager::is_vector_safe<TYPE> : public std::true_type { }; // use this for saving members of structures in arrays #define STRUCT_MEMBER(s, m) s, &save_manager::pointer_unwrap<decltype(s)>::underlying_type::m, #s "." #m @@ -99,8 +99,8 @@ class save_manager }; // set of templates to identify valid save types - template <typename ItemType> struct is_atom { static constexpr bool value = false; }; - template <typename ItemType> struct is_vector_safe { static constexpr bool value = false; }; + template <typename ItemType> struct is_atom : public std::false_type { }; + template <typename ItemType> struct is_vector_safe : public std::false_type { }; class state_entry { diff --git a/src/emu/screen.cpp b/src/emu/screen.cpp index 1a1c5dee8ad..0993473de49 100644 --- a/src/emu/screen.cpp +++ b/src/emu/screen.cpp @@ -1911,8 +1911,8 @@ void screen_device::finalize_burnin() // compute the name and create the file emu_file file(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - osd_file::error filerr = file.open(util::string_format("%s" PATH_SEPARATOR "burnin-%s.png", machine().basename(), tag() + 1)); - if (filerr == osd_file::error::NONE) + std::error_condition const filerr = file.open(util::string_format("%s" PATH_SEPARATOR "burnin-%s.png", machine().basename(), tag() + 1)); + if (!filerr) { util::png_info pnginfo; @@ -1942,7 +1942,7 @@ void screen_device::load_effect_overlay(const char *filename) // load the file m_screen_overlay_bitmap.reset(); emu_file file(machine().options().art_path(), OPEN_FLAG_READ); - if (file.open(fullname) == osd_file::error::NONE) + if (!file.open(fullname)) { render_load_png(m_screen_overlay_bitmap, file); file.close(); diff --git a/src/emu/softlist_dev.cpp b/src/emu/softlist_dev.cpp index c48f7820c23..7d25dd17013 100644 --- a/src/emu/softlist_dev.cpp +++ b/src/emu/softlist_dev.cpp @@ -288,9 +288,9 @@ void software_list_device::parse() // attempt to open the file emu_file file(mconfig().options().hash_path(), OPEN_FLAG_READ); - const osd_file::error filerr = file.open(m_list_name + ".xml"); + const std::error_condition filerr = file.open(m_list_name + ".xml"); m_filename = file.filename(); - if (filerr == osd_file::error::NONE) + if (!filerr) { // parse if no error std::ostringstream errs; @@ -298,7 +298,7 @@ void software_list_device::parse() file.close(); m_errors = errs.str(); } - else if (filerr == osd_file::error::NOT_FOUND) + else if (std::errc::no_such_file_or_directory == filerr) { osd_printf_verbose("%s: Software list %s not found\n", tag(), m_filename); } diff --git a/src/emu/uiinput.h b/src/emu/uiinput.h index 29b18d06d30..3fc89d7a4ff 100644 --- a/src/emu/uiinput.h +++ b/src/emu/uiinput.h @@ -103,7 +103,7 @@ public: private: // constants - constexpr static unsigned EVENT_QUEUE_SIZE = 128; + static constexpr unsigned EVENT_QUEUE_SIZE = 128; // internal state running_machine & m_machine; // reference to our machine diff --git a/src/emu/video.cpp b/src/emu/video.cpp index b6dada1c0b5..56f877ec8fa 100644 --- a/src/emu/video.cpp +++ b/src/emu/video.cpp @@ -359,8 +359,8 @@ void video_manager::save_active_screen_snapshots() if (machine().render().is_live(screen)) { emu_file file(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - osd_file::error filerr = open_next(file, "png"); - if (filerr == osd_file::error::NONE) + std::error_condition const filerr = open_next(file, "png"); + if (!filerr) save_snapshot(&screen, file); } } @@ -368,8 +368,8 @@ void video_manager::save_active_screen_snapshots() { // otherwise, just write a single snapshot emu_file file(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - osd_file::error filerr = open_next(file, "png"); - if (filerr == osd_file::error::NONE) + std::error_condition const filerr = open_next(file, "png"); + if (!filerr) save_snapshot(nullptr, file); } } @@ -431,12 +431,12 @@ void video_manager::begin_recording_screen(const std::string &filename, uint32_t OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); // and open the actual file - osd_file::error filerr = filename.empty() + std::error_condition filerr = filename.empty() ? open_next(*movie_file, extension) : movie_file->open(filename); - if (filerr != osd_file::error::NONE) + if (filerr) { - osd_printf_error("Error creating movie, osd_file::error=%d\n", int(filerr)); + osd_printf_error("Error creating movie, %s:%d %s\n", filerr.category().name(), filerr.value(), filerr.message()); return; } @@ -1007,8 +1007,8 @@ void video_manager::recompute_speed(const attotime &emutime) { // create a final screenshot emu_file file(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - osd_file::error filerr = file.open(machine().basename() + PATH_SEPARATOR "final.png"); - if (filerr == osd_file::error::NONE) + std::error_condition filerr = file.open(machine().basename() + PATH_SEPARATOR "final.png"); + if (!filerr) save_snapshot(nullptr, file); //printf("Scheduled exit at %f\n", emutime.as_double()); @@ -1096,7 +1096,7 @@ void video_manager::pixels(u32 *buffer) // scheme //------------------------------------------------- -osd_file::error video_manager::open_next(emu_file &file, const char *extension, uint32_t added_index) +std::error_condition video_manager::open_next(emu_file &file, const char *extension, uint32_t added_index) { u32 origflags = file.openflags(); @@ -1205,11 +1205,9 @@ osd_file::error video_manager::open_next(emu_file &file, const char *extension, strreplace(fname, "%i", string_format("%04d", seq)); // try to open the file; stop when we fail - osd_file::error filerr = file.open(fname); - if (filerr == osd_file::error::NOT_FOUND) - { + std::error_condition const filerr = file.open(fname); + if (std::errc::no_such_file_or_directory == filerr) break; - } } } diff --git a/src/emu/video.h b/src/emu/video.h index bd58db9ca1d..3544bf19823 100644 --- a/src/emu/video.h +++ b/src/emu/video.h @@ -19,6 +19,8 @@ #include "recording.h" +#include <system_error> + //************************************************************************** // CONSTANTS @@ -61,7 +63,7 @@ public: // misc void toggle_record_movie(movie_recording::format format); - osd_file::error open_next(emu_file &file, const char *extension, uint32_t index = 0); + std::error_condition open_next(emu_file &file, const char *extension, uint32_t index = 0); void compute_snapshot_size(s32 &width, s32 &height); void pixels(u32 *buffer); diff --git a/src/frontend/mame/audit.cpp b/src/frontend/mame/audit.cpp index 42ddcdad438..0a37c4a3fff 100644 --- a/src/frontend/mame/audit.cpp +++ b/src/frontend/mame/audit.cpp @@ -425,11 +425,11 @@ media_auditor::summary media_auditor::audit_samples() while (path.next(curpath, samplename)) { // attempt to access the file (.flac) or (.wav) - osd_file::error filerr = file.open(curpath + ".flac"); - if (filerr != osd_file::error::NONE) + std::error_condition filerr = file.open(curpath + ".flac"); + if (filerr) filerr = file.open(curpath + ".wav"); - if (filerr == osd_file::error::NONE) + if (!filerr) { record.set_status(audit_status::GOOD, audit_substatus::GOOD); found++; @@ -589,14 +589,14 @@ media_auditor::audit_record &media_auditor::audit_one_rom(const std::vector<std: file.set_restrict_to_mediapath(1); // open the file if we can - osd_file::error filerr; + std::error_condition filerr; if (has_crc) filerr = file.open(record.name(), crc); else filerr = file.open(record.name()); // if it worked, get the actual length and hashes, then stop - if (filerr == osd_file::error::NONE) + if (!filerr) record.set_actual(file.hashes(m_validation), file.size()); // compute the final status @@ -617,10 +617,10 @@ media_auditor::audit_record &media_auditor::audit_one_disk(const rom_entry *rom, // open the disk chd_file source; - const chd_error err = rom_load_manager::open_disk_image(m_enumerator.options(), std::forward<T>(args)..., rom, source); + const std::error_condition err = rom_load_manager::open_disk_image(m_enumerator.options(), std::forward<T>(args)..., rom, source); // if we succeeded, get the hashes - if (err == CHDERR_NONE) + if (!err) { util::hash_collection hashes; @@ -633,7 +633,7 @@ media_auditor::audit_record &media_auditor::audit_one_disk(const rom_entry *rom, } // compute the final status - compute_status(record, rom, err == CHDERR_NONE); + compute_status(record, rom, !err); return record; } diff --git a/src/frontend/mame/cheat.cpp b/src/frontend/mame/cheat.cpp index bc266cc6aae..f4a567db28f 100644 --- a/src/frontend/mame/cheat.cpp +++ b/src/frontend/mame/cheat.cpp @@ -1191,10 +1191,10 @@ bool cheat_manager::save_all(std::string const &filename) { // open the file with the proper name emu_file cheatfile(machine().options().cheat_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - osd_file::error const filerr(cheatfile.open(filename + ".xml")); + std::error_condition const filerr(cheatfile.open(filename + ".xml")); // if that failed, return nothing - if (filerr != osd_file::error::NONE) + if (filerr) return false; // wrap the rest of catch errors @@ -1391,7 +1391,7 @@ void cheat_manager::load_cheats(std::string const &filename) try { // loop over all instrances of the files found in our search paths - for (osd_file::error filerr = cheatfile.open(filename + ".xml"); filerr == osd_file::error::NONE; filerr = cheatfile.open_next()) + for (std::error_condition filerr = cheatfile.open(filename + ".xml"); !filerr; filerr = cheatfile.open_next()) { osd_printf_verbose("Loading cheats file from %s\n", cheatfile.fullpath()); diff --git a/src/frontend/mame/clifront.cpp b/src/frontend/mame/clifront.cpp index 38b61b9755f..eb77ead8e5c 100644 --- a/src/frontend/mame/clifront.cpp +++ b/src/frontend/mame/clifront.cpp @@ -1681,7 +1681,7 @@ void cli_frontend::execute_commands(std::string_view exename) { // attempt to open the output file emu_file file(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - if (file.open(std::string(emulator_info::get_configname()) + ".ini") != osd_file::error::NONE) + if (file.open(std::string(emulator_info::get_configname()) + ".ini")) throw emu_fatalerror("Unable to create file %s.ini\n",emulator_info::get_configname()); // generate the updated INI @@ -1689,7 +1689,7 @@ void cli_frontend::execute_commands(std::string_view exename) ui_options ui_opts; emu_file file_ui(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - if (file_ui.open("ui.ini") != osd_file::error::NONE) + if (file_ui.open("ui.ini")) throw emu_fatalerror("Unable to create file ui.ini\n"); // generate the updated INI @@ -1704,7 +1704,7 @@ void cli_frontend::execute_commands(std::string_view exename) plugin_opts.scan_directory(pluginpath, true); } emu_file file_plugin(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - if (file_plugin.open("plugin.ini") != osd_file::error::NONE) + if (file_plugin.open("plugin.ini")) throw emu_fatalerror("Unable to create file plugin.ini\n"); // generate the updated INI diff --git a/src/frontend/mame/language.cpp b/src/frontend/mame/language.cpp index 1cd0d1be65e..eae75b3fd6f 100644 --- a/src/frontend/mame/language.cpp +++ b/src/frontend/mame/language.cpp @@ -70,7 +70,7 @@ void load_translation(emu_options &m_options) strreplace(name, "(", ""); strreplace(name, ")", ""); emu_file file(m_options.language_path(), OPEN_FLAG_READ); - if (file.open(name + PATH_SEPARATOR "strings.mo") != osd_file::error::NONE) + if (file.open(name + PATH_SEPARATOR "strings.mo")) { osd_printf_error("Error opening translation file %s\n", name); return; diff --git a/src/frontend/mame/luaengine.cpp b/src/frontend/mame/luaengine.cpp index 9dfc9aeee0b..54fdd78b01c 100644 --- a/src/frontend/mame/luaengine.cpp +++ b/src/frontend/mame/luaengine.cpp @@ -322,48 +322,12 @@ public: } // namespace sol -int sol_lua_push(sol::types<osd_file::error>, lua_State *L, osd_file::error &&value) +int sol_lua_push(sol::types<std::error_condition>, lua_State *L, std::error_condition &&value) { - const char *strerror; - switch(value) - { - case osd_file::error::NONE: - return sol::stack::push(L, sol::lua_nil); - case osd_file::error::FAILURE: - strerror = "failure"; - break; - case osd_file::error::OUT_OF_MEMORY: - strerror = "out_of_memory"; - break; - case osd_file::error::NOT_FOUND: - strerror = "not_found"; - break; - case osd_file::error::ACCESS_DENIED: - strerror = "access_denied"; - break; - case osd_file::error::ALREADY_OPEN: - strerror = "already_open"; - break; - case osd_file::error::TOO_MANY_FILES: - strerror = "too_many_files"; - break; - case osd_file::error::INVALID_DATA: - strerror = "invalid_data"; - break; - case osd_file::error::INVALID_ACCESS: - strerror = "invalid_access"; - break; - default: - strerror = "unknown_error"; - break; - } - return sol::stack::push(L, strerror); -} - -template <typename Handler> -bool sol_lua_check(sol::types<osd_file::error>, lua_State *L, int index, Handler &&handler, sol::stack::record &tracking) -{ - return sol::stack::check<int>(L, index, std::forward<Handler>(handler)); + if (!value) + return sol::stack::push(L, sol::lua_nil); + else + return sol::stack::push(L, value.message()); } @@ -884,7 +848,7 @@ void lua_engine::initialize() })); file_type.set("read", [](emu_file &file, sol::buffer *buff) { buff->set_len(file.read(buff->get_ptr(), buff->get_len())); return buff; }); file_type.set("write", [](emu_file &file, const std::string &data) { return file.write(data.data(), data.size()); }); - file_type.set("open", static_cast<osd_file::error (emu_file::*)(std::string_view)>(&emu_file::open)); + file_type.set("open", static_cast<std::error_condition (emu_file::*)(std::string_view)>(&emu_file::open)); file_type.set("open_next", &emu_file::open_next); file_type.set("seek", sol::overload( [](emu_file &file) { return file.tell(); }, @@ -1534,12 +1498,12 @@ void lua_engine::initialize() // open the file emu_file file(is_absolute_path ? "" : machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - osd_file::error filerr; + std::error_condition filerr; if (!snapstr.empty()) filerr = file.open(snapstr); else filerr = machine().video().open_next(file, "png"); - if (filerr != osd_file::error::NONE) + if (filerr) return sol::make_object(sol(), filerr); // and save the snapshot diff --git a/src/frontend/mame/luaengine.ipp b/src/frontend/mame/luaengine.ipp index d532b8be1b4..f995b0a4a7b 100644 --- a/src/frontend/mame/luaengine.ipp +++ b/src/frontend/mame/luaengine.ipp @@ -16,6 +16,8 @@ #include <lua.hpp> +#include <system_error> + template <typename T> @@ -258,10 +260,8 @@ public: } // namespace sol -// osd_file::error customisation -int sol_lua_push(sol::types<osd_file::error>, lua_State *L, osd_file::error &&value); -template <typename Handler> -bool sol_lua_check(sol::types<osd_file::error>, lua_State *L, int index, Handler &&handler, sol::stack::record &tracking); +// automatically convert std::error_condition to string +int sol_lua_push(sol::types<std::error_condition>, lua_State &L, std::error_condition &&value); // enums to automatically convert to strings int sol_lua_push(sol::types<map_handler_type>, lua_State *L, map_handler_type &&value); diff --git a/src/frontend/mame/mame.cpp b/src/frontend/mame/mame.cpp index 1158666ff92..c7bc0879909 100644 --- a/src/frontend/mame/mame.cpp +++ b/src/frontend/mame/mame.cpp @@ -152,7 +152,7 @@ void mame_machine_manager::start_luaengine() // parse the file // attempt to open the output file emu_file file(options().ini_path(), OPEN_FLAG_READ); - if (file.open("plugin.ini") == osd_file::error::NONE) + if (!file.open("plugin.ini")) { try { @@ -198,8 +198,8 @@ void mame_machine_manager::start_luaengine() { emu_file file(options().plugins_path(), OPEN_FLAG_READ); - osd_file::error filerr = file.open("boot.lua"); - if (filerr == osd_file::error::NONE) + std::error_condition const filerr = file.open("boot.lua"); + if (!filerr) { std::string exppath; osd_subst_env(exppath, std::string(file.fullpath())); diff --git a/src/frontend/mame/mameopts.cpp b/src/frontend/mame/mameopts.cpp index 0e6c28da23d..a1d370ddb74 100644 --- a/src/frontend/mame/mameopts.cpp +++ b/src/frontend/mame/mameopts.cpp @@ -130,8 +130,8 @@ void mame_options::parse_one_ini(emu_options &options, const char *basename, int // open the file; if we fail, that's ok emu_file file(options.ini_path(), OPEN_FLAG_READ); osd_printf_verbose("Attempting load of %s.ini\n", basename); - osd_file::error filerr = file.open(std::string(basename) + ".ini"); - if (filerr != osd_file::error::NONE) + std::error_condition const filerr = file.open(std::string(basename) + ".ini"); + if (filerr) return; // parse the file diff --git a/src/frontend/mame/media_ident.cpp b/src/frontend/mame/media_ident.cpp index 690996145b2..08a7381ad3e 100644 --- a/src/frontend/mame/media_ident.cpp +++ b/src/frontend/mame/media_ident.cpp @@ -134,13 +134,13 @@ void media_identifier::collect_files(std::vector<file_info> &info, char const *p { // first attempt to examine it as a valid zip/7z file util::archive_file::ptr archive; - util::archive_file::error err; + std::error_condition err; if (core_filename_ends_with(path, ".7z")) err = util::archive_file::open_7z(path, archive); else err = util::archive_file::open_zip(path, archive); - if ((util::archive_file::error::NONE == err) && archive) + if (!err && archive) { std::vector<std::uint8_t> data; @@ -158,10 +158,10 @@ void media_identifier::collect_files(std::vector<file_info> &info, char const *p { data.resize(std::size_t(length)); err = archive->decompress(&data[0], std::uint32_t(length)); - if (util::archive_file::error::NONE == err) + if (!err) digest_data(info, curfile.c_str(), &data[0], length); else - osd_printf_error("%s: error decompressing file\n", curfile); + osd_printf_error("%s: error decompressing file (%s:%d %s)\n", curfile, err.category().name(), err.value(), err.message()); } catch (...) { @@ -205,9 +205,9 @@ void media_identifier::digest_file(std::vector<file_info> &info, char const *pat { // attempt to open as a CHD; fail if not chd_file chd; - chd_error const err = chd.open(path); + std::error_condition const err = chd.open(path); m_total++; - if (err != CHDERR_NONE) + if (err) { osd_printf_info("%-20s NOT A CHD\n", core_filename_extract_base(path)); m_nonroms++; @@ -233,7 +233,7 @@ void media_identifier::digest_file(std::vector<file_info> &info, char const *pat // load the file and process if it opens and has a valid length uint32_t length; void *data; - if (osd_file::error::NONE == util::core_file::load(path, &data, length)) + if (!util::core_file::load(path, &data, length)) { jed_data jed; if (JEDERR_NONE == jed_parse(data, length, &jed)) @@ -260,7 +260,7 @@ void media_identifier::digest_file(std::vector<file_info> &info, char const *pat // load the file and process if it opens and has a valid length util::core_file::ptr file; - if ((osd_file::error::NONE == util::core_file::open(path, OPEN_FLAG_READ, file)) && file) + if (!util::core_file::open(path, OPEN_FLAG_READ, file) && file) { util::hash_collection hashes; hashes.begin(util::hash_collection::HASH_TYPES_CRC_SHA1); diff --git a/src/frontend/mame/ui/auditmenu.cpp b/src/frontend/mame/ui/auditmenu.cpp index 9cadb5b5d97..66c1aab0597 100644 --- a/src/frontend/mame/ui/auditmenu.cpp +++ b/src/frontend/mame/ui/auditmenu.cpp @@ -229,7 +229,7 @@ void menu_audit::save_available_machines() { // attempt to open the output file emu_file file(ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - if (file.open(std::string(emulator_info::get_configname()) + "_avail.ini") == osd_file::error::NONE) + if (!file.open(std::string(emulator_info::get_configname()) + "_avail.ini")) { // generate header file.printf("#\n%s%s\n#\n\n", UI_VERSION_TAG, emulator_info::get_bare_build_version()); diff --git a/src/frontend/mame/ui/filesel.cpp b/src/frontend/mame/ui/filesel.cpp index b722afab60d..bc5c5abbd12 100644 --- a/src/frontend/mame/ui/filesel.cpp +++ b/src/frontend/mame/ui/filesel.cpp @@ -316,8 +316,8 @@ void menu_file_selector::select_item(const file_selector_entry &entry) { // drive/directory - first check the path util::zippath_directory::ptr dir; - osd_file::error const err = util::zippath_directory::open(entry.fullpath, dir); - if (err != osd_file::error::NONE) + std::error_condition const err = util::zippath_directory::open(entry.fullpath, dir); + if (err) { // this path is problematic; present the user with an error and bail ui().popup_time(1, _("Error accessing %s"), entry.fullpath); @@ -399,7 +399,7 @@ void menu_file_selector::populate(float &customtop, float &custombottom) // open the directory util::zippath_directory::ptr directory; - osd_file::error const err = util::zippath_directory::open(m_current_directory, directory); + std::error_condition const err = util::zippath_directory::open(m_current_directory, directory); // add the "[empty slot]" entry if available if (m_has_empty) @@ -421,9 +421,11 @@ void menu_file_selector::populate(float &customtop, float &custombottom) std::size_t const first = m_entrylist.size() + 1; // build the menu for each item - if (osd_file::error::NONE != err) + if (err) { - osd_printf_verbose("menu_file_selector::populate: error opening directory '%s' (%d)\n", m_current_directory, int(err)); + osd_printf_verbose( + "menu_file_selector::populate: error opening directory '%s' (%s:%d %s)\n", + m_current_directory, err.category().name(), err.value(), err.message()); } else { diff --git a/src/frontend/mame/ui/floppycntrl.cpp b/src/frontend/mame/ui/floppycntrl.cpp index 0cfc8ac2333..2f1cc9e0192 100644 --- a/src/frontend/mame/ui/floppycntrl.cpp +++ b/src/frontend/mame/ui/floppycntrl.cpp @@ -79,12 +79,11 @@ void menu_control_floppy_image::hook_load(const std::string &filename) bool can_in_place = input_format->supports_save(); if(can_in_place) { - osd_file::error filerr; std::string tmp_path; util::core_file::ptr tmp_file; // attempt to open the file for writing but *without* create - filerr = util::zippath_fopen(filename, OPEN_FLAG_READ | OPEN_FLAG_WRITE, tmp_file, tmp_path); - if(filerr == osd_file::error::NONE) + std::error_condition const filerr = util::zippath_fopen(filename, OPEN_FLAG_READ | OPEN_FLAG_WRITE, tmp_file, tmp_path); + if(!filerr) tmp_file.reset(); else can_in_place = false; diff --git a/src/frontend/mame/ui/imgcntrl.cpp b/src/frontend/mame/ui/imgcntrl.cpp index 33a71b7354a..43f40603479 100644 --- a/src/frontend/mame/ui/imgcntrl.cpp +++ b/src/frontend/mame/ui/imgcntrl.cpp @@ -85,7 +85,7 @@ menu_control_device_image::menu_control_device_image(mame_ui_manager &mui, rende // check to see if the path exists; if not then set to current directory util::zippath_directory::ptr dir; - if (util::zippath_directory::open(m_current_directory, dir) != osd_file::error::NONE) + if (util::zippath_directory::open(m_current_directory, dir)) osd_get_full_path(m_current_directory, "."); } } diff --git a/src/frontend/mame/ui/inifile.cpp b/src/frontend/mame/ui/inifile.cpp index f1e0346769a..000ea922a4a 100644 --- a/src/frontend/mame/ui/inifile.cpp +++ b/src/frontend/mame/ui/inifile.cpp @@ -45,7 +45,7 @@ inifile_manager::inifile_manager(ui_options &options) if (core_filename_ends_with(name, ".ini")) { emu_file file(m_options.categoryini_path(), OPEN_FLAG_READ); - if (file.open(name) == osd_file::error::NONE) + if (!file.open(name)) { init_category(std::move(name), file); file.close(); @@ -63,7 +63,7 @@ void inifile_manager::load_ini_category(size_t file, size_t category, std::unord { std::string const &filename(m_ini_index[file].first); emu_file fp(m_options.categoryini_path(), OPEN_FLAG_READ); - if (fp.open(filename) != osd_file::error::NONE) + if (fp.open(filename)) { osd_printf_error("Failed to open category file %s for reading\n", filename); return; @@ -216,7 +216,7 @@ favorite_manager::favorite_manager(ui_options &options) , m_need_sort(true) { emu_file file(m_options.ui_path(), OPEN_FLAG_READ); - if (file.open(FAVORITE_FILENAME) == osd_file::error::NONE) + if (!file.open(FAVORITE_FILENAME)) { char readbuf[1024]; file.gets(readbuf, 1024); @@ -537,7 +537,7 @@ void favorite_manager::save_favorites() { // attempt to open the output file emu_file file(m_options.ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - if (file.open(FAVORITE_FILENAME) == osd_file::error::NONE) + if (!file.open(FAVORITE_FILENAME)) { if (m_favorites.empty()) { diff --git a/src/frontend/mame/ui/menu.cpp b/src/frontend/mame/ui/menu.cpp index 8eb1eab47c9..923a0fae6df 100644 --- a/src/frontend/mame/ui/menu.cpp +++ b/src/frontend/mame/ui/menu.cpp @@ -92,13 +92,13 @@ menu::global_state::global_state(running_machine &machine, ui_options const &opt { m_bgrnd_bitmap = std::make_unique<bitmap_argb32>(0, 0); emu_file backgroundfile(".", OPEN_FLAG_READ); - if (backgroundfile.open("background.jpg") == osd_file::error::NONE) + if (!backgroundfile.open("background.jpg")) { render_load_jpeg(*m_bgrnd_bitmap, backgroundfile); backgroundfile.close(); } - if (!m_bgrnd_bitmap->valid() && (backgroundfile.open("background.png") == osd_file::error::NONE)) + if (!m_bgrnd_bitmap->valid() && !backgroundfile.open("background.png")) { render_load_png(*m_bgrnd_bitmap, backgroundfile); backgroundfile.close(); diff --git a/src/frontend/mame/ui/miscmenu.cpp b/src/frontend/mame/ui/miscmenu.cpp index bf1754481dc..da7989e6e3b 100644 --- a/src/frontend/mame/ui/miscmenu.cpp +++ b/src/frontend/mame/ui/miscmenu.cpp @@ -599,11 +599,11 @@ void menu_export::handle() { std::string filename("exported"); emu_file infile(ui().options().ui_path(), OPEN_FLAG_READ); - if (infile.open(filename + ".xml") == osd_file::error::NONE) + if (!infile.open(filename + ".xml")) for (int seq = 0; ; ++seq) { const std::string seqtext = string_format("%s_%04d", filename, seq); - if (infile.open(seqtext + ".xml") != osd_file::error::NONE) + if (infile.open(seqtext + ".xml")) { filename = seqtext; break; @@ -612,7 +612,7 @@ void menu_export::handle() // attempt to open the output file emu_file file(ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - if (file.open(filename + ".xml") == osd_file::error::NONE) + if (!file.open(filename + ".xml")) { const std::string fullpath(file.fullpath()); file.close(); @@ -644,11 +644,11 @@ void menu_export::handle() { std::string filename("exported"); emu_file infile(ui().options().ui_path(), OPEN_FLAG_READ); - if (infile.open(filename + ".txt") == osd_file::error::NONE) + if (!infile.open(filename + ".txt")) for (int seq = 0; ; ++seq) { const std::string seqtext = string_format("%s_%04d", filename, seq); - if (infile.open(seqtext + ".txt") != osd_file::error::NONE) + if (infile.open(seqtext + ".txt")) { filename = seqtext; break; @@ -657,7 +657,7 @@ void menu_export::handle() // attempt to open the output file emu_file file(ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - if (file.open(filename + ".txt") == osd_file::error::NONE) + if (!file.open(filename + ".txt")) { // print the header std::ostringstream buffer; @@ -754,8 +754,8 @@ void menu_machine_configure::handle() { const std::string filename(m_drv.name); emu_file file(machine().options().ini_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE); - osd_file::error filerr = file.open(filename + ".ini"); - if (filerr == osd_file::error::NONE) + std::error_condition const filerr = file.open(filename + ".ini"); + if (!filerr) { std::string inistring = m_opts.output_ini(); file.puts(inistring); @@ -891,7 +891,7 @@ menu_plugins_configure::menu_plugins_configure(mame_ui_manager &mui, render_cont menu_plugins_configure::~menu_plugins_configure() { emu_file file_plugin(machine().options().ini_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - if (file_plugin.open("plugin.ini") != osd_file::error::NONE) + if (file_plugin.open("plugin.ini")) // Can't throw in a destructor, so let's ignore silently for // now. We shouldn't write files in a destructor in any case. // diff --git a/src/frontend/mame/ui/optsmenu.cpp b/src/frontend/mame/ui/optsmenu.cpp index 0ceeca25ce2..922bbb5b6fa 100644 --- a/src/frontend/mame/ui/optsmenu.cpp +++ b/src/frontend/mame/ui/optsmenu.cpp @@ -265,7 +265,7 @@ void menu_game_options::handle_item_event(event const &menu_event) if (machine_filter::CUSTOM == filter.get_type()) { emu_file file(ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - if (file.open(util::string_format("custom_%s_filter.ini", emulator_info::get_configname())) == osd_file::error::NONE) + if (!file.open(util::string_format("custom_%s_filter.ini", emulator_info::get_configname()))) { filter.save_ini(file, 0); file.close(); diff --git a/src/frontend/mame/ui/selgame.cpp b/src/frontend/mame/ui/selgame.cpp index 338f98c42d0..ece205a8ef4 100644 --- a/src/frontend/mame/ui/selgame.cpp +++ b/src/frontend/mame/ui/selgame.cpp @@ -266,7 +266,7 @@ menu_select_game::menu_select_game(mame_ui_manager &mui, render_container &conta } emu_file file(ui().options().ui_path(), OPEN_FLAG_READ); - if (file.open_ram(fake_ini.c_str(), fake_ini.size()) == osd_file::error::NONE) + if (!file.open_ram(fake_ini.c_str(), fake_ini.size())) { m_persistent_data.filter_data().load_ini(file); file.close(); @@ -1259,12 +1259,12 @@ render_texture *menu_select_game::get_icon_texture(int linenum, void *selectedre bitmap_argb32 tmp; emu_file snapfile(std::string(m_icon_paths), OPEN_FLAG_READ); - if (snapfile.open(std::string(driver->name) + ".ico") == osd_file::error::NONE) + if (!snapfile.open(std::string(driver->name) + ".ico")) { render_load_ico_highest_detail(snapfile, tmp); snapfile.close(); } - if (!tmp.valid() && cloneof && (snapfile.open(std::string(driver->parent) + ".ico") == osd_file::error::NONE)) + if (!tmp.valid() && cloneof && !snapfile.open(std::string(driver->parent) + ".ico")) { render_load_ico_highest_detail(snapfile, tmp); snapfile.close(); @@ -1309,7 +1309,7 @@ bool menu_select_game::load_available_machines() { // try to load available drivers from file emu_file file(ui().options().ui_path(), OPEN_FLAG_READ); - if (file.open(std::string(emulator_info::get_configname()) + "_avail.ini") != osd_file::error::NONE) + if (file.open(std::string(emulator_info::get_configname()) + "_avail.ini")) return false; char rbuf[MAX_CHAR_INFO]; @@ -1361,7 +1361,7 @@ bool menu_select_game::load_available_machines() void menu_select_game::load_custom_filters() { emu_file file(ui().options().ui_path(), OPEN_FLAG_READ); - if (file.open(util::string_format("custom_%s_filter.ini", emulator_info::get_configname())) == osd_file::error::NONE) + if (!file.open(util::string_format("custom_%s_filter.ini", emulator_info::get_configname()))) { machine_filter::ptr flt(machine_filter::create(file, m_persistent_data.filter_data())); if (flt) @@ -1456,7 +1456,7 @@ void menu_select_game::filter_selected() if (machine_filter::CUSTOM == new_type) { emu_file file(ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - if (file.open(util::string_format("custom_%s_filter.ini", emulator_info::get_configname())) == osd_file::error::NONE) + if (!file.open(util::string_format("custom_%s_filter.ini", emulator_info::get_configname()))) { filter.save_ini(file, 0); file.close(); diff --git a/src/frontend/mame/ui/selmenu.cpp b/src/frontend/mame/ui/selmenu.cpp index fb3f7087e27..15c7e1c3364 100644 --- a/src/frontend/mame/ui/selmenu.cpp +++ b/src/frontend/mame/ui/selmenu.cpp @@ -36,6 +36,8 @@ #include "uiinput.h" #include "luaengine.h" +#include "util/path.h" + #include <algorithm> #include <cmath> #include <cstring> @@ -99,19 +101,19 @@ char const *const hover_msg[] = { void load_image(bitmap_argb32 &bitmap, emu_file &file, std::string const &base) { - if (file.open(base + ".png") == osd_file::error::NONE) + if (!file.open(base + ".png")) { render_load_png(bitmap, file); file.close(); } - if (!bitmap.valid() && (file.open(base + ".jpg") == osd_file::error::NONE)) + if (!bitmap.valid() && !file.open(base + ".jpg")) { render_load_jpeg(bitmap, file); file.close(); } - if (!bitmap.valid() && (file.open(base + ".bmp") == osd_file::error::NONE)) + if (!bitmap.valid() && !file.open(base + ".bmp")) { render_load_msdib(bitmap, file); file.close(); @@ -123,7 +125,7 @@ void load_driver_image(bitmap_argb32 &bitmap, emu_file &file, game_driver const { // try to load snapshot first from saved "0000.png" file std::string fullname = driver.name; - load_image(bitmap, file, fullname + PATH_SEPARATOR + "0000"); + load_image(bitmap, file, util::path_concat(fullname, "0000")); // if fail, attempt to load from standard file if (!bitmap.valid()) @@ -144,7 +146,7 @@ void load_driver_image(bitmap_argb32 &bitmap, emu_file &file, game_driver const if (isclone) { fullname = driver.parent; - load_image(bitmap, file, fullname + PATH_SEPARATOR + "0000"); + load_image(bitmap, file, util::path_concat(fullname, "0000")); if (!bitmap.valid()) load_image(bitmap, file, fullname); @@ -621,7 +623,7 @@ void menu_select_launch::launch_system(mame_ui_manager &mui, game_driver const & else moptions.set_value(OPTION_SOFTWARENAME, util::string_format("%s:%s", swinfo->listname, swinfo->shortname), OPTION_PRIORITY_CMDLINE); - moptions.set_value(OPTION_SNAPNAME, util::string_format("%s%s%s", swinfo->listname, PATH_SEPARATOR, swinfo->shortname), OPTION_PRIORITY_CMDLINE); + moptions.set_value(OPTION_SNAPNAME, util::path_concat(swinfo->listname, swinfo->shortname), OPTION_PRIORITY_CMDLINE); } reselect_last::set_software(driver, *swinfo); } @@ -1087,11 +1089,7 @@ void menu_select_launch::check_for_icons(char const *listname) { // if we're doing a software list, append it to the configured path if (listname) - { - if (!current.empty() && !util::is_directory_separator(current.back())) - current.append(PATH_SEPARATOR); - current.append(listname); - } + util::path_append(current, listname); osd_printf_verbose("Checking for icons in directory %s\n", current); // open and walk the directory @@ -1136,11 +1134,7 @@ std::string menu_select_launch::make_icon_paths(char const *listname) const { // if we're doing a software list, append it to the configured path if (listname) - { - if (!current.empty() && !util::is_directory_separator(current.back())) - current.append(PATH_SEPARATOR); - current.append(listname); - } + util::path_append(current, listname); // append the configured path if (!result.empty()) @@ -2286,11 +2280,11 @@ void menu_select_launch::arts_render(float origx1, float origy1, float origx2, f else { // First attempt from name list - load_image(tmp_bitmap, snapfile, software->listname + PATH_SEPARATOR + software->shortname); + load_image(tmp_bitmap, snapfile, util::path_concat(software->listname, software->shortname)); // Second attempt from driver name + part name if (!tmp_bitmap.valid()) - load_image(tmp_bitmap, snapfile, software->driver->name + software->part + PATH_SEPARATOR + software->shortname); + load_image(tmp_bitmap, snapfile, util::path_concat(software->driver->name + software->part, software->shortname)); } m_cache->set_snapx_software(software); diff --git a/src/frontend/mame/ui/selsoft.cpp b/src/frontend/mame/ui/selsoft.cpp index 2ac32cce987..95c02a9d853 100644 --- a/src/frontend/mame/ui/selsoft.cpp +++ b/src/frontend/mame/ui/selsoft.cpp @@ -517,7 +517,7 @@ void menu_select_software::load_sw_custom_filters() { // attempt to open the output file emu_file file(ui().options().ui_path(), OPEN_FLAG_READ); - if (file.open(util::string_format("custom_%s_filter.ini", m_driver.name)) == osd_file::error::NONE) + if (!file.open(util::string_format("custom_%s_filter.ini", m_driver.name))) { software_filter::ptr flt(software_filter::create(file, m_filter_data)); if (flt) @@ -593,12 +593,12 @@ render_texture *menu_select_software::get_icon_texture(int linenum, void *select bitmap_argb32 tmp; emu_file snapfile(std::string(paths->second), OPEN_FLAG_READ); - if (snapfile.open(std::string(swinfo->shortname) + ".ico") == osd_file::error::NONE) + if (!snapfile.open(std::string(swinfo->shortname) + ".ico")) { render_load_ico_highest_detail(snapfile, tmp); snapfile.close(); } - if (!tmp.valid() && !swinfo->parentname.empty() && (snapfile.open(std::string(swinfo->parentname) + ".ico") == osd_file::error::NONE)) + if (!tmp.valid() && !swinfo->parentname.empty() && !snapfile.open(std::string(swinfo->parentname) + ".ico")) { render_load_ico_highest_detail(snapfile, tmp); snapfile.close(); @@ -668,7 +668,7 @@ void menu_select_software::filter_selected() if (software_filter::CUSTOM == new_type) { emu_file file(ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - if (file.open(util::string_format("custom_%s_filter.ini", m_driver.name)) == osd_file::error::NONE) + if (!file.open(util::string_format("custom_%s_filter.ini", m_driver.name))) { filter.save_ini(file, 0); file.close(); diff --git a/src/frontend/mame/ui/state.cpp b/src/frontend/mame/ui/state.cpp index 8f911b8f15b..6bb0b9ccdc5 100644 --- a/src/frontend/mame/ui/state.cpp +++ b/src/frontend/mame/ui/state.cpp @@ -365,14 +365,16 @@ void menu_load_save_state_base::handle_keys(uint32_t flags, int &iptkey) machine().options().state_directory(), machine().get_statename(machine().options().state_name()), m_confirm_delete->file_name())); - osd_file::error const err(osd_file::remove(filename)); - if (osd_file::error::NONE != err) + std::error_condition const err(osd_file::remove(filename)); + if (err) { osd_printf_error( - "Error removing file %s for state %s (%d)\n", + "Error removing file %s for state %s (%s:%d %s)\n", filename, m_confirm_delete->visible_name(), - std::underlying_type_t<osd_file::error>(err)); + err.category().name(), + err.value(), + err.message()); machine().popmessage(_("Error removing saved state file %1$s"), filename); } diff --git a/src/frontend/mame/ui/ui.cpp b/src/frontend/mame/ui/ui.cpp index 9f176cca141..22404f32364 100644 --- a/src/frontend/mame/ui/ui.cpp +++ b/src/frontend/mame/ui/ui.cpp @@ -2136,7 +2136,7 @@ void mame_ui_manager::load_ui_options() // parse the file // attempt to open the output file emu_file file(machine().options().ini_path(), OPEN_FLAG_READ); - if (file.open("ui.ini") == osd_file::error::NONE) + if (!file.open("ui.ini")) { try { @@ -2157,7 +2157,7 @@ void mame_ui_manager::save_ui_options() { // attempt to open the output file emu_file file(machine().options().ini_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - if (file.open("ui.ini") == osd_file::error::NONE) + if (!file.open("ui.ini")) { // generate the updated INI file.puts(options().output_ini()); @@ -2185,13 +2185,13 @@ void mame_ui_manager::save_main_option() // attempt to open the main ini file { emu_file file(machine().options().ini_path(), OPEN_FLAG_READ); - if (file.open(std::string(emulator_info::get_configname()) + ".ini") == osd_file::error::NONE) + if (!file.open(std::string(emulator_info::get_configname()) + ".ini")) { try { options.parse_ini_file((util::core_file&)file, OPTION_PRIORITY_MAME_INI, OPTION_PRIORITY_MAME_INI < OPTION_PRIORITY_DRIVER_INI, true); } - catch(options_error_exception &) + catch (options_error_exception &) { osd_printf_error("**Error loading %s.ini**\n", emulator_info::get_configname()); return; @@ -2215,13 +2215,14 @@ void mame_ui_manager::save_main_option() // attempt to open the output file { emu_file file(machine().options().ini_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - if (file.open(std::string(emulator_info::get_configname()) + ".ini") == osd_file::error::NONE) + if (!file.open(std::string(emulator_info::get_configname()) + ".ini")) { // generate the updated INI file.puts(options.output_ini()); file.close(); } - else { + else + { machine().popmessage(_("**Error saving %s.ini**"), emulator_info::get_configname()); return; } diff --git a/src/lib/formats/acorn_dsk.cpp b/src/lib/formats/acorn_dsk.cpp index c4668478b05..40ab6eb1029 100644 --- a/src/lib/formats/acorn_dsk.cpp +++ b/src/lib/formats/acorn_dsk.cpp @@ -10,6 +10,9 @@ #include "acorn_dsk.h" +#include "ioprocs.h" + + acorn_ssd_format::acorn_ssd_format() : wd177x_format(formats) { } @@ -29,29 +32,36 @@ const char *acorn_ssd_format::extensions() const return "ssd,bbc,img"; } -int acorn_ssd_format::find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int acorn_ssd_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { uint8_t cat[8]; uint32_t sectors0, sectors2; - uint64_t size = io_generic_size(io); + uint64_t size; + if (io.length(size)) + { + LOG_FORMATS("ssd: error getting image size\n"); + return -1; + } - for(int i=0; formats[i].form_factor; i++) { + for (int i=0; formats[i].form_factor; i++) + { + size_t actual; const format &f = formats[i]; - if(form_factor != floppy_image::FF_UNKNOWN && form_factor != f.form_factor) + if (form_factor != floppy_image::FF_UNKNOWN && form_factor != f.form_factor) continue; // test for Torch CPN - test pattern at sector &0018 - io_generic_read(io, cat, 0x32800, 8); + io.read_at(0x32800, cat, 8, actual); if (memcmp(cat, "\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd", 4) == 0 && size == (uint64_t)compute_track_size(f) * f.track_count * f.head_count) return i; // test for HADFS - test pattern at sector 70 - io_generic_read(io, cat, 0x04610, 8); + io.read_at(0x04610, cat, 8, actual); if (memcmp(cat, "\x00\x28\x43\x29\x4a\x47\x48\x00", 4) == 0 && size == (uint64_t)compute_track_size(f) * f.track_count * f.head_count) return i; // test for Kenda SD - offset &0962 = 0 SD/1 DD, offset &0963 = disk size blocks / 4 (block size = 1K, ie. 0x400 bytes), reserved tracks = 3, ie. 0x1e00 bytes, soft stagger = 2 sectors, ie. 0x200 bytes - io_generic_read(io, cat, 0x0960, 8); + io.read_at(0x0960, cat, 8, actual); if (cat[2] == 0 && ((uint64_t)cat[3] * 4 * 0x400 + 0x2000) == size && size == (uint64_t)compute_track_size(f) * f.track_count * f.head_count) { // valid blocks for single sided @@ -63,20 +73,22 @@ int acorn_ssd_format::find_size(io_generic *io, uint32_t form_factor, const std: } // read sector count from side 0 catalogue - io_generic_read(io, cat, 0x100, 8); + io.read_at(0x100, cat, 8, actual); sectors0 = ((cat[6] & 3) << 8) + cat[7]; LOG_FORMATS("ssd: sector count 0: %d %s\n", sectors0, sectors0 % 10 != 0 ? "invalid" : ""); - if ((size <= (uint64_t)compute_track_size(f) * f.track_count * f.head_count) && (sectors0 <= f.track_count * f.sector_count)) { + if ((size <= (uint64_t)compute_track_size(f) * f.track_count * f.head_count) && (sectors0 <= f.track_count * f.sector_count)) + { if (f.head_count == 2) { // read sector count from side 2 catalogue - io_generic_read(io, cat, (uint64_t)compute_track_size(f) * f.track_count + 0x100, 8); // sequential + io.read_at((uint64_t)compute_track_size(f) * f.track_count + 0x100, cat, 8, actual); // sequential sectors2 = ((cat[6] & 3) << 8) + cat[7]; // exception case for Acorn CP/M System Disc 1 - io_generic_read(io, cat, 0x367ec, 8); - if (memcmp(cat, "/M ", 4) == 0) sectors2 = ((cat[6] & 3) << 8) + cat[7]; + io.read_at(0x367ec, cat, 8, actual); + if (memcmp(cat, "/M ", 4) == 0) + sectors2 = ((cat[6] & 3) << 8) + cat[7]; LOG_FORMATS("ssd: sector count 2: %d %s\n", sectors2, sectors2 % 10 != 0 ? "invalid" : ""); } @@ -93,12 +105,13 @@ int acorn_ssd_format::find_size(io_generic *io, uint32_t form_factor, const std: return -1; } -int acorn_ssd_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int acorn_ssd_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { int type = find_size(io, form_factor, variants); - if(type != -1) + if (type != -1) return 90; + return 0; } @@ -171,40 +184,49 @@ const char *acorn_dsd_format::extensions() const return "dsd"; } -int acorn_dsd_format::find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int acorn_dsd_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { uint8_t cat[8]; uint32_t sectors0, sectors2; - uint64_t size = io_generic_size(io); + uint64_t size; + if (io.length(size)) + { + LOG_FORMATS("dsd: error getting image size\n"); + return -1; + } - for (int i = 0; formats[i].form_factor; i++) { + for (int i = 0; formats[i].form_factor; i++) + { + size_t actual; const format &f = formats[i]; if (form_factor != floppy_image::FF_UNKNOWN && form_factor != f.form_factor) continue; // test for Torch CPN - test pattern at sector &0018 - io_generic_read(io, cat, 0x1200, 8); + io.read_at(0x1200, cat, 8, actual); if (memcmp(cat, "\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd", 4) == 0 && size == (uint64_t)compute_track_size(f) * f.track_count * f.head_count) return i; // test for HADFS - test pattern at sector 70 - io_generic_read(io, cat, 0x08c10, 8); + io.read_at(0x08c10, cat, 8, actual); if (memcmp(cat, "\x00\x28\x43\x29\x4a\x47\x48\x00", 4) == 0 && size == (uint64_t)compute_track_size(f) * f.track_count * f.head_count) return i; // read sector count from side 0 catalogue - io_generic_read(io, cat, 0x100, 8); + io.read_at(0x100, cat, 8, actual); sectors0 = ((cat[6] & 3) << 8) + cat[7]; LOG_FORMATS("dsd: sector count 0: %d %s\n", sectors0, sectors0 % 10 != 0 ? "invalid" : ""); - if ((size <= (uint64_t)compute_track_size(f) * f.track_count * f.head_count) && (sectors0 <= f.track_count * f.sector_count)) { + if ((size <= (uint64_t)compute_track_size(f) * f.track_count * f.head_count) && (sectors0 <= f.track_count * f.sector_count)) + { // read sector count from side 2 catalogue - io_generic_read(io, cat, 0xb00, 8); // interleaved + io.read_at(0xb00, cat, 8, actual); // interleaved sectors2 = ((cat[6] & 3) << 8) + cat[7]; // exception case for Acorn CP/M System Disc 1 - io_generic_read(io, cat, 0x97ec, 8); - if (memcmp(cat, "/M ", 4) == 0) sectors2 = ((cat[6] & 3) << 8) + cat[7]; + io.read_at(0x97ec, cat, 8, actual); + if (memcmp(cat, "/M ", 4) == 0) + sectors2 = ((cat[6] & 3) << 8) + cat[7]; LOG_FORMATS("dsd: sector count 2: %d %s\n", sectors2, sectors2 % 10 != 0 ? "invalid" : ""); @@ -216,12 +238,13 @@ int acorn_dsd_format::find_size(io_generic *io, uint32_t form_factor, const std: return -1; } -int acorn_dsd_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int acorn_dsd_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { int type = find_size(io, form_factor, variants); if (type != -1) return 90; + return 0; } @@ -274,27 +297,36 @@ const char *opus_ddos_format::extensions() const return "dds"; } -int opus_ddos_format::find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int opus_ddos_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { + size_t actual; uint8_t cat[8]; uint32_t sectors0, sectors2; // read sector count from side 0 catalogue - io_generic_read(io, cat, 0x1000, 8); + io.read_at(0x1000, cat, 8, actual); sectors0 = (cat[1] << 8) + cat[2]; LOG_FORMATS("ddos: sector count 0: %d %s\n", sectors0, sectors0 % 18 != 0 ? "invalid" : ""); - uint64_t size = io_generic_size(io); - for (int i = 0; formats[i].form_factor; i++) { + uint64_t size; + if (io.length(size)) + { + LOG_FORMATS("ddos: error getting image size\n"); + return -1; + } + + for (int i = 0; formats[i].form_factor; i++) + { const format &f = formats[i]; if (form_factor != floppy_image::FF_UNKNOWN && form_factor != f.form_factor) continue; - if ((size <= (uint64_t)compute_track_size(f) * f.track_count * f.head_count) && (sectors0 <= f.track_count * f.sector_count)) { + if ((size <= (uint64_t)compute_track_size(f) * f.track_count * f.head_count) && (sectors0 <= f.track_count * f.sector_count)) + { if (f.head_count == 2) { // read sector count from side 2 catalogue - io_generic_read(io, cat, (uint64_t)compute_track_size(f) * f.track_count + 0x1000, 8); // sequential + io.read_at((uint64_t)compute_track_size(f) * f.track_count + 0x1000, cat, 8, actual); // sequential sectors2 = (cat[1] << 8) + cat[2]; LOG_FORMATS("ddos: sector count 2: %d %s\n", sectors2, sectors2 % 18 != 0 ? "invalid" : ""); } @@ -311,12 +343,13 @@ int opus_ddos_format::find_size(io_generic *io, uint32_t form_factor, const std: return -1; } -int opus_ddos_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int opus_ddos_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { int type = find_size(io, form_factor, variants); if (type != -1) return 90; + return 0; } @@ -369,25 +402,33 @@ const char *acorn_adfs_old_format::extensions() const return "adf,ads,adm,adl"; } -int acorn_adfs_old_format::find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int acorn_adfs_old_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { + size_t actual; uint8_t map[3]; uint32_t sectors; uint8_t oldmap[4]; // read sector count from free space map - io_generic_read(io, map, 0xfc, 3); + io.read_at(0xfc, map, 3, actual); sectors = map[0] + (map[1] << 8) + (map[2] << 16); LOG_FORMATS("adfs_o: sector count %d %s\n", sectors, sectors % 16 != 0 ? "invalid" : ""); // read map identifier - io_generic_read(io, oldmap, 0x201, 4); + io.read_at(0x201, oldmap, 4, actual); LOG_FORMATS("adfs_o: map identifier %s %s\n", oldmap, memcmp(oldmap, "Hugo", 4) != 0 ? "invalid" : ""); - uint64_t size = io_generic_size(io); - for(int i=0; formats[i].form_factor; i++) { + uint64_t size; + if (io.length(size)) + { + LOG_FORMATS("adfs_o: error getting image size\n"); + return -1; + } + + for (int i=0; formats[i].form_factor; i++) + { const format &f = formats[i]; - if(form_factor != floppy_image::FF_UNKNOWN && form_factor != f.form_factor) + if (form_factor != floppy_image::FF_UNKNOWN && form_factor != f.form_factor) continue; // valid images will have map identifier 'Hugo' and sector counts adfs-s = 0x280; adfs-m = 0x500; adfs-l = 0xa00; adfs-dos = 0xaa0; though many adfs-s images are incorrect @@ -399,12 +440,13 @@ int acorn_adfs_old_format::find_size(io_generic *io, uint32_t form_factor, const return -1; } -int acorn_adfs_old_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int acorn_adfs_old_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { int type = find_size(io, form_factor, variants); if(type != -1) return 100; + return 0; } @@ -465,43 +507,50 @@ const char *acorn_adfs_new_format::extensions() const return "adf"; } -int acorn_adfs_new_format::find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int acorn_adfs_new_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { + size_t actual; uint8_t dform[4]; uint8_t eform[4]; // read map identifiers for D and E formats - io_generic_read(io, dform, 0x401, 4); + io.read_at(0x401, dform, 4, actual); LOG_FORMATS("adfs_n: map identifier (D format) %s %s\n", dform, (memcmp(dform, "Hugo", 4) != 0 && memcmp(dform, "Nick", 4) != 0) ? "invalid" : ""); - io_generic_read(io, eform, 0x801, 4); + io.read_at(0x801, eform, 4, actual); LOG_FORMATS("adfs_n: map identifier (E format) %s %s\n", eform, memcmp(eform, "Nick", 4) != 0 ? "invalid" : ""); - uint64_t size = io_generic_size(io); - for (int i = 0; formats[i].form_factor; i++) { + uint64_t size; + if (io.length(size)) + { + LOG_FORMATS("adfs_n: error getting image size\n"); + return -1; + } + + for (int i = 0; formats[i].form_factor; i++) + { const format &f = formats[i]; if (form_factor != floppy_image::FF_UNKNOWN && form_factor != f.form_factor) continue; // no further checks for 1600K images - if ((size == (uint64_t)compute_track_size(f) * f.track_count * f.head_count) && size == 0x190000) { + if ((size == (uint64_t)compute_track_size(f) * f.track_count * f.head_count) && size == 0x190000) return i; - } // valid 800K images will have map identifier Nick, Arthur D format still use Hugo - if ((size <= (uint64_t)compute_track_size(f) * f.track_count * f.head_count) && (memcmp(dform, "Hugo", 4) == 0 || memcmp(dform, "Nick", 4) == 0 || memcmp(eform, "Nick", 4) == 0)) { + if ((size <= (uint64_t)compute_track_size(f) * f.track_count * f.head_count) && (memcmp(dform, "Hugo", 4) == 0 || memcmp(dform, "Nick", 4) == 0 || memcmp(eform, "Nick", 4) == 0)) return i; - } } LOG_FORMATS("adfs_n: no match\n"); return -1; } -int acorn_adfs_new_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int acorn_adfs_new_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { int type = find_size(io, form_factor, variants); if (type != -1) return 100; + return 0; } @@ -546,33 +595,43 @@ const char *acorn_dos_format::extensions() const return "img"; } -int acorn_dos_format::find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int acorn_dos_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - uint8_t type; + uint64_t size; + if (io.length(size)) + { + LOG_FORMATS("dos: error getting image size\n"); + return -1; + } - uint64_t size = io_generic_size(io); - for(int i=0; formats[i].form_factor; i++) { + for (int i=0; formats[i].form_factor; i++) + { const format &f = formats[i]; - if(form_factor != floppy_image::FF_UNKNOWN && form_factor != f.form_factor) + if (form_factor != floppy_image::FF_UNKNOWN && form_factor != f.form_factor) continue; - if (size == (uint64_t)compute_track_size(f) * f.track_count * f.head_count) { + if (size == (uint64_t)compute_track_size(f) * f.track_count * f.head_count) + { // read media type ID from FAT - Acorn DOS = 0xfd - io_generic_read(io, &type, 0, 1); + size_t actual; + uint8_t type; + io.read_at(0, &type, 1, actual); LOG_FORMATS("dos: 800k media type id %02X %s\n", type, type != 0xfd ? "invalid" : ""); - if (type == 0xfd) return i; + if (type == 0xfd) + return i; } } LOG_FORMATS("dos: no match\n"); return -1; } -int acorn_dos_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int acorn_dos_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { int type = find_size(io, form_factor, variants); - if(type != -1) + if (type != -1) return 90; + return 0; } @@ -618,19 +677,28 @@ bool opus_ddcpm_format::supports_save() const return false; } -int opus_ddcpm_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int opus_ddcpm_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { + size_t actual; uint8_t h[8]; - io_generic_read(io, h, 0, 8); + io.read_at(0, h, 8, actual); + + uint64_t size; + if (io.length(size)) + { + LOG_FORMATS("ddcpm: error getting image size\n"); + return -1; + } - if (io_generic_size(io) == 819200 && memcmp(h, "Slogger ", 8) == 0) + if (size == 819200 && memcmp(h, "Slogger ", 8) == 0) return 100; + LOG_FORMATS("ddcpm: no match\n"); return 0; } -bool opus_ddcpm_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool opus_ddcpm_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { // Double density discs formatted with DDCPM : // @@ -644,19 +712,21 @@ bool opus_ddcpm_format::load(io_generic *io, uint32_t form_factor, const std::ve // Sector skew of 1 // Sector interleave of 2 // - int spt, bps; - - for (int head = 0; head < 2; head++) { - for (int track = 0; track < 80; track++) { - bool mfm = track > 2 || head; - bps = mfm ? 512 : 256; - spt = 10; + for (int head = 0; head < 2; head++) + { + for (int track = 0; track < 80; track++) + { + bool const mfm = track > 2 || head; + int const bps = mfm ? 512 : 256; + int const spt = 10; desc_pc_sector sects[10]; uint8_t sectdata[10*512]; - io_generic_read(io, sectdata, head * 80 * spt * 512 + track * spt * 512, spt * 512); + size_t actual; + io.read_at(head * 80 * spt * 512 + track * spt * 512, sectdata, spt * 512, actual); - for (int i = 0; i < spt; i++) { + for (int i = 0; i < spt; i++) + { sects[i].track = track; sects[i].head = head; sects[i].sector = i; @@ -677,7 +747,7 @@ bool opus_ddcpm_format::load(io_generic *io, uint32_t form_factor, const std::ve return true; } -bool opus_ddcpm_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool opus_ddcpm_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { return false; } diff --git a/src/lib/formats/acorn_dsk.h b/src/lib/formats/acorn_dsk.h index 1428212cfaa..de07e8b9fed 100644 --- a/src/lib/formats/acorn_dsk.h +++ b/src/lib/formats/acorn_dsk.h @@ -20,8 +20,8 @@ class acorn_ssd_format : public wd177x_format public: acorn_ssd_format(); - virtual int find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual int find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; virtual int get_image_offset(const format &f, int head, int track) override; virtual const char *name() const override; virtual const char *description() const override; @@ -36,8 +36,8 @@ class acorn_dsd_format : public wd177x_format public: acorn_dsd_format(); - virtual int find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual int find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; virtual int get_image_offset(const format &f, int head, int track) override; virtual const char *name() const override; virtual const char *description() const override; @@ -52,8 +52,8 @@ class opus_ddos_format : public wd177x_format public: opus_ddos_format(); - virtual int find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual int find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; virtual int get_image_offset(const format &f, int head, int track) override; virtual const char *name() const override; virtual const char *description() const override; @@ -68,8 +68,8 @@ class acorn_adfs_old_format : public wd177x_format public: acorn_adfs_old_format(); - virtual int find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual int find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; virtual int get_image_offset(const format &f, int head, int track) override; virtual const char *name() const override; virtual const char *description() const override; @@ -84,8 +84,8 @@ class acorn_adfs_new_format : public wd177x_format public: acorn_adfs_new_format(); - virtual int find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual int find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; virtual int get_image_offset(const format &f, int head, int track) override; virtual const char *name() const override; virtual const char *description() const override; @@ -100,8 +100,8 @@ class acorn_dos_format : public wd177x_format public: acorn_dos_format(); - virtual int find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual int find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; virtual int get_image_offset(const format &f, int head, int track) override; virtual const char *name() const override; virtual const char *description() const override; @@ -116,9 +116,9 @@ class opus_ddcpm_format : public floppy_image_format_t public: opus_ddcpm_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/afs_dsk.cpp b/src/lib/formats/afs_dsk.cpp index d6b275240de..000daf62df7 100644 --- a/src/lib/formats/afs_dsk.cpp +++ b/src/lib/formats/afs_dsk.cpp @@ -30,12 +30,13 @@ const char *afs_format::extensions() const return "adl,img"; } -int afs_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int afs_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { int type = find_size(io, form_factor, variants); if (type != -1) return 50; + return 0; } diff --git a/src/lib/formats/afs_dsk.h b/src/lib/formats/afs_dsk.h index 1a15e54d90d..f56b2dcb1f4 100644 --- a/src/lib/formats/afs_dsk.h +++ b/src/lib/formats/afs_dsk.h @@ -20,7 +20,7 @@ class afs_format : public wd177x_format public: afs_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; virtual int get_image_offset(const format &f, int head, int track) override; virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/aim_dsk.cpp b/src/lib/formats/aim_dsk.cpp index 489ec1752e4..6ad49b22969 100644 --- a/src/lib/formats/aim_dsk.cpp +++ b/src/lib/formats/aim_dsk.cpp @@ -12,10 +12,10 @@ *********************************************************************/ -#include <cassert> - #include "aim_dsk.h" +#include "ioprocs.h" + aim_format::aim_format() { @@ -40,18 +40,20 @@ const char *aim_format::extensions() const } -int aim_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int aim_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - if (io_generic_size(io) == 2068480) - { + uint64_t size; + if (io.length(size)) + return 0; + + if (size == 2068480) return 100; - } return 0; } -bool aim_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool aim_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { image->set_variant(floppy_image::DSQD); @@ -70,7 +72,8 @@ bool aim_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui bool header = false; // Read track - io_generic_read(io, &track_data[0], ( heads * track + head ) * track_size, track_size); + size_t actual; + io.read_at((heads * track + head) * track_size, &track_data[0], track_size, actual); // Find first sector header or index mark for (int offset = 0; offset < track_size; offset += 2) diff --git a/src/lib/formats/aim_dsk.h b/src/lib/formats/aim_dsk.h index c4737efc7e6..560943be30c 100644 --- a/src/lib/formats/aim_dsk.h +++ b/src/lib/formats/aim_dsk.h @@ -7,9 +7,10 @@ AIM disk images *********************************************************************/ +#ifndef MAME_FORMATS_AIM_DSK_H +#define MAME_FORMATS_AIM_DSK_H -#ifndef AIM_DSK_H -#define AIM_DSK_H +#pragma once #include "flopimg.h" @@ -20,8 +21,8 @@ class aim_format : public floppy_image_format_t public: aim_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; @@ -31,4 +32,4 @@ public: extern const floppy_format_type FLOPPY_AIM_FORMAT; -#endif /* AIM_DSK_H */ +#endif // MAME_FORMATS_AIM_DSK_H diff --git a/src/lib/formats/ami_dsk.cpp b/src/lib/formats/ami_dsk.cpp index 5973bc69dab..eb96b01377d 100644 --- a/src/lib/formats/ami_dsk.cpp +++ b/src/lib/formats/ami_dsk.cpp @@ -8,10 +8,11 @@ *********************************************************************/ -#include <cassert> - #include "formats/ami_dsk.h" +#include "ioprocs.h" + + adf_format::adf_format() : floppy_image_format_t() { } @@ -36,59 +37,61 @@ bool adf_format::supports_save() const return true; } -int adf_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int adf_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - uint64_t size = io_generic_size(io); + uint64_t size; + if (io.length(size)) + return 0; + if ((size == 901120) || (size == 912384) || (size == 1802240)) - { return 50; - } + return 0; } -bool adf_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool adf_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { desc_s sectors[22]; uint8_t sectdata[512*22]; bool is_hd = false; int tracks = 80; - for(int i=0; i<22; i++) { + for (int i=0; i<22; i++) { sectors[i].data = sectdata + 512*i; sectors[i].size = 512; sectors[i].sector_id = i; } - uint64_t size = io_generic_size(io); - if(size == 901120) - { + uint64_t size; + if (io.length(size)) + return false; + + if (size == 901120) { is_hd = false; tracks = 80; - } - else if (size == 912384) - { + } else if (size == 912384) { is_hd = false; tracks = 81; - } - else - { + } else { is_hd = true; tracks = 80; } if (!is_hd) { image->set_variant(floppy_image::DSDD); - for(int track=0; track < tracks; track++) { - for(int side=0; side < 2; side++) { - io_generic_read(io, sectdata, (track*2 + side)*512*11, 512*11); + for (int track=0; track < tracks; track++) { + for (int side=0; side < 2; side++) { + size_t actual; + io.read_at((track*2 + side)*512*11, sectdata, 512*11, actual); generate_track(amiga_11, track, side, sectors, 11, 100000, image); } } } else { image->set_variant(floppy_image::DSHD); - for(int track=0; track < tracks; track++) { - for(int side=0; side < 2; side++) { - io_generic_read(io, sectdata, (track*2 + side)*512*22, 512*22); + for (int track=0; track < tracks; track++) { + for (int side=0; side < 2; side++) { + size_t actual; + io.read_at((track*2 + side)*512*22, sectdata, 512*22, actual); generate_track(amiga_22, track, side, sectors, 22, 200000, image); } } @@ -100,11 +103,11 @@ bool adf_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui uint32_t adf_format::g32(const std::vector<bool> &trackbuf, uint32_t pos) { uint32_t res = 0; - for(int i=0; i != 32; i++) { - if(trackbuf[pos]) + for (int i=0; i != 32; i++) { + if (trackbuf[pos]) res |= 0x80000000 >> i; - pos ++; - if(pos == trackbuf.size()) + pos++; + if (pos == trackbuf.size()) pos = 0; } return res; @@ -113,34 +116,34 @@ uint32_t adf_format::g32(const std::vector<bool> &trackbuf, uint32_t pos) uint32_t adf_format::checksum(const std::vector<bool> &trackbuf, uint32_t pos, int long_count) { uint32_t check = 0; - for(int i=0; i<long_count; i++) + for (int i=0; i<long_count; i++) check ^= g32(trackbuf, pos+32*i); return check & 0x55555555; } -bool adf_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool adf_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { uint8_t sectdata[512*22]; - bool hd = image->get_variant() == floppy_image::DSHD; + bool const hd = image->get_variant() == floppy_image::DSHD; - int data_track_size = hd ? 512*22 : 512*11; + int const data_track_size = hd ? 512*22 : 512*11; - for(int track=0; track < 80; track++) { - for(int side=0; side < 2; side++) { + for (int track=0; track < 80; track++) { + for (int side=0; side < 2; side++) { auto trackbuf = generate_bitstream_from_track(track, side, hd ? 1000 : 2000, image); - for(uint32_t i=0; i<trackbuf.size(); i++) - if(g32(trackbuf, i) == 0x44894489 && + for (uint32_t i=0; i<trackbuf.size(); i++) + if (g32(trackbuf, i) == 0x44894489 && (g32(trackbuf, i+384) & 0x55555555) == checksum(trackbuf, i+32, 10) && (g32(trackbuf, i+448) & 0x55555555) == checksum(trackbuf, i+480, 256)) { uint32_t head = ((g32(trackbuf, i+32) & 0x55555555) << 1) | (g32(trackbuf, i+64) & 0x55555555); int sect = (head >> 8) & 0xff; - if(sect > (hd ? 22 : 11)) + if (sect > (hd ? 22 : 11)) continue; uint8_t *dest = sectdata + 512*sect; - for(int j=0; j<128; j++) { + for (int j=0; j<128; j++) { uint32_t val = ((g32(trackbuf, i+480+32*j) & 0x55555555) << 1) | (g32(trackbuf, i+4576+32*j) & 0x55555555); *dest++ = val >> 24; *dest++ = val >> 16; @@ -148,7 +151,8 @@ bool adf_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo *dest++ = val; } - io_generic_write(io, sectdata, (track*2 + side)*data_track_size, data_track_size); + size_t actual; + io.write_at((track*2 + side) * data_track_size, sectdata, data_track_size, actual); } } } diff --git a/src/lib/formats/ami_dsk.h b/src/lib/formats/ami_dsk.h index d25fd45a210..595beb1bcd3 100644 --- a/src/lib/formats/ami_dsk.h +++ b/src/lib/formats/ami_dsk.h @@ -19,9 +19,9 @@ class adf_format : public floppy_image_format_t public: adf_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/ap2_dsk.cpp b/src/lib/formats/ap2_dsk.cpp index 50b071d6432..8adc13d69d3 100644 --- a/src/lib/formats/ap2_dsk.cpp +++ b/src/lib/formats/ap2_dsk.cpp @@ -8,13 +8,15 @@ *********************************************************************/ -#include <cstdlib> -#include <cstring> -#include <cassert> - #include "ap2_dsk.h" #include "basicdsk.h" +#include "ioprocs.h" + +#include <cassert> +#include <cstdlib> +#include <cstring> + #define APPLE2_IMAGE_DO 0 #define APPLE2_IMAGE_PO 1 @@ -559,9 +561,12 @@ bool a2_16sect_format::supports_save() const return true; } -int a2_16sect_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int a2_16sect_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - uint64_t size = io_generic_size(io); + uint64_t size; + if (io.length(size)) + return 0; + //uint32_t expected_size = 35 * 16 * 256; uint32_t expected_size = APPLE2_TRACK_COUNT * 16 * 256; @@ -574,9 +579,11 @@ int a2_16sect_format::identify(io_generic *io, uint32_t form_factor, const std:: return 0; } -bool a2_16sect_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool a2_16sect_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { - uint64_t size = io_generic_size(io); + uint64_t size; + if (io.length(size)) + return false; image->set_form_variant(floppy_image::FF_525, floppy_image::SSSD); @@ -595,7 +602,8 @@ bool a2_16sect_format::load(io_generic *io, uint32_t form_factor, const std::vec static const unsigned char cpm22_block1[8] = { 0xa2, 0x55, 0xa9, 0x00, 0x9d, 0x00, 0x0d, 0xca }; static const unsigned char subnod_block1[8] = { 0x63, 0xaa, 0xf0, 0x76, 0x8d, 0x63, 0xaa, 0x8e }; - io_generic_read(io, sector_data, fpos, 256*16); + size_t actual; + io.read_at(fpos, sector_data, 256*16, actual); if (track == 0 && fpos == 0) { @@ -740,7 +748,7 @@ void a2_16sect_format::update_chk(const uint8_t *data, int size, uint32_t &chk) //#define VERBOSE_SAVE -bool a2_16sect_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool a2_16sect_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { int g_tracks, g_heads; int visualgrid[16][APPLE2_TRACK_COUNT]; // visualizer grid, cleared/initialized below @@ -938,8 +946,9 @@ bool a2_16sect_format::save(io_generic *io, const std::vector<uint32_t> &variant } for(int i=0; i<nsect; i++) { //if(nsect>0) printf("t%d,", track); - uint8_t *data = sectdata + (256)*i; - io_generic_write(io, data, pos_data, 256); + uint8_t const *const data = sectdata + (256)*i; + size_t actual; + io.write_at(pos_data, data, 256, actual); pos_data += 256; } //printf("\n"); @@ -952,11 +961,11 @@ bool a2_16sect_format::save(io_generic *io, const std::vector<uint32_t> &variant for (int i = 0; i < 16; i++) { if (visualgrid[i][j] == NOTFOUND) printf("-NF- "); else { - if (visualgrid[i][j] & ADDRFOUND) printf("a"); else printf(" "); - if (visualgrid[i][j] & ADDRGOOD) printf("A"); else printf(" "); - if (visualgrid[i][j] & DATAFOUND) printf("d"); else printf(" "); - if (visualgrid[i][j] & DATAGOOD) { printf("D"); total_good++; } else printf(" "); - if (visualgrid[i][j] & DATAPOST) printf("."); else printf(" "); + if (visualgrid[i][j] & ADDRFOUND) printf("a"); else printf(" "); + if (visualgrid[i][j] & ADDRGOOD) printf("A"); else printf(" "); + if (visualgrid[i][j] & DATAFOUND) printf("d"); else printf(" "); + if (visualgrid[i][j] & DATAGOOD) { printf("D"); total_good++; } else printf(" "); + if (visualgrid[i][j] & DATAPOST) printf("."); else printf(" "); } } printf("\n"); @@ -1019,14 +1028,16 @@ bool a2_rwts18_format::supports_save() const return true; } -int a2_rwts18_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int a2_rwts18_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - uint64_t size = io_generic_size(io); - uint32_t expected_size = APPLE2_TRACK_COUNT * 16 * 256; + uint64_t size; + if(io.length(size)) + return 0; + uint32_t const expected_size = APPLE2_TRACK_COUNT * 16 * 256; return size == expected_size; } -bool a2_rwts18_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool a2_rwts18_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { /* TODO: rewrite me properly uint8_t sector_data[(256)*16]; @@ -1046,7 +1057,8 @@ bool a2_rwts18_format::load(io_generic *io, uint32_t form_factor, const std::vec sectors[si].size = 256; sectors[si].sector_id = si; sectors[si].sector_info = format; - io_generic_read(io, data, pos_data, 256); + size_t actual; + io.read_at(pos_data, data, 256, actual); pos_data += 256; } generate_track(mac_gcr, track, head, sectors, 16, 3104*16, image); @@ -1075,7 +1087,7 @@ void a2_rwts18_format::update_chk(const uint8_t *data, int size, uint32_t &chk) { } -bool a2_rwts18_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool a2_rwts18_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { int g_tracks, g_heads; int visualgrid[18][APPLE2_TRACK_COUNT]; // visualizer grid, cleared/initialized below @@ -1266,8 +1278,9 @@ bool a2_rwts18_format::save(io_generic *io, const std::vector<uint32_t> &variant } for(int i=0; i<nsect; i++) { //if(nsect>0) printf("t%d,", track); - uint8_t *data = sectdata + (256)*i; - io_generic_write(io, data, pos_data, 256); + uint8_t const *const data = sectdata + (256)*i; + size_t actual; + io.write_at(pos_data, data, 256, actual); pos_data += 256; } @@ -1447,8 +1460,9 @@ bool a2_rwts18_format::save(io_generic *io, const std::vector<uint32_t> &variant } for(int i=0; i<nsect; i++) { //if(nsect>0) printf("t%d,", track); - uint8_t *data = sectdata + (256)*i; - io_generic_write(io, data, pos_data, 256); + uint8_t const *const data = sectdata + (256)*i; + size_t actual; + io.write_at(pos_data, data, 256, actual); pos_data += 256; } //printf("\n"); @@ -1500,9 +1514,12 @@ bool a2_edd_format::supports_save() const return false; } -int a2_edd_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int a2_edd_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - return ((io_generic_size(io) == 2244608) || (io_generic_size(io) == 2310144)) ? 50 : 0; + uint64_t size; + if (io.length(size)) + return 0; + return ((size == 2244608) || (size == 2310144)) ? 50 : 0; } uint8_t a2_edd_format::pick(const uint8_t *data, int pos) @@ -1510,23 +1527,20 @@ uint8_t a2_edd_format::pick(const uint8_t *data, int pos) return ((data[pos>>3] << 8) | data[(pos>>3)+1]) >> (8-(pos & 7)); } -bool a2_edd_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool a2_edd_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { - uint8_t *img; uint8_t nibble[16384], stream[16384]; int npos[16384]; - img = (uint8_t *) malloc(2244608); - + std::unique_ptr<uint8_t []> img(new (std::nothrow) uint8_t[2244608]); if (!img) - { return false; - } - io_generic_read(io, img, 0, 2244608); + size_t actual; + io.read_at(0, img.get(), 2244608, actual); for(int i=0; i<137; i++) { - const uint8_t *trk = img + 16384*i; + uint8_t const *const trk = &img[16384*i]; int pos = 0; int wpos = 0; while(pos < 16383*8) { @@ -1590,7 +1604,7 @@ bool a2_edd_format::load(io_generic *io, uint32_t form_factor, const std::vector generate_track_from_bitstream(i >> 2, 0, stream, len, image, i & 3); image->set_write_splice_position(i >> 2, 0, uint32_t(uint64_t(200'000'000)*splice/len), i & 3); } - free(img); + img.reset(); image->set_form_variant(floppy_image::FF_525, floppy_image::SSSD); @@ -1627,26 +1641,31 @@ bool a2_woz_format::supports_save() const const uint8_t a2_woz_format::signature[8] = { 0x57, 0x4f, 0x5a, 0x31, 0xff, 0x0a, 0x0d, 0x0a }; const uint8_t a2_woz_format::signature2[8] = { 0x57, 0x4f, 0x5a, 0x32, 0xff, 0x0a, 0x0d, 0x0a }; -int a2_woz_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int a2_woz_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { uint8_t header[8]; - io_generic_read(io, header, 0, 8); + size_t actual; + io.read_at(0, header, 8, actual); if (!memcmp(header, signature, 8)) return 100; if (!memcmp(header, signature2, 8)) return 100; return 0; } -bool a2_woz_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool a2_woz_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { - std::vector<uint8_t> img(io_generic_size(io)); - io_generic_read(io, &img[0], 0, img.size()); + uint64_t image_size; + if(io.length(image_size)) + return false; + std::vector<uint8_t> img(image_size); + size_t actual; + io.read_at(0, &img[0], img.size(), actual); // Check signature - if ((memcmp(&img[0], signature, 8)) && (memcmp(&img[0], signature2, 8))) + if((memcmp(&img[0], signature, 8)) && (memcmp(&img[0], signature2, 8))) return false; uint32_t woz_vers = 1; - if (!memcmp(&img[0], signature2, 8)) woz_vers = 2; + if(!memcmp(&img[0], signature2, 8)) woz_vers = 2; // Check integrity uint32_t crc = crc32r(&img[12], img.size() - 12); @@ -1663,7 +1682,7 @@ bool a2_woz_format::load(io_generic *io, uint32_t form_factor, const std::vector uint32_t info_vers = r8(img, off_info + 0); - if ((info_vers != 1) && (info_vers != 2)) + if((info_vers != 1) && (info_vers != 2)) return false; bool is_35 = r8(img, off_info + 1) == 2; @@ -1721,7 +1740,7 @@ bool a2_woz_format::load(io_generic *io, uint32_t form_factor, const std::vector return true; } -bool a2_woz_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool a2_woz_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { std::vector<std::vector<bool>> tracks(160); bool twosided = false; @@ -1823,7 +1842,8 @@ bool a2_woz_format::save(io_generic *io, const std::vector<uint32_t> &variants, w32(data, 8, crc32r(&data[12], data.size() - 12)); - io_generic_write(io, data.data(), 0, data.size()); + size_t actual; + io.write_at(0, data.data(), data.size(), actual); return true; } @@ -1911,12 +1931,15 @@ bool a2_nib_format::supports_save() const return false; } -int a2_nib_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int a2_nib_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - const auto size = io_generic_size(io); - if (size == expected_size_35t || size == expected_size_40t) { + uint64_t size; + if (io.length(size)) + return 0; + + if (size == expected_size_35t || size == expected_size_40t) return 50; - } + return 0; } @@ -2031,18 +2054,20 @@ std::vector<uint32_t> a2_nib_format::generate_levels_from_nibbles(const std::vec return levels; } -bool a2_nib_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool a2_nib_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { - auto size = io_generic_size(io); - if (size != expected_size_35t && size != expected_size_40t) { + uint64_t size; + if (io.length(size)) return false; - } + if (size != expected_size_35t && size != expected_size_40t) + return false; + const auto nr_tracks = size == expected_size_35t? 35 : 40; std::vector<uint8_t> nibbles(nibbles_per_track); for (unsigned track = 0; track < nr_tracks; ++track) { - io_generic_read(io, &nibbles[0], - track * nibbles_per_track, nibbles_per_track); + size_t actual; + io.read_at(track * nibbles_per_track, &nibbles[0], nibbles_per_track, actual); auto levels = generate_levels_from_nibbles(nibbles); generate_track_from_levels(track, 0, levels, diff --git a/src/lib/formats/ap2_dsk.h b/src/lib/formats/ap2_dsk.h index 7420d72d818..bab61cf96b8 100644 --- a/src/lib/formats/ap2_dsk.h +++ b/src/lib/formats/ap2_dsk.h @@ -41,9 +41,9 @@ class a2_16sect_format : public floppy_image_format_t public: a2_16sect_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; @@ -68,9 +68,9 @@ class a2_rwts18_format : public floppy_image_format_t public: a2_rwts18_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; @@ -92,8 +92,8 @@ class a2_edd_format : public floppy_image_format_t public: a2_edd_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual bool supports_save() const override; virtual const char *name() const override; @@ -111,9 +111,9 @@ class a2_woz_format : public floppy_image_format_t public: a2_woz_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual bool supports_save() const override; virtual const char *name() const override; @@ -141,8 +141,8 @@ class a2_nib_format : public floppy_image_format_t public: a2_nib_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual bool supports_save() const override; virtual const char *name() const override; diff --git a/src/lib/formats/ap_dsk35.cpp b/src/lib/formats/ap_dsk35.cpp index 9819406183c..6a3fa5d742b 100644 --- a/src/lib/formats/ap_dsk35.cpp +++ b/src/lib/formats/ap_dsk35.cpp @@ -100,6 +100,8 @@ #include "ap_dsk35.h" +#include "ioprocs.h" + #include <cassert> #include <cstdio> @@ -1233,14 +1235,15 @@ bool dc42_format::supports_save() const return true; } -int dc42_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int dc42_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - uint8_t h[0x54]; - uint64_t size = io_generic_size(io); - if(size < 0x54) + uint64_t size; + if(io.length(size) || (size < 0x54)) return 0; - io_generic_read(io, h, 0, 0x54); + uint8_t h[0x54]; + size_t actual; + io.read_at(0, h, 0x54, actual); uint32_t dsize = (h[0x40] << 24) | (h[0x41] << 16) | (h[0x42] << 8) | h[0x43]; uint32_t tsize = (h[0x44] << 24) | (h[0x45] << 16) | (h[0x46] << 8) | h[0x47]; @@ -1252,13 +1255,14 @@ int dc42_format::identify(io_generic *io, uint32_t form_factor, const std::vecto return 0; } - return size == 0x54+tsize+dsize && h[0] < 64 && h[0x52] == 1 && h[0x53] == 0 ? 100 : 0; + return (size == 0x54+tsize+dsize && h[0] < 64 && h[0x52] == 1 && h[0x53] == 0) ? 100 : 0; } -bool dc42_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool dc42_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { + size_t actual; uint8_t h[0x54]; - io_generic_read(io, h, 0, 0x54); + io.read_at(0, h, 0x54, actual); int dsize = (h[0x40] << 24) | (h[0x41] << 16) | (h[0x42] << 8) | h[0x43]; int tsize = (h[0x44] << 24) | (h[0x45] << 16) | (h[0x46] << 8) | h[0x47]; @@ -1270,8 +1274,7 @@ bool dc42_format::load(io_generic *io, uint32_t form_factor, const std::vector<u return false; } - switch (dsize) - { + switch(dsize) { case 409600: // Mac 400K image->set_form_variant(floppy_image::FF_35, floppy_image::SSDD); break; @@ -1315,13 +1318,14 @@ bool dc42_format::load(io_generic *io, uint32_t form_factor, const std::vector<u sectors[si].sector = i; sectors[si].info = format; if(tsize) { - io_generic_read(io, data, pos_tag, 12); + io.read_at(pos_tag, data, 12, actual); sectors[si].tag = data; pos_tag += 12; - } else + } else { sectors[si].tag = nullptr; + } sectors[si].data = data+12; - io_generic_read(io, data+12, pos_data, 512); + io.read_at(pos_data, data+12, 512, actual); pos_data += 512; si = (si + 2) % ns; if(si == 0) @@ -1341,7 +1345,7 @@ void dc42_format::update_chk(const uint8_t *data, int size, uint32_t &chk) } } -bool dc42_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool dc42_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { int g_tracks, g_heads; image->get_actual_geometry(g_tracks, g_heads); @@ -1381,8 +1385,9 @@ bool dc42_format::save(io_generic *io, const std::vector<uint32_t> &variants, fl for(unsigned int i=0; i < sectors.size(); i++) { auto &sdata = sectors[i]; sdata.resize(512+12); - io_generic_write(io, &sdata[0], pos_tag, 12); - io_generic_write(io, &sdata[12], pos_data, 512); + size_t actual; + io.write_at(pos_tag, &sdata[0], 12, actual); + io.write_at(pos_data, &sdata[12], 512, actual); pos_tag += 12; pos_data += 512; if(track || head || i) @@ -1401,7 +1406,8 @@ bool dc42_format::save(io_generic *io, const std::vector<uint32_t> &variants, fl h[0x4e] = tchk >> 8; h[0x4f] = tchk; - io_generic_write(io, h, 0, 0x54); + size_t actual; + io.write_at(0, h, 0x54, actual); return true; } @@ -1432,26 +1438,32 @@ bool apple_gcr_format::supports_save() const return true; } -int apple_gcr_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int apple_gcr_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - uint64_t size = io_generic_size(io); + uint64_t size; + if(io.length(size)) + return 0; + if(size == 409600 || (size == 819200 && (variants.empty() || has_variant(variants, floppy_image::DSDD)))) return 50; return 0; } -bool apple_gcr_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool apple_gcr_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { + size_t actual; desc_gcr_sector sectors[12]; uint8_t sdata[512*12]; int pos_data = 0; uint8_t header[64]; - io_generic_read(io, header, 0, 64); + io.read_at(0, header, 64, actual); - uint64_t size = io_generic_size(io); + uint64_t size; + if(io.length(size)) + return false; int head_count = size == 409600 ? 1 : size == 819200 ? 2 : 0; image->set_form_variant(floppy_image::FF_35, head_count == 2 ? floppy_image::DSDD : floppy_image::SSDD); @@ -1461,7 +1473,7 @@ bool apple_gcr_format::load(io_generic *io, uint32_t form_factor, const std::vec for(int track=0; track < 80; track++) { for(int head=0; head < head_count; head++) { int ns = 12 - (track/16); - io_generic_read(io, sdata, pos_data, 512*ns); + io.read_at(pos_data, sdata, 512*ns, actual); pos_data += 512*ns; int si = 0; @@ -1482,7 +1494,7 @@ bool apple_gcr_format::load(io_generic *io, uint32_t form_factor, const std::vec return true; } -bool apple_gcr_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool apple_gcr_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { int g_tracks, g_heads; image->get_actual_geometry(g_tracks, g_heads); @@ -1498,7 +1510,8 @@ bool apple_gcr_format::save(io_generic *io, const std::vector<uint32_t> &variant for(unsigned int i=0; i < sectors.size(); i++) { auto &sdata = sectors[i]; sdata.resize(512+12); - io_generic_write(io, &sdata[12], pos_data, 512); + size_t actual; + io.write_at(pos_data, &sdata[12], 512, actual); pos_data += 512; } } @@ -1534,10 +1547,11 @@ bool apple_2mg_format::supports_save() const return true; } -int apple_2mg_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int apple_2mg_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { uint8_t signature[4]; - io_generic_read(io, signature, 0, 4); + size_t actual; + io.read_at(0, signature, 4, actual); if (!strncmp(reinterpret_cast<char *>(signature), "2IMG", 4)) { return 100; @@ -1552,11 +1566,12 @@ int apple_2mg_format::identify(io_generic *io, uint32_t form_factor, const std:: return 0; } -bool apple_2mg_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool apple_2mg_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { + size_t actual; desc_gcr_sector sectors[12]; uint8_t sdata[512*12], header[64]; - io_generic_read(io, header, 0, 64); + io.read_at(0, header, 64, actual); uint32_t blocks = header[0x14] | (header[0x15] << 8) | (header[0x16] << 16) | (header[0x17] << 24); uint32_t pos_data = header[0x18] | (header[0x19] << 8) | (header[0x1a] << 16) | (header[0x1b] << 24); @@ -1568,7 +1583,7 @@ bool apple_2mg_format::load(io_generic *io, uint32_t form_factor, const std::vec for(int track=0; track < 80; track++) { for(int head=0; head < 2; head++) { int ns = 12 - (track/16); - io_generic_read(io, sdata, pos_data, 512*ns); + io.read_at(pos_data, sdata, 512*ns, actual); pos_data += 512*ns; int si = 0; @@ -1589,8 +1604,10 @@ bool apple_2mg_format::load(io_generic *io, uint32_t form_factor, const std::vec return true; } -bool apple_2mg_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool apple_2mg_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { + size_t actual; + uint8_t header[0x40]; int pos_data = 0x40; @@ -1611,7 +1628,7 @@ bool apple_2mg_format::save(io_generic *io, const std::vector<uint32_t> &variant header[0x18] = 0x40; // bytes of disk data header[0x1c] = 0x00; header[0x1d] = 0x80; header[0x1e] = 0x0c; // 0xC8000 (819200) - io_generic_write(io, header, 0, 0x40); + io.write_at(0, header, 0x40, actual); for(int track=0; track < 80; track++) { for(int head=0; head < 2; head++) { @@ -1619,7 +1636,7 @@ bool apple_2mg_format::save(io_generic *io, const std::vector<uint32_t> &variant for(unsigned int i=0; i < sectors.size(); i++) { auto &sdata = sectors[i]; sdata.resize(512+12); - io_generic_write(io, &sdata[12], pos_data, 512); + io.write_at(pos_data, &sdata[12], 512, actual); pos_data += 512; } } diff --git a/src/lib/formats/ap_dsk35.h b/src/lib/formats/ap_dsk35.h index def1cb86856..f4a8ec7bff8 100644 --- a/src/lib/formats/ap_dsk35.h +++ b/src/lib/formats/ap_dsk35.h @@ -29,9 +29,9 @@ class dc42_format : public floppy_image_format_t public: dc42_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; @@ -49,9 +49,9 @@ class apple_gcr_format : public floppy_image_format_t public: apple_gcr_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; @@ -66,9 +66,9 @@ class apple_2mg_format : public floppy_image_format_t public: apple_2mg_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/apd_dsk.cpp b/src/lib/formats/apd_dsk.cpp index 45d385a0800..f882d90fe23 100644 --- a/src/lib/formats/apd_dsk.cpp +++ b/src/lib/formats/apd_dsk.cpp @@ -60,9 +60,13 @@ *********************************************************************/ -#include <zlib.h> #include "formats/apd_dsk.h" +#include "ioprocs.h" + +#include <zlib.h> + + static const uint8_t APD_HEADER[8] = { 'A', 'P', 'D', 'X', '0', '0', '0', '1' }; static const uint8_t GZ_HEADER[2] = { 0x1f, 0x8b }; @@ -85,11 +89,15 @@ const char *apd_format::extensions() const return "apd"; } -int apd_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int apd_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - uint64_t size = io_generic_size(io); + uint64_t size; + if (io.length(size)) + return 0; + std::vector<uint8_t> img(size); - io_generic_read(io, &img[0], 0, size); + size_t actual; + io.read_at(0, &img[0], size, actual); int err; std::vector<uint8_t> gz_ptr(8); @@ -123,11 +131,15 @@ int apd_format::identify(io_generic *io, uint32_t form_factor, const std::vector return 0; } -bool apd_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool apd_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { - uint64_t size = io_generic_size(io); + uint64_t size; + if (io.length(size)) + return false; + std::vector<uint8_t> img(size); - io_generic_read(io, &img[0], 0, size); + size_t actual; + io.read_at(0, &img[0], size, actual); int err; std::vector<uint8_t> gz_ptr; diff --git a/src/lib/formats/apd_dsk.h b/src/lib/formats/apd_dsk.h index bc551973c4a..8c3ac6f0d42 100644 --- a/src/lib/formats/apd_dsk.h +++ b/src/lib/formats/apd_dsk.h @@ -23,8 +23,8 @@ public: virtual const char *description() const override; virtual const char *extensions() const override; - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual bool supports_save() const override; }; diff --git a/src/lib/formats/apollo_dsk.cpp b/src/lib/formats/apollo_dsk.cpp index 75c31cfe7f8..a1159ac68c8 100644 --- a/src/lib/formats/apollo_dsk.cpp +++ b/src/lib/formats/apollo_dsk.cpp @@ -8,10 +8,11 @@ *********************************************************************/ -#include <cassert> - #include "formats/apollo_dsk.h" +#include "ioprocs.h" + + apollo_format::apollo_format() : upd765_format(formats) { } @@ -46,10 +47,13 @@ const apollo_format::format apollo_format::formats[] = { const floppy_format_type FLOPPY_APOLLO_FORMAT = &floppy_image_format_creator<apollo_format>; -int apollo_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int apollo_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - uint64_t size = io_generic_size(io); - uint32_t expected_size = 77*2*8*1024; + uint64_t size; + if (io.length(size)) + return 0; + + constexpr uint32_t expected_size = 77*2*8*1024; return ((size == expected_size) || (size == 0)) ? 1 : 0; } diff --git a/src/lib/formats/apollo_dsk.h b/src/lib/formats/apollo_dsk.h index 6376c77b067..1c2c6d81030 100644 --- a/src/lib/formats/apollo_dsk.h +++ b/src/lib/formats/apollo_dsk.h @@ -19,7 +19,7 @@ class apollo_format : public upd765_format public: apollo_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; virtual const char *name() const override; virtual const char *description() const override; virtual const char *extensions() const override; diff --git a/src/lib/formats/apridisk.cpp b/src/lib/formats/apridisk.cpp index 388d358f6f8..1560c199149 100644 --- a/src/lib/formats/apridisk.cpp +++ b/src/lib/formats/apridisk.cpp @@ -12,6 +12,8 @@ #include "imageutl.h" +#include "ioprocs.h" + apridisk_format::apridisk_format() { @@ -32,10 +34,11 @@ const char *apridisk_format::extensions() const return "dsk"; } -int apridisk_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int apridisk_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { uint8_t header[APR_HEADER_SIZE]; - io_generic_read(io, header, 0, APR_HEADER_SIZE); + size_t actual; + io.read_at(0, header, APR_HEADER_SIZE, actual); const char magic[] = "ACT Apricot disk image\x1a\x04"; @@ -45,21 +48,26 @@ int apridisk_format::identify(io_generic *io, uint32_t form_factor, const std::v return 0; } -bool apridisk_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool apridisk_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { desc_pc_sector sectors[80][2][18]; std::unique_ptr<uint8_t []> sector_data(new uint8_t [MAX_SECTORS * SECTOR_SIZE]); uint8_t *data_ptr = sector_data.get(); int track_count = 0, head_count = 0, sector_count = 0; - uint64_t file_size = io_generic_size(io); + uint64_t file_size; + if (io.length(file_size)) + return false; + uint64_t file_offset = APR_HEADER_SIZE; while (file_offset < file_size) { + size_t actual; + // read sector header uint8_t sector_header[16]; - io_generic_read(io, sector_header, file_offset, 16); + io.read_at(file_offset, sector_header, 16, actual); uint32_t type = pick_integer_le(§or_header, 0, 4); uint16_t compression = pick_integer_le(§or_header, 4, 2); @@ -94,7 +102,7 @@ bool apridisk_format::load(io_generic *io, uint32_t form_factor, const std::vect case APR_COMPRESSED: { uint8_t comp[3]; - io_generic_read(io, comp, file_offset, 3); + io.read_at(file_offset, comp, 3, actual); uint16_t length = pick_integer_le(comp, 0, 2); if (length != SECTOR_SIZE) @@ -108,7 +116,7 @@ bool apridisk_format::load(io_generic *io, uint32_t form_factor, const std::vect break; case APR_UNCOMPRESSED: - io_generic_read(io, data_ptr, file_offset, SECTOR_SIZE); + io.read_at(file_offset, data_ptr, SECTOR_SIZE, actual); break; default: @@ -140,7 +148,7 @@ bool apridisk_format::load(io_generic *io, uint32_t form_factor, const std::vect return true; } -bool apridisk_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool apridisk_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { return false; } diff --git a/src/lib/formats/apridisk.h b/src/lib/formats/apridisk.h index 3e751f8d6ec..5cc8a1403fb 100644 --- a/src/lib/formats/apridisk.h +++ b/src/lib/formats/apridisk.h @@ -23,9 +23,9 @@ public: virtual const char *description() const override; virtual const char *extensions() const override; - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual bool supports_save() const override; private: diff --git a/src/lib/formats/cassimg.cpp b/src/lib/formats/cassimg.cpp index cf5812c67c1..2fab4a1ec8b 100644 --- a/src/lib/formats/cassimg.cpp +++ b/src/lib/formats/cassimg.cpp @@ -199,12 +199,15 @@ cassette_image::error cassette_image::lookup_sample(int channel, size_t sample, -cassette_image::cassette_image(const Format *format, void *file, const io_procs *procs, int flags) +cassette_image::cassette_image(const Format *format, util::random_read_write::ptr &&io, int flags) : + m_format(format), + m_io(std::move(io)), + m_channels(0), + m_flags(flags), + m_sample_frequency(0), + m_blocks(), + m_sample_count(0) { - m_format = format; - m_io.file = file; - m_io.procs = procs; - m_flags = flags; } @@ -217,17 +220,24 @@ cassette_image::~cassette_image() -cassette_image::error cassette_image::open(void *file, const io_procs *procs, - const Format *format, int flags, ptr &outcassette) +cassette_image::error cassette_image::open( + util::random_read_write::ptr &&io, + const Format *format, + int flags, + ptr &outcassette) { const Format *const formats[2] = { format, nullptr }; - return open_choices(file, procs, {}, formats, flags, outcassette); + return open_choices(std::move(io), { }, formats, flags, outcassette); } -cassette_image::error cassette_image::open_choices(void *file, const io_procs *procs, const std::string &extension, - const Format *const *formats, int flags, ptr &outcassette) +cassette_image::error cassette_image::open_choices( + util::random_read_write::ptr &&io, + const std::string &extension, + const Format *const *formats, + int flags, + ptr &outcassette) { // if not specified, use the dummy arguments if (!formats) @@ -235,7 +245,7 @@ cassette_image::error cassette_image::open_choices(void *file, const io_procs *p // create the cassette object ptr cassette; - try { cassette.reset(new cassette_image(nullptr, file, procs, flags)); } + try { cassette.reset(new cassette_image(nullptr, std::move(io), flags)); } catch (std::bad_alloc const &) { return error::OUT_OF_MEMORY; } // identify the image @@ -275,8 +285,12 @@ cassette_image::error cassette_image::open_choices(void *file, const io_procs *p -cassette_image::error cassette_image::create(void *file, const io_procs *procs, const Format *format, - const Options *opts, int flags, ptr &outcassette) +cassette_image::error cassette_image::create( + util::random_read_write::ptr &&io, + const Format *format, + const Options *opts, + int flags, + ptr &outcassette) { static const Options default_options = { 1, 16, 44100 }; @@ -294,7 +308,7 @@ cassette_image::error cassette_image::create(void *file, const io_procs *procs, // create the cassette object ptr cassette; - try { cassette.reset(new cassette_image(format, file, procs, flags)); } + try { cassette.reset(new cassette_image(format, std::move(io), flags)); } catch (std::bad_alloc const &) { return error::OUT_OF_MEMORY; } // read the options @@ -334,13 +348,13 @@ cassette_image::Info cassette_image::get_info() const -void cassette_image::change(void *file, const io_procs *procs, const Format *format, int flags) +void cassette_image::change(util::random_read_write::ptr &&io, const Format *format, int flags) { - if ((flags & FLAG_READONLY) == 0) + if (!(flags & FLAG_READONLY)) flags |= CASSETTE_FLAG_DIRTY; - m_io.file = file; - m_io.procs = procs; + m_format = format; + m_io = std::move(io); m_flags = flags; } @@ -352,7 +366,8 @@ void cassette_image::change(void *file, const io_procs *procs, const Format *for void cassette_image::image_read(void *buffer, uint64_t offset, size_t length) { - io_generic_read(&m_io, buffer, offset, length); + size_t actual; + m_io->read_at(offset, buffer, length, actual); } @@ -360,7 +375,7 @@ void cassette_image::image_read(void *buffer, uint64_t offset, size_t length) uint8_t cassette_image::image_read_byte(uint64_t offset) { uint8_t data; - io_generic_read(&m_io, &data, offset, 1); + image_read(&data, offset, 1); return data; } @@ -368,14 +383,17 @@ uint8_t cassette_image::image_read_byte(uint64_t offset) void cassette_image::image_write(const void *buffer, uint64_t offset, size_t length) { - io_generic_write(&m_io, buffer, offset, length); + size_t actual; + m_io->write_at(offset, buffer, length, actual); } uint64_t cassette_image::image_size() { - return io_generic_size(&m_io); + uint64_t size = 0; + m_io->length(size); + return size; } @@ -900,20 +918,19 @@ done: void cassette_image::dump(const char *filename) { - FILE *f = fopen(filename, "wb"); - if (!f) + util::random_read_write::ptr saved_io = util::stdio_read_write(fopen(filename, "wb"), 0); + if (!saved_io) return; - io_generic saved_io = m_io; - const Format *saved_format = m_format; + Format const *const saved_format = m_format; - m_io.file = f; - m_io.procs = &stdio_ioprocs_noclose; + using std::swap; + + swap(m_io, saved_io); m_format = &wavfile_format; + perform_save(); - m_io = saved_io; + swap(m_io, saved_io); m_format = saved_format; - - fclose(f); } diff --git a/src/lib/formats/cassimg.h b/src/lib/formats/cassimg.h index 3a59870571a..765b860b659 100644 --- a/src/lib/formats/cassimg.h +++ b/src/lib/formats/cassimg.h @@ -185,14 +185,14 @@ public: void dump(const char *filename); error save(); - void change(void *file, const io_procs *procs, const Format *format, int flags); + void change(util::random_read_write::ptr &&io, const Format *format, int flags); Info get_info() const; - static error open(void *file, const io_procs *procs, + static error open(util::random_read_write::ptr &&io, const Format *format, int flags, ptr &outcassette); - static error open_choices(void *file, const io_procs *procs, const std::string &extension, + static error open_choices(util::random_read_write::ptr &&io, const std::string &extension, const Format *const *formats, int flags, ptr &outcassette); - static error create(void *file, const io_procs *procs, const cassette_image::Format *format, + static error create(util::random_read_write::ptr &&io, const cassette_image::Format *format, const cassette_image::Options *opts, int flags, ptr &outcassette); // builtin formats @@ -201,7 +201,7 @@ public: private: struct manipulation_ranges; - cassette_image(const Format *format, void *file, const io_procs *procs, int flags); + cassette_image(const Format *format, util::random_read_write::ptr &&io, int flags); cassette_image(const cassette_image &) = delete; cassette_image(cassette_image &&) = delete; cassette_image &operator=(const cassette_image &) = delete; @@ -212,15 +212,15 @@ private: error compute_manipulation_ranges(int channel, double time_index, double sample_period, manipulation_ranges &ranges) const; error lookup_sample(int channel, size_t sample, int32_t *&ptr); - const Format *m_format = nullptr; - io_generic m_io; + const Format *m_format; + util::random_read_write::ptr m_io; - int m_channels = 0; - int m_flags = 0; - uint32_t m_sample_frequency = 0; + int m_channels; + int m_flags; + uint32_t m_sample_frequency; std::vector<std::unique_ptr<int32_t []> > m_blocks; - size_t m_sample_count = 0; + size_t m_sample_count; }; /* macros for specifying format lists */ diff --git a/src/lib/formats/ccvf_dsk.cpp b/src/lib/formats/ccvf_dsk.cpp index bba52d3922a..6ed0c14038a 100644 --- a/src/lib/formats/ccvf_dsk.cpp +++ b/src/lib/formats/ccvf_dsk.cpp @@ -11,6 +11,7 @@ #include "formats/ccvf_dsk.h" #include "coretmpl.h" // BIT +#include "ioprocs.h" ccvf_format::ccvf_format() @@ -46,12 +47,12 @@ const ccvf_format::format ccvf_format::file_formats[] = { {} }; -int ccvf_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int ccvf_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { char h[36]; - - io_generic_read(io, h, 0, 36); - if(!memcmp(h, "Compucolor Virtual Floppy Disk Image", 36)) + size_t actual; + io.read_at(0, h, 36, actual); + if (!memcmp(h, "Compucolor Virtual Floppy Disk Image", 36)) return 100; return 0; @@ -87,13 +88,17 @@ floppy_image_format_t::desc_e* ccvf_format::get_desc_8n1(const format &f, int &c return desc; } -bool ccvf_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool ccvf_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { const format &f = formats[0]; - uint64_t size = io_generic_size(io); + uint64_t size; + if (io.length(size)) + return false; + std::vector<uint8_t> img(size); - io_generic_read(io, &img[0], 0, size); + size_t actual; + io.read_at(0, &img[0], size, actual); std::string ccvf = std::string((const char *)&img[0], size); std::vector<uint8_t> bytes(78720); diff --git a/src/lib/formats/ccvf_dsk.h b/src/lib/formats/ccvf_dsk.h index 5895a882550..92f04e03ddd 100644 --- a/src/lib/formats/ccvf_dsk.h +++ b/src/lib/formats/ccvf_dsk.h @@ -39,8 +39,8 @@ public: virtual const char *description() const override; virtual const char *extensions() const override; - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual bool supports_save() const override; protected: diff --git a/src/lib/formats/concept_dsk.cpp b/src/lib/formats/concept_dsk.cpp index 67c8562e1c3..7f5edce3363 100644 --- a/src/lib/formats/concept_dsk.cpp +++ b/src/lib/formats/concept_dsk.cpp @@ -10,11 +10,11 @@ *********************************************************************/ -#include <cassert> - -#include "flopimg.h" #include "formats/concept_dsk.h" +#include "ioprocs.h" + + /* 9 sectors / track, 512 bytes per sector */ const floppy_image_format_t::desc_e cc525dsdd_format::cc_9_desc[] = { { MFM, 0x4e, 80 }, @@ -72,50 +72,50 @@ bool cc525dsdd_format::supports_save() const return true; } -void cc525dsdd_format::find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count) +void cc525dsdd_format::find_size(util::random_read &io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count) { - uint64_t size = io_generic_size(io); - track_count = 77; head_count = 2; sector_count = 9; - uint32_t expected_size = 512 * track_count*head_count*sector_count; - if (size == expected_size) - { + uint32_t const expected_size = 512 * track_count*head_count*sector_count; + + uint64_t size; + if (!io.length(size) && (size == expected_size)) return; - } track_count = head_count = sector_count = 0; } -int cc525dsdd_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int cc525dsdd_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { uint8_t track_count, head_count, sector_count; find_size(io, track_count, head_count, sector_count); - if(track_count) + if (track_count) return 50; + return 0; } -bool cc525dsdd_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool cc525dsdd_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { uint8_t track_count, head_count, sector_count; find_size(io, track_count, head_count, sector_count); uint8_t sectdata[10*512]; desc_s sectors[10]; - for(int i=0; i<sector_count; i++) { + for (int i=0; i<sector_count; i++) { sectors[i+1].data = sectdata + 512*i; sectors[i+1].size = 512; sectors[i+1].sector_id = i+1; } int track_size = sector_count*512; - for(int track=0; track < track_count; track++) { - for(int head=0; head < head_count; head++) { - io_generic_read(io, sectdata, (track*head_count + head)*track_size, track_size); + for (int track=0; track < track_count; track++) { + for (int head=0; head < head_count; head++) { + size_t actual; + io.read_at((track*head_count + head) * track_size, sectdata, track_size, actual); generate_track(cc_9_desc, track, head, sectors, sector_count, 100000, image); } } @@ -125,28 +125,29 @@ bool cc525dsdd_format::load(io_generic *io, uint32_t form_factor, const std::vec return true; } -bool cc525dsdd_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool cc525dsdd_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { int track_count, head_count, sector_count; get_geometry_mfm_pc(image, 2000, track_count, head_count, sector_count); - if(track_count != 77) + if (track_count != 77) track_count = 77; // Happens for a fully unformatted floppy - if(!head_count) + if (!head_count) head_count = 2; - if(sector_count != 9) + if (sector_count != 9) sector_count = 9; uint8_t sectdata[9*512]; int track_size = sector_count*512; - for(int track=0; track < track_count; track++) { - for(int head=0; head < head_count; head++) { + for (int track=0; track < track_count; track++) { + for (int head=0; head < head_count; head++) { get_track_data_mfm_pc(track, head, image, 2000, 512, sector_count, sectdata); - io_generic_write(io, sectdata, (track*head_count + head)*track_size, track_size); + size_t actual; + io.write_at((track*head_count + head)*track_size, sectdata, track_size, actual); } } diff --git a/src/lib/formats/concept_dsk.h b/src/lib/formats/concept_dsk.h index 58d4e1c52b3..36e3f790a84 100644 --- a/src/lib/formats/concept_dsk.h +++ b/src/lib/formats/concept_dsk.h @@ -17,9 +17,9 @@ class cc525dsdd_format : public floppy_image_format_t public: cc525dsdd_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; @@ -29,7 +29,7 @@ public: static const desc_e cc_9_desc[]; private: - void find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count); + void find_size(util::random_read &io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count); }; extern const floppy_format_type FLOPPY_CONCEPT_525DSDD_FORMAT; diff --git a/src/lib/formats/coupedsk.cpp b/src/lib/formats/coupedsk.cpp index 16842583855..9400cd41bb6 100644 --- a/src/lib/formats/coupedsk.cpp +++ b/src/lib/formats/coupedsk.cpp @@ -8,10 +8,10 @@ **************************************************************************/ -#include <cassert> +#include "coupedsk.h" + +#include "ioprocs.h" -#include "formats/coupedsk.h" -#include "flopimg.h" const floppy_image_format_t::desc_e mgt_format::desc_10[] = { { MFM, 0x4e, 60 }, @@ -64,9 +64,11 @@ bool mgt_format::supports_save() const return true; } -int mgt_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int mgt_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - uint64_t size = io_generic_size(io); + uint64_t size; + if(io.length(size)) + return 0; if(/*size == 737280 || */ size == 819200) return 50; @@ -74,10 +76,12 @@ int mgt_format::identify(io_generic *io, uint32_t form_factor, const std::vector return 0; } -bool mgt_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool mgt_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { - uint64_t size = io_generic_size(io); - int sector_count = size == 737280 ? 9 : 10; + uint64_t size; + if(io.length(size)) + return false; + int const sector_count = (size == 737280) ? 9 : 10; uint8_t sectdata[10*512]; desc_s sectors[10]; @@ -90,7 +94,8 @@ bool mgt_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui int track_size = sector_count*512; for(int head=0; head < 2; head++) { for(int track=0; track < 80; track++) { - io_generic_read(io, sectdata, (track*2+head)*track_size, track_size); + size_t actual; + io.read_at((track*2+head)*track_size, sectdata, track_size, actual); generate_track(desc_10, track, head, sectors, sector_count+1, 100000, image); } } @@ -99,7 +104,7 @@ bool mgt_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui return true; } -bool mgt_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool mgt_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { int track_count, head_count, sector_count; get_geometry_mfm_pc(image, 2000, track_count, head_count, sector_count); @@ -115,7 +120,8 @@ bool mgt_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo for(int head=0; head < 2; head++) { for(int track=0; track < 80; track++) { get_track_data_mfm_pc(track, head, image, 2000, 512, sector_count, sectdata); - io_generic_write(io, sectdata, (track*2+head)*track_size, track_size); + size_t actual; + io.write_at((track*2+head)*track_size, sectdata, track_size, actual); } } diff --git a/src/lib/formats/coupedsk.h b/src/lib/formats/coupedsk.h index 3700d3e9974..e9ef4b118ca 100644 --- a/src/lib/formats/coupedsk.h +++ b/src/lib/formats/coupedsk.h @@ -19,9 +19,9 @@ class mgt_format : public floppy_image_format_t public: mgt_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/cqm_dsk.cpp b/src/lib/formats/cqm_dsk.cpp index 5f79a4d3694..6639e50f801 100644 --- a/src/lib/formats/cqm_dsk.cpp +++ b/src/lib/formats/cqm_dsk.cpp @@ -8,9 +8,12 @@ *********************************************************************/ +#include "cqm_dsk.h" + +#include "ioprocs.h" + #include <cstring> -#include <cassert> -#include "flopimg.h" + #define CQM_HEADER_SIZE 133 @@ -231,17 +234,6 @@ FLOPPY_CONSTRUCT( cqm_dsk_construct ) - -/********************************************************************* - - formats/cqm_dsk.c - - CopyQM disk images - -*********************************************************************/ - -#include "cqm_dsk.h" - cqm_format::cqm_format() { } @@ -261,10 +253,11 @@ const char *cqm_format::extensions() const return "cqm,cqi,dsk"; } -int cqm_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int cqm_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { uint8_t h[3]; - io_generic_read(io, h, 0, 3); + size_t actual; + io.read_at(0, h, 3, actual); if (h[0] == 'C' && h[1] == 'Q' && h[2] == 0x14) return 100; @@ -272,12 +265,13 @@ int cqm_format::identify(io_generic *io, uint32_t form_factor, const std::vector return 0; } -bool cqm_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool cqm_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { + size_t actual; const int max_size = 4*1024*1024; // 4MB ought to be large enough for any floppy std::vector<uint8_t> imagebuf(max_size); uint8_t header[CQM_HEADER_SIZE]; - io_generic_read(io, header, 0, CQM_HEADER_SIZE); + io.read_at(0, header, CQM_HEADER_SIZE, actual); int sector_size = (header[0x04] << 8) | header[0x03]; int sector_per_track = (header[0x11] << 8) | header[0x10]; @@ -318,9 +312,11 @@ bool cqm_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui int rpm = form_factor == floppy_image::FF_8 || (form_factor == floppy_image::FF_525 && rate >= 300000) ? 360 : 300; int base_cell_count = rate*60/rpm; - int cqm_size = io_generic_size(io); + uint64_t cqm_size; + if (io.length(cqm_size)) + return false; std::vector<uint8_t> cqmbuf(cqm_size); - io_generic_read(io, &cqmbuf[0], 0, cqm_size); + io.read_at(0, &cqmbuf[0], cqm_size, actual); // decode the RLE data for (int s = 0, pos = CQM_HEADER_SIZE + comment_size; pos < cqm_size; ) @@ -369,7 +365,7 @@ bool cqm_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui return true; } -bool cqm_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool cqm_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { return false; } diff --git a/src/lib/formats/cqm_dsk.h b/src/lib/formats/cqm_dsk.h index 183c0b83e68..fc8376a2b85 100644 --- a/src/lib/formats/cqm_dsk.h +++ b/src/lib/formats/cqm_dsk.h @@ -19,9 +19,9 @@ class cqm_format : public floppy_image_format_t public: cqm_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/d64_dsk.cpp b/src/lib/formats/d64_dsk.cpp index 4819ecc68d2..149130f0b3c 100644 --- a/src/lib/formats/d64_dsk.cpp +++ b/src/lib/formats/d64_dsk.cpp @@ -12,6 +12,8 @@ #include "formats/d64_dsk.h" +#include "ioprocs.h" + d64_format::d64_format() { @@ -79,9 +81,12 @@ const int d64_format::speed_zone[] = 0, 0 // 41-42 }; -int d64_format::find_size(io_generic *io, uint32_t form_factor) const +int d64_format::find_size(util::random_read &io, uint32_t form_factor) const { - uint64_t size = io_generic_size(io); + uint64_t size; + if(io.length(size)) + return 0; + for(int i=0; formats[i].sector_count; i++) { const format &f = formats[i]; if(size == (uint32_t) f.sector_count*f.sector_base_size*f.head_count) @@ -89,12 +94,13 @@ int d64_format::find_size(io_generic *io, uint32_t form_factor) const if(size == (uint32_t) (f.sector_count*f.sector_base_size*f.head_count) + f.sector_count) return i; } + return -1; } -int d64_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int d64_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - int type = find_size(io, form_factor); + const int type = find_size(io, form_factor); if (type != -1) return 50; @@ -114,10 +120,11 @@ int d64_format::get_disk_id_offset(const format &f) return 0x165a2; } -void d64_format::get_disk_id(const format &f, io_generic *io, uint8_t &id1, uint8_t &id2) +void d64_format::get_disk_id(const format &f, util::random_read &io, uint8_t &id1, uint8_t &id2) { uint8_t id[2]; - io_generic_read(io, id, get_disk_id_offset(f), 2); + size_t actual; + io.read_at(get_disk_id_offset(f), id, 2, actual); id1 = id[0]; id2 = id[1]; } @@ -206,7 +213,7 @@ void d64_format::fix_end_gap(floppy_image_format_t::desc_e* desc, int remaining_ desc[22].p1 >>= remaining_size & 0x01; } -bool d64_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool d64_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { int type = find_size(io, form_factor); if(type == -1) @@ -214,7 +221,9 @@ bool d64_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui const format &f = formats[type]; - uint64_t size = io_generic_size(io); + uint64_t size; + if(io.length(size)) + return false; std::vector<uint8_t> img; if(size == (uint32_t)f.sector_count*f.sector_base_size) { @@ -225,7 +234,8 @@ bool d64_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui img.resize(size); } - io_generic_read(io, &img[0], 0, size); + size_t actual; + io.read_at(0, &img[0], size, actual); int track_offset = 0, error_offset = f.sector_count*f.sector_base_size; @@ -266,7 +276,7 @@ bool d64_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui return true; } -bool d64_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool d64_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { const format &f = formats[0]; @@ -280,7 +290,8 @@ bool d64_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo build_sector_description(f, sectdata, 0, 0, sectors, sector_count); extract_sectors(image, f, sectors, track, head, sector_count); - io_generic_write(io, sectdata, offset, track_size); + size_t actual; + io.write_at(offset, sectdata, track_size, actual); } } diff --git a/src/lib/formats/d64_dsk.h b/src/lib/formats/d64_dsk.h index 665f6489a81..13f1bd4e91c 100644 --- a/src/lib/formats/d64_dsk.h +++ b/src/lib/formats/d64_dsk.h @@ -37,9 +37,9 @@ public: virtual const char *description() const override; virtual const char *extensions() const override; - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual bool supports_save() const override { return true; } protected: @@ -61,12 +61,12 @@ protected: const format *formats; - int find_size(io_generic *io, uint32_t form_factor) const; + int find_size(util::random_read &io, uint32_t form_factor) const; virtual int get_physical_track(const format &f, int head, int track); virtual uint32_t get_cell_size(const format &f, int track); virtual int get_sectors_per_track(const format &f, int track); virtual int get_disk_id_offset(const format &f); - void get_disk_id(const format &f, io_generic *io, uint8_t &id1, uint8_t &id2); + void get_disk_id(const format &f, util::random_read &io, uint8_t &id1, uint8_t &id2); virtual int get_image_offset(const format &f, int head, int track); int compute_track_size(const format &f, int track); virtual int get_gap2(const format &f, int head, int track) { return f.gap_2; } diff --git a/src/lib/formats/d80_dsk.cpp b/src/lib/formats/d80_dsk.cpp index d350411b159..338f00292a9 100644 --- a/src/lib/formats/d80_dsk.cpp +++ b/src/lib/formats/d80_dsk.cpp @@ -8,10 +8,11 @@ *********************************************************************/ -#include <cassert> - #include "formats/d80_dsk.h" +#include "ioprocs.h" + + d80_format::d80_format() : d64_format(file_formats), formats(nullptr) { } diff --git a/src/lib/formats/d88_dsk.cpp b/src/lib/formats/d88_dsk.cpp index 7c4eaa079dc..6e29f10df6a 100644 --- a/src/lib/formats/d88_dsk.cpp +++ b/src/lib/formats/d88_dsk.cpp @@ -29,11 +29,12 @@ * */ - #include <cassert> - #include "flopimg.h" #include "imageutl.h" +#include "ioprocs.h" + + #define D88_HEADER_LEN 0x2b0 struct d88_tag @@ -414,12 +415,15 @@ const char *d88_format::extensions() const return "d77,d88,1dd"; } -int d88_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int d88_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - uint64_t size = io_generic_size(io); - uint8_t h[32]; + uint64_t size; + if(io.length(size)) + return 0; - io_generic_read(io, h, 0, 32); + uint8_t h[32]; + size_t actual; + io.read_at(0, h, 32, actual); if((little_endianize_int32(*(uint32_t *)(h+0x1c)) == size) && (h[0x1b] == 0x00 || h[0x1b] == 0x10 || h[0x1b] == 0x20 || h[0x1b] == 0x30 || h[0x1b] == 0x40)) return 100; @@ -427,11 +431,12 @@ int d88_format::identify(io_generic *io, uint32_t form_factor, const std::vector return 0; } -bool d88_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool d88_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { - uint8_t h[32]; + size_t actual; - io_generic_read(io, h, 0, 32); + uint8_t h[32]; + io.read_at(0, h, 32, actual); int cell_count = 0; int track_count = 0; @@ -477,9 +482,11 @@ bool d88_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui return false; uint32_t track_pos[164]; - io_generic_read(io, track_pos, 32, 164*4); + io.read_at(32, track_pos, 164*4, actual); - uint64_t file_size = io_generic_size(io); + uint64_t file_size; + if(io.length(file_size)) + return false; for(int track=0; track < track_count; track++) for(int head=0; head < head_count; head++) { @@ -496,7 +503,7 @@ bool d88_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui return true; uint8_t hs[16]; - io_generic_read(io, hs, pos, 16); + io.read_at(pos, hs, 16, actual); pos += 16; uint16_t size = little_endianize_int16(*(uint16_t *)(hs+14)); @@ -521,7 +528,7 @@ bool d88_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui if(size) { sects[i].data = sect_data + sdatapos; - io_generic_read(io, sects[i].data, pos, size); + io.read_at(pos, sects[i].data, size, actual); pos += size; sdatapos += size; @@ -536,7 +543,7 @@ bool d88_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui } -bool d88_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool d88_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { return false; } diff --git a/src/lib/formats/d88_dsk.h b/src/lib/formats/d88_dsk.h index c7c85fc1949..aeed5ed16e8 100644 --- a/src/lib/formats/d88_dsk.h +++ b/src/lib/formats/d88_dsk.h @@ -20,9 +20,9 @@ class d88_format : public floppy_image_format_t public: d88_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/dcp_dsk.cpp b/src/lib/formats/dcp_dsk.cpp index b3beb40404f..7d419628bdc 100644 --- a/src/lib/formats/dcp_dsk.cpp +++ b/src/lib/formats/dcp_dsk.cpp @@ -20,10 +20,11 @@ *********************************************************************/ -#include <cassert> - #include "dcp_dsk.h" +#include "ioprocs.h" + + dcp_format::dcp_format() { } @@ -43,14 +44,18 @@ const char *dcp_format::extensions() const return "dcp,dcu"; } -int dcp_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int dcp_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - uint64_t size = io_generic_size(io); + uint64_t size; + if (io.length(size)) + return 0; + uint8_t h[0xa2]; int heads, tracks, spt, bps, count_tracks = 0; bool is_hdb = false; - io_generic_read(io, h, 0, 0xa2); + size_t actual; + io.read_at(0, h, 0xa2, actual); // First byte is the disk format (see below in load() for details) switch (h[0]) @@ -112,13 +117,14 @@ int dcp_format::identify(io_generic *io, uint32_t form_factor, const std::vector return 0; } -bool dcp_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool dcp_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { + size_t actual; uint8_t h[0xa2]; int heads, tracks, spt, bps; bool is_hdb = false; - io_generic_read(io, h, 0, 0xa2); + io.read_at(0, h, 0xa2, actual); // First byte is the disk format: switch (h[0]) @@ -215,7 +221,7 @@ bool dcp_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui for (int track = 0; track < tracks; track++) for (int head = 0; head < heads; head++) { - io_generic_read(io, sect_data, 0xa2 + bps * spt * (track * heads + head), bps * spt); + io.read_at(0xa2 + bps * spt * (track * heads + head), sect_data, bps * spt, actual); for (int i = 0; i < spt; i++) { @@ -235,7 +241,7 @@ bool dcp_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui else // FIXME: the code below is untested, because no image was found... there might be some silly mistake in the disk geometry! { // Read Head 0 Track 0 is FM with 26 sectors of 128bytes instead of 256 - io_generic_read(io, sect_data, 0xa2, 128 * spt); + io.read_at(0xa2, sect_data, 128 * spt, actual); for (int i = 0; i < spt; i++) { @@ -252,7 +258,7 @@ bool dcp_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui build_pc_track_fm(0, 0, image, cell_count, spt, sects, calc_default_pc_gap3_size(form_factor, 128)); // Read Head 1 Track 0 is MFM with 26 sectors of 256bytes - io_generic_read(io, sect_data, 0xa2 + 128 * spt, bps * spt); + io.read_at(0xa2 + 128 * spt, sect_data, bps * spt, actual); for (int i = 0; i < spt; i++) { @@ -273,7 +279,7 @@ bool dcp_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui for (int track = 1; track < tracks; track++) for (int head = 0; head < heads; head++) { - io_generic_read(io, sect_data, data_offs + bps * spt * ((track - 1) * heads + head), bps * spt); + io.read_at(data_offs + bps * spt * ((track - 1) * heads + head), sect_data, bps * spt, actual); for (int i = 0; i < spt; i++) { diff --git a/src/lib/formats/dcp_dsk.h b/src/lib/formats/dcp_dsk.h index c06396d527e..716814ffd48 100644 --- a/src/lib/formats/dcp_dsk.h +++ b/src/lib/formats/dcp_dsk.h @@ -20,8 +20,8 @@ class dcp_format : public floppy_image_format_t public: dcp_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/dfi_dsk.cpp b/src/lib/formats/dfi_dsk.cpp index 409797e9583..607be56f741 100644 --- a/src/lib/formats/dfi_dsk.cpp +++ b/src/lib/formats/dfi_dsk.cpp @@ -13,7 +13,8 @@ #include "dfi_dsk.h" -#include <zlib.h> +#include "ioprocs.h" + #define NUMBER_OF_MULTIREADS 3 // thresholds for brickwall windowing @@ -56,24 +57,28 @@ bool dfi_format::supports_save() const return false; } -int dfi_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int dfi_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { char sign[4]; - io_generic_read(io, sign, 0, 4); + size_t actual; + io.read_at(0, sign, 4, actual); return memcmp(sign, "DFE2", 4) ? 0 : 100; } -bool dfi_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool dfi_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { + size_t actual; char sign[4]; - io_generic_read(io, sign, 0, 4); - if (memcmp(sign, "DFER", 4) == 0) - { + io.read_at(0, sign, 4, actual); + if(memcmp(sign, "DFER", 4) == 0) { osd_printf_error("dfi_dsk: Old type Discferret image detected; the mess Discferret decoder will not handle this properly, bailing out!\n"); return false; } - uint64_t size = io_generic_size(io); + uint64_t size; + if(io.length(size)) + return false; + uint64_t pos = 4; std::vector<uint8_t> data; int onerev_time = 0; // time for one revolution, used to guess clock and rpm for DFE2 files @@ -81,7 +86,7 @@ bool dfi_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui int rpm=360; // drive rpm while(pos < size) { uint8_t h[10]; - io_generic_read(io, h, pos, 10); + io.read_at(pos, h, 10, actual); uint16_t track = (h[0] << 8) | h[1]; uint16_t head = (h[2] << 8) | h[3]; // Ignore sector @@ -97,7 +102,7 @@ bool dfi_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui data.resize(tsize); pos += 10; // skip the header, we already read it - io_generic_read(io, &data[0], pos, tsize); + io.read_at(pos, &data[0], tsize, actual); pos += tsize; // for next time we read, increment to the beginning of next header int index_time = 0; // what point the last index happened diff --git a/src/lib/formats/dfi_dsk.h b/src/lib/formats/dfi_dsk.h index d727f1d3c06..71b69c43d70 100644 --- a/src/lib/formats/dfi_dsk.h +++ b/src/lib/formats/dfi_dsk.h @@ -12,9 +12,9 @@ class dfi_format : public floppy_image_format_t public: dfi_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - // virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image); + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + // virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image); virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/dim_dsk.cpp b/src/lib/formats/dim_dsk.cpp index 964f19ce028..04f6e3b8995 100644 --- a/src/lib/formats/dim_dsk.cpp +++ b/src/lib/formats/dim_dsk.cpp @@ -8,12 +8,14 @@ *********************************************************************/ -#include <cstring> -#include <cassert> - #include "dim_dsk.h" #include "basicdsk.h" +#include "ioprocs.h" + +#include <cstring> + + FLOPPY_IDENTIFY(dim_dsk_identify) { uint8_t dim_header[16]; @@ -132,11 +134,12 @@ const char *dim_format::extensions() const return "dim"; } -int dim_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int dim_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { uint8_t h[16]; - io_generic_read(io, h, 0xab, 16); + size_t actual; + io.read_at(0xab, h, 16, actual); if(strncmp((const char *)h, "DIFC HEADER", 11) == 0) return 100; @@ -144,14 +147,15 @@ int dim_format::identify(io_generic *io, uint32_t form_factor, const std::vector return 0; } -bool dim_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool dim_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { + size_t actual; int offset = 0x100; uint8_t h; uint8_t track_total = 77; int cell_count = form_factor == floppy_image::FF_35 ? 200000 : 166666; - io_generic_read(io, &h, 0, 1); + io.read_at(0, &h, 1, actual); int spt, gap3, bps, size; switch(h) { @@ -211,7 +215,7 @@ bool dim_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui sects[i].deleted = false; sects[i].bad_crc = false; sects[i].data = §_data[sdatapos]; - io_generic_read(io, sects[i].data, offset, bps); + io.read_at(offset, sects[i].data, bps, actual); offset += bps; sdatapos += bps; } @@ -223,7 +227,7 @@ bool dim_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui } -bool dim_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool dim_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { return false; } diff --git a/src/lib/formats/dim_dsk.h b/src/lib/formats/dim_dsk.h index e0227e2e221..5c84f329cb6 100644 --- a/src/lib/formats/dim_dsk.h +++ b/src/lib/formats/dim_dsk.h @@ -25,9 +25,9 @@ class dim_format : public floppy_image_format_t public: dim_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/dip_dsk.cpp b/src/lib/formats/dip_dsk.cpp index a33d6fe35d6..17a7f856efe 100644 --- a/src/lib/formats/dip_dsk.cpp +++ b/src/lib/formats/dip_dsk.cpp @@ -14,10 +14,11 @@ *********************************************************************/ -#include <cassert> - #include "dip_dsk.h" +#include "ioprocs.h" + + dip_format::dip_format() { } @@ -37,9 +38,11 @@ const char *dip_format::extensions() const return "dip"; } -int dip_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int dip_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - uint64_t size = io_generic_size(io); + uint64_t size; + if (io.length(size)) + return 0; if (size == 0x134000 + 0x100) return 100; @@ -47,7 +50,7 @@ int dip_format::identify(io_generic *io, uint32_t form_factor, const std::vector return 0; } -bool dip_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool dip_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { int heads, tracks, spt, bps; @@ -69,7 +72,8 @@ bool dip_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui for (int track = 0; track < tracks; track++) for (int head = 0; head < heads; head++) { - io_generic_read(io, sect_data, 0x100 + bps * spt * (track * heads + head), bps * spt); + size_t actual; + io.read_at(0x100 + bps * spt * (track * heads + head), sect_data, bps * spt, actual); for (int i = 0; i < spt; i++) { diff --git a/src/lib/formats/dip_dsk.h b/src/lib/formats/dip_dsk.h index 255e4e6c8a1..e310ef3f655 100644 --- a/src/lib/formats/dip_dsk.h +++ b/src/lib/formats/dip_dsk.h @@ -20,8 +20,8 @@ class dip_format : public floppy_image_format_t public: dip_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/dmk_dsk.cpp b/src/lib/formats/dmk_dsk.cpp index 39c23223ec5..6a9e1dc0f0b 100644 --- a/src/lib/formats/dmk_dsk.cpp +++ b/src/lib/formats/dmk_dsk.cpp @@ -13,10 +13,10 @@ TODO: *********************************************************************/ -#include <cassert> - #include "dmk_dsk.h" +#include "ioprocs.h" + dmk_format::dmk_format() { @@ -41,14 +41,16 @@ const char *dmk_format::extensions() const } -int dmk_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int dmk_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { + uint64_t size; + if (io.length(size)) + return 0; + const int header_size = 16; uint8_t header[header_size]; - - uint64_t size = io_generic_size(io); - - io_generic_read(io, header, 0, header_size); + size_t actual; + io.read_at(0, header, header_size, actual); int tracks = header[1]; int track_size = ( header[3] << 8 ) | header[2]; @@ -81,12 +83,13 @@ int dmk_format::identify(io_generic *io, uint32_t form_factor, const std::vector } -bool dmk_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool dmk_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { + size_t actual; + const int header_size = 16; uint8_t header[header_size]; - - io_generic_read(io, header, 0, header_size); + io.read_at(0, header, header_size, actual); const int tracks = header[1]; const int track_size = ( header[3] << 8 ) | header[2]; @@ -128,7 +131,7 @@ bool dmk_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui int dam_location[64]; // Read track - io_generic_read(io, &track_data[0], header_size + ( heads * track + head ) * track_size, track_size); + io.read_at(header_size + (heads * track + head) * track_size, &track_data[0], track_size, actual); for (int i = 0; i < 64; i++) { @@ -213,7 +216,7 @@ bool dmk_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui } -bool dmk_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool dmk_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { return false; } diff --git a/src/lib/formats/dmk_dsk.h b/src/lib/formats/dmk_dsk.h index a2e7898dece..5485869b5b6 100644 --- a/src/lib/formats/dmk_dsk.h +++ b/src/lib/formats/dmk_dsk.h @@ -21,9 +21,9 @@ class dmk_format : public floppy_image_format_t public: dmk_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/ds9_dsk.cpp b/src/lib/formats/ds9_dsk.cpp index fdf4f5e2299..c97a2cced51 100644 --- a/src/lib/formats/ds9_dsk.cpp +++ b/src/lib/formats/ds9_dsk.cpp @@ -14,10 +14,10 @@ ************************************************************************/ -#include <cassert> - #include "formats/ds9_dsk.h" +#include "ioprocs.h" + static FLOPPY_IDENTIFY(ds9_dsk_identify) { @@ -97,33 +97,32 @@ const char *ds9_format::extensions() const return "ds9"; } -void ds9_format::find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count) +void ds9_format::find_size(util::random_read &io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count) { - uint32_t expected_size = 0; - uint64_t size = io_generic_size(io); - head_count = 2; track_count = 80; sector_count = 21; - expected_size = 256 * track_count * head_count * sector_count; + uint32_t const expected_size = 256 * track_count * head_count * sector_count; - if (size >= expected_size) // standard format has 860160 bytes + uint64_t size; + if (!io.length(size) && (size >= expected_size)) // standard format has 860160 bytes return; track_count = head_count = sector_count = 0; } -int ds9_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int ds9_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { uint8_t track_count, head_count, sector_count; find_size(io, track_count, head_count, sector_count); - if (track_count) return 50; + if (track_count) + return 50; return 0; } -bool ds9_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool ds9_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { uint8_t track_count, head_count, sector_count; find_size(io, track_count, head_count, sector_count); @@ -143,7 +142,8 @@ bool ds9_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui { for (int head = 0; head < head_count; head++) { - io_generic_read(io, sectdata, (track * head_count + head) * track_size, track_size); + size_t actual; + io.read_at((track * head_count + head) * track_size, sectdata, track_size, actual); generate_track(ds9_desc, track, head, sectors, sector_count, 104000, image); } } diff --git a/src/lib/formats/ds9_dsk.h b/src/lib/formats/ds9_dsk.h index 317134eab87..abdf152b2b3 100644 --- a/src/lib/formats/ds9_dsk.h +++ b/src/lib/formats/ds9_dsk.h @@ -5,9 +5,10 @@ formats/ds9_dsk.h *********************************************************************/ +#ifndef MAME_FORMATS_DS9_DSK_H +#define MAME_FORMATS_DS9_DSK_H -#ifndef DS9_DSK_H_ -#define DS9_DSK_H_ +#pragma once #include "flopimg.h" #include "formats/basicdsk.h" @@ -19,8 +20,8 @@ class ds9_format : public floppy_image_format_t public: ds9_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; @@ -30,9 +31,9 @@ public: static const desc_e ds9_desc[]; private: - void find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count); + void find_size(util::random_read &io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count); }; extern const floppy_format_type FLOPPY_DS9_FORMAT; -#endif /* DS9_DSK_H_ */ +#endif // MAME_FORMATS_DS9_DSK_H diff --git a/src/lib/formats/dsk_dsk.cpp b/src/lib/formats/dsk_dsk.cpp index dba11347887..fcf967edcb1 100644 --- a/src/lib/formats/dsk_dsk.cpp +++ b/src/lib/formats/dsk_dsk.cpp @@ -8,11 +8,12 @@ *********************************************************************/ -#include <cstring> -#include <cassert> - +#include "dsk_dsk.h" #include "imageutl.h" -#include "flopimg.h" + +#include "ioprocs.h" + +#include <cstring> #define MV_CPC "MV - CPC" #define EXTENDED "EXTENDED" @@ -270,7 +271,8 @@ FLOPPY_CONSTRUCT( dsk_dsk_construct ) return FLOPPY_ERROR_SUCCESS; } -#include "dsk_dsk.h" + + #define DSK_FORMAT_HEADER "MV - CPC" #define EXT_FORMAT_HEADER "EXTENDED CPC DSK" @@ -299,11 +301,12 @@ bool dsk_format::supports_save() const return false; } -int dsk_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int dsk_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { uint8_t header[16]; - io_generic_read(io, &header, 0, sizeof(header)); + size_t actual; + io.read_at(0, &header, sizeof(header), actual); if ( memcmp( header, DSK_FORMAT_HEADER, 8 ) ==0) { return 100; } @@ -344,14 +347,18 @@ struct sector_header #pragma pack() -bool dsk_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool dsk_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { + size_t actual; + uint8_t header[0x100]; bool extendformat = false; - uint64_t image_size = io_generic_size(io); + uint64_t image_size; + if (io.length(image_size)) + return false; - io_generic_read(io, &header, 0, sizeof(header)); + io.read_at(0, &header, sizeof(header), actual); if ( memcmp( header, EXT_FORMAT_HEADER, 16 ) ==0) { extendformat = true; } @@ -418,7 +425,7 @@ bool dsk_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui if(track_offsets[(track<<1)+side] >= image_size) continue; track_header tr; - io_generic_read(io, &tr,track_offsets[(track<<1)+side],sizeof(tr)); + io.read_at(track_offsets[(track<<1)+side], &tr, sizeof(tr), actual); // skip if there are no sectors in this track if (tr.number_of_sector == 0) @@ -428,7 +435,7 @@ bool dsk_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui int first_sector_code = -1; for(int j=0;j<tr.number_of_sector;j++) { sector_header sector; - io_generic_read(io, §or,track_offsets[(track<<1)+side]+sizeof(tr)+(sizeof(sector)*j),sizeof(sector)); + io.read_at(track_offsets[(track<<1)+side]+sizeof(tr)+(sizeof(sector)*j), §or, sizeof(sector), actual); if (j == 0) first_sector_code = sector.sector_size_code; @@ -447,7 +454,7 @@ bool dsk_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui for(int j=0;j<tr.number_of_sector;j++) { sector_header sector; - io_generic_read(io, §or,track_offsets[(track<<1)+side]+sizeof(tr)+(sizeof(sector)*j),sizeof(sector)); + io.read_at(track_offsets[(track<<1)+side]+sizeof(tr)+(sizeof(sector)*j), §or, sizeof(sector), actual); sects[j].track = sector.track; sects[j].head = sector.side; @@ -470,7 +477,7 @@ bool dsk_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui if(!(sector.fdc_status_reg1 & 0x04)) { sects[j].data = sect_data + sdatapos; - io_generic_read(io, sects[j].data, pos, sects[j].actual_size); + io.read_at(pos, sects[j].data, sects[j].actual_size, actual); sdatapos += sects[j].actual_size; } else diff --git a/src/lib/formats/dsk_dsk.h b/src/lib/formats/dsk_dsk.h index a08e3955888..7d6b3bc43dc 100644 --- a/src/lib/formats/dsk_dsk.h +++ b/src/lib/formats/dsk_dsk.h @@ -19,8 +19,8 @@ class dsk_format : public floppy_image_format_t public: dsk_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/dvk_mx_dsk.cpp b/src/lib/formats/dvk_mx_dsk.cpp index 07d7a38cf95..08156d29e9c 100644 --- a/src/lib/formats/dvk_mx_dsk.cpp +++ b/src/lib/formats/dvk_mx_dsk.cpp @@ -18,11 +18,11 @@ ************************************************************************/ -#include <cassert> - -#include "flopimg.h" #include "formats/dvk_mx_dsk.h" +#include "ioprocs.h" + + const floppy_image_format_t::desc_e dvk_mx_format::dvk_mx_new_desc[] = { /* 01 */ { FM, 0x00, 8*2 }, // eight 0x0000 words /* 03 */ { FM, 0x00, 1 }, @@ -81,9 +81,14 @@ bool dvk_mx_format::supports_save() const return false; } -void dvk_mx_format::find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count) +void dvk_mx_format::find_size(util::random_read &io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count) { - uint64_t size = io_generic_size(io); + uint64_t size; + if (io.length(size)) + { + track_count = head_count = sector_count = 0; + return; + } switch (size) { @@ -108,7 +113,7 @@ void dvk_mx_format::find_size(io_generic *io, uint8_t &track_count, uint8_t &hea } } -int dvk_mx_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int dvk_mx_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { uint8_t track_count, head_count, sector_count; @@ -117,7 +122,8 @@ int dvk_mx_format::identify(io_generic *io, uint32_t form_factor, const std::vec if (track_count) { uint8_t sectdata[512]; - io_generic_read(io, sectdata, 512, 512); + size_t actual; + io.read_at(512, sectdata, 512, actual); // check value in RT-11 home block. see src/tools/imgtool/modules/rt11.cpp if (pick_integer_le(sectdata, 0724, 2) == 6) return 100; @@ -129,7 +135,7 @@ int dvk_mx_format::identify(io_generic *io, uint32_t form_factor, const std::vec return 0; } -bool dvk_mx_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool dvk_mx_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { uint8_t track_count, head_count, sector_count; @@ -150,7 +156,8 @@ bool dvk_mx_format::load(io_generic *io, uint32_t form_factor, const std::vector { for (int head = 0; head < head_count; head++) { - io_generic_read(io, sectdata, (track * head_count + head) * track_size, track_size); + size_t actual; + io.read_at((track * head_count + head) * track_size, sectdata, track_size, actual); generate_track(dvk_mx_new_desc, track, head, sectors, sector_count, 45824, image); } } diff --git a/src/lib/formats/dvk_mx_dsk.h b/src/lib/formats/dvk_mx_dsk.h index 38fd895d154..e20066fc3ec 100644 --- a/src/lib/formats/dvk_mx_dsk.h +++ b/src/lib/formats/dvk_mx_dsk.h @@ -5,9 +5,8 @@ formats/dvk_mx_dsk.h *********************************************************************/ - -#ifndef DVK_MX_DSK_H_ -#define DVK_MX_DSK_H_ +#ifndef MAME_FORMATS_DVK_MX_DSK_H +#define MAME_FORMATS_DVK_MX_DSK_H #pragma once @@ -19,8 +18,8 @@ class dvk_mx_format : public floppy_image_format_t public: dvk_mx_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; @@ -31,9 +30,9 @@ public: static const desc_e dvk_mx_new_desc[]; private: - void find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count); + void find_size(util::random_read &io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count); }; extern const floppy_format_type FLOPPY_DVK_MX_FORMAT; -#endif /* DVK_MX_DSK_H_ */ +#endif // MAME_FORMATS_DVK_MX_DSK_H diff --git a/src/lib/formats/esq16_dsk.cpp b/src/lib/formats/esq16_dsk.cpp index 10802d26495..b33e529fef2 100644 --- a/src/lib/formats/esq16_dsk.cpp +++ b/src/lib/formats/esq16_dsk.cpp @@ -10,10 +10,10 @@ *********************************************************************/ -#include <cassert> +#include "esq16_dsk.h" + +#include "ioprocs.h" -#include "flopimg.h" -#include "formats/esq16_dsk.h" const floppy_image_format_t::desc_e esqimg_format::esq_10_desc[] = { { MFM, 0x4e, 80 }, @@ -71,23 +71,23 @@ bool esqimg_format::supports_save() const return true; } -void esqimg_format::find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count) +void esqimg_format::find_size(util::random_read &io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count) { - uint64_t size = io_generic_size(io); - track_count = 80; - head_count = 2; - sector_count = 10; - - uint32_t expected_size = 512 * track_count*head_count*sector_count; - if (size == expected_size) - { - return; - } + uint64_t size; + if(!io.length(size)) { + track_count = 80; + head_count = 2; + sector_count = 10; + uint32_t expected_size = 512 * track_count*head_count*sector_count; + if(size == expected_size) { + return; + } + } track_count = head_count = sector_count = 0; } -int esqimg_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int esqimg_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { uint8_t track_count, head_count, sector_count; find_size(io, track_count, head_count, sector_count); @@ -97,7 +97,7 @@ int esqimg_format::identify(io_generic *io, uint32_t form_factor, const std::vec return 0; } -bool esqimg_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool esqimg_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { uint8_t track_count, head_count, sector_count; find_size(io, track_count, head_count, sector_count); @@ -113,7 +113,8 @@ bool esqimg_format::load(io_generic *io, uint32_t form_factor, const std::vector int track_size = sector_count*512; for(int track=0; track < track_count; track++) { for(int head=0; head < head_count; head++) { - io_generic_read(io, sectdata, (track*head_count + head)*track_size, track_size); + size_t actual; + io.read_at((track*head_count + head)*track_size, sectdata, track_size, actual); generate_track(esq_10_desc, track, head, sectors, sector_count, 110528, image); } } @@ -123,7 +124,7 @@ bool esqimg_format::load(io_generic *io, uint32_t form_factor, const std::vector return true; } -bool esqimg_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool esqimg_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { int track_count, head_count, sector_count; get_geometry_mfm_pc(image, 2000, track_count, head_count, sector_count); @@ -144,7 +145,8 @@ bool esqimg_format::save(io_generic *io, const std::vector<uint32_t> &variants, for(int track=0; track < track_count; track++) { for(int head=0; head < head_count; head++) { get_track_data_mfm_pc(track, head, image, 2000, 512, sector_count, sectdata); - io_generic_write(io, sectdata, (track*head_count + head)*track_size, track_size); + size_t actual; + io.write_at((track*head_count + head)*track_size, sectdata, track_size, actual); } } diff --git a/src/lib/formats/esq16_dsk.h b/src/lib/formats/esq16_dsk.h index 8cc49150d2c..2347d64f59c 100644 --- a/src/lib/formats/esq16_dsk.h +++ b/src/lib/formats/esq16_dsk.h @@ -21,9 +21,9 @@ class esqimg_format : public floppy_image_format_t public: esqimg_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; @@ -33,7 +33,7 @@ public: static const desc_e esq_10_desc[]; private: - void find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count); + void find_size(util::random_read &io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count); }; extern const floppy_format_type FLOPPY_ESQIMG_FORMAT; diff --git a/src/lib/formats/esq8_dsk.cpp b/src/lib/formats/esq8_dsk.cpp index f9dcb3d0727..952dd16edbd 100644 --- a/src/lib/formats/esq8_dsk.cpp +++ b/src/lib/formats/esq8_dsk.cpp @@ -12,10 +12,10 @@ *********************************************************************/ -#include <cassert> +#include "esq8_dsk.h" + +#include "ioprocs.h" -#include "flopimg.h" -#include "formats/esq8_dsk.h" const floppy_image_format_t::desc_e esq8img_format::esq_6_desc[] = { { MFM, 0x4e, 80 }, @@ -73,22 +73,24 @@ bool esq8img_format::supports_save() const return true; } -void esq8img_format::find_size(io_generic *io, int &track_count, int &head_count, int §or_count) +void esq8img_format::find_size(util::random_read &io, int &track_count, int &head_count, int §or_count) { - uint64_t size = io_generic_size(io); - track_count = 80; - head_count = 1; - sector_count = 6; - - if(size == 5632 * 80) + uint64_t size; + if(!io.length(size)) { - return; - } + track_count = 80; + head_count = 1; + sector_count = 6; + if(size == 5632 * 80) + { + return; + } + } track_count = head_count = sector_count = 0; } -int esq8img_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int esq8img_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { int track_count, head_count, sector_count; find_size(io, track_count, head_count, sector_count); @@ -99,7 +101,7 @@ int esq8img_format::identify(io_generic *io, uint32_t form_factor, const std::ve return 0; } -bool esq8img_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool esq8img_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { int track_count, head_count, sector_count; find_size(io, track_count, head_count, sector_count); @@ -128,7 +130,8 @@ bool esq8img_format::load(io_generic *io, uint32_t form_factor, const std::vecto { for(int head=0; head < head_count; head++) { - io_generic_read(io, sectdata, (track*head_count + head)*track_size, track_size); + size_t actual; + io.read_at((track*head_count + head)*track_size, sectdata, track_size, actual); generate_track(esq_6_desc, track, head, sectors, sector_count, 109376, image); } } @@ -138,7 +141,7 @@ bool esq8img_format::load(io_generic *io, uint32_t form_factor, const std::vecto return true; } -bool esq8img_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool esq8img_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { uint64_t file_offset = 0; int track_count, head_count, sector_count; @@ -175,7 +178,8 @@ bool esq8img_format::save(io_generic *io, const std::vector<uint32_t> &variants, return false; } - io_generic_write(io, sectors[sector].data(), file_offset, sector_expected_size); + size_t actual; + io.write_at(file_offset, sectors[sector].data(), sector_expected_size, actual); file_offset += sector_expected_size; } } diff --git a/src/lib/formats/esq8_dsk.h b/src/lib/formats/esq8_dsk.h index c4fe5a74f1b..aa09fd278a7 100644 --- a/src/lib/formats/esq8_dsk.h +++ b/src/lib/formats/esq8_dsk.h @@ -23,9 +23,9 @@ class esq8img_format : public floppy_image_format_t public: esq8img_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; @@ -35,7 +35,7 @@ public: static const desc_e esq_6_desc[]; private: - void find_size(io_generic *io, int &track_count, int &head_count, int §or_count); + void find_size(util::random_read &io, int &track_count, int &head_count, int §or_count); }; extern const floppy_format_type FLOPPY_ESQ8IMG_FORMAT; diff --git a/src/lib/formats/fdd_dsk.cpp b/src/lib/formats/fdd_dsk.cpp index df5fd3caa8c..8c8249c9452 100644 --- a/src/lib/formats/fdd_dsk.cpp +++ b/src/lib/formats/fdd_dsk.cpp @@ -31,10 +31,11 @@ *********************************************************************/ -#include <cassert> - #include "fdd_dsk.h" +#include "ioprocs.h" + + fdd_format::fdd_format() { } @@ -54,10 +55,11 @@ const char *fdd_format::extensions() const return "fdd"; } -int fdd_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int fdd_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { uint8_t h[7]; - io_generic_read(io, h, 0, 7); + size_t actual; + io.read_at(0, h, 7, actual); if (strncmp((const char *)h, "VFD1.0", 6) == 0) return 100; @@ -65,7 +67,7 @@ int fdd_format::identify(io_generic *io, uint32_t form_factor, const std::vector return 0; } -bool fdd_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool fdd_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { uint8_t hsec[0x0c]; @@ -86,7 +88,8 @@ bool fdd_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui for (int sect = 0; sect < 26; sect++) { // read sector map for this sector - io_generic_read(io, hsec, pos, 0x0c); + size_t actual; + io.read_at(pos, hsec, 0x0c, actual); pos += 0x0c; if (hsec[0] == 0xff) // unformatted/unused sector @@ -118,10 +121,11 @@ bool fdd_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui cur_sec_map = track * 26 + i; sector_size = 128 << sec_sizes[cur_sec_map]; + size_t actual; if (sec_offs[cur_sec_map] == 0xffffffff) memset(sect_data + cur_pos, fill_vals[cur_sec_map], sector_size); else - io_generic_read(io, sect_data + cur_pos, sec_offs[cur_sec_map], sector_size); + io.read_at(sec_offs[cur_sec_map], sect_data + cur_pos, sector_size, actual); sects[i].track = tracks[cur_sec_map]; sects[i].head = heads[cur_sec_map]; diff --git a/src/lib/formats/fdd_dsk.h b/src/lib/formats/fdd_dsk.h index ec013c58571..c1a3ae8a29b 100644 --- a/src/lib/formats/fdd_dsk.h +++ b/src/lib/formats/fdd_dsk.h @@ -20,8 +20,8 @@ class fdd_format : public floppy_image_format_t public: fdd_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/flex_dsk.cpp b/src/lib/formats/flex_dsk.cpp index 692cc4bdc9d..4989a25e707 100644 --- a/src/lib/formats/flex_dsk.cpp +++ b/src/lib/formats/flex_dsk.cpp @@ -50,7 +50,11 @@ */ #include "flex_dsk.h" -#include "formats/imageutl.h" + +#include "imageutl.h" + +#include "ioprocs.h" + flex_format::flex_format() : wd177x_format(formats) { @@ -71,7 +75,7 @@ const char *flex_format::extensions() const return "dsk"; } -int flex_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int flex_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { int type = find_size(io, form_factor, variants); @@ -80,17 +84,21 @@ int flex_format::identify(io_generic *io, uint32_t form_factor, const std::vecto return 0; } -int flex_format::find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int flex_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - uint64_t size = io_generic_size(io); + uint64_t size; + if (io.length(size)) + return -1; + uint8_t boot0[256], boot1[256]; + size_t actual; // Look at the boot sector. // Density, sides, link?? - io_generic_read(io, &boot0, 256 * 0, sizeof(boot0)); - io_generic_read(io, &boot1, 256 * 1, sizeof(boot1)); + io.read_at(256 * 0, &boot0, sizeof(boot0), actual); + io.read_at(256 * 1, &boot1, sizeof(boot1), actual); // Look at the system information sector. - io_generic_read(io, &info, 256 * 2, sizeof(struct sysinfo_sector)); + io.read_at(256 * 2, &info, sizeof(struct sysinfo_sector), actual); LOG_FORMATS("FLEX floppy dsk: size %d bytes, %d total sectors, %d remaining bytes, expected form factor %x\n", (uint32_t)size, (uint32_t)size / 256, (uint32_t)size % 256, form_factor); diff --git a/src/lib/formats/flex_dsk.h b/src/lib/formats/flex_dsk.h index 094c6854b24..0048e4e088f 100644 --- a/src/lib/formats/flex_dsk.h +++ b/src/lib/formats/flex_dsk.h @@ -21,8 +21,8 @@ public: virtual const char *name() const override; virtual const char *description() const override; virtual const char *extensions() const override; - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual int find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual int find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; virtual const wd177x_format::format &get_track_format(const format &f, int head, int track) override; private: diff --git a/src/lib/formats/flopimg.cpp b/src/lib/formats/flopimg.cpp index 48c2fa1b610..55d00d1bb83 100644 --- a/src/lib/formats/flopimg.cpp +++ b/src/lib/formats/flopimg.cpp @@ -11,9 +11,10 @@ #include "flopimg.h" #include "imageutl.h" -#include "osdcore.h" #include "ioprocs.h" +#include "osdcore.h" + #include <cassert> #include <cctype> #include <climits> @@ -30,7 +31,7 @@ using util::BIT; struct floppy_image_legacy { - struct io_generic io = { 0 }; + util::random_read_write::ptr io = nullptr; const struct FloppyFormat *floppy_option = nullptr; struct FloppyCallbacks format = { 0 }; @@ -69,22 +70,20 @@ OPTION_GUIDE_START(floppy_option_guide) OPTION_GUIDE_END -static void floppy_close_internal(floppy_image_legacy *floppy, bool close_file); +static void floppy_close_internal(floppy_image_legacy *floppy); /********************************************************************* opening, closing and creating of floppy images *********************************************************************/ /* basic floppy_image_legacy initialization common to floppy_open() and floppy_create() */ -static floppy_image_legacy *floppy_init(void *fp, const struct io_procs *procs, int flags) +static floppy_image_legacy *floppy_init(util::random_read_write::ptr &&io, int flags) { floppy_image_legacy *floppy; floppy = new floppy_image_legacy; - floppy->io.file = fp; - floppy->io.procs = procs; - floppy->io.filler = 0xFF; + floppy->io = std::move(io); floppy->flags = (uint8_t) flags; return floppy; } @@ -93,7 +92,7 @@ static floppy_image_legacy *floppy_init(void *fp, const struct io_procs *procs, /* main code for identifying and maybe opening a disk image; not exposed * directly because this function is big and hideous */ -static floperr_t floppy_open_internal(void *fp, const struct io_procs *procs, const std::string &extension, +static floperr_t floppy_open_internal(util::random_read_write::ptr &&io, const std::string &extension, const struct FloppyFormat *floppy_options, int max_options, int flags, floppy_image_legacy **outfloppy, int *outoption) { @@ -104,7 +103,7 @@ static floperr_t floppy_open_internal(void *fp, const struct io_procs *procs, co int vote; size_t i; - floppy = floppy_init(fp, procs, flags); + floppy = floppy_init(std::move(io), flags); if (!floppy) { err = FLOPPY_ERROR_OUTOFMEMORY; @@ -163,7 +162,7 @@ done: /* if we have a floppy disk and we either errored or are not keeping it, close it */ if (floppy && (!outfloppy || err)) { - floppy_close_internal(floppy, false); + floppy_close_internal(floppy); floppy = nullptr; } @@ -176,31 +175,31 @@ done: -floperr_t floppy_identify(void *fp, const struct io_procs *procs, const char *extension, +floperr_t floppy_identify(util::random_read_write::ptr &&io, const char *extension, const struct FloppyFormat *formats, int *identified_format) { - return floppy_open_internal(fp, procs, extension, formats, INT_MAX, FLOPPY_FLAGS_READONLY, nullptr, identified_format); + return floppy_open_internal(std::move(io), extension, formats, INT_MAX, FLOPPY_FLAGS_READONLY, nullptr, identified_format); } -floperr_t floppy_open(void *fp, const struct io_procs *procs, const std::string &extension, +floperr_t floppy_open(util::random_read_write::ptr &&io, const std::string &extension, const struct FloppyFormat *format, int flags, floppy_image_legacy **outfloppy) { - return floppy_open_internal(fp, procs, extension, format, 1, flags, outfloppy, nullptr); + return floppy_open_internal(std::move(io), extension, format, 1, flags, outfloppy, nullptr); } -floperr_t floppy_open_choices(void *fp, const struct io_procs *procs, const std::string &extension, +floperr_t floppy_open_choices(util::random_read_write::ptr &&io, const std::string &extension, const struct FloppyFormat *formats, int flags, floppy_image_legacy **outfloppy) { - return floppy_open_internal(fp, procs, extension, formats, INT_MAX, flags, outfloppy, nullptr); + return floppy_open_internal(std::move(io), extension, formats, INT_MAX, flags, outfloppy, nullptr); } -floperr_t floppy_create(void *fp, const struct io_procs *procs, const struct FloppyFormat *format, util::option_resolution *parameters, floppy_image_legacy **outfloppy) +floperr_t floppy_create(util::random_read_write::ptr &&io, const struct FloppyFormat *format, util::option_resolution *parameters, floppy_image_legacy **outfloppy) { floppy_image_legacy *floppy = nullptr; floperr_t err; @@ -210,7 +209,7 @@ floperr_t floppy_create(void *fp, const struct io_procs *procs, const struct Flo assert(format); /* create the new image */ - floppy = floppy_init(fp, procs, 0); + floppy = floppy_init(std::move(io), 0); if (!floppy) { err = FLOPPY_ERROR_OUTOFMEMORY; @@ -266,28 +265,26 @@ floperr_t floppy_create(void *fp, const struct io_procs *procs, const struct Flo done: if (err && floppy) { - floppy_close_internal(floppy, false); + floppy_close_internal(floppy); floppy = nullptr; } if (outfloppy) *outfloppy = floppy; else if (floppy) - floppy_close_internal(floppy, false); + floppy_close_internal(floppy); return err; } -static void floppy_close_internal(floppy_image_legacy *floppy, bool close_file) +static void floppy_close_internal(floppy_image_legacy *floppy) { if (floppy) { floppy_track_unload(floppy); if(floppy->floppy_option && floppy->floppy_option->destruct) floppy->floppy_option->destruct(floppy, floppy->floppy_option); - if (close_file) - io_generic_close(&floppy->io); delete floppy; } @@ -297,7 +294,7 @@ static void floppy_close_internal(floppy_image_legacy *floppy, bool close_file) void floppy_close(floppy_image_legacy *floppy) { - floppy_close_internal(floppy, true); + floppy_close_internal(floppy); } @@ -332,14 +329,16 @@ void *floppy_create_tag(floppy_image_legacy *floppy, size_t tagsize) uint8_t floppy_get_filler(floppy_image_legacy *floppy) { - return floppy->io.filler; + // FIXME: remove this function, it's here for legacy reasons + // the caller actually sets the filler byte - in practice it's always 0xff but there's no actual guarantee + return 0xff; } -void floppy_set_filler(floppy_image_legacy *floppy, uint8_t filler) +util::random_read_write &floppy_get_io(floppy_image_legacy *floppy) { - floppy->io.filler = filler; + return *floppy->io; } @@ -350,28 +349,42 @@ void floppy_set_filler(floppy_image_legacy *floppy, uint8_t filler) void floppy_image_read(floppy_image_legacy *floppy, void *buffer, uint64_t offset, size_t length) { - io_generic_read(&floppy->io, buffer, offset, length); + size_t actual; + floppy->io->read_at(offset, buffer, length, actual); } void floppy_image_write(floppy_image_legacy *floppy, const void *buffer, uint64_t offset, size_t length) { - io_generic_write(&floppy->io, buffer, offset, length); + size_t actual; + floppy->io->write_at(offset, buffer, length, actual); } void floppy_image_write_filler(floppy_image_legacy *floppy, uint8_t filler, uint64_t offset, size_t length) { - io_generic_write_filler(&floppy->io, filler, offset, length); + uint8_t buffer[512]; + memset(buffer, filler, std::min(sizeof(buffer), length)); + + while (length) + { + size_t const block = std::min(sizeof(buffer), length); + size_t actual; + floppy->io->write_at(offset, buffer, block, actual); + offset += block; + length -= block; + } } uint64_t floppy_image_size(floppy_image_legacy *floppy) { - return io_generic_size(&floppy->io); + uint64_t result; + floppy->io->length(result); + return result; } @@ -976,7 +989,7 @@ bool floppy_image_format_t::has_variant(const std::vector<uint32_t> &variants, u return false; } -bool floppy_image_format_t::save(io_generic *, const std::vector<uint32_t> &, floppy_image *) +bool floppy_image_format_t::save(util::random_read_write &io, const std::vector<uint32_t> &, floppy_image *) { return false; } diff --git a/src/lib/formats/flopimg.h b/src/lib/formats/flopimg.h index 101d9bd86bd..6279def82f8 100644 --- a/src/lib/formats/flopimg.h +++ b/src/lib/formats/flopimg.h @@ -12,11 +12,13 @@ #pragma once -#include "osdcore.h" -#include "ioprocs.h" -#include "opresolv.h" #include "coretmpl.h" +#include "opresolv.h" +#include "utilfwd.h" + +#include "osdcore.h" +#include <memory> #include <vector> #ifndef LOG_FORMATS @@ -166,20 +168,20 @@ LEGACY_FLOPPY_OPTIONS_EXTERN(default); OPTION_GUIDE_EXTERN(floppy_option_guide); /* opening, closing and creating of floppy images */ -floperr_t floppy_open(void *fp, const struct io_procs *procs, const std::string &extension, const struct FloppyFormat *format, int flags, floppy_image_legacy **outfloppy); -floperr_t floppy_open_choices(void *fp, const struct io_procs *procs, const std::string &extension, const struct FloppyFormat *formats, int flags, floppy_image_legacy **outfloppy); -floperr_t floppy_create(void *fp, const struct io_procs *procs, const struct FloppyFormat *format, util::option_resolution *parameters, floppy_image_legacy **outfloppy); +floperr_t floppy_open(std::unique_ptr<util::random_read_write> &&io, const std::string &extension, const struct FloppyFormat *format, int flags, floppy_image_legacy **outfloppy); +floperr_t floppy_open_choices(std::unique_ptr<util::random_read_write> &&io, const std::string &extension, const struct FloppyFormat *formats, int flags, floppy_image_legacy **outfloppy); +floperr_t floppy_create(std::unique_ptr<util::random_read_write> &&io, const struct FloppyFormat *format, util::option_resolution *parameters, floppy_image_legacy **outfloppy); void floppy_close(floppy_image_legacy *floppy); /* useful for identifying a floppy image */ -floperr_t floppy_identify(void *fp, const struct io_procs *procs, const char *extension, const struct FloppyFormat *formats, int *identified_format); +floperr_t floppy_identify(std::unique_ptr<util::random_read_write> &&io, const char *extension, const struct FloppyFormat *formats, int *identified_format); /* functions useful within format constructors */ void *floppy_tag(floppy_image_legacy *floppy); void *floppy_create_tag(floppy_image_legacy *floppy, size_t tagsize); struct FloppyCallbacks *floppy_callbacks(floppy_image_legacy *floppy); uint8_t floppy_get_filler(floppy_image_legacy *floppy); -void floppy_set_filler(floppy_image_legacy *floppy, uint8_t filler); +util::random_read_write &floppy_get_io(floppy_image_legacy *floppy); /* calls for accessing disk image data */ floperr_t floppy_read_sector(floppy_image_legacy *floppy, int head, int track, int sector, int offset, void *buffer, size_t buffer_len); @@ -235,7 +237,7 @@ public: @param variants the variants from floppy_image the drive can handle @return 1 if image valid, 0 otherwise. */ - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) = 0; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) = 0; /*! @brief Load an image. The load function opens an image file and converts it to the @@ -247,7 +249,7 @@ public: @param image output buffer for data in MESS internal format. @return true on success, false otherwise. */ - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) = 0; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) = 0; /*! @brief Save an image. The save function writes back an image from the MESS internal @@ -257,7 +259,7 @@ public: @param image source buffer containing data in MESS internal format. @return true on success, false otherwise. */ - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image); + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image); //! @returns string containing name of format. virtual const char *name() const = 0; diff --git a/src/lib/formats/fsd_dsk.cpp b/src/lib/formats/fsd_dsk.cpp index c5ebd243875..ffb23035420 100644 --- a/src/lib/formats/fsd_dsk.cpp +++ b/src/lib/formats/fsd_dsk.cpp @@ -10,6 +10,8 @@ #include "fsd_dsk.h" +#include "ioprocs.h" + /********************************************************************* @@ -83,11 +85,12 @@ bool fsd_format::supports_save() const return false; } -int fsd_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int fsd_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { uint8_t h[3]; - io_generic_read(io, h, 0, 3); + size_t actual; + io.read_at(0, h, 3, actual); if (memcmp(h, "FSD", 3) == 0) { return 100; } @@ -95,16 +98,19 @@ int fsd_format::identify(io_generic *io, uint32_t form_factor, const std::vector return 0; } -bool fsd_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool fsd_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { const char* result[255]; result[0x00] = "OK"; result[0x0e] = "Data CRC Error"; result[0x20] = "Deleted Data"; - uint64_t size = io_generic_size(io); + uint64_t size; + if(io.length(size)) + return false; std::vector<uint8_t> img(size); - io_generic_read(io, &img[0], 0, size); + size_t actual; + io.read_at(0, &img[0], size, actual); uint64_t pos; std::string title; diff --git a/src/lib/formats/fsd_dsk.h b/src/lib/formats/fsd_dsk.h index ee2c4aa466c..779ee28ec02 100644 --- a/src/lib/formats/fsd_dsk.h +++ b/src/lib/formats/fsd_dsk.h @@ -33,8 +33,8 @@ public: virtual const char *extensions() const override; virtual bool supports_save() const override; - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; }; extern const floppy_format_type FLOPPY_FSD_FORMAT; diff --git a/src/lib/formats/g64_dsk.cpp b/src/lib/formats/g64_dsk.cpp index 02098db88e0..8e6b9c75e44 100644 --- a/src/lib/formats/g64_dsk.cpp +++ b/src/lib/formats/g64_dsk.cpp @@ -12,6 +12,8 @@ #include "formats/g64_dsk.h" +#include "ioprocs.h" + #define G64_FORMAT_HEADER "GCR-1541" @@ -27,22 +29,27 @@ const uint32_t g64_format::c1541_cell_size[] = 3250 // 16MHz/13/4 }; -int g64_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int g64_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { char h[8]; - io_generic_read(io, h, 0, 8); + size_t actual; + io.read_at(0, h, 8, actual); if (!memcmp(h, G64_FORMAT_HEADER, 8)) return 100; return 0; } -bool g64_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool g64_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { - uint64_t size = io_generic_size(io); + uint64_t size; + if (io.length(size)) + return false; + std::vector<uint8_t> img(size); - io_generic_read(io, &img[0], 0, size); + size_t actual; + io.read_at(0, &img[0], size, actual); if (img[POS_VERSION]) { @@ -109,15 +116,19 @@ int g64_format::generate_bitstream(int track, int head, int speed_zone, std::vec return ((actual_cell_size >= cell_size-10) && (actual_cell_size <= cell_size+10)) ? speed_zone : -1; } -bool g64_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool g64_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { + uint8_t const zerofill[] = { 0x00, 0x00, 0x00, 0x00 }; + std::vector<uint8_t> const prefill(TRACK_LENGTH, 0xff); + size_t actual; + int tracks, heads; image->get_actual_geometry(tracks, heads); tracks = TRACK_COUNT * heads; // write header uint8_t header[] = { 'G', 'C', 'R', '-', '1', '5', '4', '1', 0x00, static_cast<uint8_t>(tracks), TRACK_LENGTH & 0xff, TRACK_LENGTH >> 8 }; - io_generic_write(io, header, POS_SIGNATURE, sizeof(header)); + io.write_at(POS_SIGNATURE, header, sizeof(header), actual); // write tracks for (int head = 0; head < heads; head++) { @@ -126,12 +137,12 @@ bool g64_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo std::vector<bool> trackbuf; for (int track = 0; track < TRACK_COUNT; track++) { - uint32_t tpos = POS_TRACK_OFFSET + (track * 4); - uint32_t spos = tpos + (tracks * 4); - uint32_t dpos = POS_TRACK_OFFSET + (tracks * 4 * 2) + (tracks_written * TRACK_LENGTH); + uint32_t const tpos = POS_TRACK_OFFSET + (track * 4); + uint32_t const spos = tpos + (tracks * 4); + uint32_t const dpos = POS_TRACK_OFFSET + (tracks * 4 * 2) + (tracks_written * TRACK_LENGTH); - io_generic_write_filler(io, 0x00, tpos, 4); - io_generic_write_filler(io, 0x00, spos, 4); + io.write_at(tpos, zerofill, 4, actual); + io.write_at(spos, zerofill, 4, actual); if (image->get_buffer(track, head).size() <= 1) continue; @@ -163,11 +174,11 @@ bool g64_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo place_integer_le(speed_offset, 0, 4, speed_zone); place_integer_le(track_length, 0, 2, packed.size()); - io_generic_write(io, track_offset, tpos, 4); - io_generic_write(io, speed_offset, spos, 4); - io_generic_write_filler(io, 0xff, dpos, TRACK_LENGTH); - io_generic_write(io, track_length, dpos, 2); - io_generic_write(io, packed.data(), dpos + 2, packed.size()); + io.write_at(tpos, track_offset, 4, actual); + io.write_at(spos, speed_offset, 4, actual); + io.write_at(dpos, prefill.data(), TRACK_LENGTH, actual); + io.write_at(dpos, track_length, 2, actual); + io.write_at(dpos + 2, packed.data(), packed.size(), actual); tracks_written++; } diff --git a/src/lib/formats/g64_dsk.h b/src/lib/formats/g64_dsk.h index 6691146c70e..fcd48d96796 100644 --- a/src/lib/formats/g64_dsk.h +++ b/src/lib/formats/g64_dsk.h @@ -20,9 +20,9 @@ class g64_format : public floppy_image_format_t public: g64_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/hpi_dsk.cpp b/src/lib/formats/hpi_dsk.cpp index d9fc788fd45..bdccc66803d 100644 --- a/src/lib/formats/hpi_dsk.cpp +++ b/src/lib/formats/hpi_dsk.cpp @@ -48,6 +48,7 @@ #include "hpi_dsk.h" #include "coretmpl.h" // BIT +#include "ioprocs.h" // Debugging @@ -78,9 +79,12 @@ hpi_format::hpi_format() (void)HPI_RED_IMAGE_SIZE; } -int hpi_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int hpi_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - uint64_t size = io_generic_size(io); + uint64_t size; + if (io.length(size)) { + return 0; + } // we try to stay back and give only 50 points, since another image // format may also have images of the same size (there is no header and no @@ -142,12 +146,15 @@ bool hpi_format::geometry_from_size(uint64_t image_size , unsigned& heads , unsi } } -bool hpi_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool hpi_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { unsigned heads; unsigned cylinders; - uint64_t size = io_generic_size(io); + uint64_t size; + if (io.length(size)) { + return false; + } if (!geometry_from_size(size, heads, cylinders)) { return false; } @@ -161,7 +168,8 @@ bool hpi_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui // Suck in the whole image std::vector<uint8_t> image_data(size); - io_generic_read(io, (void *)image_data.data(), 0, size); + size_t actual; + io.read_at(0, image_data.data(), size, actual); // Get interleave factor from image unsigned il = (unsigned)image_data[ IL_OFFSET ] * 256 + image_data[ IL_OFFSET + 1 ]; @@ -191,7 +199,7 @@ bool hpi_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui return true; } -bool hpi_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool hpi_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { int tracks; int heads; @@ -206,7 +214,8 @@ bool hpi_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo while (get_next_sector(bitstream , pos , track_no , head_no , sector_no , sector_data)) { if (track_no == cyl && head_no == head && sector_no < HPI_SECTORS) { unsigned offset_in_image = chs_to_lba(cyl, head, sector_no, heads) * HPI_SECTOR_SIZE; - io_generic_write(io, sector_data, offset_in_image, HPI_SECTOR_SIZE); + size_t actual; + io.write_at(offset_in_image, sector_data, HPI_SECTOR_SIZE, actual); } } } diff --git a/src/lib/formats/hpi_dsk.h b/src/lib/formats/hpi_dsk.h index 38c70e91c33..ca8aa1ffe11 100644 --- a/src/lib/formats/hpi_dsk.h +++ b/src/lib/formats/hpi_dsk.h @@ -28,9 +28,9 @@ class hpi_format : public floppy_image_format_t public: hpi_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; virtual const char *extensions() const override; diff --git a/src/lib/formats/hti_tape.cpp b/src/lib/formats/hti_tape.cpp index 7f77e3f99df..8fbaeef91cc 100644 --- a/src/lib/formats/hti_tape.cpp +++ b/src/lib/formats/hti_tape.cpp @@ -10,6 +10,8 @@ #include "imageutl.h" +#include "ioprocs.h" + static constexpr uint32_t OLD_FILE_MAGIC = 0x5441434f; // Magic value at start of old-format image file: "TACO" static constexpr uint32_t FILE_MAGIC_DELTA = 0x48544930; // Magic value at start of delta-modulation image file: "HTI0" @@ -47,22 +49,25 @@ hti_format_t::hti_format_t() clear_tape(); } -bool hti_format_t::load_tape(io_generic *io) +bool hti_format_t::load_tape(util::random_read &io) { + if (io.seek(0, SEEK_SET)) { + return false; + } + + size_t actual; uint8_t tmp[ 4 ]; - io_generic_read(io, tmp, 0, 4); + io.read(tmp, 4, actual); auto magic = pick_integer_be(tmp , 0 , 4); if (((m_img_format == HTI_DELTA_MOD_16_BITS || m_img_format == HTI_DELTA_MOD_17_BITS) && magic != FILE_MAGIC_DELTA && magic != OLD_FILE_MAGIC) || (m_img_format == HTI_MANCHESTER_MOD && magic != FILE_MAGIC_MANCHESTER)) { return false; } - uint64_t offset = 4; - for (unsigned i = 0; i < no_of_tracks(); i++) { tape_track_t& track = m_tracks[ i ]; - if (!load_track(io , offset , track , magic == OLD_FILE_MAGIC)) { + if (!load_track(io, track, magic == OLD_FILE_MAGIC)) { clear_tape(); return false; } @@ -71,14 +76,15 @@ bool hti_format_t::load_tape(io_generic *io) return true; } -void hti_format_t::save_tape(io_generic *io) +void hti_format_t::save_tape(util::random_read_write &io) { + io.seek(0, SEEK_SET); + + size_t actual; uint8_t tmp[ 4 ]; place_integer_be(tmp, 0, 4, m_img_format == HTI_MANCHESTER_MOD ? FILE_MAGIC_MANCHESTER : FILE_MAGIC_DELTA); - io_generic_write(io, tmp, 0, 4); - - uint64_t offset = 4; + io.write(tmp, 4, actual); for (unsigned i = 0; i < no_of_tracks(); i++) { const tape_track_t& track = m_tracks[ i ]; @@ -87,18 +93,17 @@ void hti_format_t::save_tape(io_generic *io) tape_track_t::const_iterator it_start; for (tape_track_t::const_iterator it = track.cbegin(); it != track.cend(); ++it) { if (it->first != next_pos) { - dump_sequence(io , offset , it_start , n_words); + dump_sequence(io, it_start, n_words); it_start = it; n_words = 0; } next_pos = it->first + word_length(it->second); n_words++; } - dump_sequence(io , offset , it_start , n_words); + dump_sequence(io, it_start, n_words); // End of track place_integer_le(tmp, 0, 4, (uint32_t)-1); - io_generic_write(io, tmp, offset, 4); - offset += 4; + io.write(tmp, 4, actual); } } @@ -374,8 +379,9 @@ bool hti_format_t::next_gap(unsigned track_no , tape_pos_t& pos , bool forward , return n_gaps == 0; } -bool hti_format_t::load_track(io_generic *io , uint64_t& offset , tape_track_t& track , bool old_format) +bool hti_format_t::load_track(util::random_read &io , tape_track_t& track , bool old_format) { + size_t actual; uint8_t tmp[ 4 ]; uint32_t tmp32; tape_pos_t delta_pos = 0; @@ -385,8 +391,7 @@ bool hti_format_t::load_track(io_generic *io , uint64_t& offset , tape_track_t& while (1) { // Read no. of words to follow - io_generic_read(io, tmp, offset, 4); - offset += 4; + io.read(tmp, 4, actual); tmp32 = pick_integer_le(tmp, 0, 4); @@ -398,8 +403,7 @@ bool hti_format_t::load_track(io_generic *io , uint64_t& offset , tape_track_t& unsigned n_words = tmp32; // Read tape position of block - io_generic_read(io, tmp, offset, 4); - offset += 4; + io.read(tmp, 4, actual); tmp32 = pick_integer_le(tmp, 0, 4); @@ -411,8 +415,7 @@ bool hti_format_t::load_track(io_generic *io , uint64_t& offset , tape_track_t& for (unsigned i = 0; i < n_words; i++) { uint16_t tmp16; - io_generic_read(io, tmp, offset, 2); - offset += 2; + io.read(tmp, 2, actual); tmp16 = pick_integer_le(tmp, 0, 2); if (!old_format) { @@ -469,19 +472,18 @@ bool hti_format_t::load_track(io_generic *io , uint64_t& offset , tape_track_t& } } -void hti_format_t::dump_sequence(io_generic *io , uint64_t& offset , tape_track_t::const_iterator it_start , unsigned n_words) +void hti_format_t::dump_sequence(util::random_read_write &io , tape_track_t::const_iterator it_start , unsigned n_words) { if (n_words) { + size_t actual; uint8_t tmp[ 8 ]; place_integer_le(tmp, 0, 4, n_words); place_integer_le(tmp, 4, 4, it_start->first); - io_generic_write(io, tmp, offset, 8); - offset += 8; + io.write(tmp, 8, actual); for (unsigned i = 0; i < n_words; i++) { place_integer_le(tmp, 0, 2, it_start->second); - io_generic_write(io, tmp, offset, 2); - offset += 2; + io.write(tmp, 2, actual); ++it_start; } } diff --git a/src/lib/formats/hti_tape.h b/src/lib/formats/hti_tape.h index 7725b87fa2a..373c971d174 100644 --- a/src/lib/formats/hti_tape.h +++ b/src/lib/formats/hti_tape.h @@ -13,10 +13,12 @@ #pragma once -#include "ioprocs.h" +#include "utilfwd.h" +#include <cstdint> #include <map> + class hti_format_t { public: @@ -71,8 +73,8 @@ public: // Return number of tracks unsigned no_of_tracks() const { return m_img_format == HTI_MANCHESTER_MOD ? 1 : 2; } - bool load_tape(io_generic *io); - void save_tape(io_generic *io); + bool load_tape(util::random_read &io); + void save_tape(util::random_read_write &io); void clear_tape(); // Return physical length of a bit on tape @@ -127,8 +129,8 @@ private: // Image format image_format_t m_img_format; - bool load_track(io_generic *io , uint64_t& offset , tape_track_t& track , bool old_format); - static void dump_sequence(io_generic *io , uint64_t& offset , tape_track_t::const_iterator it_start , unsigned n_words); + bool load_track(util::random_read &io , tape_track_t& track , bool old_format); + static void dump_sequence(util::random_read_write &io , tape_track_t::const_iterator it_start , unsigned n_words); tape_pos_t word_end_pos(const track_iterator_t& it) const; void adjust_it(tape_track_t& track , track_iterator_t& it , tape_pos_t pos) const; diff --git a/src/lib/formats/hxchfe_dsk.cpp b/src/lib/formats/hxchfe_dsk.cpp index 68360f4e9bb..15598bbd746 100644 --- a/src/lib/formats/hxchfe_dsk.cpp +++ b/src/lib/formats/hxchfe_dsk.cpp @@ -101,6 +101,9 @@ #include "hxchfe_dsk.h" +#include "ioprocs.h" + + #define HFE_FORMAT_HEADER "HXCPICFE" #define HEADER_LENGTH 512 @@ -144,19 +147,21 @@ bool hfe_format::supports_save() const return true; } -int hfe_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int hfe_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { uint8_t header[8]; - io_generic_read(io, &header, 0, sizeof(header)); + size_t actual; + io.read_at(0, &header, sizeof(header), actual); if ( memcmp( header, HFE_FORMAT_HEADER, 8 ) ==0) { return 100; } return 0; } -bool hfe_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool hfe_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { + size_t actual; uint8_t header[HEADER_LENGTH]; uint8_t track_table[TRACK_TABLE_LENGTH]; @@ -164,7 +169,7 @@ bool hfe_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui image->get_maximal_geometry(drivecyl, driveheads); // read header - io_generic_read(io, header, 0, HEADER_LENGTH); + io.read_at(0, header, HEADER_LENGTH, actual); // get values // Format revision must be 0 @@ -236,7 +241,7 @@ bool hfe_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui // read track lookup table (multiple of 512) int table_offset = (header[18] & 0xff) | ((header[19] & 0xff)<<8); - io_generic_read(io, track_table, table_offset<<9, TRACK_TABLE_LENGTH); + io.read_at(table_offset<<9, track_table, TRACK_TABLE_LENGTH, actual); for (int i=0; i < m_cylinders; i++) { @@ -252,7 +257,7 @@ bool hfe_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui // The HFE format defines an interleave of the two sides per cylinder // at every 256 bytes cylinder_buffer.resize(m_cyl_length[cyl]); - io_generic_read(io, &cylinder_buffer[0], m_cyl_offset[cyl]<<9, m_cyl_length[cyl]); + io.read_at(m_cyl_offset[cyl]<<9, &cylinder_buffer[0], m_cyl_length[cyl], actual); generate_track_from_hfe_bitstream(cyl, 0, samplelength, &cylinder_buffer[0], m_cyl_length[cyl], image); if (m_heads == 2) @@ -412,8 +417,9 @@ void hfe_format::generate_track_from_hfe_bitstream(int cyl, int head, int sample image->set_write_splice_position(cyl, head, 0, 0); } -bool hfe_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool hfe_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { + size_t actual; std::vector<uint8_t> cylbuf; // Create a buffer that is big enough to handle HD formats. We don't @@ -484,7 +490,7 @@ bool hfe_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo header[13] = (m_bit_rate >> 8) & 0xff; // Now write the header - io_generic_write(io, header, 0, HEADER_LENGTH); + io.write_at(0, header, HEADER_LENGTH, actual); // Set up the track lookup table // We need the encoding value to be sure about the track length @@ -505,10 +511,10 @@ bool hfe_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo for (int i=m_cylinders*4; i < TRACK_TABLE_LENGTH; i++) track_table[i] = 0xff; - io_generic_write(io, track_table, 0x200, TRACK_TABLE_LENGTH); + io.write_at(0x200, track_table, TRACK_TABLE_LENGTH, actual); } // Write the current cylinder - io_generic_write(io, &cylbuf[0], m_cyl_offset[cyl]<<9, (m_cyl_length[cyl] + 0x1ff) & 0xfe00); + io.write_at(m_cyl_offset[cyl]<<9, &cylbuf[0], (m_cyl_length[cyl] + 0x1ff) & 0xfe00, actual); } return true; } diff --git a/src/lib/formats/hxchfe_dsk.h b/src/lib/formats/hxchfe_dsk.h index 9d2dbdeae77..4ea98ed861c 100644 --- a/src/lib/formats/hxchfe_dsk.h +++ b/src/lib/formats/hxchfe_dsk.h @@ -47,9 +47,9 @@ public: hfe_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/hxcmfm_dsk.cpp b/src/lib/formats/hxcmfm_dsk.cpp index b6845b28e4a..e7bf03acd2f 100644 --- a/src/lib/formats/hxcmfm_dsk.cpp +++ b/src/lib/formats/hxcmfm_dsk.cpp @@ -1,10 +1,11 @@ // license:BSD-3-Clause // copyright-holders:Olivier Galibert -#include <cassert> - #include "hxcmfm_dsk.h" +#include "ioprocs.h" + + #define MFM_FORMAT_HEADER "HXCMFM" #pragma pack(1) @@ -57,24 +58,26 @@ bool mfm_format::supports_save() const return true; } -int mfm_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int mfm_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { uint8_t header[7]; - io_generic_read(io, &header, 0, sizeof(header)); + size_t actual; + io.read_at(0, &header, sizeof(header), actual); if ( memcmp( header, MFM_FORMAT_HEADER, 6 ) ==0) { return 100; } return 0; } -bool mfm_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool mfm_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { + size_t actual; MFMIMG header; MFMTRACKIMG trackdesc; // read header - io_generic_read(io, &header, 0, sizeof(header)); + io.read_at(0, &header, sizeof(header), actual); int drivecyl, driveheads; image->get_maximal_geometry(drivecyl, driveheads); @@ -86,12 +89,12 @@ bool mfm_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui for(int side=0; side < header.number_of_side; side++) { if (!skip_odd || track%2 == 0) { // read location of - io_generic_read(io, &trackdesc,(header.mfmtracklistoffset)+( counter *sizeof(trackdesc)),sizeof(trackdesc)); + io.read_at((header.mfmtracklistoffset)+( counter *sizeof(trackdesc)), &trackdesc, sizeof(trackdesc), actual); trackbuf.resize(trackdesc.mfmtracksize); // actual data read - io_generic_read(io, &trackbuf[0], trackdesc.mfmtrackoffset, trackdesc.mfmtracksize); + io.read_at(trackdesc.mfmtrackoffset, &trackbuf[0], trackdesc.mfmtracksize, actual); if (skip_odd) { generate_track_from_bitstream(track/2, side, &trackbuf[0], trackdesc.mfmtracksize*8, image); @@ -109,9 +112,10 @@ bool mfm_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui return true; } -bool mfm_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool mfm_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { // TODO: HD support + size_t actual; MFMIMG header; int track_count, head_count; image->get_actual_geometry(track_count, head_count); @@ -124,7 +128,7 @@ bool mfm_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo header.floppyiftype = 4; header.mfmtracklistoffset = sizeof(MFMIMG); - io_generic_write(io, &header, 0, sizeof(MFMIMG)); + io.write_at(0, &header, sizeof(MFMIMG), actual); int tpos = sizeof(MFMIMG); int dpos = tpos + track_count*head_count*sizeof(MFMTRACKIMG); @@ -143,8 +147,8 @@ bool mfm_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo trackdesc.mfmtracksize = packed.size(); trackdesc.mfmtrackoffset = dpos; - io_generic_write(io, &trackdesc, tpos, sizeof(MFMTRACKIMG)); - io_generic_write(io, packed.data(), dpos, packed.size()); + io.write_at(tpos, &trackdesc, sizeof(MFMTRACKIMG), actual); + io.write_at(dpos, packed.data(), packed.size(), actual); tpos += sizeof(MFMTRACKIMG); dpos += packed.size(); diff --git a/src/lib/formats/hxcmfm_dsk.h b/src/lib/formats/hxcmfm_dsk.h index a6f884ab03e..c42190f3aae 100644 --- a/src/lib/formats/hxcmfm_dsk.h +++ b/src/lib/formats/hxcmfm_dsk.h @@ -19,9 +19,9 @@ class mfm_format : public floppy_image_format_t public: mfm_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/ibmxdf_dsk.cpp b/src/lib/formats/ibmxdf_dsk.cpp index b18ffad63dc..5a44290a337 100644 --- a/src/lib/formats/ibmxdf_dsk.cpp +++ b/src/lib/formats/ibmxdf_dsk.cpp @@ -32,6 +32,8 @@ #include "ibmxdf_dsk.h" +#include "ioprocs.h" + ibmxdf_format::ibmxdf_format() : wd177x_format(formats) { @@ -52,7 +54,7 @@ const char *ibmxdf_format::extensions() const return "xdf,img"; } -int ibmxdf_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int ibmxdf_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { int type = find_size(io, form_factor, variants); @@ -61,9 +63,11 @@ int ibmxdf_format::identify(io_generic *io, uint32_t form_factor, const std::vec return 0; } -int ibmxdf_format::find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int ibmxdf_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - uint64_t size = io_generic_size(io); + uint64_t size; + if (io.length(size)) + return -1; if (size != 1884160) return -1; @@ -173,7 +177,7 @@ const ibmxdf_format::format ibmxdf_format::formats_head1_track0[] = { {} }; -bool ibmxdf_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool ibmxdf_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { int type = find_size(io, form_factor, variants); if(type == -1) @@ -207,8 +211,9 @@ bool ibmxdf_format::load(io_generic *io, uint32_t form_factor, const std::vector desc[16].p1 = get_track_dam_mfm(tf, head, track); build_sector_description(tf, sectdata, sectors, track, head); - int track_size = compute_track_size(f) * 2; // read both sides at once - io_generic_read(io, sectdata, get_image_offset(f, head, track), track_size); + int const track_size = compute_track_size(f) * 2; // read both sides at once + size_t actual; + io.read_at(get_image_offset(f, head, track), sectdata, track_size, actual); generate_track(desc, track, head, sectors, tf.sector_count, total_size, image); } diff --git a/src/lib/formats/ibmxdf_dsk.h b/src/lib/formats/ibmxdf_dsk.h index 6d37142ac30..dbb448f8ad3 100644 --- a/src/lib/formats/ibmxdf_dsk.h +++ b/src/lib/formats/ibmxdf_dsk.h @@ -23,11 +23,11 @@ public: virtual const char *description() const override; virtual const char *extensions() const override; - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual bool supports_save() const override { return false; } - virtual int find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual int find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; virtual int get_image_offset(const format &f, int head, int track) override; virtual const wd177x_format::format &get_track_format(const format &f, int head, int track) override; diff --git a/src/lib/formats/imd_dsk.cpp b/src/lib/formats/imd_dsk.cpp index b3d4eac8229..b0e9a4159d9 100644 --- a/src/lib/formats/imd_dsk.cpp +++ b/src/lib/formats/imd_dsk.cpp @@ -10,7 +10,8 @@ #include "imd_dsk.h" -#include <cassert> +#include "ioprocs.h" + #include <cstring> @@ -409,25 +410,29 @@ void imd_format::fixnum(char *start, char *end) const }; } -int imd_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int imd_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { char h[4]; - io_generic_read(io, h, 0, 4); + size_t actual; + io.read_at(0, h, 4, actual); if(!memcmp(h, "IMD ", 4)) return 100; return 0; } -bool imd_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool imd_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { - uint64_t size = io_generic_size(io); + uint64_t size; + if(io.length(size)) + return false; std::vector<uint8_t> img(size); - io_generic_read(io, &img[0], 0, size); + size_t actual; + io.read_at(0, &img[0], size, actual); uint64_t pos, savepos; - for(pos=0; pos < size && img[pos] != 0x1a; pos++) {}; + for(pos=0; pos < size && img[pos] != 0x1a; pos++) { } pos++; m_comment.resize(pos); @@ -627,39 +632,34 @@ bool can_compress(const uint8_t* buffer, uint8_t ptrn, uint64_t size) return true; } -bool imd_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool imd_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { - uint64_t pos = 0; - io_generic_write(io, &m_comment[0], pos, m_comment.size()); - pos += m_comment.size(); + if(io.seek(0, SEEK_SET)) + return false; + + size_t written; + io.write(&m_comment[0], m_comment.size(), written); for (int i = 0; i < m_mode.size(); i++) { - io_generic_write(io, &m_mode[i], pos++, 1); - io_generic_write(io, &m_track[i], pos++, 1); - io_generic_write(io, &m_head[i], pos++, 1); - io_generic_write(io, &m_sector_count[i], pos++, 1); - io_generic_write(io, &m_ssize[i], pos++, 1); + io.write(&m_mode[i], 1, written); + io.write(&m_track[i], 1, written); + io.write(&m_head[i], 1, written); + io.write(&m_sector_count[i], 1, written); + io.write(&m_ssize[i], 1, written); - io_generic_write(io, &m_snum[i][0], pos, m_sector_count[i]); - pos += m_sector_count[i]; + io.write(&m_snum[i][0], m_sector_count[i], written); if (m_tnum[i].size()) - { - io_generic_write(io, &m_tnum[i][0], pos, m_sector_count[i]); - pos += m_sector_count[i]; - } + io.write(&m_tnum[i][0], m_sector_count[i], written); if (m_hnum[i].size()) - { - io_generic_write(io, &m_hnum[i][0], pos, m_sector_count[i]); - pos += m_sector_count[i]; - } + io.write(&m_hnum[i][0], m_sector_count[i], written); - uint32_t actual_size = m_ssize[i] < 7 ? 128 << m_ssize[i] : 8192; - uint8_t head = m_head[i] & 0x3f; + uint32_t const actual_size = m_ssize[i] < 7 ? 128 << m_ssize[i] : 8192; + uint8_t const head = m_head[i] & 0x3f; - bool fm = m_mode[i]< 3; + bool const fm = m_mode[i]< 3; auto bitstream = generate_bitstream_from_track(m_track[i]*m_trackmult, head, fm ? 4000 : 2000, image); std::vector<std::vector<uint8_t>> sectors; @@ -674,11 +674,10 @@ bool imd_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo const auto &data = sectors[m_snum[i][j]]; - uint8_t mode; if (data.empty()) { - mode = 0; - io_generic_write(io, &mode, pos++, 1); + uint8_t const mode = 0; + io.write(&mode, 1, written); continue; } else if (data.size() < actual_size) { @@ -690,16 +689,15 @@ bool imd_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo if (can_compress(sdata, sdata[0], actual_size)) { - mode = 2; - io_generic_write(io, &mode, pos++, 1); - io_generic_write(io, &sdata[0], pos++, 1); + uint8_t const mode = 2; + io.write(&mode, 1, written); + io.write(&sdata[0], 1, written); } else { - mode = 1; - io_generic_write(io, &mode, pos++, 1); - io_generic_write(io, &sdata, pos, actual_size); - pos += actual_size; + uint8_t const mode = 1; + io.write(&mode, 1, written); + io.write(&sdata, actual_size, written); } } } diff --git a/src/lib/formats/imd_dsk.h b/src/lib/formats/imd_dsk.h index ba04a0c09e7..acf7da9b892 100644 --- a/src/lib/formats/imd_dsk.h +++ b/src/lib/formats/imd_dsk.h @@ -17,9 +17,9 @@ class imd_format : public floppy_image_format_t public: imd_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image* image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image* image) override; virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/img_dsk.cpp b/src/lib/formats/img_dsk.cpp index 757f695d923..73ae499c764 100644 --- a/src/lib/formats/img_dsk.cpp +++ b/src/lib/formats/img_dsk.cpp @@ -17,6 +17,7 @@ #include "img_dsk.h" #include "coretmpl.h" // BIT +#include "ioprocs.h" // Debugging @@ -40,9 +41,12 @@ img_format::img_format() { } -int img_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int img_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - uint64_t size = io_generic_size(io); + uint64_t size; + if (io.length(size)) { + return 0; + } if (((form_factor == floppy_image::FF_8) || (form_factor == floppy_image::FF_UNKNOWN)) && size == IMG_IMAGE_SIZE) { @@ -52,17 +56,18 @@ int img_format::identify(io_generic *io, uint32_t form_factor, const std::vector } } -bool img_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool img_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { - uint64_t size = io_generic_size(io); - if (size != IMG_IMAGE_SIZE) { + uint64_t size; + if (io.length(size) || (size != IMG_IMAGE_SIZE)) { return false; } image->set_variant(floppy_image::SSDD); // Suck in the whole image std::vector<uint8_t> image_data(size); - io_generic_read(io, (void *)image_data.data(), 0, size); + size_t actual; + io.read_at(0, image_data.data(), size, actual); for (unsigned cyl = 0; cyl < TRACKS; cyl++) { std::vector<uint32_t> track_data; @@ -96,7 +101,7 @@ bool img_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui return true; } -bool img_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool img_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { for (int cyl = 0; cyl < TRACKS; cyl++) { auto bitstream = generate_bitstream_from_track(cyl , 0 , CELL_SIZE , image , 0); @@ -106,7 +111,8 @@ bool img_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo while (get_next_sector(bitstream , pos , track_no , sector_no , sector_data)) { if (track_no == cyl && sector_no >= 1 && sector_no <= SECTORS) { unsigned offset_in_image = (cyl * SECTORS + sector_no - 1) * SECTOR_SIZE; - io_generic_write(io, sector_data, offset_in_image, SECTOR_SIZE); + size_t actual; + io.write_at(offset_in_image, sector_data, SECTOR_SIZE, actual); } } } diff --git a/src/lib/formats/img_dsk.h b/src/lib/formats/img_dsk.h index af9a2d62466..bbd7a0fc03e 100644 --- a/src/lib/formats/img_dsk.h +++ b/src/lib/formats/img_dsk.h @@ -27,9 +27,9 @@ public: img_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; virtual const char *extensions() const override; diff --git a/src/lib/formats/ioprocs.cpp b/src/lib/formats/ioprocs.cpp deleted file mode 100644 index 78e009aa112..00000000000 --- a/src/lib/formats/ioprocs.cpp +++ /dev/null @@ -1,214 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Nathan Woods -#include <cstdio> -#include <cstring> -#include <cassert> -#include "ioprocs.h" -#include "corefile.h" - - -/********************************************************************* - ioprocs implementation on stdio -*********************************************************************/ - -static void stdio_closeproc(void *file) -{ - fclose((FILE*)file); -} - -static int stdio_seekproc(void *file, int64_t offset, int whence) -{ - return fseek((FILE*)file, (long) offset, whence); -} - -static size_t stdio_readproc(void *file, void *buffer, size_t length) -{ - return fread(buffer, 1, length, (FILE*)file); -} - -static size_t stdio_writeproc(void *file, const void *buffer, size_t length) -{ - return fwrite(buffer, 1, length, (FILE*)file); -} - -static uint64_t stdio_filesizeproc(void *file) -{ - long l, sz; - l = ftell((FILE*)file); - if (fseek((FILE*)file, 0, SEEK_END)) - return (size_t) -1; - sz = ftell((FILE*)file); - if (fseek((FILE*)file, l, SEEK_SET)) - return (size_t) -1; - return (size_t) sz; -} - -const struct io_procs stdio_ioprocs = -{ - stdio_closeproc, - stdio_seekproc, - stdio_readproc, - stdio_writeproc, - stdio_filesizeproc -}; - -const struct io_procs stdio_ioprocs_noclose = -{ - nullptr, - stdio_seekproc, - stdio_readproc, - stdio_writeproc, - stdio_filesizeproc -}; - -/********************************************************************* - ioprocs implementation on corefile -*********************************************************************/ - -static void corefile_closeproc(void *file) -{ - delete (util::core_file*)file; -} - -static int corefile_seekproc(void *file, int64_t offset, int whence) -{ - return ((util::core_file*)file)->seek(offset, whence); -} - -static size_t corefile_readproc(void *file, void *buffer, size_t length) -{ - return ((util::core_file*)file)->read(buffer, length); -} - -static size_t corefile_writeproc(void *file, const void *buffer, size_t length) -{ - return ((util::core_file*)file)->write(buffer, length); -} - -static uint64_t corefile_filesizeproc(void *file) -{ - const auto l = ((util::core_file*)file)->tell(); - if (((util::core_file*)file)->seek(0, SEEK_END)) - return (size_t) -1; - const auto sz = ((util::core_file*)file)->tell(); - if (((util::core_file*)file)->seek(l, SEEK_SET)) - return uint64_t(-1); - return uint64_t(sz); -} - -const struct io_procs corefile_ioprocs = -{ - corefile_closeproc, - corefile_seekproc, - corefile_readproc, - corefile_writeproc, - corefile_filesizeproc -}; - -const struct io_procs corefile_ioprocs_noclose = -{ - nullptr, - corefile_seekproc, - corefile_readproc, - corefile_writeproc, - corefile_filesizeproc -}; - - - -/********************************************************************* - calls for accessing generic IO -*********************************************************************/ - -static void io_generic_seek(struct io_generic *genio, uint64_t offset) -{ - genio->procs->seekproc(genio->file, offset, SEEK_SET); -} - - - -void io_generic_close(struct io_generic *genio) -{ - if (genio->procs->closeproc) - genio->procs->closeproc(genio->file); -} - - - -void io_generic_read(struct io_generic *genio, void *buffer, uint64_t offset, size_t length) -{ - uint64_t size; - size_t bytes_read; - - size = io_generic_size(genio); - if (size <= offset) - { - bytes_read = 0; - } - else - { - io_generic_seek(genio, offset); - bytes_read = genio->procs->readproc(genio->file, buffer, length); - } - memset(((uint8_t *) buffer) + bytes_read, genio->filler, length - bytes_read); -} - - - -void io_generic_write(struct io_generic *genio, const void *buffer, uint64_t offset, size_t length) -{ - uint64_t filler_size = 0; - char filler_buffer[1024]; - size_t bytes_to_write; - uint64_t size; - - size = io_generic_size(genio); - - if (size < offset) - { - filler_size = offset - size; - offset = size; - } - - io_generic_seek(genio, offset); - - if (filler_size) - { - memset(filler_buffer, genio->filler, sizeof(filler_buffer)); - do - { - bytes_to_write = (filler_size > sizeof(filler_buffer)) ? sizeof(filler_buffer) : (size_t) filler_size; - genio->procs->writeproc(genio->file, filler_buffer, bytes_to_write); - filler_size -= bytes_to_write; - } - while(filler_size > 0); - } - - if (length > 0) - genio->procs->writeproc(genio->file, buffer, length); -} - - - -void io_generic_write_filler(struct io_generic *genio, uint8_t filler, uint64_t offset, size_t length) -{ - uint8_t buffer[512]; - size_t this_length; - - memset(buffer, filler, std::min(length, sizeof(buffer))); - - while(length > 0) - { - this_length = std::min(length, sizeof(buffer)); - io_generic_write(genio, buffer, offset, this_length); - offset += this_length; - length -= this_length; - } -} - - - -uint64_t io_generic_size(struct io_generic *genio) -{ - return genio->procs->filesizeproc(genio->file); -} diff --git a/src/lib/formats/ioprocs.h b/src/lib/formats/ioprocs.h deleted file mode 100644 index 1244873f14c..00000000000 --- a/src/lib/formats/ioprocs.h +++ /dev/null @@ -1,70 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Nathan Woods -/********************************************************************* - - ioprocs.h - - File IO abstraction layer - -*********************************************************************/ -#ifndef MAME_FORMATS_IOPROCS_H -#define MAME_FORMATS_IOPROCS_H - -#pragma once - -#include <cstdint> -#include <cstdlib> - - - -/*************************************************************************** - - Type definitions - -***************************************************************************/ - -struct io_procs -{ - void (*closeproc)(void *file) = nullptr; - int (*seekproc)(void *file, int64_t offset, int whence) = nullptr; - size_t (*readproc)(void *file, void *buffer, size_t length) = nullptr; - size_t (*writeproc)(void *file, const void *buffer, size_t length) = nullptr; - uint64_t (*filesizeproc)(void *file) = nullptr; -}; - - - -struct io_generic -{ - const struct io_procs *procs = nullptr; - void *file = nullptr; - uint8_t filler = 0; -}; - - -/*************************************************************************** - - Globals - -***************************************************************************/ - -extern const io_procs stdio_ioprocs; -extern const io_procs stdio_ioprocs_noclose; -extern const io_procs corefile_ioprocs; -extern const io_procs corefile_ioprocs_noclose; - - - -/*************************************************************************** - - Prototypes - -***************************************************************************/ - -void io_generic_close(struct io_generic *genio); -void io_generic_read(struct io_generic *genio, void *buffer, uint64_t offset, size_t length); -void io_generic_write(struct io_generic *genio, const void *buffer, uint64_t offset, size_t length); -void io_generic_write_filler(struct io_generic *genio, uint8_t filler, uint64_t offset, size_t length); -uint64_t io_generic_size(struct io_generic *genio); - -#endif // MAME_FORMATS_IOPROCS_H diff --git a/src/lib/formats/ipf_dsk.cpp b/src/lib/formats/ipf_dsk.cpp index 0f1725f5c14..10c9ba2c4a9 100644 --- a/src/lib/formats/ipf_dsk.cpp +++ b/src/lib/formats/ipf_dsk.cpp @@ -2,6 +2,8 @@ // copyright-holders:Olivier Galibert #include "ipf_dsk.h" +#include "ioprocs.h" + #include <cassert> @@ -27,11 +29,12 @@ bool ipf_format::supports_save() const return false; } -int ipf_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int ipf_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { static const uint8_t refh[12] = { 0x43, 0x41, 0x50, 0x53, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0xd5, 0x73, 0xba }; uint8_t h[12]; - io_generic_read(io, h, 0, 12); + size_t actual; + io.read_at(0, h, 12, actual); if(!memcmp(h, refh, 12)) return 100; @@ -39,14 +42,16 @@ int ipf_format::identify(io_generic *io, uint32_t form_factor, const std::vector return 0; } -bool ipf_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool ipf_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { - ipf_decode dec; - uint64_t size = io_generic_size(io); + uint64_t size; + if (io.length(size)) + return false; std::vector<uint8_t> data(size); - io_generic_read(io, &data[0], 0, size); - bool res = dec.parse(data, image); - return res; + size_t actual; + io.read_at(0, &data[0], size, actual); + ipf_decode dec; + return dec.parse(data, image); } uint32_t ipf_format::ipf_decode::r32(const uint8_t *p) diff --git a/src/lib/formats/ipf_dsk.h b/src/lib/formats/ipf_dsk.h index d848a5bb3a0..28d552d5812 100644 --- a/src/lib/formats/ipf_dsk.h +++ b/src/lib/formats/ipf_dsk.h @@ -12,8 +12,8 @@ class ipf_format : public floppy_image_format_t { public: - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/jfd_dsk.cpp b/src/lib/formats/jfd_dsk.cpp index 947d6ba4022..7a1da472356 100644 --- a/src/lib/formats/jfd_dsk.cpp +++ b/src/lib/formats/jfd_dsk.cpp @@ -158,9 +158,13 @@ *********************************************************************/ -#include <zlib.h> #include "formats/jfd_dsk.h" +#include "ioprocs.h" + +#include <zlib.h> + + static const uint8_t JFD_HEADER[4] = { 'J', 'F', 'D', 'I' }; static const uint8_t GZ_HEADER[2] = { 0x1f, 0x8b }; @@ -183,11 +187,14 @@ const char *jfd_format::extensions() const return "jfd"; } -int jfd_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int jfd_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - uint64_t size = io_generic_size(io); + uint64_t size; + if (io.length(size)) + return 0; std::vector<uint8_t> img(size); - io_generic_read(io, &img[0], 0, size); + size_t actual; + io.read_at(0, &img[0], size, actual); int err; std::vector<uint8_t> gz_ptr(4); @@ -221,11 +228,15 @@ int jfd_format::identify(io_generic *io, uint32_t form_factor, const std::vector return 0; } -bool jfd_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool jfd_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { - uint64_t size = io_generic_size(io); + uint64_t size; + if (io.length(size)) + return false; + std::vector<uint8_t> img(size); - io_generic_read(io, &img[0], 0, size); + size_t actual; + io.read_at(0, &img[0], size, actual); int err; std::vector<uint8_t> gz_ptr; diff --git a/src/lib/formats/jfd_dsk.h b/src/lib/formats/jfd_dsk.h index 75b9910c426..7231ccf3460 100644 --- a/src/lib/formats/jfd_dsk.h +++ b/src/lib/formats/jfd_dsk.h @@ -23,8 +23,8 @@ public: virtual const char *description() const override; virtual const char *extensions() const override; - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual bool supports_save() const override; }; diff --git a/src/lib/formats/jvc_dsk.cpp b/src/lib/formats/jvc_dsk.cpp index 8332f86bace..c71f2c3be06 100644 --- a/src/lib/formats/jvc_dsk.cpp +++ b/src/lib/formats/jvc_dsk.cpp @@ -106,6 +106,8 @@ #include "jvc_dsk.h" +#include "ioprocs.h" + jvc_format::jvc_format() { @@ -126,19 +128,22 @@ const char *jvc_format::extensions() const return "jvc,dsk"; } -bool jvc_format::parse_header(io_generic *io, int &header_size, int &tracks, int &heads, int §ors, int §or_size, int &base_sector_id) +bool jvc_format::parse_header(util::random_read &io, int &header_size, int &tracks, int &heads, int §ors, int §or_size, int &base_sector_id) { // The JVC format has a header whose size is the size of the image modulo 256. Currently, we only // handle up to five header bytes - uint64_t size = io_generic_size(io); + uint64_t size; + if (io.length(size)) + return false; header_size = size % 256; uint8_t header[5]; // if we know that this is a header of a bad size, we can fail immediately; otherwise read the header + size_t actual; if (header_size >= sizeof(header)) return false; if (header_size > 0) - io_generic_read(io, header, 0, header_size); + io.read_at(0, header, header_size, actual); // default values heads = 1; @@ -168,13 +173,13 @@ bool jvc_format::parse_header(io_generic *io, int &header_size, int &tracks, int return tracks * heads * sectors * sector_size == (size - header_size); } -int jvc_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int jvc_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { int header_size, tracks, heads, sectors, sector_size, sector_base_id; return parse_header(io, header_size, tracks, heads, sectors, sector_size, sector_base_id) ? 50 : 0; } -bool jvc_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool jvc_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { int header_size, track_count, head_count, sector_count, sector_size, sector_base_id; @@ -210,7 +215,8 @@ bool jvc_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui sectors[interleave[i]].bad_crc = false; sectors[interleave[i]].data = §or_data[sector_offset]; - io_generic_read(io, sectors[interleave[i]].data, file_offset, sector_size); + size_t actual; + io.read_at(file_offset, sectors[interleave[i]].data, sector_size, actual); sector_offset += sector_size; file_offset += sector_size; @@ -223,7 +229,7 @@ bool jvc_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui return true; } -bool jvc_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool jvc_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { uint64_t file_offset = 0; @@ -236,7 +242,8 @@ bool jvc_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo uint8_t header[2]; header[0] = 18; header[1] = 2; - io_generic_write(io, header, file_offset, sizeof(header)); + size_t actual; + io.write_at(file_offset, header, sizeof(header), actual); file_offset += sizeof(header); } @@ -256,7 +263,8 @@ bool jvc_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo return false; } - io_generic_write(io, sectors[1 + i].data(), file_offset, 256); + size_t actual; + io.write_at(file_offset, sectors[1 + i].data(), 256, actual); file_offset += 256; } } diff --git a/src/lib/formats/jvc_dsk.h b/src/lib/formats/jvc_dsk.h index 7c744a0acb5..1b8b59c725f 100644 --- a/src/lib/formats/jvc_dsk.h +++ b/src/lib/formats/jvc_dsk.h @@ -35,13 +35,13 @@ public: virtual const char *description() const override; virtual const char *extensions() const override; - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual bool supports_save() const override; private: - bool parse_header(io_generic *io, int &header_size, int &tracks, int &heads, int §ors, int §or_size, int &base_sector_id); + bool parse_header(util::random_read &io, int &header_size, int &tracks, int &heads, int §ors, int §or_size, int &base_sector_id); }; extern const floppy_format_type FLOPPY_JVC_FORMAT; diff --git a/src/lib/formats/m20_dsk.cpp b/src/lib/formats/m20_dsk.cpp index 60b2ae58176..05c52c2f211 100644 --- a/src/lib/formats/m20_dsk.cpp +++ b/src/lib/formats/m20_dsk.cpp @@ -16,6 +16,9 @@ #include "m20_dsk.h" +#include "ioprocs.h" + + m20_format::m20_format() { } @@ -40,21 +43,27 @@ bool m20_format::supports_save() const return true; } -int m20_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int m20_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - if(io_generic_size(io) == 286720) + uint64_t size; + if (io.length(size)) + return 0; + + if (size == 286720) return 50; + return 0; } -bool m20_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool m20_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { for (int track = 0; track < 35; track++) for (int head = 0; head < 2; head ++) { bool mfm = track || head; desc_pc_sector sects[16]; uint8_t sectdata[16*256]; - io_generic_read(io, sectdata, 16*256*(track*2+head), 16*256); + size_t actual; + io.read_at(16*256*(track*2+head), sectdata, 16*256, actual); for (int i = 0; i < 16; i++) { int j = i/2 + (i & 1 ? 0 : 8); sects[i].track = track; @@ -76,7 +85,7 @@ bool m20_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui return true; } -bool m20_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool m20_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { uint64_t file_offset = 0; @@ -87,26 +96,27 @@ bool m20_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo auto bitstream = generate_bitstream_from_track(0, 0, 4000, image); auto sectors = extract_sectors_from_bitstream_fm_pc(bitstream); - for (int i = 0; i < 16; i++) - { - io_generic_write(io, sectors[i + 1].data(), file_offset, 128); + for (int i = 0; i < 16; i++) { + size_t actual; + io.write_at(file_offset, sectors[i + 1].data(), 128, actual); file_offset += 256; //128; } // rest are mfm tracks - for (int track = 0; track < track_count; track++) - { - for (int head = 0; head < head_count; head++) - { + for (int track = 0; track < track_count; track++) { + for (int head = 0; head < head_count; head++) { // skip track 0, head 0 - if (track == 0) { if (head_count == 1) break; else head++; } + if (track == 0) { + if (head_count == 1) break; + else head++; + } bitstream = generate_bitstream_from_track(track, head, 2000, image); sectors = extract_sectors_from_bitstream_mfm_pc(bitstream); - for (int i = 0; i < 16; i++) - { - io_generic_write(io, sectors[i + 1].data(), file_offset, 256); + for (int i = 0; i < 16; i++) { + size_t actual; + io.write_at(file_offset, sectors[i + 1].data(), 256, actual); file_offset += 256; } } diff --git a/src/lib/formats/m20_dsk.h b/src/lib/formats/m20_dsk.h index ed8a7bc4517..d9bd7a45425 100644 --- a/src/lib/formats/m20_dsk.h +++ b/src/lib/formats/m20_dsk.h @@ -18,9 +18,9 @@ class m20_format : public floppy_image_format_t { public: m20_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/mdos_dsk.cpp b/src/lib/formats/mdos_dsk.cpp index b96be2f327e..e49d825ea9a 100644 --- a/src/lib/formats/mdos_dsk.cpp +++ b/src/lib/formats/mdos_dsk.cpp @@ -50,7 +50,9 @@ */ #include "mdos_dsk.h" -#include "formats/imageutl.h" +#include "imageutl.h" + +#include "ioprocs.h" mdos_format::mdos_format() : wd177x_format(formats) @@ -72,12 +74,13 @@ const char *mdos_format::extensions() const return "dsk"; } -int mdos_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int mdos_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - int type = find_size(io, form_factor, variants); + int type = find_size(io, form_factor, variants); if (type != -1) return 75; + return 0; } @@ -109,12 +112,15 @@ int mdos_format::parse_date_field(uint8_t *str) return (high - 0x30) * 10 + (low - 0x30); } -int mdos_format::find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int mdos_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - uint64_t size = io_generic_size(io); + size_t actual; + uint64_t size; + if (io.length(size)) + return -1; // Look at the disk id sector. - io_generic_read(io, &info, 0, sizeof(struct disk_id_sector)); + io.read_at(0, &info, sizeof(struct disk_id_sector), actual); LOG_FORMATS("MDOS floppy dsk: size %d bytes, %d total sectors, %d remaining bytes, expected form factor %x\n", (uint32_t)size, (uint32_t)size / 128, (uint32_t)size % 128, form_factor); @@ -176,8 +182,8 @@ int mdos_format::find_size(io_generic *io, uint32_t form_factor, const std::vect // the extent of the disk are free or available. uint8_t cluster_allocation[128], cluster_available[128]; - io_generic_read(io, &cluster_allocation, 1 * 128, sizeof(cluster_allocation)); - io_generic_read(io, &cluster_available, 2 * 128, sizeof(cluster_available)); + io.read_at(1 * 128, &cluster_allocation, sizeof(cluster_allocation), actual); + io.read_at(2 * 128, &cluster_available, sizeof(cluster_available), actual); for (int cluster = 0; cluster < sizeof(cluster_allocation) * 8; cluster++) { if (cluster * 4 * 128 + 4 * 128 > size) { diff --git a/src/lib/formats/mdos_dsk.h b/src/lib/formats/mdos_dsk.h index 65e7bca9f14..56dd29c9954 100644 --- a/src/lib/formats/mdos_dsk.h +++ b/src/lib/formats/mdos_dsk.h @@ -19,8 +19,8 @@ public: virtual const char *name() const override; virtual const char *description() const override; virtual const char *extensions() const override; - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual int find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual int find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; virtual const wd177x_format::format &get_track_format(const format &f, int head, int track) override; private: diff --git a/src/lib/formats/mfi_dsk.cpp b/src/lib/formats/mfi_dsk.cpp index 7670bf6bfb9..8272253c36a 100644 --- a/src/lib/formats/mfi_dsk.cpp +++ b/src/lib/formats/mfi_dsk.cpp @@ -1,10 +1,12 @@ // license:BSD-3-Clause // copyright-holders:Olivier Galibert -#include <cassert> - #include "mfi_dsk.h" + +#include "ioprocs.h" + #include <zlib.h> + /* Mess floppy image structure: @@ -94,11 +96,12 @@ bool mfi_format::supports_save() const return true; } -int mfi_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int mfi_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { header h; - io_generic_read(io, &h, 0, sizeof(header)); + size_t actual; + io.read_at(0, &h, sizeof(header), actual); if(memcmp( h.sign, sign, 16 ) == 0 && (h.cyl_count & CYLINDER_MASK) <= 84 && (h.cyl_count >> RESOLUTION_SHIFT) < 3 && @@ -108,15 +111,16 @@ int mfi_format::identify(io_generic *io, uint32_t form_factor, const std::vector return 0; } -bool mfi_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool mfi_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { + size_t actual; header h; entry entries[84*2*4]; - io_generic_read(io, &h, 0, sizeof(header)); + io.read_at(0, &h, sizeof(header), actual); int resolution = h.cyl_count >> RESOLUTION_SHIFT; h.cyl_count &= CYLINDER_MASK; - io_generic_read(io, &entries, sizeof(header), (h.cyl_count << resolution)*h.head_count*sizeof(entry)); + io.read_at(sizeof(header), &entries, (h.cyl_count << resolution)*h.head_count*sizeof(entry), actual); image->set_form_variant(h.form_factor, h.variant); @@ -139,7 +143,7 @@ bool mfi_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui compressed.resize(ent->compressed_size); - io_generic_read(io, &compressed[0], ent->offset, ent->compressed_size); + io.read_at(ent->offset, &compressed[0], ent->compressed_size, actual); unsigned int cell_count = ent->uncompressed_size/4; std::vector<uint32_t> &trackbuf = image->get_buffer(cyl >> 2, head, cyl & 3);; @@ -169,8 +173,9 @@ bool mfi_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui return true; } -bool mfi_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool mfi_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { + size_t actual; int tracks, heads; image->get_actual_geometry(tracks, heads); int resolution = image->get_resolution(); @@ -190,7 +195,7 @@ bool mfi_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo h.form_factor = image->get_form_factor(); h.variant = image->get_variant(); - io_generic_write(io, &h, 0, sizeof(header)); + io.write_at(0, &h, sizeof(header), actual); memset(entries, 0, sizeof(entries)); @@ -226,11 +231,11 @@ bool mfi_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo entries[epos].write_splice = image->get_write_splice_position(track >> 2, head, track & 3); epos++; - io_generic_write(io, postcomp.get(), pos, csize); + io.write_at(pos, postcomp.get(), csize, actual); pos += csize; } - io_generic_write(io, entries, sizeof(header), (tracks << resolution)*heads*sizeof(entry)); + io.write_at(sizeof(header), entries, (tracks << resolution)*heads*sizeof(entry), actual); return true; } diff --git a/src/lib/formats/mfi_dsk.h b/src/lib/formats/mfi_dsk.h index 129a9ee599e..d0dd36c3d68 100644 --- a/src/lib/formats/mfi_dsk.h +++ b/src/lib/formats/mfi_dsk.h @@ -12,9 +12,9 @@ class mfi_format : public floppy_image_format_t public: mfi_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/mfm_hd.cpp b/src/lib/formats/mfm_hd.cpp index 98d8079443c..738f0999863 100644 --- a/src/lib/formats/mfm_hd.cpp +++ b/src/lib/formats/mfm_hd.cpp @@ -294,9 +294,9 @@ int mfmhd_generic_format::chs_to_lba(int cylinder, int head, int sector) else return -1; } -chd_error mfmhd_generic_format::load(chd_file* chdfile, uint16_t* trackimage, int tracksize, int cylinder, int head) +std::error_condition mfmhd_generic_format::load(chd_file* chdfile, uint16_t* trackimage, int tracksize, int cylinder, int head) { - chd_error state = CHDERR_NONE; + std::error_condition state; uint8_t sector_content[16384]; int sectorcount = m_param.sectors_per_track; @@ -382,8 +382,9 @@ chd_error mfmhd_generic_format::load(chd_file* chdfile, uint16_t* trackimage, in int lbaposition = chs_to_lba(cylinder, head, sec_number); if (lbaposition>=0) { - chd_error state = chdfile->read_units(lbaposition, sector_content); - if (state != CHDERR_NONE) break; + state = chdfile->read_units(lbaposition, sector_content); + if (state) + break; } else { @@ -413,7 +414,7 @@ chd_error mfmhd_generic_format::load(chd_file* chdfile, uint16_t* trackimage, in if (TRACE_LAYOUT) osd_printf_verbose("\n"); // Gap 4 - if (state == CHDERR_NONE) + if (!state) { // Fill the rest with 0x4e mfm_encode(trackimage, position, 0x4e, tracksize-position); @@ -433,7 +434,7 @@ enum CHECK_CRC }; -chd_error mfmhd_generic_format::save(chd_file* chdfile, uint16_t* trackimage, int tracksize, int current_cylinder, int current_head) +std::error_condition mfmhd_generic_format::save(chd_file* chdfile, uint16_t* trackimage, int tracksize, int current_cylinder, int current_head) { if (TRACE_RWTRACK) osd_printf_verbose("%s: write back (c=%d,h=%d) to CHD\n", tag(), current_cylinder, current_head); @@ -490,7 +491,7 @@ chd_error mfmhd_generic_format::save(chd_file* chdfile, uint16_t* trackimage, in bool countgap3 = false; bool countsync = false; - chd_error chdstate = CHDERR_NONE; + std::error_condition chdstate; if (TRACE_IMAGE) { @@ -643,7 +644,7 @@ chd_error mfmhd_generic_format::save(chd_file* chdfile, uint16_t* trackimage, in if (TRACE_DETAIL) osd_printf_verbose("%s: Writing sector chs=(%d,%d,%d) to CHD\n", tag(), current_cylinder, current_head, sector); chdstate = chdfile->write_units(chs_to_lba(current_cylinder, current_head, sector), buffer); - if (chdstate != CHDERR_NONE) + if (chdstate) { osd_printf_verbose("%s: Write error while writing sector chs=(%d,%d,%d)\n", tag(), cylinder, head, sector); } diff --git a/src/lib/formats/mfm_hd.h b/src/lib/formats/mfm_hd.h index 7d28adc518d..472062d1440 100644 --- a/src/lib/formats/mfm_hd.h +++ b/src/lib/formats/mfm_hd.h @@ -151,10 +151,10 @@ public: virtual ~mfmhd_image_format_t() {}; // Load the image. - virtual chd_error load(chd_file* chdfile, uint16_t* trackimage, int tracksize, int cylinder, int head) = 0; + virtual std::error_condition load(chd_file* chdfile, uint16_t* trackimage, int tracksize, int cylinder, int head) = 0; // Save the image. - virtual chd_error save(chd_file* chdfile, uint16_t* trackimage, int tracksize, int cylinder, int head) = 0; + virtual std::error_condition save(chd_file* chdfile, uint16_t* trackimage, int tracksize, int cylinder, int head) = 0; // Return the original parameters of the image mfmhd_layout_params* get_initial_params() { return &m_param_old; } @@ -196,8 +196,8 @@ class mfmhd_generic_format : public mfmhd_image_format_t { public: mfmhd_generic_format() { m_devtag = std::string("mfmhd_generic_format"); }; - chd_error load(chd_file* chdfile, uint16_t* trackimage, int tracksize, int cylinder, int head) override; - chd_error save(chd_file* chdfile, uint16_t* trackimage, int tracksize, int cylinder, int head) override; + std::error_condition load(chd_file* chdfile, uint16_t* trackimage, int tracksize, int cylinder, int head) override; + std::error_condition save(chd_file* chdfile, uint16_t* trackimage, int tracksize, int cylinder, int head) override; // Yes, we want to save all parameters virtual bool save_param(mfmhd_param_t type) override { return true; } diff --git a/src/lib/formats/nfd_dsk.cpp b/src/lib/formats/nfd_dsk.cpp index 1a0430f9af1..4a51e0db54c 100644 --- a/src/lib/formats/nfd_dsk.cpp +++ b/src/lib/formats/nfd_dsk.cpp @@ -77,10 +77,11 @@ *********************************************************************/ - #include <cassert> - #include "nfd_dsk.h" +#include "ioprocs.h" + + nfd_format::nfd_format() { } @@ -100,10 +101,11 @@ const char *nfd_format::extensions() const return "nfd"; } -int nfd_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int nfd_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { uint8_t h[16]; - io_generic_read(io, h, 0, 16); + size_t actual; + io.read_at(0, h, 16, actual); if (strncmp((const char *)h, "T98FDDIMAGE.R0", 14) == 0 || strncmp((const char *)h, "T98FDDIMAGE.R1", 14) == 0) return 100; @@ -111,11 +113,14 @@ int nfd_format::identify(io_generic *io, uint32_t form_factor, const std::vector return 0; } -bool nfd_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool nfd_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { - uint64_t size = io_generic_size(io); + size_t actual; + uint64_t size; + if (io.length(size)) + return false; uint8_t h[0x120], hsec[0x10]; - io_generic_read(io, h, 0, 0x120); + io.read_at(0, h, 0x120, actual); int format_version = !strncmp((const char *)h, "T98FDDIMAGE.R0", 14) ? 0 : 1; // sector map (the 164th entry is only used by rev.1 format, loops with track < 163 are correct for rev.0) @@ -140,7 +145,7 @@ bool nfd_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui { int curr_track_size = 0; // read sector map absolute location - io_generic_read(io, hsec, pos, 4); + io.read_at(pos, hsec, 4, actual); pos += 4; uint32_t secmap_addr = little_endianize_int32(*(uint32_t *)(hsec)); @@ -149,14 +154,14 @@ bool nfd_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui // read actual sector map for the sectors of this track // for rev.1 format the first 0x10 are a track summary: // first WORD is # of sectors, second WORD is # of special data sectors - io_generic_read(io, hsec, secmap_addr, 0x10); + io.read_at(secmap_addr, hsec, 0x10, actual); secmap_addr += 0x10; num_secs[track] = little_endianize_int16(*(uint16_t *)(hsec)); num_specials[track] = little_endianize_int16(*(uint16_t *)(hsec + 0x2)); for (int sect = 0; sect < num_secs[track]; sect++) { - io_generic_read(io, hsec, secmap_addr, 0x10); + io.read_at(secmap_addr, hsec, 0x10, actual); if (track == 0 && sect == 0) disk_type = hsec[0xb]; // can this change across the disk? I don't think so... @@ -175,7 +180,7 @@ bool nfd_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui { for (int sect = 0; sect < num_specials[track]; sect++) { - io_generic_read(io, hsec, secmap_addr, 0x10); + io.read_at(secmap_addr, hsec, 0x10, actual); secmap_addr += 0x10; curr_track_size += (hsec[9] + 1) * little_endianize_int32(*(uint32_t *)(hsec + 0x0a)); } @@ -198,7 +203,7 @@ bool nfd_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui { // read sector map for this sector // for rev.0 format each sector uses 0x10 bytes - io_generic_read(io, hsec, pos, 0x10); + io.read_at(pos, hsec, 0x10, actual); if (track == 0 && sect == 0) disk_type = hsec[0xa]; // can this change across the disk? I don't think so... @@ -245,7 +250,7 @@ bool nfd_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui for (int track = 0; track < 163 && pos < size; track++) { - io_generic_read(io, sect_data, pos, track_sizes[track]); + io.read_at(pos, sect_data, track_sizes[track], actual); for (int i = 0; i < num_secs[track]; i++) { diff --git a/src/lib/formats/nfd_dsk.h b/src/lib/formats/nfd_dsk.h index 5eb41893c5f..c0030b073a5 100644 --- a/src/lib/formats/nfd_dsk.h +++ b/src/lib/formats/nfd_dsk.h @@ -20,8 +20,8 @@ class nfd_format : public floppy_image_format_t public: nfd_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/opd_dsk.cpp b/src/lib/formats/opd_dsk.cpp index e105d53d678..964b30b75a0 100644 --- a/src/lib/formats/opd_dsk.cpp +++ b/src/lib/formats/opd_dsk.cpp @@ -30,12 +30,13 @@ const char *opd_format::extensions() const return "opd,opu"; } -int opd_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int opd_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - int type = find_size(io, form_factor, variants); + int const type = find_size(io, form_factor, variants); if (type != -1) return 90; + return 0; } diff --git a/src/lib/formats/opd_dsk.h b/src/lib/formats/opd_dsk.h index 9a4205314ec..9236320f154 100644 --- a/src/lib/formats/opd_dsk.h +++ b/src/lib/formats/opd_dsk.h @@ -21,7 +21,7 @@ class opd_format : public wd177x_format public: opd_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; virtual int get_image_offset(const format &f, int head, int track) override; virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/oric_dsk.cpp b/src/lib/formats/oric_dsk.cpp index 22d70124572..f5b0783a112 100644 --- a/src/lib/formats/oric_dsk.cpp +++ b/src/lib/formats/oric_dsk.cpp @@ -8,7 +8,9 @@ *********************************************************************/ -#include "formats/oric_dsk.h" +#include "oric_dsk.h" + +#include "ioprocs.h" const char *oric_dsk_format::name() const @@ -31,10 +33,11 @@ bool oric_dsk_format::supports_save() const return true; } -int oric_dsk_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int oric_dsk_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { uint8_t h[256]; - io_generic_read(io, h, 0, 256); + size_t actual; + io.read_at(0, h, 256, actual); if(memcmp(h, "MFM_DISK", 8)) return 0; @@ -43,27 +46,30 @@ int oric_dsk_format::identify(io_generic *io, uint32_t form_factor, const std::v int tracks = (h[15] << 24) | (h[14] << 16) | (h[13] << 8) | h[12]; int geom = (h[19] << 24) | (h[18] << 16) | (h[17] << 8) | h[16]; - int size = io_generic_size(io); + uint64_t size; + if(io.length(size)) + return 0; if(sides < 0 || sides > 2 || geom != 1 || size != 256+6400*sides*tracks) return 0; return 100; } -bool oric_dsk_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool oric_dsk_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { + size_t actual; uint8_t h[256]; uint8_t t[6250+3]; t[6250] = t[6251] = t[6252] = 0; - io_generic_read(io, h, 0, 256); + io.read_at(0, h, 256, actual); int sides = (h[11] << 24) | (h[10] << 16) | (h[ 9] << 8) | h[ 8]; int tracks = (h[15] << 24) | (h[14] << 16) | (h[13] << 8) | h[12]; for(int side=0; side<sides; side++) for(int track=0; track<tracks; track++) { - io_generic_read(io, t, 256+6400*(tracks*side + track), 6250); + io.read_at(256+6400*(tracks*side + track), t, 6250, actual); std::vector<uint32_t> stream; int sector_size = 128; for(int i=0; i<6250; i++) { @@ -99,8 +105,9 @@ bool oric_dsk_format::load(io_generic *io, uint32_t form_factor, const std::vect return true; } -bool oric_dsk_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool oric_dsk_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { + // FIXME: surely this should return false, since it does't actually save anything? return true; } @@ -127,28 +134,35 @@ bool oric_jasmin_format::supports_save() const return true; } -int oric_jasmin_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int oric_jasmin_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - int size = io_generic_size(io); - bool can_ds = variants.empty() || has_variant(variants, floppy_image::DSDD); + uint64_t size; + if(io.length(size)) + return 0; + + bool const can_ds = variants.empty() || has_variant(variants, floppy_image::DSDD); if(size == 41*17*256 || (can_ds && size == 41*17*256*2)) return 50; return 0; } -bool oric_jasmin_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool oric_jasmin_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { - int size = io_generic_size(io); - bool can_ds = variants.empty() || has_variant(variants, floppy_image::DSDD); + uint64_t size; + if(io.length(size)) + return false; + + bool const can_ds = variants.empty() || has_variant(variants, floppy_image::DSDD); if(size != 41*17*256 && (!can_ds || size != 41*17*256*2)) return false; - int heads = size == 41*17*256 ? 1 : 2; + int const heads = size == 41*17*256 ? 1 : 2; std::vector<uint8_t> data(size); - io_generic_read(io, data.data(), 0, size); + size_t actual; + io.read_at(0, data.data(), size, actual); for(int head = 0; head != heads; head++) for(int track = 0; track != 41; track++) { @@ -173,7 +187,7 @@ bool oric_jasmin_format::load(io_generic *io, uint32_t form_factor, const std::v return true; } -bool oric_jasmin_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool oric_jasmin_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { int tracks, heads; image->get_actual_geometry(tracks, heads); @@ -191,8 +205,9 @@ bool oric_jasmin_format::save(io_generic *io, const std::vector<uint32_t> &varia for(int track = 0; track != 41; track++) { auto sectors = extract_sectors_from_bitstream_mfm_pc(generate_bitstream_from_track(track, head, 2000, image)); for(unsigned int sector = 0; sector != 17; sector ++) { - const uint8_t *data = sector+1 < sectors.size() && !sectors[sector+1].empty() ? sectors[sector+1].data() : zero; - io_generic_write(io, data, 256 * (sector + track*17 + head*17*41), 256); + uint8_t const *const data = (sector+1 < sectors.size() && !sectors[sector+1].empty()) ? sectors[sector+1].data() : zero; + size_t actual; + io.write_at(256 * (sector + track*17 + head*17*41), data, 256, actual); } } return true; diff --git a/src/lib/formats/oric_dsk.h b/src/lib/formats/oric_dsk.h index e42b876e52f..6fd1021384b 100644 --- a/src/lib/formats/oric_dsk.h +++ b/src/lib/formats/oric_dsk.h @@ -18,9 +18,9 @@ class oric_dsk_format : public floppy_image_format_t { public: oric_dsk_format() = default; - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; @@ -35,9 +35,9 @@ class oric_jasmin_format : public floppy_image_format_t public: oric_jasmin_format() = default; - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/os9_dsk.cpp b/src/lib/formats/os9_dsk.cpp index b28e4f8d293..ba1b2427811 100644 --- a/src/lib/formats/os9_dsk.cpp +++ b/src/lib/formats/os9_dsk.cpp @@ -48,6 +48,7 @@ #include "imageutl.h" #include "coretmpl.h" // BIT +#include "ioprocs.h" os9_format::os9_format() : wd177x_format(formats) @@ -69,21 +70,25 @@ const char *os9_format::extensions() const return "dsk,os9"; } -int os9_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int os9_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - int type = find_size(io, form_factor, variants); + int const type = find_size(io, form_factor, variants); if (type != -1) return 75; + return 0; } -int os9_format::find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int os9_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - uint64_t size = io_generic_size(io); + uint64_t size; + if (io.length(size)) + return -1; uint8_t os9_header[0x60]; - io_generic_read(io, os9_header, 0, sizeof(os9_header)); + size_t actual; + io.read_at(0, os9_header, sizeof(os9_header), actual); int os9_total_sectors = pick_integer_be(os9_header, 0x00, 3); int os9_heads = util::BIT(os9_header[0x10], 0) ? 2 : 1; diff --git a/src/lib/formats/os9_dsk.h b/src/lib/formats/os9_dsk.h index 57dfbfc9ab5..124c019d155 100644 --- a/src/lib/formats/os9_dsk.h +++ b/src/lib/formats/os9_dsk.h @@ -21,8 +21,8 @@ public: virtual const char *name() const override; virtual const char *description() const override; virtual const char *extensions() const override; - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual int find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual int find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; virtual const wd177x_format::format &get_track_format(const format &f, int head, int track) override; private: diff --git a/src/lib/formats/pasti_dsk.cpp b/src/lib/formats/pasti_dsk.cpp index 0ab6dc2f064..1a418096cd3 100644 --- a/src/lib/formats/pasti_dsk.cpp +++ b/src/lib/formats/pasti_dsk.cpp @@ -2,6 +2,8 @@ // copyright-holders:Olivier Galibert #include "pasti_dsk.h" +#include "ioprocs.h" + // Pasti format supported using the documentation at // http://www.sarnau.info/atari:pasti_file_format @@ -36,10 +38,11 @@ bool pasti_format::supports_save() const return false; } -int pasti_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int pasti_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { uint8_t h[16]; - io_generic_read(io, h, 0, 16); + size_t actual; + io.read_at(0, h, 16, actual); if(!memcmp(h, "RSY\0\3\0", 6) && (1 || (h[10] >= 80 && h[10] <= 82) || (h[10] >= 160 && h[10] <= 164))) @@ -58,10 +61,11 @@ static void hexdump(const uint8_t *d, int s) } } -bool pasti_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool pasti_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { + size_t actual; uint8_t fh[16]; - io_generic_read(io, fh, 0, 16); + io.read_at(0, fh, 16, actual); std::vector<uint8_t> raw_track; @@ -76,7 +80,7 @@ bool pasti_format::load(io_generic *io, uint32_t form_factor, const std::vector< for(int track=0; track < tracks; track++) { for(int head=0; head < heads; head++) { uint8_t th[16]; - io_generic_read(io, th, pos, 16); + io.read_at(pos, th, 16, actual); int entry_len = th[0] | (th[1] << 8) | (th[2] << 16) | (th[3] << 24); int fuzz_len = th[4] | (th[5] << 8) | (th[6] << 16) | (th[7] << 24); int sect = th[8] | (th[9] << 8); @@ -87,7 +91,7 @@ bool pasti_format::load(io_generic *io, uint32_t form_factor, const std::vector< raw_track.resize(entry_len-16); - io_generic_read(io, &raw_track[0], pos+16, entry_len-16); + io.read_at(pos+16, &raw_track[0], entry_len-16, actual); uint8_t *fuzz = fuzz_len ? &raw_track[16*sect] : nullptr; uint8_t *bdata = fuzz ? fuzz+fuzz_len : &raw_track[16*sect]; diff --git a/src/lib/formats/pasti_dsk.h b/src/lib/formats/pasti_dsk.h index b3fc869da4d..2575c12eeb4 100644 --- a/src/lib/formats/pasti_dsk.h +++ b/src/lib/formats/pasti_dsk.h @@ -12,8 +12,8 @@ class pasti_format : public floppy_image_format_t public: pasti_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/pc98fdi_dsk.cpp b/src/lib/formats/pc98fdi_dsk.cpp index 2d503acebe4..61fb8fb8fe3 100644 --- a/src/lib/formats/pc98fdi_dsk.cpp +++ b/src/lib/formats/pc98fdi_dsk.cpp @@ -8,9 +8,11 @@ *********************************************************************/ -#include <cassert> #include "pc98fdi_dsk.h" +#include "ioprocs.h" + + pc98fdi_format::pc98fdi_format() { } @@ -30,47 +32,53 @@ const char *pc98fdi_format::extensions() const return "fdi"; } -int pc98fdi_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int pc98fdi_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - uint64_t size = io_generic_size(io); - uint8_t h[32]; + uint64_t size; + if(io.length(size)) + return 0; - io_generic_read(io, h, 0, 32); - uint32_t hsize = little_endianize_int32(*(uint32_t *) (h + 0x8)); - uint32_t psize = little_endianize_int32(*(uint32_t *) (h + 0xc)); - uint32_t ssize = little_endianize_int32(*(uint32_t *) (h + 0x10)); - uint32_t scnt = little_endianize_int32(*(uint32_t *) (h + 0x14)); - uint32_t sides = little_endianize_int32(*(uint32_t *) (h + 0x18)); - uint32_t ntrk = little_endianize_int32(*(uint32_t *) (h + 0x1c)); + uint8_t h[32]; + size_t actual; + io.read_at(0, h, 32, actual); + + uint32_t const hsize = little_endianize_int32(*(uint32_t *) (h + 0x8)); + uint32_t const psize = little_endianize_int32(*(uint32_t *) (h + 0xc)); + uint32_t const ssize = little_endianize_int32(*(uint32_t *) (h + 0x10)); + uint32_t const scnt = little_endianize_int32(*(uint32_t *) (h + 0x14)); + uint32_t const sides = little_endianize_int32(*(uint32_t *) (h + 0x18)); + uint32_t const ntrk = little_endianize_int32(*(uint32_t *) (h + 0x1c)); if(size == hsize + psize && psize == ssize*scnt*sides*ntrk) return 100; return 0; } -bool pc98fdi_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool pc98fdi_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { - uint8_t h[32]; + size_t actual; - io_generic_read(io, h, 0, 32); + uint8_t h[32]; + io.read_at(0, h, 32, actual); - uint32_t hsize = little_endianize_int32(*(uint32_t *)(h+0x8)); - uint32_t sector_size = little_endianize_int32(*(uint32_t *)(h+0x10)); - uint32_t sector_count = little_endianize_int32(*(uint32_t *)(h+0x14)); - uint32_t head_count = little_endianize_int32(*(uint32_t *)(h+0x18)); - uint32_t track_count = little_endianize_int32(*(uint32_t *)(h+0x1c)); + uint32_t const hsize = little_endianize_int32(*(uint32_t *)(h+0x8)); + uint32_t const sector_size = little_endianize_int32(*(uint32_t *)(h+0x10)); + uint32_t const sector_count = little_endianize_int32(*(uint32_t *)(h+0x14)); + uint32_t const head_count = little_endianize_int32(*(uint32_t *)(h+0x18)); + uint32_t const track_count = little_endianize_int32(*(uint32_t *)(h+0x1c)); - int cell_count = form_factor == floppy_image::FF_35 ? 200000 : 166666; + int const cell_count = form_factor == floppy_image::FF_35 ? 200000 : 166666; - int ssize; - for(ssize=0; (128 << ssize) < sector_size; ssize++) {}; + int ssize = 0; + while ((128 << ssize) < sector_size) + ssize++; desc_pc_sector sects[256]; uint8_t sect_data[65536]; for(int track=0; track < track_count; track++) for(int head=0; head < head_count; head++) { - io_generic_read(io, sect_data, hsize + sector_size*sector_count*(track*head_count + head), sector_size*sector_count); + io.read_at(hsize + sector_size*sector_count*(track*head_count + head), sect_data, sector_size*sector_count, actual); for(int i=0; i<sector_count; i++) { sects[i].track = track; diff --git a/src/lib/formats/pc98fdi_dsk.h b/src/lib/formats/pc98fdi_dsk.h index 1c60f059cbe..1c539f06094 100644 --- a/src/lib/formats/pc98fdi_dsk.h +++ b/src/lib/formats/pc98fdi_dsk.h @@ -20,8 +20,8 @@ class pc98fdi_format : public floppy_image_format_t public: pc98fdi_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/pc_dsk.cpp b/src/lib/formats/pc_dsk.cpp index c814afbe6dc..6fe2a82196a 100644 --- a/src/lib/formats/pc_dsk.cpp +++ b/src/lib/formats/pc_dsk.cpp @@ -8,10 +8,12 @@ *********************************************************************/ +#include "formats/pc_dsk.h" + +#include "ioprocs.h" + #include <cstring> -#include <cassert> -#include "formats/pc_dsk.h" pc_format::pc_format() : upd765_format(formats) { @@ -32,9 +34,12 @@ const char *pc_format::extensions() const return "dsk,ima,img,ufi,360"; } -int pc_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int pc_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - uint64_t size = io_generic_size(io); + uint64_t size; + if (io.length(size)) { + return 0; + } /* some 360K images have a 512-byte header */ if (size == 368640 + 0x200) { diff --git a/src/lib/formats/pc_dsk.h b/src/lib/formats/pc_dsk.h index d53879611b9..8c99a35457f 100644 --- a/src/lib/formats/pc_dsk.h +++ b/src/lib/formats/pc_dsk.h @@ -20,7 +20,7 @@ class pc_format : public upd765_format public: pc_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/poly_dsk.cpp b/src/lib/formats/poly_dsk.cpp index a865729864e..8845643eb72 100644 --- a/src/lib/formats/poly_dsk.cpp +++ b/src/lib/formats/poly_dsk.cpp @@ -10,6 +10,9 @@ #include "poly_dsk.h" +#include "ioprocs.h" + + poly_cpm_format::poly_cpm_format() { } @@ -34,30 +37,35 @@ bool poly_cpm_format::supports_save() const return true; } -int poly_cpm_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int poly_cpm_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - uint8_t boot[16]; - uint64_t size = io_generic_size(io); + uint64_t size; + if (io.length(size)) + return 0; // check for valid sizes if (size == 630784 || size == 622592 || size == 256256) { // check for Poly CP/M boot sector - io_generic_read(io, boot, 0, 16); + uint8_t boot[16]; + size_t actual; + io.read_at(0, boot, 16, actual); if (memcmp(boot, "\x86\xc3\xb7\x00\x00\x8e\x10\xc0\xbf\x00\x01\xbf\xe0\x60\x00\x00", 16) == 0) { return 100; } } + return 0; } -bool poly_cpm_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool poly_cpm_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { - int total_tracks, spt, bps, head_num; - - uint64_t size = io_generic_size(io); + uint64_t size; + if (io.length(size) || io.seek(0, SEEK_SET)) + return false; + int total_tracks, spt, bps, head_num; switch (size) { case 622592: @@ -83,8 +91,7 @@ bool poly_cpm_format::load(io_generic *io, uint32_t form_factor, const std::vect break; } - int cell_count = (form_factor == floppy_image::FF_525) ? 50000 : 100000; - int offset = 0; + int const cell_count = (form_factor == floppy_image::FF_525) ? 50000 : 100000; for (int track = 0; track < total_tracks; track++) for (int head = 0; head < head_num; head++) @@ -105,8 +112,8 @@ bool poly_cpm_format::load(io_generic *io, uint32_t form_factor, const std::vect sects[i].deleted = false; sects[i].bad_crc = false; sects[i].data = §_data[sdatapos]; - io_generic_read(io, sects[i].data, offset, bps); - offset += bps; + size_t actual; + io.read(sects[i].data, bps, actual); sdatapos += bps; } // gap sizes unverified diff --git a/src/lib/formats/poly_dsk.h b/src/lib/formats/poly_dsk.h index 8fd3c9be4a5..8afb6836302 100644 --- a/src/lib/formats/poly_dsk.h +++ b/src/lib/formats/poly_dsk.h @@ -20,8 +20,8 @@ public: virtual const char *name() const override; virtual const char *description() const override; virtual const char *extensions() const override; - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual bool supports_save() const override; }; diff --git a/src/lib/formats/rx50_dsk.cpp b/src/lib/formats/rx50_dsk.cpp index d0d8f270c56..f81e2fa5b67 100644 --- a/src/lib/formats/rx50_dsk.cpp +++ b/src/lib/formats/rx50_dsk.cpp @@ -29,11 +29,11 @@ FORMAT A: /F:160 on DOS; turn MEDIACHK ON ************************************************************************/ -#include <cassert> - -#include "flopimg.h" #include "formats/rx50_dsk.h" +#include "ioprocs.h" + + // Controller: WD1793 // TRACK LAYOUT IS UNVERIFED. SEE SOURCES: // - 'esq_dsk16' (uses WD 1772) @@ -95,12 +95,17 @@ bool rx50img_format::supports_save() const return true; } -void rx50img_format::find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count) +void rx50img_format::find_size(util::random_read &io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count) { head_count = 1; uint32_t expected_size = 0; - uint64_t size = io_generic_size(io); + uint64_t size; + if (io.length(size)) + { + track_count = head_count = sector_count = 0; + return; + } track_count = 80; sector_count = 10; @@ -124,7 +129,7 @@ void rx50img_format::find_size(io_generic *io, uint8_t &track_count, uint8_t &he track_count = head_count = sector_count = 0; } -int rx50img_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int rx50img_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { uint8_t track_count, head_count, sector_count; find_size(io, track_count, head_count, sector_count); @@ -135,7 +140,7 @@ int rx50img_format::identify(io_generic *io, uint32_t form_factor, const std::ve } // /* Sectors are numbered 1 to 10 */ -bool rx50img_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool rx50img_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { uint8_t track_count, head_count, sector_count; find_size(io, track_count, head_count, sector_count); @@ -153,7 +158,8 @@ bool rx50img_format::load(io_generic *io, uint32_t form_factor, const std::vecto int track_size = sector_count*512; for(int track=0; track < track_count; track++) { for(int head=0; head < head_count; head++) { - io_generic_read(io, sectdata, (track*head_count + head)*track_size, track_size); + size_t actual; + io.read_at((track*head_count + head)*track_size, sectdata, track_size, actual); generate_track(rx50_10_desc, track, head, sectors, sector_count, 102064, image); // 98480 } } @@ -163,7 +169,7 @@ bool rx50img_format::load(io_generic *io, uint32_t form_factor, const std::vecto return true; } -bool rx50img_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool rx50img_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { int track_count, head_count, sector_count; get_geometry_mfm_pc(image, 2000, track_count, head_count, sector_count); @@ -199,7 +205,8 @@ bool rx50img_format::save(io_generic *io, const std::vector<uint32_t> &variants, for(int track=0; track < track_count; track++) { for(int head=0; head < head_count; head++) { get_track_data_mfm_pc(track, head, image, 2000, 512, sector_count, sectdata); - io_generic_write(io, sectdata, (track*head_count + head)*track_size, track_size); + size_t actual; + io.write_at((track*head_count + head)*track_size, sectdata, track_size, actual); } } return true; diff --git a/src/lib/formats/rx50_dsk.h b/src/lib/formats/rx50_dsk.h index 9cac83bd67f..d28ea398d30 100644 --- a/src/lib/formats/rx50_dsk.h +++ b/src/lib/formats/rx50_dsk.h @@ -23,9 +23,9 @@ class rx50img_format : public floppy_image_format_t public: rx50img_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; @@ -35,7 +35,7 @@ public: static const desc_e rx50_10_desc[]; private: - void find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count); + void find_size(util::random_read &io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count); }; extern const floppy_format_type FLOPPY_RX50IMG_FORMAT; diff --git a/src/lib/formats/sdd_dsk.cpp b/src/lib/formats/sdd_dsk.cpp index cac33948db0..f3e8df51bda 100644 --- a/src/lib/formats/sdd_dsk.cpp +++ b/src/lib/formats/sdd_dsk.cpp @@ -8,10 +8,11 @@ *********************************************************************/ -#include <cassert> - #include "formats/sdd_dsk.h" +#include "ioprocs.h" + + sdd_format::sdd_format() : wd177x_format(formats) { } diff --git a/src/lib/formats/sdf_dsk.cpp b/src/lib/formats/sdf_dsk.cpp index 223b6dc8d8a..f57540f3c35 100644 --- a/src/lib/formats/sdf_dsk.cpp +++ b/src/lib/formats/sdf_dsk.cpp @@ -12,7 +12,9 @@ *********************************************************************/ #include "sdf_dsk.h" -#include <cassert> + +#include "ioprocs.h" + sdf_format::sdf_format() { @@ -37,18 +39,18 @@ const char *sdf_format::extensions() const } -int sdf_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int sdf_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { uint8_t header[HEADER_SIZE]; - uint64_t size = io_generic_size(io); - - if (size < HEADER_SIZE) + uint64_t size; + if (io.length(size) || (size < HEADER_SIZE)) { return 0; } - io_generic_read(io, header, 0, HEADER_SIZE); + size_t actual; + io.read_at(0, header, HEADER_SIZE, actual); int tracks = header[4]; int heads = header[5]; @@ -74,13 +76,14 @@ int sdf_format::identify(io_generic *io, uint32_t form_factor, const std::vector } -bool sdf_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool sdf_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { + size_t actual; uint8_t header[HEADER_SIZE]; std::vector<uint8_t> track_data(TOTAL_TRACK_SIZE); std::vector<uint32_t> raw_track_data; - io_generic_read(io, header, 0, HEADER_SIZE); + io.read_at(0, header, HEADER_SIZE, actual); const int tracks = header[4]; const int heads = header[5]; @@ -104,7 +107,7 @@ bool sdf_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui raw_track_data.clear(); // Read track - io_generic_read(io, &track_data[0], HEADER_SIZE + ( heads * track + head ) * TOTAL_TRACK_SIZE, TOTAL_TRACK_SIZE); + io.read_at(HEADER_SIZE + (heads * track + head) * TOTAL_TRACK_SIZE, &track_data[0], TOTAL_TRACK_SIZE, actual); int sector_count = track_data[0]; @@ -181,7 +184,7 @@ bool sdf_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui } -bool sdf_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool sdf_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { return false; } diff --git a/src/lib/formats/sdf_dsk.h b/src/lib/formats/sdf_dsk.h index fe3f6eb7a98..b86692f618a 100644 --- a/src/lib/formats/sdf_dsk.h +++ b/src/lib/formats/sdf_dsk.h @@ -22,9 +22,9 @@ class sdf_format : public floppy_image_format_t public: sdf_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/st_dsk.cpp b/src/lib/formats/st_dsk.cpp index cb363cbe3e3..d044bc5bdac 100644 --- a/src/lib/formats/st_dsk.cpp +++ b/src/lib/formats/st_dsk.cpp @@ -8,10 +8,11 @@ *********************************************************************/ -#include <cassert> - #include "formats/st_dsk.h" +#include "ioprocs.h" + + st_format::st_format() { } @@ -36,18 +37,20 @@ bool st_format::supports_save() const return true; } -void st_format::find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count) +void st_format::find_size(util::random_read &io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count) { - uint64_t size = io_generic_size(io); - for(track_count=80; track_count <= 82; track_count++) - for(head_count=1; head_count <= 2; head_count++) - for(sector_count=9; sector_count <= 11; sector_count++) - if(size == (uint32_t)512*track_count*head_count*sector_count) - return; + uint64_t size; + if(!io.length(size)) { + for(track_count=80; track_count <= 82; track_count++) + for(head_count=1; head_count <= 2; head_count++) + for(sector_count=9; sector_count <= 11; sector_count++) + if(size == (uint32_t)512*track_count*head_count*sector_count) + return; + } track_count = head_count = sector_count = 0; } -int st_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int st_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { uint8_t track_count, head_count, sector_count; find_size(io, track_count, head_count, sector_count); @@ -57,7 +60,7 @@ int st_format::identify(io_generic *io, uint32_t form_factor, const std::vector< return 0; } -bool st_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool st_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { uint8_t track_count, head_count, sector_count; find_size(io, track_count, head_count, sector_count); @@ -73,7 +76,8 @@ bool st_format::load(io_generic *io, uint32_t form_factor, const std::vector<uin int track_size = sector_count*512; for(int track=0; track < track_count; track++) { for(int head=0; head < head_count; head++) { - io_generic_read(io, sectdata, (track*head_count + head)*track_size, track_size); + size_t actual; + io.read_at((track*head_count + head)*track_size, sectdata, track_size, actual); generate_track(atari_st_fcp_get_desc(track, head, head_count, sector_count), track, head, sectors, sector_count, 100000, image); } @@ -84,7 +88,7 @@ bool st_format::load(io_generic *io, uint32_t form_factor, const std::vector<uin return true; } -bool st_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool st_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { int track_count, head_count, sector_count; get_geometry_mfm_pc(image, 2000, track_count, head_count, sector_count); @@ -109,7 +113,8 @@ bool st_format::save(io_generic *io, const std::vector<uint32_t> &variants, flop for(int track=0; track < track_count; track++) { for(int head=0; head < head_count; head++) { get_track_data_mfm_pc(track, head, image, 2000, 512, sector_count, sectdata); - io_generic_write(io, sectdata, (track*head_count + head)*track_size, track_size); + size_t actual; + io.write_at((track*head_count + head)*track_size, sectdata, track_size, actual); } } @@ -141,10 +146,11 @@ bool msa_format::supports_save() const return true; } -void msa_format::read_header(io_generic *io, uint16_t &sign, uint16_t §, uint16_t &head, uint16_t &strack, uint16_t &etrack) +void msa_format::read_header(util::random_read &io, uint16_t &sign, uint16_t §, uint16_t &head, uint16_t &strack, uint16_t &etrack) { uint8_t h[10]; - io_generic_read(io, h, 0, 10); + size_t actual; + io.read_at(0, h, 10, actual); sign = (h[0] << 8) | h[1]; sect = (h[2] << 8) | h[3]; head = (h[4] << 8) | h[5]; @@ -206,7 +212,7 @@ bool msa_format::compress(const uint8_t *buffer, int usize, uint8_t *dest, int & return dst < usize; } -int msa_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int msa_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { uint16_t sign, sect, head, strack, etrack; read_header(io, sign, sect, head, strack, etrack); @@ -220,7 +226,7 @@ int msa_format::identify(io_generic *io, uint32_t form_factor, const std::vector return 0; } -bool msa_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool msa_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { uint16_t sign, sect, heads, strack, etrack; read_header(io, sign, sect, heads, strack, etrack); @@ -238,11 +244,12 @@ bool msa_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui for(int track=strack; track <= etrack; track++) { for(int head=0; head <= heads; head++) { + size_t actual; uint8_t th[2]; - io_generic_read(io, th, pos, 2); + io.read_at(pos, th, 2, actual); pos += 2; int tsize = (th[0] << 8) | th[1]; - io_generic_read(io, sectdata, pos, tsize); + io.read_at(pos, sectdata, tsize, actual); pos += tsize; if(tsize < track_size) { if(!uncompress(sectdata, tsize, track_size)) @@ -258,7 +265,7 @@ bool msa_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui } -bool msa_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool msa_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { int track_count, head_count, sector_count; get_geometry_mfm_pc(image, 2000, track_count, head_count, sector_count); @@ -289,9 +296,10 @@ bool msa_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo header[8] = 0; header[9] = track_count-1; - io_generic_write(io, header, 0, 10); - - int pos = 10; + if(io.seek(0, SEEK_SET)) + return false; + size_t actual; + io.write(header, 10, actual); uint8_t sectdata[11*512]; uint8_t compdata[11*512]; @@ -305,16 +313,14 @@ bool msa_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo uint8_t th[2]; th[0] = csize >> 8; th[1] = csize; - io_generic_write(io, th, pos, 2); - io_generic_write(io, compdata, pos+2, csize); - pos += 2+csize; + io.write(th, 2, actual); + io.write(compdata, csize, actual); } else { uint8_t th[2]; th[0] = track_size >> 8; th[1] = track_size; - io_generic_write(io, th, pos, 2); - io_generic_write(io, sectdata, pos+2, track_size); - pos += 2+track_size; + io.write(th, 2, actual); + io.write(sectdata, track_size, actual); } } } diff --git a/src/lib/formats/st_dsk.h b/src/lib/formats/st_dsk.h index ce501a9f516..34f303bb1ae 100644 --- a/src/lib/formats/st_dsk.h +++ b/src/lib/formats/st_dsk.h @@ -19,9 +19,9 @@ class st_format : public floppy_image_format_t public: st_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; @@ -29,7 +29,7 @@ public: virtual bool supports_save() const override; private: - void find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count); + void find_size(util::random_read &io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count); }; class msa_format : public floppy_image_format_t @@ -37,9 +37,9 @@ class msa_format : public floppy_image_format_t public: msa_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; @@ -49,7 +49,7 @@ public: private: bool uncompress(uint8_t *buffer, int csize, int usize); bool compress(const uint8_t *src, int usize, uint8_t *dest, int &csize); - void read_header(io_generic *io, uint16_t &sign, uint16_t §, uint16_t &head, uint16_t &strack, uint16_t &etrack); + void read_header(util::random_read &io, uint16_t &sign, uint16_t §, uint16_t &head, uint16_t &strack, uint16_t &etrack); }; extern const floppy_format_type FLOPPY_ST_FORMAT; diff --git a/src/lib/formats/svi_dsk.cpp b/src/lib/formats/svi_dsk.cpp index e3cfa294fcb..0a05bd15c80 100644 --- a/src/lib/formats/svi_dsk.cpp +++ b/src/lib/formats/svi_dsk.cpp @@ -10,6 +10,9 @@ #include "svi_dsk.h" +#include "ioprocs.h" + + svi_format::svi_format() { } @@ -29,9 +32,11 @@ const char *svi_format::extensions() const return "dsk"; } -int svi_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int svi_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - uint64_t size = io_generic_size(io); + uint64_t size; + if (io.length(size)) + return 0; if (size == 172032 || size == 346112) return 50; @@ -39,11 +44,13 @@ int svi_format::identify(io_generic *io, uint32_t form_factor, const std::vector return 0; } -bool svi_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool svi_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { - uint64_t size = io_generic_size(io); - int head_count; + uint64_t size; + if (io.length(size)) + return false; + int head_count; switch (size) { case 172032: head_count = 1; break; @@ -51,7 +58,8 @@ bool svi_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui default: return false; } - int file_offset = 0; + if (io.seek(0, SEEK_SET)) + return false; for (int track = 0; track < 40; track++) { @@ -75,10 +83,10 @@ bool svi_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui sectors[i].bad_crc = false; sectors[i].data = §or_data[sector_offset]; - io_generic_read(io, sectors[i].data, file_offset, sector_size); + size_t actual; + io.read(sectors[i].data, sector_size, actual); sector_offset += sector_size; - file_offset += sector_size; } if (track == 0 && head == 0) @@ -91,9 +99,10 @@ bool svi_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui return true; } -bool svi_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool svi_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { - uint64_t file_offset = 0; + if (io.seek(0, SEEK_SET)) + return false; int track_count, head_count; image->get_actual_geometry(track_count, head_count); @@ -104,8 +113,8 @@ bool svi_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo for (int i = 0; i < 18; i++) { - io_generic_write(io, sectors[i + 1].data(), file_offset, 128); - file_offset += 128; + size_t actual; + io.write(sectors[i + 1].data(), 128, actual); } // rest are mfm tracks @@ -121,8 +130,8 @@ bool svi_format::save(io_generic *io, const std::vector<uint32_t> &variants, flo for (int i = 0; i < 17; i++) { - io_generic_write(io, sectors[i + 1].data(), file_offset, 256); - file_offset += 256; + size_t actual; + io.write(sectors[i + 1].data(), 256, actual); } } } diff --git a/src/lib/formats/svi_dsk.h b/src/lib/formats/svi_dsk.h index 57f4f89ccca..a631bdf498c 100644 --- a/src/lib/formats/svi_dsk.h +++ b/src/lib/formats/svi_dsk.h @@ -23,9 +23,9 @@ public: virtual const char *description() const override; virtual const char *extensions() const override; - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual bool supports_save() const override; }; diff --git a/src/lib/formats/td0_dsk.cpp b/src/lib/formats/td0_dsk.cpp index edac0aae010..345a242c86b 100644 --- a/src/lib/formats/td0_dsk.cpp +++ b/src/lib/formats/td0_dsk.cpp @@ -16,9 +16,11 @@ #include "flopimg.h" -#include <cassert> +#include "ioprocs.h" + #include <cstring> + #define BUFSZ 512 // new input buffer /* LZSS Parameters */ @@ -59,7 +61,16 @@ struct tdlzhuf { struct td0dsk_t { - io_generic *floppy_file; +public: + td0dsk_t(util::random_read &f) : floppy_file(f) { } + + void set_floppy_file_offset(uint64_t o) { floppy_file_offset = o; } + + void init_Decode(); + int Decode(uint8_t *buf, int len); + +private: + util::random_read &floppy_file; uint64_t floppy_file_offset; struct tdlzhuf tdctl; @@ -87,29 +98,10 @@ struct td0dsk_t void update(int c); int16_t DecodeChar(); int16_t DecodePosition(); - void init_Decode(); - int Decode(uint8_t *buf, int len); }; //static td0dsk_t td0dsk; -struct floppy_image_legacy -{ - struct io_generic io; - - const struct FloppyFormat *floppy_option; - struct FloppyCallbacks format; - - /* loaded track stuff */ - int loaded_track_head; - int loaded_track_index; - uint32_t loaded_track_size; - void *loaded_track_data; - uint8_t loaded_track_status; - uint8_t flags; -}; - - static struct td0dsk_tag *get_tag(floppy_image_legacy *floppy) { struct td0dsk_tag *tag; @@ -332,11 +324,13 @@ static floperr_t td0_get_indexed_sector_info(floppy_image_legacy *floppy, int he int td0dsk_t::data_read(uint8_t *buf, uint16_t size) { - uint64_t image_size = io_generic_size(floppy_file); + uint64_t image_size = 0; + floppy_file.length(image_size); if (size > image_size - floppy_file_offset) { size = image_size - floppy_file_offset; } - io_generic_read(floppy_file,buf,floppy_file_offset,size); + size_t actual; + floppy_file.read_at(floppy_file_offset, buf, size, actual); floppy_file_offset += size; return size; } @@ -675,7 +669,6 @@ int td0dsk_t::Decode(uint8_t *buf, int len) /* Decoding/Uncompressing */ FLOPPY_CONSTRUCT( td0_dsk_construct ) { - td0dsk_t state; struct FloppyCallbacks *callbacks; struct td0dsk_tag *tag; uint8_t *header; @@ -706,9 +699,9 @@ FLOPPY_CONSTRUCT( td0_dsk_construct ) int rd; int off = 12; int size = 0; - state.floppy_file = &(floppy->io); + td0dsk_t state(floppy_get_io(floppy)); state.init_Decode(); - state.floppy_file_offset = 12; + state.set_floppy_file_offset(12); do { if((rd = state.Decode(obuf, BUFSZ)) > 0) size += rd; @@ -720,7 +713,7 @@ FLOPPY_CONSTRUCT( td0_dsk_construct ) return FLOPPY_ERROR_OUTOFMEMORY; } memcpy(tag->data,obuf,12); - state.floppy_file_offset = 12; + state.set_floppy_file_offset(12); state.init_Decode(); do { @@ -815,20 +808,22 @@ const char *td0_format::extensions() const return "td0"; } -int td0_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int td0_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { + size_t actual; uint8_t h[7]; - io_generic_read(io, h, 0, 7); + io.read_at(0, h, 7, actual); if(((h[0] == 'T') && (h[1] == 'D')) || ((h[0] == 't') && (h[1] == 'd'))) { - return 100; + return 100; } return 0; } -bool td0_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool td0_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { + size_t actual; int track_count = 0; int head_count = 0; int track_spt; @@ -837,20 +832,24 @@ bool td0_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui std::vector<uint8_t> imagebuf(max_size); uint8_t header[12]; - io_generic_read(io, header, 0, 12); + io.read_at(0, header, 12, actual); head_count = header[9]; if(header[0] == 't') { - td0dsk_t disk_decode; + td0dsk_t disk_decode(io); - disk_decode.floppy_file = io; disk_decode.init_Decode(); - disk_decode.floppy_file_offset = 12; + disk_decode.set_floppy_file_offset(12); disk_decode.Decode(&imagebuf[0], max_size); } else - io_generic_read(io, &imagebuf[0], 12, io_generic_size(io)); + { + uint64_t image_size; + if(io.length(image_size)) + return false; + io.read_at(12, &imagebuf[0], image_size, actual); + } if(header[7] & 0x80) offset = 10 + imagebuf[2] + (imagebuf[3] << 8); @@ -1024,7 +1023,7 @@ bool td0_format::load(io_generic *io, uint32_t form_factor, const std::vector<ui } -bool td0_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool td0_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { return false; } diff --git a/src/lib/formats/td0_dsk.h b/src/lib/formats/td0_dsk.h index b4656305920..cf625374130 100644 --- a/src/lib/formats/td0_dsk.h +++ b/src/lib/formats/td0_dsk.h @@ -13,9 +13,9 @@ class td0_format : public floppy_image_format_t public: td0_format(); - virtual int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; - virtual bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - virtual bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; virtual const char *name() const override; virtual const char *description() const override; diff --git a/src/lib/formats/ti99_dsk.cpp b/src/lib/formats/ti99_dsk.cpp index 06ce98dfda0..507d7dc0ae0 100644 --- a/src/lib/formats/ti99_dsk.cpp +++ b/src/lib/formats/ti99_dsk.cpp @@ -43,6 +43,8 @@ #include "ti99_dsk.h" #include "imageutl.h" +#include "ioprocs.h" + #include "osdcore.h" // osd_printf_* (in osdcore.h) #include <cstring> @@ -80,13 +82,16 @@ int ti99_floppy_format::get_encoding(int cell_size) /* Load the image from disk and convert it into a sequence of flux levels. */ -bool ti99_floppy_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool ti99_floppy_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { + uint64_t file_size; + if (io.length(file_size)) + return false; + int cell_size = 0; int sector_count = 0; int heads = 0; int log_track_count = 0; - int file_size = io_generic_size(io); bool img_high_tpi = false; bool drive_high_tpi = false; @@ -211,7 +216,7 @@ bool ti99_floppy_format::load(io_generic *io, uint32_t form_factor, const std::v /* Save all tracks to the image file. */ -bool ti99_floppy_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +bool ti99_floppy_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) { uint8_t sectordata[9216]; // max size (36*256) @@ -916,9 +921,12 @@ const char *ti99_sdf_format::extensions() const return "dsk"; } -int ti99_sdf_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int ti99_sdf_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { - uint64_t file_size = io_generic_size(io); + uint64_t file_size; + if (io.length(file_size)) + return 0; + int vote = 0; // Adding support for another sector image format which adds 768 bytes @@ -947,7 +955,8 @@ int ti99_sdf_format::identify(io_generic *io, uint32_t form_factor, const std::v { // Read first sector (Volume Information Block) ti99vib vib; - io_generic_read(io, &vib, 0, sizeof(ti99vib)); + size_t actual; + io.read_at(0, &vib, sizeof(ti99vib), actual); // Check from contents if ((vib.id[0]=='D')&&(vib.id[1]=='S')&&(vib.id[2]=='K')) @@ -964,10 +973,14 @@ int ti99_sdf_format::identify(io_generic *io, uint32_t form_factor, const std::v return vote; } -void ti99_sdf_format::determine_sizes(io_generic *io, int& cell_size, int& sector_count, int& heads, int& tracks) +void ti99_sdf_format::determine_sizes(util::random_read &io, int& cell_size, int& sector_count, int& heads, int& tracks) { - uint64_t file_size = io_generic_size(io); - ti99vib vib; + uint64_t file_size; + if (io.length(file_size)) + { + cell_size = sector_count = heads = tracks = 0; + return; + } cell_size = 0; sector_count = 0; @@ -980,7 +993,9 @@ void ti99_sdf_format::determine_sizes(io_generic *io, int& cell_size, int& secto file_size -= 768; // Read first sector - io_generic_read(io, &vib, 0, sizeof(ti99vib)); + ti99vib vib; + size_t actual; + io.read_at(0, &vib, sizeof(ti99vib), actual); // Check from contents if ((vib.id[0]=='D')&&(vib.id[1]=='S')&&(vib.id[2]=='K')) @@ -1059,13 +1074,14 @@ int ti99_sdf_format::get_track_size(int sector_count) return sector_count * SECTOR_SIZE; } -void ti99_sdf_format::load_track(io_generic *io, uint8_t *sectordata, int *sector, int *secoffset, int head, int track, int sectorcount, int trackcount) +void ti99_sdf_format::load_track(util::random_read &io, uint8_t *sectordata, int *sector, int *secoffset, int head, int track, int sectorcount, int trackcount) { // Calculate the track offset from the beginning of the image file int logicaltrack = (head==0)? track : (2*trackcount - track - 1); int position = logicaltrack * get_track_size(sectorcount); - io_generic_read(io, sectordata, position, sectorcount*SECTOR_SIZE); + size_t actual; + io.read_at(position, sectordata, sectorcount*SECTOR_SIZE, actual); // Interleave and skew int interleave = 7; @@ -1133,19 +1149,18 @@ std::string ti99_floppy_format::dumpline(uint8_t* line, int address) const Write the data to the disk. We have a list of sector positions, so we just need to go through that list and save each sector in the sector data. */ -void ti99_sdf_format::write_track(io_generic *io, uint8_t *sectordata, int *sector, int track, int head, int sector_count, int track_count) +void ti99_sdf_format::write_track(util::random_read_write &io, uint8_t *sectordata, int *sector, int track, int head, int sector_count, int track_count) { - uint8_t* buf; - int logicaltrack = head * track_count; logicaltrack += ((head&1)==0)? track : (track_count - 1 - track); int trackoffset = logicaltrack * sector_count * SECTOR_SIZE; for (int i=0; i < sector_count; i++) { - buf = sectordata + i * SECTOR_SIZE; + uint8_t const *const buf = sectordata + i * SECTOR_SIZE; LOGMASKED(LOG_DETAIL, "[ti99_dsk] Writing sector %d (offset %06x)\n", sector[i], sector[i] * SECTOR_SIZE); - io_generic_write(io, buf, trackoffset + sector[i] * SECTOR_SIZE, SECTOR_SIZE); + size_t actual; + io.write_at(trackoffset + sector[i] * SECTOR_SIZE, buf, SECTOR_SIZE, actual); } } @@ -1209,7 +1224,7 @@ const char *ti99_tdf_format::extensions() const /* Determine whether the image file can be interpreted as a track dump */ -int ti99_tdf_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int ti99_tdf_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { int vote = 0; uint8_t fulltrack[6872]; @@ -1232,7 +1247,8 @@ int ti99_tdf_format::identify(io_generic *io, uint32_t form_factor, const std::v LOGMASKED(LOG_INFO, "[ti99_dsk] Image file length matches TDF\n"); // Fetch track 0 - io_generic_read(io, fulltrack, 0, get_track_size(sector_count)); + size_t actual; + io.read_at(0, fulltrack, get_track_size(sector_count), actual); if (sector_count == 9) { @@ -1279,9 +1295,14 @@ int ti99_tdf_format::identify(io_generic *io, uint32_t form_factor, const std::v Find the proper format for a given image file. Tracks are counted per side. Note that only two formats are actually compatible with the PC99 emulator. */ -void ti99_tdf_format::determine_sizes(io_generic *io, int& cell_size, int& sector_count, int& heads, int& tracks) +void ti99_tdf_format::determine_sizes(util::random_read &io, int& cell_size, int& sector_count, int& heads, int& tracks) { - uint64_t file_size = io_generic_size(io); + uint64_t file_size; + if (io.length(file_size)) + { + cell_size = sector_count = heads = tracks = 0; + return; + } // LOGMASKED(LOG_INFO, "[ti99_dsk] Image size = %ld\n", file_size); // doesn't compile switch (file_size) @@ -1336,13 +1357,14 @@ void ti99_tdf_format::determine_sizes(io_generic *io, int& cell_size, int& secto track from scratch. TDF is not as flexible as it suggests, it does not allow different gap lengths and so on. */ -void ti99_tdf_format::load_track(io_generic *io, uint8_t *sectordata, int *sector, int *secoffset, int head, int track, int sectorcount, int trackcount) +void ti99_tdf_format::load_track(util::random_read &io, uint8_t *sectordata, int *sector, int *secoffset, int head, int track, int sectorcount, int trackcount) { + size_t actual; uint8_t fulltrack[12544]; // space for a full TDF track // Read beginning of track 0. We need this to get the first gap, according // to the format - io_generic_read(io, fulltrack, 0, 100); + io.read_at(0, fulltrack, 100, actual); int offset = 0; int tracksize = get_track_size(sectorcount); @@ -1383,7 +1405,7 @@ void ti99_tdf_format::load_track(io_generic *io, uint8_t *sectordata, int *secto int base = (head * trackcount + track) * tracksize; int position = 0; - io_generic_read(io, fulltrack, base, tracksize); + io.read_at(base, fulltrack, tracksize, actual); for (int i=0; i < sectorcount; i++) { @@ -1431,7 +1453,7 @@ void ti99_tdf_format::load_track(io_generic *io, uint8_t *sectordata, int *secto need the sector contents and the sector sequence, which are passed via sectordata, sector, and sector_count. */ -void ti99_tdf_format::write_track(io_generic *io, uint8_t *sectordata, int *sector, int track, int head, int sector_count, int track_count) +void ti99_tdf_format::write_track(util::random_read_write &io, uint8_t *sectordata, int *sector, int track, int head, int sector_count, int track_count) { uint8_t trackdata[12544]; int offset = ((track_count * head) + track) * get_track_size(sector_count); @@ -1485,7 +1507,8 @@ void ti99_tdf_format::write_track(io_generic *io, uint8_t *sectordata, int *sect for (int i=0; i < param[WGAP3]; i++) trackdata[pos++] = param[WGAPBYTE]; } for (int i=0; i < param[WGAP4]; i++) trackdata[pos++] = param[WGAPBYTE]; - io_generic_write(io, trackdata, offset, get_track_size(sector_count)); + size_t actual; + io.write_at(offset, trackdata, get_track_size(sector_count), actual); } int ti99_tdf_format::get_track_size(int sector_count) diff --git a/src/lib/formats/ti99_dsk.h b/src/lib/formats/ti99_dsk.h index 5b59b164344..6590d1e7dd2 100644 --- a/src/lib/formats/ti99_dsk.h +++ b/src/lib/formats/ti99_dsk.h @@ -23,8 +23,8 @@ class ti99_floppy_format : public floppy_image_format_t { public: bool supports_save() const override { return true; } - bool load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; - bool save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) override; + bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override; + bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) override; protected: uint8_t get_data_from_encoding(uint16_t raw); @@ -32,10 +32,10 @@ protected: virtual int min_heads() =0; - virtual void determine_sizes(io_generic *io, int& cell_size, int& sector_count, int& heads, int& tracks) =0; + virtual void determine_sizes(util::random_read &io, int& cell_size, int& sector_count, int& heads, int& tracks) =0; virtual int get_track_size(int sector_count) =0; - virtual void load_track(io_generic *io, uint8_t *sectordata, int *sector, int *secoffset, int head, int track, int sectorcount, int trackcount) =0; - virtual void write_track(io_generic *io, uint8_t *sectordata, int *sector, int track, int head, int sector_count, int track_count) =0; + virtual void load_track(util::random_read &io, uint8_t *sectordata, int *sector, int *secoffset, int head, int track, int sectorcount, int trackcount) =0; + virtual void write_track(util::random_read_write &io, uint8_t *sectordata, int *sector, int track, int head, int sector_count, int track_count) =0; int get_encoding(int cell_size); @@ -53,16 +53,16 @@ protected: class ti99_sdf_format : public ti99_floppy_format { public: - int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; const char *name() const override; const char *description() const override; const char *extensions() const override; private: - void determine_sizes(io_generic *io, int& cell_size, int& sector_count, int& heads, int& tracks) override; + void determine_sizes(util::random_read &io, int& cell_size, int& sector_count, int& heads, int& tracks) override; int get_track_size(int sector_count) override; - void write_track(io_generic *io, uint8_t *sectordata, int *sector, int track, int head, int sector_count, int track_count) override; - void load_track(io_generic *io, uint8_t *sectordata, int *sector, int *secoffset, int head, int track, int sector_count, int track_count) override; + void write_track(util::random_read_write &io, uint8_t *sectordata, int *sector, int track, int head, int sector_count, int track_count) override; + void load_track(util::random_read &io, uint8_t *sectordata, int *sector, int *secoffset, int head, int track, int sector_count, int track_count) override; // This format supports single-sided images int min_heads() override { return 1; } @@ -92,15 +92,15 @@ extern const floppy_format_type FLOPPY_TI99_SDF_FORMAT; class ti99_tdf_format : public ti99_floppy_format { public: - int identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; + int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override; const char *name() const override; const char *description() const override; const char *extensions() const override; private: - void determine_sizes(io_generic *io, int& cell_size, int& sector_count, int& heads, int& tracks) override; - void load_track(io_generic *io, uint8_t *sectordata, int *sector, int *secoffset, int head, int track, int sectorcount, int trackcount) override; - void write_track(io_generic *io, uint8_t *sectordata, int *sector, int track, int head, int sector_count, int track_count) override; + void determine_sizes(util::random_read &io, int& cell_size, int& sector_count, int& heads, int& tracks) override; + void load_track(util::random_read &io, uint8_t *sectordata, int *sector, int *secoffset, int head, int track, int sectorcount, int trackcount) override; + void write_track(util::random_read_write &io, uint8_t *sectordata, int *sector, int track, int head, int sector_count, int track_count) override; int get_track_size(int sector_count) override; // This format only supports double-sided images diff --git a/src/lib/formats/trd_dsk.cpp b/src/lib/formats/trd_dsk.cpp index 26b6ce5b6a5..4236259cca5 100644 --- a/src/lib/formats/trd_dsk.cpp +++ b/src/lib/formats/trd_dsk.cpp @@ -8,10 +8,11 @@ *********************************************************************/ -#include <cassert> - #include "formats/trd_dsk.h" +#include "ioprocs.h" + + trd_format::trd_format() : wd177x_format(formats) { } @@ -31,10 +32,13 @@ const char *trd_format::extensions() const return "trd"; } -int trd_format::find_size(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int trd_format::find_size(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) { + uint64_t size; + if (io.length(size)) + return -1; + int index = -1; - uint64_t size = io_generic_size(io); for (int i = 0; formats[i].form_factor; i++) { const format &f = formats[i]; @@ -47,12 +51,13 @@ int trd_format::find_size(io_generic *io, uint32_t form_factor, const std::vecto { index = i; // at least size match, save it for the case if there will be no exact matches + size_t actual; uint8_t sectdata[0x100]; if (f.encoding == floppy_image::MFM) - io_generic_read(io, sectdata, 0x800, 0x100); + io.read_at(0x800, sectdata, 0x100, actual); else { - io_generic_read(io, sectdata, 0x100, 0x100); + io.read_at(0x100, sectdata, 0x100, actual); for (int i = 0; i < 0x100; i++) sectdata[i] ^= 0xff; } diff --git a/src/lib/formats/trd_dsk.h b/src/lib/formats/trd_dsk.h index 6f19f9976a5..c5a411c60bb 100644 --- a/src/lib/formats/trd_dsk.h +++ b/src/lib/formats/trd_dsk.h @@ -24,7 +24,7 @@ public: private: static const form |